@doegis/core
Version:
DOE GIS API
3 lines (1 loc) • 20 kB
JavaScript
import{_ as e}from"../chunks/tslib.es6.js";import"../intl.js";import{neverReached as t}from"../core/compilerUtils.js";import{isSome as i,isNone as a}from"../core/maybe.js";import{watch as n}from"../core/reactiveUtils.js";import{property as s}from"../core/accessorSupport/decorators/property.js";import"../core/accessorSupport/ensureType.js";import"../core/arrayUtils.js";import{subclass as l}from"../core/accessorSupport/decorators/subclass.js";import{getDomainRange as r}from"../layers/support/domainUtils.js";import{getFieldRange as o}from"../layers/support/fieldUtils.js";import u from"./Widget.js";import{CSS as d}from"./FeatureForm/css.js";import{isGroupField as p,isFieldElementWithInputType as c}from"./FeatureForm/featureFormUtils.js";import m from"./FeatureForm/FeatureFormViewModel.js";import{Heading as h,incrementHeadingLevel as f}from"./support/Heading.js";import"./support/widgetUtils.js";import{messageBundle as g}from"./support/decorators/messageBundle.js";import{vmEvent as b}from"./support/decorators/vmEvent.js";import{tsx as v}from"./support/jsxFactory.js";import{DateTime as _}from"luxon";import{getLocale as I}from"../intl/locale.js";const F="TT",y="data-field-name",w="latn",V=e=>"valueAsDate"in e;let D=class extends u{constructor(e,t){super(e,t),this._dateInputFieldMap=new Map,this._activeInputName="",this._activeNumberFieldEdit=null,this._fieldFocusNeeded=!1,this._fieldToInitialIncompatibleDomainValue=new Map,this._switchFieldsWithInitialIncompatibleValue=new Set,this._userUpdatedInputFieldNames=new Set,this.disabled=!1,this.groupDisplay="all",this.headingLevel=2,this.messages=null,this.messagesTemplates=null,this.viewModel=new m,this._handleInputInput=e=>{this._commitInputValue(e.currentTarget)},this._handleFormKeyDown=this._handleFormKeyDown.bind(this),this._handleInputBlur=this._handleInputBlur.bind(this),this._handleInputFocus=this._handleInputFocus.bind(this),this._handleNumberInputMouseDown=this._handleNumberInputMouseDown.bind(this),this._handleInputKeyDown=this._handleInputKeyDown.bind(this),this._handleOptionChange=this._handleOptionChange.bind(this),this._handleGroupClick=this._handleGroupClick.bind(this),this._handleSubmit=this._handleSubmit.bind(this),this._afterInputCreateOrUpdate=this._afterInputCreateOrUpdate.bind(this),this._afterDateInputCreateOrUpdate=this._afterDateInputCreateOrUpdate.bind(this)}initialize(){this.addHandles([n((()=>this.feature),(()=>{const e=this._getFocusableInput("forward");this._activeInputName=e?.name||"",this._userUpdatedInputFieldNames.clear(),this._fieldToInitialIncompatibleDomainValue.clear(),this._switchFieldsWithInitialIncompatibleValue.clear(),this._dateInputFieldMap.clear(),this._fieldFocusNeeded=!0})),this.on("submit",(e=>{if(e.invalid.length>0){const[t]=e.invalid;e.invalid.forEach((e=>this._userUpdatedInputFieldNames.add(e))),this._activeInputName=t,this._fieldFocusNeeded=!0,this.scheduleRender()}}))])}loadDependencies(){return Promise.all([import("@esri/calcite-components/dist/components/calcite-combobox.js"),import("@esri/calcite-components/dist/components/calcite-combobox-item.js"),import("@esri/calcite-components/dist/components/calcite-combobox-item-group.js"),import("@esri/calcite-components/dist/components/calcite-input-message.js"),import("@esri/calcite-components/dist/components/calcite-progress.js"),import("@esri/calcite-components/dist/components/calcite-switch.js"),import("@esri/calcite-components/dist/components/calcite-input-date-picker.js"),import("@esri/calcite-components/dist/components/calcite-input-time-picker.js")])}get feature(){return this.viewModel.feature}set feature(e){this.viewModel.feature=e}get formTemplate(){return this.viewModel.formTemplate}set formTemplate(e){this.viewModel.formTemplate=e}get label(){return this.messages?.widgetLabel??""}set label(e){this._overrideIfSome("label",e)}get layer(){return this.viewModel.layer}set layer(e){this.viewModel.layer=e}get spatialReference(){return this.viewModel.spatialReference}set spatialReference(e){this.viewModel.spatialReference=e}get strict(){return this.viewModel.strict}set strict(e){this.viewModel.strict=e}get view(){return this.viewModel.view}set view(e){this.viewModel.view=e}getValues(){return this.viewModel.getValues()}submit(){return this.viewModel.submit()}render(){const{state:e}=this.viewModel;return v("div",{class:this.classes(d.base,d.widget,d.panel)},"ready"===e?this.renderForm():null)}renderForm(){const e=this.viewModel,t=i(e.formTitle)&&v(h,{key:"title",level:this.headingLevel},e.formTitle),a=i(e.formDescription)&&v("p",{class:d.description,key:"description"},e.formDescription),n=t||a?v("div",{class:d.formHeader},t,a):null;return v("form",{class:d.form,novalidate:!0,onsubmit:this._handleSubmit,onkeydown:this._handleFormKeyDown},n,this.renderFields())}renderFields(){const{viewModel:{inputFields:e}}=this;return e.filter((e=>e.visible)).map(((e,t)=>p(e)?this.renderGroup(e,t):this.renderLabeledField(e)))}renderGroup(e,t){const{formTemplate:a,disabled:n}=this,{description:s,inputFields:l,label:r,state:o}=e,u=l.filter((e=>e.visible)),p=this.viewModel.findField(this._activeInputName),c=!(!p||p.group!==e),m=`${this.id}_group_${t}`,g=`${this.id}_group-label_${t}`,b=`${this.id}_group-description_${t}`,_=s?v("p",{class:this.classes(d.groupDescription,d.description),id:b},s):null,I="sequential"===this.groupDisplay,F=I?c:"expanded"===o,y=F?d.collapseIcon:d.expandIcon;return v("fieldset",{"aria-expanded":F.toString(),"aria-labelledby":g,"aria-describedby":s?b:"",class:this.classes(d.group,I?d.groupSequential:null,F?null:d.groupCollapsed,c?d.groupActive:null,n?d.inputDisabled:null),disabled:n,"data-group":e,id:m,key:t,onclick:this._handleGroupClick},v("button",{role:I?"presentation":void 0,class:d.groupHeader,type:"button",tabIndex:I?-1:0},v("div",{class:d.groupTitle},v(h,{class:d.groupLabel,id:g,level:i(a)&&a.title?f(this.headingLevel):this.headingLevel},r),_),I?null:v("span",{class:this.classes(y,d.groupToggleIcon)})),u.map((e=>this.renderLabeledField(e))))}_getFocusableInput(e,t){const i=this.viewModel.allInputFields,a="forward"===e?i:i.slice().reverse();let n;if(t)if(p(t))n=a.indexOf(t.inputFields[0]);else{let i;if(this._isInputFieldInGroup(t)&&"collapsed"===t.group.state){const{inputFields:a}=t.group;i="forward"===e?a[a.length-1]:a[0]}else i=t;n=a.indexOf(i)+1}else n=0;for(let s=n;s<a.length;s++){const e=a[s];if(e.visible)return e}return null}renderLabeledField(e){const{feature:t,label:i,layer:a,type:n}=e;return v("label",{key:`${a.id}-${t.uid}-${e.name}`,class:d.label},[i,"unsupported"!==n?this.renderInputField(e):this.renderUnsupportedField(e),this.renderAuxiliaryText(e)])}renderInputField(e){const{domain:t,name:a,type:n,updating:s,value:l}=e,r=this.getCommonInputProps(e);if("coded-value"===t?.type){if(c(e.fieldElement,"switch")){const{fieldElement:t}=e;if(!(this._switchFieldsWithInitialIncompatibleValue.has(a)||null==l||t.input.onValue!==l&&t.input.offValue!==l))return this.renderSwitchInputField(e,r);this._switchFieldsWithInitialIncompatibleValue.add(a)}return"radio-buttons"===e.inputType?this.renderRadioButtonsInputField(e,t.codedValues.map((({code:e,name:t})=>({value:e,name:t}))),r):this.renderSelectInputField(e,this._getFieldValueOptions(a,t),r)}if("datetime-picker"===e.inputType||"date"===n)return this.renderDateInputField(e,r);const o="number"===n?v("input",{type:"number",...r,value:i(this._activeNumberFieldEdit)&&this._activeNumberFieldEdit.fieldName===e.name?this._activeNumberFieldEdit.value:`${r.value}`}):"text-area"===e.inputType?v("textarea",{...r}):v("input",{type:"text",...r});return s?v("div",{class:d.inputFieldWrapper},o,v("div",{class:d.inputFieldLoader},v("calcite-progress",{type:"indeterminate"}))):o}renderDateInputField(e,t){const{includeTime:a,label:n,name:s,valid:l,value:r}=e,{readOnly:o,required:u}=t,{date:p,time:c}=this._formatValueForDateInputs(r),m=i(t.max)?this._formatValueForDateInputs(t.max):void 0,h=i(t.min)?this._formatValueForDateInputs(t.min):void 0,f=m?.date??void 0,g=h?.date??void 0,b={afterCreate:this._afterDateInputCreate,afterUpdate:this._afterDateInputCreateOrUpdate,"aria-invalid":!l,label:n,numberingSystem:w,overlayPositioning:"fixed",readOnly:o,required:u,tabIndex:0,[y]:s};return v("div",{key:`${t.key}-date-time-container`,class:d.dateInputContainer},v("calcite-input-date-picker",{bind:this,...b,class:this.classes(t.class,d.inputDate),"data-date-part":"date",key:`${t.key}-date-input`,valueAsDate:p??void 0,maxAsDate:f,minAsDate:g,onCalciteInputDatePickerChange:e=>this._commitDateChanges(e.target),onblur:e=>this._commitDateChanges(e.target,!0)}),a?v("calcite-input-time-picker",{bind:this,...b,class:this.classes(t.class,d.inputTime),"data-date-part":"time",key:`${t.key}-time-input`,value:c??void 0,step:1,onCalciteInputTimePickerChange:e=>this._commitDateChanges(e.target),onfocus:e=>{e.target.calciteTimePickerEl&&(e.target.calciteTimePickerEl.showSecond=!0)},onblur:e=>this._commitDateChanges(e.target,!0)}):null)}renderUnsupportedField(e){const t=this.getCommonInputProps(e);return v("input",{afterCreate:t.afterCreate,afterUpdate:t.afterUpdate,class:this.classes(d.input,d.inputField,d.inputDisabled),onfocus:t.onfocus,readOnly:!0,tabIndex:t.tabIndex,type:"text",value:t.value,[y]:t[y]})}renderSelectInputField(e,t,i){const{value:n}=e,{messages:s,messagesTemplates:l}=this,r=t.map((e=>e.map((e=>v("calcite-combobox-item",{value:`${e.value}`,textLabel:e.name,key:`#${e.value}`,selected:n===e.value}))))),[o,u]=r;this._registerIncompatibleValue(n,t.flat(),e,(e=>{u.unshift(v("calcite-combobox-item",{value:`${e}`,textLabel:`${e}`,key:"incompatible-option",readOnly:!0}))}));const d=u.length>0?[v("calcite-combobox-item-group",{key:"recommended",label:s.recommended},o),v("calcite-combobox-item-group",{key:"other",label:l.other},u)]:o,p=a(e.fieldElement)||c(e.fieldElement,"combo-box")&&e.fieldElement.input.showNoValueOption;if(!e.required&&p){const t="",i=c(e.fieldElement,"combo-box")&&e.fieldElement.input.noValueOptionLabel||this.messages.empty;d.unshift(v("calcite-combobox-item",{value:t,textLabel:this.messages.empty,key:"empty-option"},i))}return v("calcite-combobox",{...i,selectionMode:"single",disabled:i.readOnly,allowCustomValues:!1,onCalciteComboboxChange:e=>this._handleOptionChange(e.target)},d)}_registerIncompatibleValue(e,t,i,a){const n=this._fieldToInitialIncompatibleDomainValue,s=n.has(i.name);(s||null!=e&&""!==e&&!t.some((t=>t.value===e)))&&(s||n.set(i.name,e),a?.(e))}renderRadioButtonsInputField(e,t,i){const{value:n}=e,s=t.map((t=>this.renderRadioButton({key:t.name,label:t.name,name:e.name,value:t.value,selected:t.value===n,props:i})));this._registerIncompatibleValue(n,t,e);const l=a(e.fieldElement)||c(e.fieldElement,"radio-buttons")&&e.fieldElement.input.showNoValueOption;if(!e.required&&l){const t="",a=c(e.fieldElement,"radio-buttons")&&e.fieldElement.input.noValueOptionLabel||this.messages.empty,l=n===t||null===n;s.unshift(this.renderRadioButton({key:"empty-option",label:a,name:e.name,value:t,selected:l,props:i}))}return v("div",{key:`${i.key}-radio`,class:d.inputRadioGroup},s)}renderSwitchInputField(e,t){const{value:i}=e,a=!!c(e.fieldElement,"switch")&&i===e.fieldElement.input.onValue;return v("calcite-switch",{...t,class:d.inputSwitch,onCalciteSwitchChange:e=>this._commitInputValue(e.target),checked:a,disabled:t.readOnly})}renderRadioButton({key:e,name:t,value:i,selected:a,label:n,props:s}){return v("label",{key:e,class:d.inputRadioLabel},v("input",{...s,class:d.inputRadio,name:t,type:"radio",value:i,checked:a,disabled:s.readOnly,onchange:e=>this._commitInputValue(e.target)}),n)}renderAuxiliaryText(e){const t=this._userUpdatedInputFieldNames.has(e.name)&&!e.valid?e.errorMessage:i(this.viewModel.contingencyConstraintViolations.get(e.name))?this.messages.validationErrors.valuesIncompatible:i(e.valueExpressionExecutor)&&e.valueExpressionExecutor.stale?this.messages.valueExpressionError:null;return i(t)?v("calcite-input-message",{status:"invalid",icon:!0},t):e.description?v("div",{key:"description",class:d.description},e.description):null}getCommonInputProps(e){const{disabled:t,groupDisplay:a}=this,{editable:n,group:s,hint:l,label:r,maxLength:o,minLength:u,name:p,required:c,type:m,valid:h,value:f}=e,g=this._userUpdatedInputFieldNames.has(p),b=!n||t,v="all"===a&&i(s)&&"collapsed"===s.state;return{afterCreate:this._afterInputCreateOrUpdate,afterUpdate:this._afterInputCreateOrUpdate,"aria-invalid":h?"false":"true",class:this.classes(d.input,d.inputField,b?d.inputDisabled:null,g&&!h?d.inputInvalid:null),key:p,label:r,minlength:u>-1?`${u}`:"",maxlength:o>-1?`${o}`:"",...this._getNumberFieldConstraints(e),readOnly:b,value:null==f?"":`${f}`,[y]:p,onfocus:this._handleInputFocus,oninput:this._handleInputInput,onblur:this._handleInputBlur,onkeydown:this._handleInputKeyDown,onmousedown:"number"===m?this._handleNumberInputMouseDown:null,placeholder:"number"===m||"text"===m?l:"",required:c,tabIndex:v?-1:0}}_isInputFieldInGroup(e){return!p(e)&&i(e.group)}_handleNumberInputMouseDown({target:e}){e.focus(),this.scheduleRender()}_getFieldValueOptions(e,t){const i=t.codedValues.map((({code:e,name:t})=>({value:e,name:t}))),a=this.viewModel.fieldsWithContingentValues.has(e)?this._getContingentValueOptions(e):[];if(a.length>0){const e=new Set(a.map((e=>e.value)));return[a,i.filter((t=>!e.has(t.value)))]}return[i,[]]}_getContingentValueOptions(e){const t={};for(const s of this.viewModel.allInputFields){const{name:i,value:n}=s;!a(n)&&i!==e&&this.viewModel.fieldsWithContingentValues.has(i)&&(t[i]=n)}const i=this.viewModel.joinedContingentValues.slice(),n=new Map;for(const s of i){const i=s.values[e];if(a(i)||"code"!==i.objectType&&"null"!==i.objectType)continue;const{code:l,name:r}=i.codedValue&&"null"!==i.objectType?i.codedValue:{code:"",name:this.messages.empty};if(n.has(l))continue;Object.entries(t).every((([e,t])=>!s.values.hasOwnProperty(e)||this._valueIsValidContingentValue(t,s.values[e])))&&n.set(l,{name:r,value:l})}return[...n.values()]}_getInputFieldFromInput(e){return this.viewModel.findField(e.getAttribute(y))}_getNumberFieldConstraints(e){const t=r(e.domain)||o(e.field);return t&&t.max!==Number.MAX_VALUE&&t.min!==Number.MIN_VALUE?t:{min:null,max:null}}async _afterDateInputCreate(e){!V(e)&&i(e.value)&&"setValue"in e&&e.setValue({value:e.value,origin:"external"}),this._afterDateInputCreateOrUpdate(e)}_afterDateInputCreateOrUpdate(e){const{name:t}=this._getInputFieldFromInput(e),a=this._dateInputFieldMap.get(t),n=V(e);i(a)?n?a.date=e:a.time=e:this._dateInputFieldMap.set(t,{[n?"date":"time"]:e}),this._afterInputCreateOrUpdate(e)}_afterInputCreateOrUpdate(e){const{viewModel:t}=this,i=this._getInputFieldFromInput(e),a=t.findField(this._activeInputName),n=this._fieldToInitialIncompatibleDomainValue.get(i.name)===i.value;this._fieldFocusNeeded&&a===i&&("radio-buttons"!==i.inputType||n||e.checked)&&(this._fieldFocusNeeded=!1,this._isInputFieldInGroup(i)&&(i.group.state="expanded"),e.focus())}_handleInputFocus(e){const t=e.target,i=this._getInputFieldFromInput(t);this._activeInputName=i.name,this._isNumberInputField(i)&&(this._activeNumberFieldEdit={fieldName:i.name,input:t,value:t.value})}_isNumberInputField({domain:e,inputType:t="text-box",type:i}){return"number"===i&&"text-box"===t&&(!e||"coded-value"!==e.type)}_handleInputBlur(e){const t=e.target,a=this._getInputFieldFromInput(t);"number"===a.type&&i(this._activeNumberFieldEdit)&&(this._activeNumberFieldEdit.input.value=`${a.value}`,this._activeNumberFieldEdit=null),this._commitInputValue(t),this.scheduleRender()}_commitDateChanges(e,t=!1){const{name:i}=this._getInputFieldFromInput(e);if(!this._dateInputFieldMap.has(i))return;const a=this._dateInputFieldMap.get(i);if(!a||!a.date)return;const n=this._getFieldValueFromDateInput(e),s=this._getFieldValueFromDateInputs(a.date,a.time);this.viewModel.getValue(i)!==s&&(null!==n&&null!==s?this._updateFieldValue(i,s):t&&this._updateFieldValue(i,null))}_commitInputValue(e){const t=this._getInputFieldFromInput(e);i(this._activeNumberFieldEdit)&&this._isNumberInputField(t)&&(this._activeNumberFieldEdit.value=e.value),this._updateFieldValue(t.name,this._parseValue(e))}_handleInputKeyDown(e){const{key:t,altKey:i,ctrlKey:a,metaKey:n}=e,s=this._getInputFieldFromInput(e.target);if("Enter"===t)this._isInputFieldInGroup(s)&&"collapsed"===s.group.state&&(s.group.state="expanded");else{const{type:l}=s.field,r="single"===l||"double"===l;if(("integer"===l||"small-integer"===l||r)&&(!i&&!a&&!n)&&1===t.length){const i=Number(t),a=["-","+"],n=["e","."],s=r?[...a,...n]:a;isNaN(i)&&!s.includes(t)&&e.preventDefault()}}}_updateFieldValue(e,t){if(this.viewModel.setValue(e,t),this._userUpdatedInputFieldNames.add(e),this.viewModel.fieldsWithContingentValues.has(e)){const e=Object.fromEntries(Object.entries(this.getValues()).filter((([e,t])=>i(t))));this.viewModel.validateContingencyConstraints(e)}}_parseValue(e){const t=this._getInputFieldFromInput(e),i=e.value;if(c(t.fieldElement,"switch")&&"CALCITE-COMBOBOX"!==e.tagName)return e.checked?t.fieldElement.input.onValue:t.fieldElement.input.offValue;if("radio-buttons"===t.inputType&&"radio"===e.type&&!e.checked)return t.value;const{type:a}=t;return"number"===a?i?parseFloat(i):null:i}_handleOptionChange(e){this._commitInputValue(e),this.scheduleRender()}_handleGroupClick(e){const t=e.currentTarget["data-group"],i="expanded"===t.state,a="sequential"===this.groupDisplay,n=`.${d.groupHeader}`;if(!(i&&!e.target.closest(n))){if(this._activeInputName=this._getFocusableInput("forward",t)?.name||"",a){const a=e.target.closest(n);if(i&&!a)return;this.viewModel.inputFields.forEach((e=>{p(e)&&e!==t&&(e.state="collapsed")}))}t.state=i?"collapsed":"expanded",this._fieldFocusNeeded=a,this.scheduleRender()}}_handleSubmit(e){e.preventDefault()}_handleFormKeyDown(e){"Enter"===e.key&&this.viewModel.submit()}_getDefaultLocaleOptions(){return{locale:I(),numberingSystem:w}}_getFieldValueFromDateInputs(e,t){const a=this._getDateTimeFromInput(e),n=this._getDateTimeFromInput(t);if(!a&&!n)return null;const s=this._getInputFieldFromInput(e),l=this._getNumberFieldConstraints(s),r=Date.now(),o=i(l.max)&&l.max<r?l.max:r,u=_.fromMillis(o,this._getDefaultLocaleOptions()),d=a||u,{year:p,month:c,day:m}=d,{hour:h,minute:f,second:g}=n||u,b=d.set({year:p,month:c,day:m,hour:h,minute:f,second:g});return b.isValid?b.toMillis():null}_getDateTimeFromInput(e){if(!e)return null;let t=null;if(V(e)){const i=e.valueAsDate;if(!i||Array.isArray(i))return null;t=_.fromJSDate(i)}else{if(!e.value)return null;t=_.fromFormat(e.value,F,this._getDefaultLocaleOptions())}return t??null}_getFieldValueFromDateInput(e){return this._dateTimeToFieldValue(this._getDateTimeFromInput(e))}_dateTimeToFieldValue(e){return e?.isValid?e.toMillis():null}_dateTimeFromFieldValue(e){return null===e?null:_.fromMillis(e,this._getDefaultLocaleOptions())}_formatValueForDateInputs(e){if(null==e||isNaN(e))return{date:null,time:null};const t=this._dateTimeFromFieldValue(e);return t?{date:t.toJSDate(),time:t.toFormat(F,this._getDefaultLocaleOptions())}:{date:null,time:null}}_valueIsValidContingentValue(e,a){switch(a.objectType){case"any":return!0;case"null":return null==e;case"code":return e===a.codedValue?.code;case"range":return i(e)&&i(a.minValue)&&i(a.maxValue)&&e>=a.minValue&&e<=a.maxValue;default:return t(a.objectType),!1}}};e([s()],D.prototype,"disabled",void 0),e([s()],D.prototype,"feature",null),e([s()],D.prototype,"formTemplate",null),e([s()],D.prototype,"groupDisplay",void 0),e([s()],D.prototype,"headingLevel",void 0),e([s()],D.prototype,"label",null),e([s()],D.prototype,"layer",null),e([s(),g("esri/widgets/FeatureForm/t9n/FeatureForm")],D.prototype,"messages",void 0),e([s(),g("esri/widgets/FeatureTemplates/t9n/FeatureTemplates")],D.prototype,"messagesTemplates",void 0),e([s()],D.prototype,"spatialReference",null),e([s()],D.prototype,"strict",null),e([s()],D.prototype,"view",null),e([s(),b(["value-change","submit"])],D.prototype,"viewModel",void 0),D=e([l("esri.widgets.FeatureForm")],D);const x=D;export{x as default};