const maptaskrEntityDefinition = [
{
pathName: "create-case",
relationshipName: "contoso_Incident",
entityName: "incident",
entityPluralName: "incidents"
},
{
pathName: "edit-case",
relationshipName: "contoso_Incident",
entityName: "incident",
entityPluralName: "incidents"
},
{
pathName: "account",
relationshipName: "maptaskr_Account",
entityName: "account",
entityPluralName: "accounts"
}
]
const onValidateFailErrorMessage = 'Please upload a file or draw a shape';
const onUploadFailErrorMessage = 'Something has gone wrong during submission, please check your connection and try again.';
const onIntersectionMessage = 'Intersections / Exclusions have been found, please check your shapes and try again.';
const clientValidationFunction = async() => {
const shapeIntersections = await _getShapeIntersections();
if (shapeIntersections && shapeIntersections.length > 0){
if (shapeIntersections.some(res => res.intersectionType == 'Warning'))
{
}
if (shapeIntersections.some(res => res.intersectionType == 'Error'))
{
throw new Error(onIntersectionMessage);
}
if (shapeIntersections.some(res => res.intersectionType == 'Exclusion'))
{
throw new Error(onIntersectionMessage);
}
}
}
(function (webapi, $) {
function safeAjax(ajaxOptions) {
var deferredAjax = $.Deferred();
shell.getTokenDeferred().done(function (token) {
if (!ajaxOptions.headers) {
$.extend(ajaxOptions, {
headers: {
"__RequestVerificationToken": token
}
});
} else {
ajaxOptions.headers["__RequestVerificationToken"] = token;
}
$.ajax(ajaxOptions)
.done(function (data, textStatus, jqXHR) {
validateLoginSession(data, textStatus, jqXHR, deferredAjax.resolve);
}).fail(deferredAjax.reject);
}).fail(function () {
deferredAjax.rejectWith(this, arguments);
});
return deferredAjax.promise();
}
webapi.safeAjax = safeAjax;
})(window.webapi = window.webapi || {}, jQuery);
function _getCurrentEntityName() {
var currentPageEntity = maptaskrEntityDefinition.filter((x) => window.location.pathname.includes(x.pathName));
if (currentPageEntity.length == 1)
return currentPageEntity[0];
return { pathname: null, entityPluralName: null };
}
function _getParentId(checkProposal) {
var url = new URL(window.location.href);
const urlSearchParams = new URLSearchParams(url.search);
var parentId = $("#EntityFormView_EntityID").val();
if (checkProposal) {
var recordId = $("#id").val();
}
if (recordId != null || recordId != undefined) { parentId = recordId; }
if (!parentId) {
var parentId = urlSearchParams.get("id");
}
return parentId;
}
async function validateAnnotationsAndShapes() {
window.maptaskrPCF.handleLoadingSpinner(true, "Validating shape...");
try {
await clientValidationFunction();
return true;
}
catch(err) {
showPortalWarning(err);
}
return false;
}
function saveAnnotationsAndShapes() {
return new Promise(async (resolve, reject) => {
var parentId = _getParentId(false);
try {
let clientValidationSuccess = await validateAnnotationsAndShapes();
if (clientValidationSuccess)
{
window.maptaskrPCF.handleLoadingSpinner(true, "Saving shape...");
if (_getShapeLambpetIds() && _getShapeLambpetIds().length > 0) {
await _deleteRemovedShapes();
}
await _addNewShapes(parentId);
resolve();
}
else
{
reject();
}
} catch (err) {
showPortalWarning(onUploadFailErrorMessage);
reject(err)
}
});
}
function _deleteRemovedShapes() {
return new Promise(async (resolve, reject) => {
var remainingShapes = _getShapes();
var remainingAnnotation = _getAnnotation();
var lambpets = _getShapeLambpetIds();
for (var i = 0; i < lambpets.length; i++) {
var existingAnnotationId = lambpets[i].id.split("___")[1];
let existingLambpetId = lambpets[i].id.split("___")[0];
let existingShapeName = lambpets[i].name;
if (existingAnnotationId) {
try {
let shapeStillExists = false;
if (remainingShapes && remainingShapes.filter((s)=> s.annotationId == existingAnnotationId)?.length > 0)
{
shapeStillExists = true;
}
if (remainingAnnotation && remainingAnnotation.annotationId == existingAnnotationId)
{
shapeStillExists = true;
}
if (!shapeStillExists)
{
setProgressDialogMessage(`Deleting existing '${existingShapeName}'...`);
await webapi.safeAjax({
type: "DELETE",
url: `/_api/maptaskr_lambpets(${existingLambpetId})`,
contentType: "application/json",
});
window.maptaskrPCF.fire("LambpetDeleted", existingLambpetId);
}
} catch (err) {
reject(err);
}
}
}
resolve();
});
}
async function _addNewShapes(parentId){
try{
await _addLambpets(parentId, _getShapes(true), true);
let annotation = _getAnnotation();
if (annotation && annotation.annotationId == null)
{
await _addLambpet(parentId, annotation, false);
}
await _attachOriginalFilesToEntity(parentId, _getUploadedFiles());
return;
}catch(err){
throw err;
}
}
function _addLambpets(entityId, areas) {
var promises = [];
for (var i = 0; i < areas.length; i++) {
promises.push(_addLambpet(entityId, areas[i]));
}
return Promise.all(promises);
}
function _addLambpet(parentId, area, isChildShape = true) {
var tableNames = _getCurrentEntityName();
var data = {
"maptaskr_name": area.DocumentType,
"maptaskr_parententityid": parentId,
"maptaskr_json": area.styleProperty ? JSON.stringify(area.styleProperty) : "null",
"maptaskr_ischild": isChildShape,
"maptaskr_longitude": area.longlat[0],
"maptaskr_latitude": area.longlat[1],
};
data[`${tableNames.relationshipName}@odata.bind`] = `/${tableNames.entityPluralName}(${parentId})`;
setProgressDialogMessage(`Adding new '${area.DocumentType}'...`);
return new Promise((resolve, reject) => {
webapi.safeAjax({
type: "POST",
url: "/_api/maptaskr_lambpets",
contentType: "application/json",
data: JSON.stringify(data),
success: function (res, status, xhr) {
var lambpetId = xhr.getResponseHeader("entityid");
window.maptaskrPCF.fire("LambpetCreated", lambpetId, JSON.stringify(data));
_createAnnotation(lambpetId, JSON.stringify(area), area).then(() => {
resolve();
}).catch((err) => {
reject(err);
});
},
error: function () {
reject();
}
});
});
}
function _createAnnotation(parentId, geojson, rawgeojson) {
var data = {
filename: rawgeojson.DocumentType,
mimetype: "geojson",
documentbody: strToBase64(geojson),
objecttypecode: "maptaskr_lambpet",
subject: rawgeojson.DocumentType
};
data["objectid_maptaskr_lambpet@odata.bind"] =
"/maptaskr_lambpets(" + parentId + ")";
return new Promise((resolve, reject) => {
webapi.safeAjax({
type: "POST",
url: "/_api/annotations",
contentType: "application/json",
data: JSON.stringify(data),
success: function (res, status, xhr) {
var annotationId = xhr.getResponseHeader("entityid");
window.maptaskrPCF.fire("AnnotationCreated", annotationId, JSON.stringify(data));
resolve();
},
error: function () {
reject();
}
});
});
}
function _createAnnotationForParent(parentId, utf8encodedFile, file) {
var tableNames = _getCurrentEntityName();
var data = {
filename: `${file.name}`,
mimetype: `${file.type}`,
documentbody: window.btoa(utf8encodedFile),
objecttypecode: `${tableNames.entityName}`,
};
data[`objectid_${tableNames.entityName}@odata.bind`] = `/${tableNames.entityPluralName}(${parentId})`;
return new Promise((resolve, reject) => {
webapi.safeAjax({
type: "POST",
url: "/_api/annotations",
contentType: "application/json",
data: JSON.stringify(data),
success: function (res, status, xhr) {
var annotationId = xhr.getResponseHeader("entityid");
window.maptaskrPCF.fire("OriginalFileUploaded", annotationId, JSON.stringify(data));
resolve();
},
error: function () {
reject();
}
});
});
}
function _attachOriginalFilesToEntity(entityId, files) {
return new Promise(async (resolve, reject) => {
if (files.length == 0) {
resolve();
return;
}
var uploadedOriginalShapes = 0;
for (var i = 0; i < files.length; i++) {
console.log('File', files[i]);
var file = files[i];
if (file) {
try {
var utf8DocBody = await _readFileAsBufferToUTF8(file);
await _createAnnotationForParent(entityId, utf8DocBody, file);
uploadedOriginalShapes++;
} catch (err) {
reject(err);
return;
}
}
}
if (uploadedOriginalShapes == files.length) {
resolve();
} else {
reject();
}
});
}
function _getShapeLambpetIds() {
return window.maptaskrPCF.getLambpetIds();
}
function _getShapes(getNewShapesOnly = false) {
let uploadedPolygons = window.maptaskrPCF.getUploadedShapes();
let drawnPolygons = window.maptaskrPCF.getDrawnShapes();
let shapes = [];
uploadedPolygons.forEach(element => {
if (!getNewShapesOnly || element.annotationId == null)
shapes.push(element);
});
drawnPolygons.forEach(element => {
if (!getNewShapesOnly || element.annotationId == null)
shapes.push(element);
});
return shapes;
}
function _getAnnotation() {
return window.maptaskrPCF.getAnnotation();
}
function _getUploadedFiles() {
return window.maptaskrPCF.getUploadedFiles();
}
function _readFileAsBufferToUTF8(file) {
return new Promise((resolve, reject) => {
const reader = new FileReader();
reader.onload = () => resolve(_arrayBufferToUTF8(reader.result));
reader.readAsArrayBuffer(file);
reader.onerror = (error) => reject(error);
});
}
function _arrayBufferToUTF8(buffer) {
var binary = '';
var bytes = new Uint8Array(buffer);
var len = bytes.byteLength;
for (var i = 0; i < len; i++) {
binary += String.fromCharCode(bytes[i]);
}
return binary;
}
function showPortalWarning(msg) {
window.maptaskrPCF.showWarningMessage(msg, 5000);
$('html, body').animate({
'scrollTop': $('.validation-map').position().top
});
}
function enableButtons() {
var inputs = document.getElementsByTagName("input");
for (var i = 0, j = inputs.length; i < j; i++) {
if (inputs[i].type === 'submit' || inputs[i].type === 'button') {
inputs[i].disabled = false;
}
}
}
function _getShapeIntersections() {
return new Promise(async (resolve, reject) => {
try {
const response = await window.maptaskrPCF.getShapeIntersections();
resolve(response);
} catch {
reject();
}
});
}
function strToBase64(str) {
return window.btoa(unescape(encodeURIComponent(str)))
}
function setProgressDialogMessage(message) {
window.maptaskrPCF.updateLoadingSpinnerMessage(message)
}