@arcgis/core
Version:
ArcGIS Maps SDK for JavaScript: A complete 2D and 3D mapping and data visualization API
6 lines (5 loc) • 18 kB
JavaScript
/*
All material copyright ESRI, All Rights Reserved, unless otherwise specified.
See https://js.arcgis.com/4.33/esri/copyright.txt for details.
*/
import{_ as e}from"../../chunks/tslib.es6.js";import t from"../../Graphic.js";import a from"../../core/Error.js";import{makeHandle as i}from"../../core/handleUtils.js";import o from"../../core/Logger.js";import{abortMaybe as r}from"../../core/maybe.js";import{debounce as s,createResolver as n,onAbort as l,createAbortError as d,throwIfAborted as c}from"../../core/promiseUtils.js";import p from"../../core/Queue.js";import{whenOnce as u,watch as h,sync as w,when as f}from"../../core/reactiveUtils.js";import{last as g}from"../../core/SetUtils.js";import{property as v}from"../../core/accessorSupport/decorators/property.js";import"../../core/has.js";import"../../core/RandomLCG.js";import{subclass as k}from"../../core/accessorSupport/decorators/subclass.js";import{isEditableLayer as m}from"../../layers/support/editableLayers.js";import{isFeatureLayer as y,isSubtypeSublayer as W,isSubtypeGroupLayer as b,isTable as C}from"../../layers/support/layerUtils.js";import{createFeatureServices as A}from"../../rest/featureService/utils.js";import _ from"../../views/draw/support/HighlightHelper.js";import{ViewEventPriorities as F}from"../../views/input/InputManager.js";import M from"../../views/interactive/sketch/SketchOptions.js";import{temporaryHighlightName as S}from"../../views/support/HighlightDefaults.js";import I from"./CreateFeaturesWorkflow.js";import{UpdateFeatureWorkflow as E}from"./UpdateFeatureWorkflow.js";import{UpdateRecordWorkflow as V}from"./UpdateRecordWorkflow.js";import j from"./UpdateWorkflowData.js";import U from"./Workflow.js";import{isUpdateRecordWorkflow as P,createWorkflowSteps as R,fetchCandidates as L}from"./workflowUtils.js";import{findUtilityNetwork as O,isGraphicForRelatableFeatureSupportedLayer as x}from"../Feature/support/featureUtils.js";var T;let H=T=class extends U{constructor(e){super(e),this._workflowStack=new p(g),this._sketchStack=new p(g),this.data=void 0,this.type="update"}destroy(){this._drainWorkflowStack((e=>e.cancel({force:!0})))}get activeEditorItem(){return this.activeWorkflow?.data.editorItem??void 0}get activeFeatureFormViewModel(){return this.activeWorkflow?.featureFormViewModel}get activeUtilityNetworkAssociationAddAssociationViewModel(){return"add-association"===this.activeWorkflow?.type?this.activeWorkflow.utilityNetworkAssociationAddAssociationViewModel:null}get activeSketchViewModel(){return this._sketchStack.peek()?.viewModel}get canDeleteAssociation(){const{activeFeatureFormViewModel:e}=this;if(!this.activeWorkflow||!this.data.viewModel.view?.map||!e)return!1;const{activeAssociation:t,feature:a}=e;return!(!t||!a?.sourceLayer||!y(a?.sourceLayer)&&!W(a?.sourceLayer))}get activeWorkflow(){return this._workflowStack.last()}get updating(){return this._updatingHandles.updating||!!this.activeWorkflow?.updating}get hasPreviousStep(){const e=this.activeWorkflow?.featureFormViewModel;return this._stepIndex>0||this.nestedWorkflowCount>1||null!=e?.relationshipId||"view"!==this.data.viewModel.attachmentsViewModel.mode||null!=e?.associationId||null!=e?.associatedLayer}get hasUpdatableCandidates(){const{candidates:e,viewModel:t}=this.data;return e.some((({layer:e})=>t.findEditorItemForLayer(e)?.supportsUpdateWorkflow))}get nestedWorkflowCount(){return this._workflowStack.length}get shouldShowAttachments(){return!!this.activeEditorItem?.capabilities.attachments.enabled}get shouldAllowAttachmentEditing(){return!!this.activeEditorItem?.capabilities.update.attachments.enabled}get hasPendingEdits(){return Array.from(this._workflowStack).some((e=>e.hasPendingEdits))}get helpMessage(){return this.activeWorkflow?.helpMessage?this.activeWorkflow.helpMessage:"awaiting-feature-to-update"===this.stepId?"select":void 0}get reliesOnOwnerAdminPrivileges(){return this.activeWorkflow?.reliesOnOwnerAdminPrivileges??!1}get hasInvalidFormTemplate(){return!!this.activeEditorItem?.hasInvalidFormTemplate}async back(e=()=>Promise.resolve(!0)){const{activeWorkflow:t}=this,a=t?.featureFormViewModel;if(a?.activeRelationshipInput){const e=a.activeRelationshipInput;if(e.activeCategory)return void(e.activeCategory=null);if(null!=a.relationshipId)return void(a.relationshipId=null);if(e.showAllEnabled)return void(e.showAllEnabled=!1)}if("add-association"===t?.type){const{activeUtilityNetworkAssociationAddAssociationViewModel:e}=this;if(e?.filterOptionsVisible)return void(e.filterOptionsVisible=!1);e?.featureSpatialItems.length&&e.reset()}if(null==a?.associatedLayer)if(null==a?.associationId)if("create-features"===t?.type&&t.hasPreviousStep)await t.previous({cancelCurrentStep:!0});else if(t){if(t.hasPendingEdits&&!a?.disabled){if(!await e())return}t.hasPreviousStep?await t.previous({cancelCurrentStep:!0}):await this.cancelActiveWorkflow({force:!0})}else this.hasPreviousStep?await this.previous({cancelCurrentStep:!0}):await this.cancel({force:!0});else a.associationId=null;else a.associatedLayer=null}async cancelActiveWorkflow(e){await(this.activeWorkflow?.cancel(e)),await this._popWorkflow()}async commit(){await this._drainWorkflowStack((e=>e.commit())),await super.commit()}static create(e){const{viewModel:t,snappingManager:a,startAt:i,addAttachmentsCallback:o,applyEditsCallback:r,applyEditsFeatureServiceCallback:s}=e,n=e.sketchOptions??new M,l=new T({data:new j({addAttachmentsCallback:o,applyEditsCallback:r,applyEditsFeatureServiceCallback:s,sketchOptions:n,snappingManager:a,viewModel:t}),onCommit:async()=>{}});return l._set("steps",this._createWorkflowSteps(l,i)),l}async save(){const{activeFeatureFormViewModel:e}=this;if(e){if(e.submit(),!e.submittable||e.pendingSubtypeChoice)return;const t=e.getValues();if(e.validateContingencyConstraints(t,{includeIncompleteViolations:!0}).length>0)return}this.nestedWorkflowCount>1?(await(this.activeWorkflow?.commit()),await this._popWorkflow()):await this.commit()}async startCreatingRelatedRecord(e){try{const t=await this._createNestedCreateFeaturesWorkflow(e);await this._pushWorkflow(t)}catch(t){throw new a("editor:unable-to-start-creating","Could not begin updating the provided feature or table record.",{error:t})}}async startUpdating(e,t,i=!1){try{const a=await this._createNestedUpdateWorkflow(e,i,t);await this._pushWorkflow(a)}catch(o){throw new a("editor:unable-to-start-updating","Could not begin updating the provided feature or table record.",{error:o})}}async startAddAssociation(e,t,i){try{const a=await this._createNestedAddAssociationWorkflow(e,t,i);await this._pushWorkflow(a)}catch(o){throw new a("editor:unable-to-start-updating","Could not begin updating the provided feature or table record.",{error:o})}}async deleteActiveFeature(){const{activeWorkflow:e}=this;if(!e)throw new a("editor:nothing-to-delete","There is no feature to delete");const t=P(e);t?(e.stageDelete(),e.data.edits.feature===this.data.rootFeature&&this._removeRootFeatureFromCandidates()):await e.cancel(),this.nestedWorkflowCount<2?t?await this.commit():await this.cancel({force:!0}):(t&&await e.commit(),await this._popWorkflow(),await this._returnToPageWithContent())}async deleteActiveAssociation(){if(!this.canDeleteAssociation)throw new a("editor:nothing-to-delete","There is no association to delete");await this._deleteActiveAssociation(),await this._popWorkflow(),await this._returnToPageWithContent()}async cancelAll(){await this._drainWorkflowStack((e=>e.cancel({force:!0})))}async _deleteActiveAssociation(){const{activeFeatureFormViewModel:e,data:t}=this,{activeAssociation:i,feature:o}=e,{applyEditsFeatureServiceCallback:r,viewModel:s}=t,{sourceLayer:n}=o,l=W(n)&&n.parent?n.parent:n,d=A([l]),c=d.values().next().value?.featureService;if(!c)throw new a("editor:failed-to-delete-association","Could not retrieve feature service needed to delete association");await(c?.load());const p=s.view.map,u=O(p,l);await(u?.networkSystemLayers.loadAssociationsTable());const h=u?.generateDeleteAssociations([i]);if(!h)throw new a("editor:failed-to-delete-association","Could not create payload needed to delete association");const w=u?.gdbVersion??void 0;await r(c,[h],{gdbVersion:w,globalIdUsed:!0})}_removeRootFeatureFromCandidates(){const{candidates:e,rootFeature:t}=this.data;if(0===e.length||!t)return;const a=e.indexOf(t);a>-1&&e.splice(a,1)}async _returnToPageWithContent(){const{activeFeatureFormViewModel:e}=this;if(!e?.activeAssociationInput)return;const{activeAssociationInput:t,associationId:a}=e;await t.refresh(),t.associatedLayer&&!t.associatedFeatures?.length&&(e.associatedLayer=null),null==a||t.associatedFeatureInfos.size||(e.associationId=null)}async _createNestedCreateFeaturesWorkflow(e){const{relatedLayer:t}=e,{addAttachmentsCallback:i,applyEditsCallback:o,applyEditsFeatureServiceCallback:r,sketchOptions:s,snappingManager:n,viewModel:l}=this.data;if(!m(t))throw new a("editor:unsupported-layer","Editing is not supported on the provided layer");const d=this._getCreationInfoForNestedCreateFeaturesWorkflow(e),c=d.template||d.initialFeature?"creating-features":"awaiting-feature-creation-info",p="create-features"!==this.activeWorkflow?.type&&"add-association"!==this.activeWorkflow?.type?this.activeWorkflow:void 0;return I.create({addAttachmentsCallback:i,applyEditsCallback:o,applyEditsFeatureServiceCallback:r,creationInfo:d,isNested:!0,parent:p,sketchOptions:s,snappingManager:n,startAt:c,viewModel:l})}_getCreationInfoForNestedCreateFeaturesWorkflow(e){const{relatedLayer:i}=e;if(!m(i)||b(i))throw new a("editor:unsupported-layer","Editing is not supported on the provided layer");const{viewModel:o}=this.data,r={layer:i,maxFeatures:1},s=this._makeRelatedRecordAttributes(e),n=o.getTemplatesForLayer(i);return n?.length>0?(r.attributeOverrides=s,1===n.length&&(r.template=n[0])):r.initialFeature=new t({sourceLayer:i,attributes:s}),r}async _createNestedUpdateWorkflow(e,t,a){const i=C(e.sourceLayer)?V:E,{applyEditsCallback:o,applyEditsFeatureServiceCallback:r,sketchOptions:s,snappingManager:n,viewModel:l}=this.data,d="create-features"!==this.activeWorkflow?.type&&"add-association"!==this.activeWorkflow?.type?this.activeWorkflow:void 0,c=await i.create({association:a,feature:e,parent:d,sketchOptions:s,snappingManager:n,viewModel:l,readOnly:t,applyEdits:o,applyEditsFeatureService:r,featureFormCallbacks:{addRelatedRecord:async e=>await this._updatingHandles.addPromise(this.startCreatingRelatedRecord(e)),editRelatedRecord:async({relatedFeature:e,readOnly:t})=>await this._updatingHandles.addPromise(this.startUpdating(e,void 0,t)),selectAssociatedFeature:async({feature:e,association:a})=>await this._updatingHandles.addPromise(this.startUpdating(e,a,t)),addAssociation:async e=>await this._updatingHandles.addPromise(this.startAddAssociation(e.feature,e.utilityNetwork,e.associationType))}});return await u((()=>!c.updating)),c}async _createNestedAddAssociationWorkflow(e,t,a){const{AddAssociationWorkflow:i}=await import("./AddAssociationWorkflow.js"),{applyEditsCallback:o,applyEditsFeatureServiceCallback:r,viewModel:s}=this.data,n="create-features"!==this.activeWorkflow?.type&&"add-association"!==this.activeWorkflow?.type?this.activeWorkflow:void 0,l=this.activeFeatureFormViewModel?.activeAssociationInput,d=await i.create({utilityNetwork:t,associationType:a,feature:e,parent:n,viewModel:s,associationInput:l,applyEdits:o,applyEditsFeatureService:r});return await u((()=>!d.updating)),d}async _drainWorkflowStack(e){const t=this._workflowStack,a=[];for(const i of t){const t=e(i).finally((()=>i.destroy()));this._updatingHandles.addPromise(t),a.push(t)}await Promise.all(a),this._workflowStack.clear(),this._sketchStack.clear()}_makeRelatedRecordAttributes(e){const{parentFeature:t,relatedLayer:a,relationshipId:i}=e;if(!x(t))return;const o=a.relationships?.find((e=>e.id===i));if(!o)return void this._logContinuingWithoutRelationshipWarning("relationship-not-found","Could not begin creating a related record because the relationship specified could not be found on the destination layer.");if("origin"===o.role)return void this._logContinuingWithoutRelationshipWarning("unsupported-role","Creating new related records in the 'origin' table of a relationship is not yet supported");const r=t.sourceLayer;o.relatedTableId!==r.layerId&&this._logContinuingWithoutRelationshipWarning("invalid-argument-combination","The given parent feature does not belong to the relationship designated by the given relationship ID.");const s=r.relationships?.find((e=>e.id===i));if(!s)return void this._logContinuingWithoutRelationshipWarning("relationship-not-found","Could not begin creating a related record because the relationship specified could not be found on the origin layer.");const n=N(r,s),l=t.getAttribute(n);l||this._logContinuingWithoutRelationshipWarning("no-key-on-origin-feature","The given parent feature does not have a value for the relationship's origin primary key field.");const d=N(a,o);return{[d]:l}}async _popWorkflow(){this._workflowStack.pop()?.destroy(),this._sketchStack.pop();const e=await this._reconcileWorkflowStack();if(e.failureCount>0)throw new a("editor:next-workflow-failed","Popped the top workflow, but the next workflow in the stack failed to activate",e)}async _pushWorkflow(e){const t=this._workflowRequiresSketchViewModel(e);this.activeWorkflow?.exit({removeSketchHandles:t});const i=this._sketchStack,o=await(e?.start()),r=i.peek();o?(r?.exit(),i.push(o)):i.push(this._cloneSketchController(r)),this._workflowStack.push(e);const s=await this._reconcileWorkflowStack();if(s.failureCount>0)throw new a("editor:failed-to-start-updating-feature","Failed to enter the provided workflow.",s)}async _reconcileWorkflowStack(){const e=this._workflowStack,t=this._sketchStack;try{const a=e.peek();return await(a?.enter()),await(t.peek()?.enter()),{activeWorkflow:a,failureCount:0}}catch(a){e.pop().destroy(),t.pop();const{activeWorkflow:i,failureCount:o}=await this._reconcileWorkflowStack();return{activeWorkflow:i,failureCount:o+1}}}_cloneSketchController(e){return{enter:e?.enter??(async()=>{}),exit:e?.exit??(async()=>{}),viewModel:e?.viewModel}}_workflowRequiresSketchViewModel(e){const{type:t}=e;return"update-feature"===t||"create-features"===t&&!C(e.data.creationInfo?.layer)}static _createWorkflowSteps(e,t="awaiting-feature-to-update"){const{data:o}=e;return R(["awaiting-feature-to-update","awaiting-update-feature-candidate","editing-existing-feature","adding-attachment","editing-attachment"],t,{"awaiting-feature-to-update":()=>({id:"awaiting-feature-to-update",async setUp(){const{spinnerViewModel:t}=o.viewModel,a=o.viewModel.view;a.activeTool=null;let s=null;e.addHandles(i((()=>{s=r(s)})),this.id),o.rootFeature=null,o.candidates=[];const p=a.on("immediate-click",(async i=>{const r=n();e._updatingHandles.addPromise(r.promise);try{t.location=i.mapPoint,t.visible=!0,s?.abort();const{editorItems:r}=o.viewModel;s=new AbortController;const n=await i.defer((()=>new Promise(((e,t)=>{l(s?.signal,(()=>t(d()))),e(L(r,a,i,s?.signal))}))));if(c(s),o.candidates=n.filter((e=>"fulfilled"===e.status)).flatMap((e=>e.value)).filter((e=>!e.isAggregate)),t.visible=1===o.candidates.length,0===o.candidates.length)return;i.stopPropagation(),1===o.candidates.length?(o.rootFeature=o.candidates[0],e.go("editing-existing-feature").catch((()=>{})).then((()=>t.visible=!1))):e.next()}finally{r.resolve()}}),F.TOOL),u=f((()=>null!=a.activeTool),(()=>e.cancel({force:!0})),{once:!0});a.focus(),e.addHandles([p,u],this.id)},async tearDown(){0===o.candidates.length&&(o.viewModel.spinnerViewModel.visible=!1),e.removeHandles(this.id)}}),"awaiting-update-feature-candidate":()=>({id:"awaiting-update-feature-candidate",async setUp(){o.rootFeature=null;const{view:t}=o.viewModel;if(!t)return;const a=new _({view:t,highlightName:S});e.addHandles([h((()=>o.rootFeature),((e,t)=>{a.remove(t),a.add(e)}),w),i((()=>a.removeAll()))],this.id)},async tearDown(){e.removeHandles(this.id)}}),"editing-existing-feature":()=>({id:"editing-existing-feature",async setUp(){const{rootFeature:t,viewModel:i}=e.data;if(!t)throw new a("editor:no-feature-specified","Cannot setup the 'updating-existing-feature' step until the root feature is defined");await e.startUpdating(t),i.spinnerViewModel.visible=!1;const o=s((async()=>{await u((()=>!e.updating)),e.previous()}));e.addHandles([h((()=>e.nestedWorkflowCount),((e,t)=>{0===e&&0!==t&&o()}),w)],this.id)},async tearDown(){await e.cancelAll(),e.removeHandles(this.id)}}),"adding-attachment":()=>({id:"adding-attachment",parent:"editing-existing-feature",async setUp(){},async tearDown(){o.viewModel.attachmentsViewModel.mode="view"}}),"editing-attachment":()=>({id:"editing-attachment",parent:"editing-existing-feature",async setUp(){},async tearDown(){o.viewModel.attachmentsViewModel.mode="view"}})})}_logContinuingWithoutRelationshipWarning(e,t){o.getLogger(this).warn(`editor:${e}`,t,"The create operation will be allowed to proceed, but the resulting feature may not be related to the given parent feature.")}};function N(e,{keyField:t}){return e.getField(t)?.name??t}e([v()],H.prototype,"activeEditorItem",null),e([v()],H.prototype,"activeFeatureFormViewModel",null),e([v()],H.prototype,"activeUtilityNetworkAssociationAddAssociationViewModel",null),e([v()],H.prototype,"activeSketchViewModel",null),e([v()],H.prototype,"canDeleteAssociation",null),e([v()],H.prototype,"activeWorkflow",null),e([v()],H.prototype,"updating",null),e([v()],H.prototype,"data",void 0),e([v()],H.prototype,"hasPreviousStep",null),e([v()],H.prototype,"hasUpdatableCandidates",null),e([v()],H.prototype,"nestedWorkflowCount",null),e([v()],H.prototype,"shouldShowAttachments",null),e([v()],H.prototype,"shouldAllowAttachmentEditing",null),e([v()],H.prototype,"hasPendingEdits",null),e([v()],H.prototype,"helpMessage",null),e([v()],H.prototype,"reliesOnOwnerAdminPrivileges",null),e([v()],H.prototype,"hasInvalidFormTemplate",null),H=T=e([k("esri.widgets.Editor.UpdateWorkflow")],H);const D=H;export{D as default};