@open-pioneer/feature-editing 1.4.0-dev.20260727093741 → 1.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +3 -1
- package/api/editor/context.js.map +1 -1
- package/api/editor/editor.d.ts +2 -2
- package/api/editor/editor.js.map +1 -1
- package/api/model/InteractionOptions.d.ts +1 -1
- package/implementation/FeatureEditor.js.map +1 -1
- package/implementation/components/action-selector/ActionSelector.js.map +1 -1
- package/implementation/components/action-selector/DrawingControls.js.map +1 -1
- package/implementation/components/action-selector/SelectButton.js.map +1 -1
- package/implementation/components/action-selector/TemplateItem.js.map +1 -1
- package/implementation/components/action-selector/TemplateSelector.js.map +1 -1
- package/implementation/components/controls/ColorPickerControl.js +1 -1
- package/implementation/components/controls/ColorPickerControl.js.map +1 -1
- package/implementation/components/controls/ComboBoxControl.js.map +1 -1
- package/implementation/components/controls/DefaultControl.js +1 -1
- package/implementation/components/controls/DefaultControl.js.map +1 -1
- package/implementation/components/controls/NumberFieldControl.js.map +1 -1
- package/implementation/components/controls/RadioGroupControl.js.map +1 -1
- package/implementation/components/controls/SelectControl.js.map +1 -1
- package/implementation/components/controls/option-hooks.js.map +1 -1
- package/implementation/components/property-editor/ButtonRow.js +1 -1
- package/implementation/components/property-editor/ButtonRow.js.map +1 -1
- package/implementation/components/property-editor/CancelConfirmationDialog.js.map +1 -1
- package/implementation/components/property-editor/DeleteConfirmationDialog.js.map +1 -1
- package/implementation/components/property-editor/PropertyEditor.js +6 -3
- package/implementation/components/property-editor/PropertyEditor.js.map +1 -1
- package/implementation/components/property-editor/PropertyField.js.map +1 -1
- package/implementation/components/property-editor/PropertyForm.js +1 -1
- package/implementation/components/property-editor/PropertyForm.js.map +1 -1
- package/implementation/context/PropertyFormContext.js.map +1 -1
- package/implementation/context/usePropertyFormContext.js.map +1 -1
- package/implementation/editor/editorHooks.d.ts +1 -1
- package/implementation/editor/editorHooks.js +1 -1
- package/implementation/editor/editorHooks.js.map +1 -1
- package/implementation/editor/useEditingCallbacks.d.ts +1 -1
- package/implementation/editor/useEditingCallbacks.js +1 -1
- package/implementation/editor/useEditingCallbacks.js.map +1 -1
- package/implementation/geometry-editing/controller/DrawingSession.js.map +1 -1
- package/implementation/geometry-editing/controller/EditingController.d.ts +2 -2
- package/implementation/geometry-editing/controller/EditingController.js.map +1 -1
- package/implementation/geometry-editing/controller/UndoManager.js.map +1 -1
- package/implementation/geometry-editing/controller/geometryState.js.map +1 -1
- package/implementation/geometry-editing/interactions/BaseInteraction.js.map +1 -1
- package/implementation/geometry-editing/interactions/DoubleClickInteraction.js.map +1 -1
- package/implementation/geometry-editing/interactions/DrawingInteraction.d.ts +4 -4
- package/implementation/geometry-editing/interactions/DrawingInteraction.js +2 -2
- package/implementation/geometry-editing/interactions/DrawingInteraction.js.map +1 -1
- package/implementation/geometry-editing/interactions/HighlightingInteraction.js.map +1 -1
- package/implementation/geometry-editing/interactions/KeyboardInteraction.d.ts +1 -1
- package/implementation/geometry-editing/interactions/KeyboardInteraction.js.map +1 -1
- package/implementation/geometry-editing/interactions/ModificationInteraction.d.ts +1 -1
- package/implementation/geometry-editing/interactions/ModificationInteraction.js.map +1 -1
- package/implementation/geometry-editing/interactions/SelectionInteraction.d.ts +2 -2
- package/implementation/geometry-editing/interactions/SelectionInteraction.js +1 -1
- package/implementation/geometry-editing/interactions/SelectionInteraction.js.map +1 -1
- package/implementation/geometry-editing/interactions/SnappingInteraction.d.ts +1 -1
- package/implementation/geometry-editing/interactions/SnappingInteraction.js.map +1 -1
- package/implementation/geometry-editing/useGeometryEditing.d.ts +1 -1
- package/implementation/geometry-editing/useGeometryEditing.js.map +1 -1
- package/package.json +9 -9
|
@@ -3,13 +3,13 @@ import { Flex, useDisclosure } from '@chakra-ui/react';
|
|
|
3
3
|
import { useEvent } from '@open-pioneer/react-utils';
|
|
4
4
|
import { useReactiveSnapshot } from '@open-pioneer/reactivity';
|
|
5
5
|
import { useMemo, useCallback } from 'react';
|
|
6
|
+
import { DeclarativeFormContext, CustomFormContextImpl, FormContext } from '../../context/PropertyFormContext.js';
|
|
7
|
+
import { usePropertyFormContext } from '../../context/usePropertyFormContext.js';
|
|
6
8
|
import { ButtonRow } from './ButtonRow.js';
|
|
7
9
|
import { CancelConfirmationDialog } from './CancelConfirmationDialog.js';
|
|
8
10
|
import { DeleteConfirmationDialog } from './DeleteConfirmationDialog.js';
|
|
9
|
-
import { DeclarativeFormContext, CustomFormContextImpl, FormContext } from '../../context/PropertyFormContext.js';
|
|
10
11
|
import { PropertyField } from './PropertyField.js';
|
|
11
12
|
import { PropertyForm } from './PropertyForm.js';
|
|
12
|
-
import { usePropertyFormContext } from '../../context/usePropertyFormContext.js';
|
|
13
13
|
|
|
14
14
|
function PropertyEditor(props) {
|
|
15
15
|
const { editingStep, callbacks, templates, resolveFormTemplate } = props;
|
|
@@ -32,7 +32,10 @@ function PropertyEditor(props) {
|
|
|
32
32
|
height: "full",
|
|
33
33
|
overflowY: "hidden",
|
|
34
34
|
children: [
|
|
35
|
-
/* @__PURE__ */ jsx(PropertyForm, { children: formTemplate.kind === "dynamic" ? formTemplate.renderForm() : formTemplate.fields.map((field, index) =>
|
|
35
|
+
/* @__PURE__ */ jsx(PropertyForm, { children: formTemplate.kind === "dynamic" ? formTemplate.renderForm() : formTemplate.fields.map((field, index) => (
|
|
36
|
+
// oxlint-disable-next-line react/no-array-index-key
|
|
37
|
+
/* @__PURE__ */ jsx(PropertyField, { field }, index)
|
|
38
|
+
)) }),
|
|
36
39
|
/* @__PURE__ */ jsx(EditorControls, {})
|
|
37
40
|
]
|
|
38
41
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PropertyEditor.js","sources":["PropertyEditor.tsx"],"sourcesContent":["// SPDX-FileCopyrightText: 2023-2025 Open Pioneer project (https://github.com/open-pioneer)\n// SPDX-License-Identifier: Apache-2.0\nimport { Flex, useDisclosure } from \"@chakra-ui/react\";\nimport { useEvent } from \"@open-pioneer/react-utils\";\nimport { useReactiveSnapshot } from \"@open-pioneer/reactivity\";\nimport { useCallback, useMemo, type ReactElement } from \"react\";\nimport {
|
|
1
|
+
{"version":3,"file":"PropertyEditor.js","sources":["PropertyEditor.tsx"],"sourcesContent":["// SPDX-FileCopyrightText: 2023-2025 Open Pioneer project (https://github.com/open-pioneer)\n// SPDX-License-Identifier: Apache-2.0\n\nimport { Flex, useDisclosure } from \"@chakra-ui/react\";\nimport { useEvent } from \"@open-pioneer/react-utils\";\nimport { useReactiveSnapshot } from \"@open-pioneer/reactivity\";\nimport { useCallback, useMemo, type ReactElement } from \"react\";\nimport { FeatureEditorProps, FormTemplateContext } from \"../../../api/editor/editor\";\nimport { CreationStep, UpdateStep } from \"../../../api/model/EditingStep\";\nimport { FeatureTemplate, FormTemplate } from \"../../../api/model/FeatureTemplate\";\nimport {\n DeclarativeFormContext,\n CustomFormContextImpl,\n FormContext\n} from \"../../context/PropertyFormContext\";\nimport { usePropertyFormContext } from \"../../context/usePropertyFormContext\";\nimport { EditingCallbacks } from \"../../editor/useEditingCallbacks\";\nimport { ButtonRow } from \"./ButtonRow\";\nimport { CancelConfirmationDialog } from \"./CancelConfirmationDialog\";\nimport { DeleteConfirmationDialog } from \"./DeleteConfirmationDialog\";\nimport { PropertyField } from \"./PropertyField\";\nimport { PropertyForm } from \"./PropertyForm\";\n\nexport function PropertyEditor(props: {\n editingStep: CreationStep | UpdateStep;\n callbacks: EditingCallbacks;\n templates: FeatureTemplate[];\n resolveFormTemplate: FeatureEditorProps[\"resolveFormTemplate\"];\n}) {\n const { editingStep, callbacks, templates, resolveFormTemplate } = props;\n const formTemplate = useFormTemplate(templates, resolveFormTemplate, editingStep);\n\n const context = useMemo(() => {\n if (!formTemplate) {\n return undefined;\n }\n\n if (formTemplate.kind === \"declarative\") {\n return new DeclarativeFormContext(editingStep, callbacks, formTemplate);\n } else {\n return new CustomFormContextImpl(editingStep, callbacks, formTemplate);\n }\n }, [formTemplate, editingStep, callbacks]);\n\n return (\n context &&\n formTemplate && (\n <FormContext value={context}>\n <Flex\n className=\"editor__property-editor\"\n direction=\"column\"\n height=\"full\"\n overflowY={\"hidden\"}\n >\n <PropertyForm>\n {formTemplate.kind === \"dynamic\"\n ? formTemplate.renderForm()\n : formTemplate.fields.map((field, index) => (\n // oxlint-disable-next-line react/no-array-index-key\n <PropertyField key={index} field={field} />\n ))}\n </PropertyForm>\n <EditorControls />\n </Flex>\n </FormContext>\n )\n );\n}\n\nfunction useFormTemplate(\n templates: FeatureTemplate[],\n customResolver: FeatureEditorProps[\"resolveFormTemplate\"],\n editingStep: CreationStep | UpdateStep\n): FormTemplate | undefined {\n const defaultResolver = useDefaultFormTemplateResolver(templates);\n const resolveFormTemplate = customResolver ?? defaultResolver;\n\n const feature = editingStep.feature;\n const layer = editingStep.id === \"update\" ? editingStep.layer : undefined;\n const explicitTemplate = editingStep.id === \"creation\" ? editingStep.template : undefined;\n\n return useMemo(() => {\n if (explicitTemplate) {\n return explicitTemplate;\n } else if (editingStep.id === \"update\") {\n return resolveFormTemplate({ feature, layer });\n } else {\n return undefined;\n }\n }, [explicitTemplate, editingStep.id, feature, layer, resolveFormTemplate]);\n}\n\nfunction useDefaultFormTemplateResolver(templates: FeatureTemplate[]) {\n return useCallback(\n ({ layer }: FormTemplateContext) => {\n if (layer?.id != null) {\n return templates.find(({ layerId }) => layer.id === layerId);\n } else {\n return undefined;\n }\n },\n [templates]\n );\n}\n\nfunction EditorControls(): ReactElement {\n const context = usePropertyFormContext();\n const canSave = useReactiveSnapshot(() => context.isValid, [context]);\n\n const {\n open: deleteDialogIsOpen,\n onOpen: openDeleteDialog,\n onClose: closeDeleteDialog\n } = useDisclosure();\n const {\n open: cancelDialogIsOpen,\n onOpen: openCancelDialog,\n onClose: closeCancelConfirmationDialog\n } = useDisclosure();\n\n const onSaveClick = useEvent(async () => {\n const properties = context.getPropertiesAsObject();\n context.feature.setProperties(properties);\n await context.callbacks.onSave();\n });\n\n const onDeleteClick = useEvent(async () => {\n await context.callbacks.onDelete();\n closeDeleteDialog();\n });\n\n const onConfirmCancelClick = useEvent(() => {\n context.callbacks.onCancel();\n closeCancelConfirmationDialog();\n });\n\n return (\n <>\n <ButtonRow\n canSave={canSave}\n showDeleteButton={context.mode === \"update\"}\n onSave={onSaveClick}\n onDelete={openDeleteDialog}\n onCancel={openCancelDialog}\n />\n <DeleteConfirmationDialog\n isOpen={deleteDialogIsOpen}\n onDelete={onDeleteClick}\n onCancel={closeDeleteDialog}\n />\n <CancelConfirmationDialog\n isOpen={cancelDialogIsOpen}\n onConfirmCancel={onConfirmCancelClick}\n onAbortCancel={closeCancelConfirmationDialog}\n />\n </>\n );\n}\n"],"names":[],"mappings":";;;;;;;;;;;;;AAuBO,SAAS,eAAe,KAAA,EAK5B;AACC,EAAA,MAAM,EAAE,WAAA,EAAa,SAAA,EAAW,SAAA,EAAW,qBAAoB,GAAI,KAAA;AACnE,EAAA,MAAM,YAAA,GAAe,eAAA,CAAgB,SAAA,EAAW,mBAAA,EAAqB,WAAW,CAAA;AAEhF,EAAA,MAAM,OAAA,GAAU,QAAQ,MAAM;AAC1B,IAAA,IAAI,CAAC,YAAA,EAAc;AACf,MAAA,OAAO,MAAA;AAAA,IACX;AAEA,IAAA,IAAI,YAAA,CAAa,SAAS,aAAA,EAAe;AACrC,MAAA,OAAO,IAAI,sBAAA,CAAuB,WAAA,EAAa,SAAA,EAAW,YAAY,CAAA;AAAA,IAC1E,CAAA,MAAO;AACH,MAAA,OAAO,IAAI,qBAAA,CAAsB,WAAA,EAAa,SAAA,EAAW,YAAY,CAAA;AAAA,IACzE;AAAA,EACJ,CAAA,EAAG,CAAC,YAAA,EAAc,WAAA,EAAa,SAAS,CAAC,CAAA;AAEzC,EAAA,OACI,OAAA,IACA,YAAA,oBACI,GAAA,CAAC,WAAA,EAAA,EAAY,OAAO,OAAA,EAChB,QAAA,kBAAA,IAAA;AAAA,IAAC,IAAA;AAAA,IAAA;AAAA,MACG,SAAA,EAAU,yBAAA;AAAA,MACV,SAAA,EAAU,QAAA;AAAA,MACV,MAAA,EAAO,MAAA;AAAA,MACP,SAAA,EAAW,QAAA;AAAA,MAEX,QAAA,EAAA;AAAA,wBAAA,GAAA,CAAC,YAAA,EAAA,EACI,QAAA,EAAA,YAAA,CAAa,IAAA,KAAS,SAAA,GACjB,YAAA,CAAa,UAAA,EAAW,GACxB,YAAA,CAAa,MAAA,CAAO,GAAA,CAAI,CAAC,KAAA,EAAO,KAAA;AAAA;AAAA,0BAE5B,GAAA,CAAC,aAAA,EAAA,EAA0B,KAAA,EAAA,EAAP,KAAqB;AAAA,SAC5C,CAAA,EACX,CAAA;AAAA,4BACC,cAAA,EAAA,EAAe;AAAA;AAAA;AAAA,GACpB,EACJ,CAAA;AAGZ;AAEA,SAAS,eAAA,CACL,SAAA,EACA,cAAA,EACA,WAAA,EACwB;AACxB,EAAA,MAAM,eAAA,GAAkB,+BAA+B,SAAS,CAAA;AAChE,EAAA,MAAM,sBAAsB,cAAA,IAAkB,eAAA;AAE9C,EAAA,MAAM,UAAU,WAAA,CAAY,OAAA;AAC5B,EAAA,MAAM,KAAA,GAAQ,WAAA,CAAY,EAAA,KAAO,QAAA,GAAW,YAAY,KAAA,GAAQ,MAAA;AAChE,EAAA,MAAM,gBAAA,GAAmB,WAAA,CAAY,EAAA,KAAO,UAAA,GAAa,YAAY,QAAA,GAAW,MAAA;AAEhF,EAAA,OAAO,QAAQ,MAAM;AACjB,IAAA,IAAI,gBAAA,EAAkB;AAClB,MAAA,OAAO,gBAAA;AAAA,IACX,CAAA,MAAA,IAAW,WAAA,CAAY,EAAA,KAAO,QAAA,EAAU;AACpC,MAAA,OAAO,mBAAA,CAAoB,EAAE,OAAA,EAAS,KAAA,EAAO,CAAA;AAAA,IACjD,CAAA,MAAO;AACH,MAAA,OAAO,MAAA;AAAA,IACX;AAAA,EACJ,CAAA,EAAG,CAAC,gBAAA,EAAkB,WAAA,CAAY,IAAI,OAAA,EAAS,KAAA,EAAO,mBAAmB,CAAC,CAAA;AAC9E;AAEA,SAAS,+BAA+B,SAAA,EAA8B;AAClE,EAAA,OAAO,WAAA;AAAA,IACH,CAAC,EAAE,KAAA,EAAM,KAA2B;AAChC,MAAA,IAAI,KAAA,EAAO,MAAM,IAAA,EAAM;AACnB,QAAA,OAAO,SAAA,CAAU,KAAK,CAAC,EAAE,SAAQ,KAAM,KAAA,CAAM,OAAO,OAAO,CAAA;AAAA,MAC/D,CAAA,MAAO;AACH,QAAA,OAAO,MAAA;AAAA,MACX;AAAA,IACJ,CAAA;AAAA,IACA,CAAC,SAAS;AAAA,GACd;AACJ;AAEA,SAAS,cAAA,GAA+B;AACpC,EAAA,MAAM,UAAU,sBAAA,EAAuB;AACvC,EAAA,MAAM,UAAU,mBAAA,CAAoB,MAAM,QAAQ,OAAA,EAAS,CAAC,OAAO,CAAC,CAAA;AAEpE,EAAA,MAAM;AAAA,IACF,IAAA,EAAM,kBAAA;AAAA,IACN,MAAA,EAAQ,gBAAA;AAAA,IACR,OAAA,EAAS;AAAA,MACT,aAAA,EAAc;AAClB,EAAA,MAAM;AAAA,IACF,IAAA,EAAM,kBAAA;AAAA,IACN,MAAA,EAAQ,gBAAA;AAAA,IACR,OAAA,EAAS;AAAA,MACT,aAAA,EAAc;AAElB,EAAA,MAAM,WAAA,GAAc,SAAS,YAAY;AACrC,IAAA,MAAM,UAAA,GAAa,QAAQ,qBAAA,EAAsB;AACjD,IAAA,OAAA,CAAQ,OAAA,CAAQ,cAAc,UAAU,CAAA;AACxC,IAAA,MAAM,OAAA,CAAQ,UAAU,MAAA,EAAO;AAAA,EACnC,CAAC,CAAA;AAED,EAAA,MAAM,aAAA,GAAgB,SAAS,YAAY;AACvC,IAAA,MAAM,OAAA,CAAQ,UAAU,QAAA,EAAS;AACjC,IAAA,iBAAA,EAAkB;AAAA,EACtB,CAAC,CAAA;AAED,EAAA,MAAM,oBAAA,GAAuB,SAAS,MAAM;AACxC,IAAA,OAAA,CAAQ,UAAU,QAAA,EAAS;AAC3B,IAAA,6BAAA,EAA8B;AAAA,EAClC,CAAC,CAAA;AAED,EAAA,uBACI,IAAA,CAAA,QAAA,EAAA,EACI,QAAA,EAAA;AAAA,oBAAA,GAAA;AAAA,MAAC,SAAA;AAAA,MAAA;AAAA,QACG,OAAA;AAAA,QACA,gBAAA,EAAkB,QAAQ,IAAA,KAAS,QAAA;AAAA,QACnC,MAAA,EAAQ,WAAA;AAAA,QACR,QAAA,EAAU,gBAAA;AAAA,QACV,QAAA,EAAU;AAAA;AAAA,KACd;AAAA,oBACA,GAAA;AAAA,MAAC,wBAAA;AAAA,MAAA;AAAA,QACG,MAAA,EAAQ,kBAAA;AAAA,QACR,QAAA,EAAU,aAAA;AAAA,QACV,QAAA,EAAU;AAAA;AAAA,KACd;AAAA,oBACA,GAAA;AAAA,MAAC,wBAAA;AAAA,MAAA;AAAA,QACG,MAAA,EAAQ,kBAAA;AAAA,QACR,eAAA,EAAiB,oBAAA;AAAA,QACjB,aAAA,EAAe;AAAA;AAAA;AACnB,GAAA,EACJ,CAAA;AAER;;;;"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PropertyField.js","sources":["PropertyField.tsx"],"sourcesContent":["// SPDX-FileCopyrightText: 2023-2025 Open Pioneer project (https://github.com/open-pioneer)\n// SPDX-License-Identifier: Apache-2.0\nimport { Field } from \"@chakra-ui/react\";\nimport { useReactiveSnapshot } from \"@open-pioneer/reactivity\";\nimport { useIntl } from \"open-pioneer:react-hooks\";\nimport { useMemo, useState, type ReactElement } from \"react\";\nimport type { PropertyFunction, PropertyFunctionOr } from \"../../../api/fields/BaseFieldConfig\";\nimport type { FieldConfig } from \"../../../api/fields/FieldConfig\";\nimport {\n useDeclarativeFormContext,\n usePropertyFormContext\n} from \"../../context/usePropertyFormContext\";\nimport { DefaultControl } from \"../controls/DefaultControl\";\n\nexport interface PropertyFieldProps {\n readonly field: FieldConfig;\n}\n\nexport function PropertyField({ field }: PropertyFieldProps): ReactElement | undefined {\n const context = useDeclarativeFormContext();\n const isRequired = useValue(field.isRequired) ?? false;\n const isEnabled = useValue(field.isEnabled) ?? true;\n const isVisible = useValue(field.isVisible) ?? true;\n const isValid = useReactiveSnapshot(() => context.isFieldValid(field), [context, field]);\n\n const defaultErrorText = useDefaultErrorText(field);\n const errorText = useValue(field.errorText) ?? defaultErrorText;\n const helperText = useValue(field.helperText);\n\n const [hadFocus, setHadFocus] = useState(false);\n\n if (isVisible) {\n return (\n <Field.Root\n className=\"editor__property-field\"\n required={isRequired}\n disabled={!isEnabled}\n invalid={hadFocus && !isValid}\n data-editor-property-name={field.propertyName}\n onFocus={() => {\n setHadFocus(true);\n }}\n >\n <Field.Label>\n {field.label}\n <Field.RequiredIndicator />\n </Field.Label>\n <DefaultControl field={field} />\n {helperText && <Field.HelperText>{helperText}</Field.HelperText>}\n {errorText && <Field.ErrorText>{errorText}</Field.ErrorText>}\n </Field.Root>\n );\n } else {\n return undefined;\n }\n}\n\nfunction useDefaultErrorText(field: FieldConfig): string | undefined {\n const intl = useIntl();\n return useMemo(() => {\n if (field.type !== \"number-field\" || (field.min == null && field.max == null)) {\n return undefined;\n }\n\n const { min, max } = field;\n let messageId;\n if (min != null && max != null) {\n messageId = \"propertyEditor.errors.minAndMax\";\n } else if (min != null) {\n messageId = \"propertyEditor.errors.minOnly\";\n } else {\n messageId = \"propertyEditor.errors.maxOnly\";\n }\n return intl.formatMessage({ id: messageId }, { min, max });\n }, [intl, field]);\n}\n\nfunction useValue<T>(value: PropertyFunctionOr<T> | undefined): T | undefined {\n const context = usePropertyFormContext();\n\n return useReactiveSnapshot(() => {\n if (isPropertyFunction(value)) {\n const properties = context.getPropertiesAsObject();\n return value(properties);\n } else {\n return value;\n }\n }, [context, value]);\n}\n\nfunction isPropertyFunction<T>(value: PropertyFunctionOr<T>): value is PropertyFunction<T> {\n return typeof value === \"function\";\n}\n"],"names":[],"mappings":";;;;;;;;
|
|
1
|
+
{"version":3,"file":"PropertyField.js","sources":["PropertyField.tsx"],"sourcesContent":["// SPDX-FileCopyrightText: 2023-2025 Open Pioneer project (https://github.com/open-pioneer)\n// SPDX-License-Identifier: Apache-2.0\n\nimport { Field } from \"@chakra-ui/react\";\nimport { useReactiveSnapshot } from \"@open-pioneer/reactivity\";\nimport { useIntl } from \"open-pioneer:react-hooks\";\nimport { useMemo, useState, type ReactElement } from \"react\";\nimport type { PropertyFunction, PropertyFunctionOr } from \"../../../api/fields/BaseFieldConfig\";\nimport type { FieldConfig } from \"../../../api/fields/FieldConfig\";\nimport {\n useDeclarativeFormContext,\n usePropertyFormContext\n} from \"../../context/usePropertyFormContext\";\nimport { DefaultControl } from \"../controls/DefaultControl\";\n\nexport interface PropertyFieldProps {\n readonly field: FieldConfig;\n}\n\nexport function PropertyField({ field }: PropertyFieldProps): ReactElement | undefined {\n const context = useDeclarativeFormContext();\n const isRequired = useValue(field.isRequired) ?? false;\n const isEnabled = useValue(field.isEnabled) ?? true;\n const isVisible = useValue(field.isVisible) ?? true;\n const isValid = useReactiveSnapshot(() => context.isFieldValid(field), [context, field]);\n\n const defaultErrorText = useDefaultErrorText(field);\n const errorText = useValue(field.errorText) ?? defaultErrorText;\n const helperText = useValue(field.helperText);\n\n const [hadFocus, setHadFocus] = useState(false);\n\n if (isVisible) {\n return (\n <Field.Root\n className=\"editor__property-field\"\n required={isRequired}\n disabled={!isEnabled}\n invalid={hadFocus && !isValid}\n data-editor-property-name={field.propertyName}\n onFocus={() => {\n setHadFocus(true);\n }}\n >\n <Field.Label>\n {field.label}\n <Field.RequiredIndicator />\n </Field.Label>\n <DefaultControl field={field} />\n {helperText && <Field.HelperText>{helperText}</Field.HelperText>}\n {errorText && <Field.ErrorText>{errorText}</Field.ErrorText>}\n </Field.Root>\n );\n } else {\n return undefined;\n }\n}\n\nfunction useDefaultErrorText(field: FieldConfig): string | undefined {\n const intl = useIntl();\n return useMemo(() => {\n if (field.type !== \"number-field\" || (field.min == null && field.max == null)) {\n return undefined;\n }\n\n const { min, max } = field;\n let messageId;\n if (min != null && max != null) {\n messageId = \"propertyEditor.errors.minAndMax\";\n } else if (min != null) {\n messageId = \"propertyEditor.errors.minOnly\";\n } else {\n messageId = \"propertyEditor.errors.maxOnly\";\n }\n return intl.formatMessage({ id: messageId }, { min, max });\n }, [intl, field]);\n}\n\nfunction useValue<T>(value: PropertyFunctionOr<T> | undefined): T | undefined {\n const context = usePropertyFormContext();\n\n return useReactiveSnapshot(() => {\n if (isPropertyFunction(value)) {\n const properties = context.getPropertiesAsObject();\n return value(properties);\n } else {\n return value;\n }\n }, [context, value]);\n}\n\nfunction isPropertyFunction<T>(value: PropertyFunctionOr<T>): value is PropertyFunction<T> {\n return typeof value === \"function\";\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { jsx, jsxs } from 'react/jsx-runtime';
|
|
2
2
|
import { Flex, VStack, Text } from '@chakra-ui/react';
|
|
3
3
|
import { TitledSection, SectionHeading } from '@open-pioneer/react-utils';
|
|
4
|
+
import { useReactiveSnapshot } from '@open-pioneer/reactivity';
|
|
4
5
|
import { useIntl } from '../../../_virtual/hooks.js';
|
|
5
6
|
import { usePropertyFormContext } from '../../context/usePropertyFormContext.js';
|
|
6
|
-
import { useReactiveSnapshot } from '@open-pioneer/reactivity';
|
|
7
7
|
|
|
8
8
|
function PropertyForm(props) {
|
|
9
9
|
const { children } = props;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PropertyForm.js","sources":["PropertyForm.tsx"],"sourcesContent":["// SPDX-FileCopyrightText: 2023-2025 Open Pioneer project (https://github.com/open-pioneer)\n// SPDX-License-Identifier: Apache-2.0\nimport { Flex, VStack, Text } from \"@chakra-ui/react\";\nimport { SectionHeading, TitledSection } from \"@open-pioneer/react-utils\";\nimport { useIntl } from \"open-pioneer:react-hooks\";\nimport { ReactNode, type ReactElement } from \"react\";\nimport { usePropertyFormContext } from \"../../context/usePropertyFormContext\";\
|
|
1
|
+
{"version":3,"file":"PropertyForm.js","sources":["PropertyForm.tsx"],"sourcesContent":["// SPDX-FileCopyrightText: 2023-2025 Open Pioneer project (https://github.com/open-pioneer)\n// SPDX-License-Identifier: Apache-2.0\n\nimport { Flex, VStack, Text } from \"@chakra-ui/react\";\nimport { SectionHeading, TitledSection } from \"@open-pioneer/react-utils\";\nimport { useReactiveSnapshot } from \"@open-pioneer/reactivity\";\nimport { useIntl } from \"open-pioneer:react-hooks\";\nimport { ReactNode, type ReactElement } from \"react\";\nimport { usePropertyFormContext } from \"../../context/usePropertyFormContext\";\n\nexport interface PropertyFormProps {\n children?: ReactNode;\n}\n\nexport function PropertyForm(props: PropertyFormProps): ReactElement {\n const { children } = props;\n const heading = useHeading();\n const context = usePropertyFormContext();\n const hasRequiredFields = useReactiveSnapshot(() => context.hasRequiredFields, [context]);\n const { formatRichMessage } = useIntl();\n\n return (\n <TitledSection>\n <Flex\n className=\"editor__property-form\"\n direction={\"column\"}\n flex={1}\n overflowY=\"hidden\"\n >\n <SectionHeading mb={2} size=\"sm\">\n {heading}\n </SectionHeading>\n <VStack\n gap={4}\n align=\"stretch\"\n // for focus ring\n px=\"1px\"\n pb=\"4px\"\n flex={1}\n overflowY={\"auto\"}\n >\n {children}\n </VStack>\n {hasRequiredFields && (\n <Text\n fontSize={\"sm\"}\n aria-hidden=\"true\"\n textAlign={\"right\"}\n paddingRight={2}\n mb={2}\n >\n <Text as=\"span\" color=\"fg.error\">\n *\n </Text>{\" \"}\n {formatRichMessage({ id: \"propertyEditor.requiredFieldHint\" })}\n </Text>\n )}\n </Flex>\n </TitledSection>\n );\n}\n\nfunction useHeading() {\n const intl = useIntl();\n const { mode, formTemplate: template } = usePropertyFormContext();\n const defaultHeading = intl.formatMessage({\n id:\n mode === \"update\"\n ? \"propertyEditor.defaultEditHeading\"\n : \"propertyEditor.defaultCreateHeading\"\n });\n return template?.name ? `${defaultHeading}: ${template?.name} ` : defaultHeading;\n}\n"],"names":[],"mappings":";;;;;;;AAcO,SAAS,aAAa,KAAA,EAAwC;AACjE,EAAA,MAAM,EAAE,UAAS,GAAI,KAAA;AACrB,EAAA,MAAM,UAAU,UAAA,EAAW;AAC3B,EAAA,MAAM,UAAU,sBAAA,EAAuB;AACvC,EAAA,MAAM,oBAAoB,mBAAA,CAAoB,MAAM,QAAQ,iBAAA,EAAmB,CAAC,OAAO,CAAC,CAAA;AACxF,EAAA,MAAM,EAAE,iBAAA,EAAkB,GAAI,OAAA,EAAQ;AAEtC,EAAA,2BACK,aAAA,EAAA,EACG,QAAA,kBAAA,IAAA;AAAA,IAAC,IAAA;AAAA,IAAA;AAAA,MACG,SAAA,EAAU,uBAAA;AAAA,MACV,SAAA,EAAW,QAAA;AAAA,MACX,IAAA,EAAM,CAAA;AAAA,MACN,SAAA,EAAU,QAAA;AAAA,MAEV,QAAA,EAAA;AAAA,wBAAA,GAAA,CAAC,cAAA,EAAA,EAAe,EAAA,EAAI,CAAA,EAAG,IAAA,EAAK,MACvB,QAAA,EAAA,OAAA,EACL,CAAA;AAAA,wBACA,GAAA;AAAA,UAAC,MAAA;AAAA,UAAA;AAAA,YACG,GAAA,EAAK,CAAA;AAAA,YACL,KAAA,EAAM,SAAA;AAAA,YAEN,EAAA,EAAG,KAAA;AAAA,YACH,EAAA,EAAG,KAAA;AAAA,YACH,IAAA,EAAM,CAAA;AAAA,YACN,SAAA,EAAW,MAAA;AAAA,YAEV;AAAA;AAAA,SACL;AAAA,QACC,iBAAA,oBACG,IAAA;AAAA,UAAC,IAAA;AAAA,UAAA;AAAA,YACG,QAAA,EAAU,IAAA;AAAA,YACV,aAAA,EAAY,MAAA;AAAA,YACZ,SAAA,EAAW,OAAA;AAAA,YACX,YAAA,EAAc,CAAA;AAAA,YACd,EAAA,EAAI,CAAA;AAAA,YAEJ,QAAA,EAAA;AAAA,8BAAA,GAAA,CAAC,IAAA,EAAA,EAAK,EAAA,EAAG,MAAA,EAAO,KAAA,EAAM,YAAW,QAAA,EAAA,GAAA,EAEjC,CAAA;AAAA,cAAQ,GAAA;AAAA,cACP,iBAAA,CAAkB,EAAE,EAAA,EAAI,kCAAA,EAAoC;AAAA;AAAA;AAAA;AACjE;AAAA;AAAA,GAER,EACJ,CAAA;AAER;AAEA,SAAS,UAAA,GAAa;AAClB,EAAA,MAAM,OAAO,OAAA,EAAQ;AACrB,EAAA,MAAM,EAAE,IAAA,EAAM,YAAA,EAAc,QAAA,KAAa,sBAAA,EAAuB;AAChE,EAAA,MAAM,cAAA,GAAiB,KAAK,aAAA,CAAc;AAAA,IACtC,EAAA,EACI,IAAA,KAAS,QAAA,GACH,mCAAA,GACA;AAAA,GACb,CAAA;AACD,EAAA,OAAO,UAAU,IAAA,GAAO,CAAA,EAAG,cAAc,CAAA,EAAA,EAAK,QAAA,EAAU,IAAI,CAAA,CAAA,CAAA,GAAM,cAAA;AACtE;;;;"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PropertyFormContext.js","sources":["PropertyFormContext.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2023-2025 Open Pioneer project (https://github.com/open-pioneer)\n// SPDX-License-Identifier: Apache-2.0\nimport {\n computed,\n reactive,\n reactiveMap,\n ReadonlyReactive,\n type ReactiveMap\n} from \"@conterra/reactivity-core\";\nimport type { Layer } from \"@open-pioneer/map\";\nimport type { Feature } from \"ol\";\nimport { createContext } from \"react\";\nimport type { CustomFormContext, Mode } from \"../../api/editor/context\";\nimport { PropertyFunctionOr } from \"../../api/fields/BaseFieldConfig\";\nimport { FieldConfig } from \"../../api/fields/FieldConfig\";\nimport type { ModificationStep } from \"../../api/model/EditingStep\";\nimport type {\n DeclarativeFormTemplate,\n FeatureTemplate,\n FormTemplate\n} from \"../../api/model/FeatureTemplate\";\nimport { EditingCallbacks } from \"../editor/useEditingCallbacks\";\n\nexport abstract class BaseFormContext {\n readonly #propertiesMap: ReactiveMap<string, unknown>;\n readonly #modificationStep: ModificationStep;\n readonly #formTemplate: FormTemplate;\n readonly #propsAsObject: ReadonlyReactive<Record<string, unknown>>;\n\n readonly callbacks: EditingCallbacks;\n\n constructor(\n modificationStep: ModificationStep,\n callbacks: EditingCallbacks,\n formTemplate: FormTemplate\n ) {\n this.#modificationStep = modificationStep;\n this.callbacks = callbacks;\n this.#formTemplate = formTemplate;\n\n const entries = BaseFormContext.#getPropertyEntries(modificationStep.feature);\n this.#propertiesMap = reactiveMap(entries);\n this.#propsAsObject = computed(() => {\n const entries = this.properties.entries();\n const object = Object.fromEntries(entries);\n return object;\n });\n }\n\n getPropertiesAsObject(): Record<string, unknown> {\n return this.#propsAsObject.value;\n }\n\n get feature(): Feature {\n return this.editingStep.feature;\n }\n\n get mode(): Mode {\n return this.editingStep.id === \"creation\" ? \"create\" : \"update\";\n }\n\n get editingStep(): ModificationStep {\n return this.#modificationStep;\n }\n\n get properties(): ReactiveMap<string, unknown> {\n return this.#propertiesMap;\n }\n\n get formTemplate(): FormTemplate {\n return this.#formTemplate;\n }\n\n get template(): FeatureTemplate | undefined {\n return this.editingStep.id === \"creation\" ? this.editingStep.template : undefined;\n }\n\n get layer(): Layer | undefined {\n return this.editingStep.id === \"update\" ? this.editingStep.layer : undefined;\n }\n\n abstract get isValid(): boolean;\n abstract get hasRequiredFields(): boolean;\n\n static #getPropertyEntries(feature: Feature): [string, unknown][] {\n const properties = feature.getProperties();\n const geometryName = feature.getGeometryName();\n return Object.entries(properties).filter(([key, _]) => key !== geometryName);\n }\n}\n\nexport class DeclarativeFormContext extends BaseFormContext {\n readonly #isValid: ReadonlyReactive<boolean>;\n readonly #hasRequiredFields: ReadonlyReactive<boolean>;\n\n constructor(\n modificationStep: ModificationStep,\n callbacks: EditingCallbacks,\n template: DeclarativeFormTemplate\n ) {\n super(modificationStep, callbacks, template);\n\n this.#isValid = computed(() => {\n const props = this.getPropertiesAsObject();\n return this.formTemplate.fields.every((field) => this.#isFieldValidImpl(field, props));\n });\n this.#hasRequiredFields = computed(() => {\n const props = this.getPropertiesAsObject();\n return this.formTemplate.fields.some((field) => isTrue(field.isRequired, props, false));\n });\n }\n\n isFieldValid(field: FieldConfig) {\n const props = this.getPropertiesAsObject();\n return this.#isFieldValidImpl(field, props);\n }\n\n #isFieldValidImpl(field: FieldConfig, props: Record<string, unknown>) {\n const isRequired = isTrue(field.isRequired, props, false);\n const isPresent = props[field.propertyName] != null;\n if (!isRequired && !isPresent) {\n return true;\n }\n\n if (isRequired && !isPresent) {\n return false;\n }\n\n // Perform user-defined validation first.\n if (!isTrue(field.isValid, props, true)) {\n return false;\n }\n\n // Fallback/default validation for builtin rules.\n if (field.type === \"number-field\") {\n const value = props[field.propertyName] as number | undefined;\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n if (field.min != null && (!isPresent || value! < field.min)) {\n return false;\n }\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n if (field.max != null && (!isPresent || value! > field.max)) {\n return false;\n }\n }\n\n return true;\n }\n\n get isValid(): boolean {\n return this.#isValid.value;\n }\n\n override get formTemplate(): DeclarativeFormTemplate {\n // See constructor\n return super.formTemplate as DeclarativeFormTemplate;\n }\n\n get hasRequiredFields(): boolean {\n return this.#hasRequiredFields.value;\n }\n}\n\nexport class CustomFormContextImpl extends BaseFormContext implements CustomFormContext {\n readonly #isValid = reactive(false);\n\n constructor(\n modificationStep: ModificationStep,\n callbacks: EditingCallbacks,\n template: FormTemplate\n ) {\n super(modificationStep, callbacks, template);\n }\n\n get isValid(): boolean {\n return this.#isValid.value;\n }\n\n set isValid(isValid: boolean) {\n this.#isValid.value = isValid;\n }\n\n get hasRequiredFields(): boolean {\n return false;\n }\n}\n\nexport type AnyPropertyFormContext = DeclarativeFormContext | CustomFormContextImpl;\n\nexport const FormContext = createContext<AnyPropertyFormContext | undefined>(undefined);\n\nfunction isTrue(\n value: PropertyFunctionOr<boolean> | undefined,\n properties: Record<string, unknown>,\n defaultValue: boolean\n): boolean {\n if (value == null) {\n return defaultValue;\n }\n return typeof value === \"function\" ? value(properties) : value;\n}\n"],"names":["entries"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"PropertyFormContext.js","sources":["PropertyFormContext.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2023-2025 Open Pioneer project (https://github.com/open-pioneer)\n// SPDX-License-Identifier: Apache-2.0\n\nimport {\n computed,\n reactive,\n reactiveMap,\n ReadonlyReactive,\n type ReactiveMap\n} from \"@conterra/reactivity-core\";\nimport type { Layer } from \"@open-pioneer/map\";\nimport type { Feature } from \"ol\";\nimport { createContext } from \"react\";\nimport type { CustomFormContext, Mode } from \"../../api/editor/context\";\nimport { PropertyFunctionOr } from \"../../api/fields/BaseFieldConfig\";\nimport { FieldConfig } from \"../../api/fields/FieldConfig\";\nimport type { ModificationStep } from \"../../api/model/EditingStep\";\nimport type {\n DeclarativeFormTemplate,\n FeatureTemplate,\n FormTemplate\n} from \"../../api/model/FeatureTemplate\";\nimport { EditingCallbacks } from \"../editor/useEditingCallbacks\";\n\nexport abstract class BaseFormContext {\n readonly #propertiesMap: ReactiveMap<string, unknown>;\n readonly #modificationStep: ModificationStep;\n readonly #formTemplate: FormTemplate;\n readonly #propsAsObject: ReadonlyReactive<Record<string, unknown>>;\n\n readonly callbacks: EditingCallbacks;\n\n constructor(\n modificationStep: ModificationStep,\n callbacks: EditingCallbacks,\n formTemplate: FormTemplate\n ) {\n this.#modificationStep = modificationStep;\n this.callbacks = callbacks;\n this.#formTemplate = formTemplate;\n\n const entries = BaseFormContext.#getPropertyEntries(modificationStep.feature);\n this.#propertiesMap = reactiveMap(entries);\n this.#propsAsObject = computed(() => {\n const entries = this.properties.entries();\n const object = Object.fromEntries(entries);\n return object;\n });\n }\n\n getPropertiesAsObject(): Record<string, unknown> {\n return this.#propsAsObject.value;\n }\n\n get feature(): Feature {\n return this.editingStep.feature;\n }\n\n get mode(): Mode {\n return this.editingStep.id === \"creation\" ? \"create\" : \"update\";\n }\n\n get editingStep(): ModificationStep {\n return this.#modificationStep;\n }\n\n get properties(): ReactiveMap<string, unknown> {\n return this.#propertiesMap;\n }\n\n get formTemplate(): FormTemplate {\n return this.#formTemplate;\n }\n\n get template(): FeatureTemplate | undefined {\n return this.editingStep.id === \"creation\" ? this.editingStep.template : undefined;\n }\n\n get layer(): Layer | undefined {\n return this.editingStep.id === \"update\" ? this.editingStep.layer : undefined;\n }\n\n abstract get isValid(): boolean;\n abstract get hasRequiredFields(): boolean;\n\n static #getPropertyEntries(feature: Feature): [string, unknown][] {\n const properties = feature.getProperties();\n const geometryName = feature.getGeometryName();\n return Object.entries(properties).filter(([key, _]) => key !== geometryName);\n }\n}\n\nexport class DeclarativeFormContext extends BaseFormContext {\n readonly #isValid: ReadonlyReactive<boolean>;\n readonly #hasRequiredFields: ReadonlyReactive<boolean>;\n\n constructor(\n modificationStep: ModificationStep,\n callbacks: EditingCallbacks,\n template: DeclarativeFormTemplate\n ) {\n super(modificationStep, callbacks, template);\n\n this.#isValid = computed(() => {\n const props = this.getPropertiesAsObject();\n return this.formTemplate.fields.every((field) => this.#isFieldValidImpl(field, props));\n });\n this.#hasRequiredFields = computed(() => {\n const props = this.getPropertiesAsObject();\n return this.formTemplate.fields.some((field) => isTrue(field.isRequired, props, false));\n });\n }\n\n isFieldValid(field: FieldConfig) {\n const props = this.getPropertiesAsObject();\n return this.#isFieldValidImpl(field, props);\n }\n\n #isFieldValidImpl(field: FieldConfig, props: Record<string, unknown>) {\n const isRequired = isTrue(field.isRequired, props, false);\n const isPresent = props[field.propertyName] != null;\n if (!isRequired && !isPresent) {\n return true;\n }\n\n if (isRequired && !isPresent) {\n return false;\n }\n\n // Perform user-defined validation first.\n if (!isTrue(field.isValid, props, true)) {\n return false;\n }\n\n // Fallback/default validation for builtin rules.\n if (field.type === \"number-field\") {\n const value = props[field.propertyName] as number | undefined;\n // oxlint-disable-next-line @typescript-eslint/no-non-null-assertion\n if (field.min != null && (!isPresent || value! < field.min)) {\n return false;\n }\n // oxlint-disable-next-line @typescript-eslint/no-non-null-assertion\n if (field.max != null && (!isPresent || value! > field.max)) {\n return false;\n }\n }\n\n return true;\n }\n\n get isValid(): boolean {\n return this.#isValid.value;\n }\n\n override get formTemplate(): DeclarativeFormTemplate {\n // See constructor\n return super.formTemplate as DeclarativeFormTemplate;\n }\n\n get hasRequiredFields(): boolean {\n return this.#hasRequiredFields.value;\n }\n}\n\nexport class CustomFormContextImpl extends BaseFormContext implements CustomFormContext {\n readonly #isValid = reactive(false);\n\n constructor(\n modificationStep: ModificationStep,\n callbacks: EditingCallbacks,\n template: FormTemplate\n ) {\n super(modificationStep, callbacks, template);\n }\n\n get isValid(): boolean {\n return this.#isValid.value;\n }\n\n set isValid(isValid: boolean) {\n this.#isValid.value = isValid;\n }\n\n get hasRequiredFields(): boolean {\n return false;\n }\n}\n\nexport type AnyPropertyFormContext = DeclarativeFormContext | CustomFormContextImpl;\n\nexport const FormContext = createContext<AnyPropertyFormContext | undefined>(undefined);\n\nfunction isTrue(\n value: PropertyFunctionOr<boolean> | undefined,\n properties: Record<string, unknown>,\n defaultValue: boolean\n): boolean {\n if (value == null) {\n return defaultValue;\n }\n return typeof value === \"function\" ? value(properties) : value;\n}\n"],"names":["entries"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"usePropertyFormContext.js","sources":["usePropertyFormContext.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2023-2025 Open Pioneer project (https://github.com/open-pioneer)\n// SPDX-License-Identifier: Apache-2.0\nimport { useContext } from \"react\";\nimport {\n CustomFormContextImpl,\n DeclarativeFormContext,\n FormContext,\n type AnyPropertyFormContext\n} from \"./PropertyFormContext\";\n\n/**\n * Used by the property editor, internally.\n *\n * @internal\n */\nexport function usePropertyFormContext(): AnyPropertyFormContext {\n const context = useContext(FormContext);\n if (context != null) {\n return context;\n } else {\n throw new Error(\"No property form context available\");\n }\n}\n\n/**\n * Used by the property editor, internally.\n *\n * @internal\n */\nexport function useDeclarativeFormContext(): DeclarativeFormContext {\n const value = usePropertyFormContext();\n if (!(value instanceof DeclarativeFormContext)) {\n throw new Error(\"No declarative form context available\");\n }\n return value;\n}\n\n/**\n * Used for custom form contents.\n */\nexport function useCustomFormContext(): CustomFormContextImpl {\n const value = usePropertyFormContext();\n if (!(value instanceof CustomFormContextImpl)) {\n throw new Error(\"No custom form context available\");\n }\n return value;\n}\n"],"names":[],"mappings":";;;
|
|
1
|
+
{"version":3,"file":"usePropertyFormContext.js","sources":["usePropertyFormContext.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2023-2025 Open Pioneer project (https://github.com/open-pioneer)\n// SPDX-License-Identifier: Apache-2.0\n\nimport { useContext } from \"react\";\nimport {\n CustomFormContextImpl,\n DeclarativeFormContext,\n FormContext,\n type AnyPropertyFormContext\n} from \"./PropertyFormContext\";\n\n/**\n * Used by the property editor, internally.\n *\n * @internal\n */\nexport function usePropertyFormContext(): AnyPropertyFormContext {\n const context = useContext(FormContext);\n if (context != null) {\n return context;\n } else {\n throw new Error(\"No property form context available\");\n }\n}\n\n/**\n * Used by the property editor, internally.\n *\n * @internal\n */\nexport function useDeclarativeFormContext(): DeclarativeFormContext {\n const value = usePropertyFormContext();\n if (!(value instanceof DeclarativeFormContext)) {\n throw new Error(\"No declarative form context available\");\n }\n return value;\n}\n\n/**\n * Used for custom form contents.\n */\nexport function useCustomFormContext(): CustomFormContextImpl {\n const value = usePropertyFormContext();\n if (!(value instanceof CustomFormContextImpl)) {\n throw new Error(\"No custom form context available\");\n }\n return value;\n}\n"],"names":[],"mappings":";;;AAgBO,SAAS,sBAAA,GAAiD;AAC7D,EAAA,MAAM,OAAA,GAAU,WAAW,WAAW,CAAA;AACtC,EAAA,IAAI,WAAW,IAAA,EAAM;AACjB,IAAA,OAAO,OAAA;AAAA,EACX,CAAA,MAAO;AACH,IAAA,MAAM,IAAI,MAAM,oCAAoC,CAAA;AAAA,EACxD;AACJ;AAOO,SAAS,yBAAA,GAAoD;AAChE,EAAA,MAAM,QAAQ,sBAAA,EAAuB;AACrC,EAAA,IAAI,EAAE,iBAAiB,sBAAA,CAAA,EAAyB;AAC5C,IAAA,MAAM,IAAI,MAAM,uCAAuC,CAAA;AAAA,EAC3D;AACA,EAAA,OAAO,KAAA;AACX;AAKO,SAAS,oBAAA,GAA8C;AAC1D,EAAA,MAAM,QAAQ,sBAAA,EAAuB;AACrC,EAAA,IAAI,EAAE,iBAAiB,qBAAA,CAAA,EAAwB;AAC3C,IAAA,MAAM,IAAI,MAAM,kCAAkC,CAAA;AAAA,EACtD;AACA,EAAA,OAAO,KAAA;AACX;;;;"}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { type Layer, type MapModel } from "@open-pioneer/map";
|
|
2
2
|
import type { Vector as VectorSource } from "ol/source";
|
|
3
|
-
import type { Action } from "../components/action-selector/ActionSelector";
|
|
4
3
|
import type { EditingStep } from "../../api/model/EditingStep";
|
|
5
4
|
import type { FeatureTemplate } from "../../api/model/FeatureTemplate";
|
|
5
|
+
import type { Action } from "../components/action-selector/ActionSelector";
|
|
6
6
|
type StatePair<S> = [S, (newState: S) => void];
|
|
7
7
|
export declare function useEditingStep(onEditingStepChange: ((newStep: EditingStep) => void) | undefined): StatePair<EditingStep>;
|
|
8
8
|
export declare function useOnActionChange(mapModel: MapModel | undefined, selectableLayers: Layer[] | undefined, templates: FeatureTemplate[], setEditingStep: (newEditingStep: EditingStep) => void): (newAction: Action | undefined) => void;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { useReactiveSnapshot } from '@open-pioneer/reactivity';
|
|
2
1
|
import { isLayer } from '@open-pioneer/map';
|
|
2
|
+
import { useReactiveSnapshot } from '@open-pioneer/reactivity';
|
|
3
3
|
import { Vector } from 'ol/layer.js';
|
|
4
4
|
import { useState, useEffect, useMemo, useCallback } from 'react';
|
|
5
5
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"editorHooks.js","sources":["editorHooks.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2023-2025 Open Pioneer project (https://github.com/open-pioneer)\n// SPDX-License-Identifier: Apache-2.0\nimport {
|
|
1
|
+
{"version":3,"file":"editorHooks.js","sources":["editorHooks.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2023-2025 Open Pioneer project (https://github.com/open-pioneer)\n// SPDX-License-Identifier: Apache-2.0\n\nimport { isLayer, type Layer, type MapModel } from \"@open-pioneer/map\";\nimport { useReactiveSnapshot } from \"@open-pioneer/reactivity\";\nimport { Vector as VectorLayer } from \"ol/layer\";\nimport type { Vector as VectorSource } from \"ol/source\";\nimport { useCallback, useEffect, useMemo, useState } from \"react\";\nimport type {\n DrawingStep,\n EditingStep,\n InitialStep,\n SelectionStep\n} from \"../../api/model/EditingStep\";\nimport type { FeatureTemplate } from \"../../api/model/FeatureTemplate\";\nimport type { Action } from \"../components/action-selector/ActionSelector\";\n\ntype StatePair<S> = [S, (newState: S) => void];\n\nexport function useEditingStep(\n onEditingStepChange: ((newStep: EditingStep) => void) | undefined\n): StatePair<EditingStep> {\n const [editingStep, setEditingStep] = useState<EditingStep>({ id: \"initial\" });\n\n useEffect(() => {\n onEditingStepChange?.(editingStep);\n }, [editingStep, onEditingStepChange]);\n\n return [editingStep, setEditingStep];\n}\n\nexport function useOnActionChange(\n mapModel: MapModel | undefined,\n selectableLayers: Layer[] | undefined,\n templates: FeatureTemplate[],\n setEditingStep: (newEditingStep: EditingStep) => void\n): (newAction: Action | undefined) => void {\n const defaultLayers = useDefaultLayers(mapModel, templates);\n\n return useCallback(\n (action) => {\n if (action == null) {\n setEditingStep({ id: \"initial\" } satisfies InitialStep);\n } else if (action.mode === \"update\") {\n setEditingStep({\n id: \"selection\",\n layers: selectableLayers ?? defaultLayers\n } satisfies SelectionStep);\n } else {\n setEditingStep({ id: \"drawing\", template: action.template } satisfies DrawingStep);\n }\n },\n [defaultLayers, selectableLayers, setEditingStep]\n );\n}\n\nexport function useSnappingSources(\n mapModel: MapModel | undefined,\n snappableLayers: Layer[] | undefined,\n templates: FeatureTemplate[]\n): VectorSource[] {\n const defaultLayers = useDefaultLayers(mapModel, templates);\n\n return useMemo(() => {\n return compactMap(snappableLayers ?? defaultLayers, (layer) =>\n layer.olLayer instanceof VectorLayer ? layer.olLayer.getSource() : undefined\n );\n }, [defaultLayers, snappableLayers]);\n}\n\nfunction useDefaultLayers(mapModel: MapModel | undefined, templates: FeatureTemplate[]): Layer[] {\n return useReactiveSnapshot(() => {\n const layerIds = compactMap(templates, ({ layerId }) => layerId);\n const uniqueLayerIds = new Set(layerIds);\n const layers = compactMap([...uniqueLayerIds], (id) => mapModel?.layers.getLayerById(id));\n return layers.filter((layer) => isLayer(layer));\n }, [mapModel, templates]);\n}\n\nfunction compactMap<T, U>(array: T[], mapper: (element: T) => U | undefined): U[] {\n return array.flatMap((element) => {\n const value = mapper(element);\n return value != null ? [value] : [];\n });\n}\n"],"names":["VectorLayer"],"mappings":";;;;;AAmBO,SAAS,eACZ,mBAAA,EACsB;AACtB,EAAA,MAAM,CAAC,aAAa,cAAc,CAAA,GAAI,SAAsB,EAAE,EAAA,EAAI,WAAW,CAAA;AAE7E,EAAA,SAAA,CAAU,MAAM;AACZ,IAAA,mBAAA,GAAsB,WAAW,CAAA;AAAA,EACrC,CAAA,EAAG,CAAC,WAAA,EAAa,mBAAmB,CAAC,CAAA;AAErC,EAAA,OAAO,CAAC,aAAa,cAAc,CAAA;AACvC;AAEO,SAAS,iBAAA,CACZ,QAAA,EACA,gBAAA,EACA,SAAA,EACA,cAAA,EACuC;AACvC,EAAA,MAAM,aAAA,GAAgB,gBAAA,CAAiB,QAAA,EAAU,SAAS,CAAA;AAE1D,EAAA,OAAO,WAAA;AAAA,IACH,CAAC,MAAA,KAAW;AACR,MAAA,IAAI,UAAU,IAAA,EAAM;AAChB,QAAA,cAAA,CAAe,EAAE,EAAA,EAAI,SAAA,EAAiC,CAAA;AAAA,MAC1D,CAAA,MAAA,IAAW,MAAA,CAAO,IAAA,KAAS,QAAA,EAAU;AACjC,QAAA,cAAA,CAAe;AAAA,UACX,EAAA,EAAI,WAAA;AAAA,UACJ,QAAQ,gBAAA,IAAoB;AAAA,SACP,CAAA;AAAA,MAC7B,CAAA,MAAO;AACH,QAAA,cAAA,CAAe,EAAE,EAAA,EAAI,SAAA,EAAW,QAAA,EAAU,MAAA,CAAO,UAAgC,CAAA;AAAA,MACrF;AAAA,IACJ,CAAA;AAAA,IACA,CAAC,aAAA,EAAe,gBAAA,EAAkB,cAAc;AAAA,GACpD;AACJ;AAEO,SAAS,kBAAA,CACZ,QAAA,EACA,eAAA,EACA,SAAA,EACc;AACd,EAAA,MAAM,aAAA,GAAgB,gBAAA,CAAiB,QAAA,EAAU,SAAS,CAAA;AAE1D,EAAA,OAAO,QAAQ,MAAM;AACjB,IAAA,OAAO,UAAA;AAAA,MAAW,eAAA,IAAmB,aAAA;AAAA,MAAe,CAAC,UACjD,KAAA,CAAM,OAAA,YAAmBA,SAAc,KAAA,CAAM,OAAA,CAAQ,WAAU,GAAI;AAAA,KACvE;AAAA,EACJ,CAAA,EAAG,CAAC,aAAA,EAAe,eAAe,CAAC,CAAA;AACvC;AAEA,SAAS,gBAAA,CAAiB,UAAgC,SAAA,EAAuC;AAC7F,EAAA,OAAO,oBAAoB,MAAM;AAC7B,IAAA,MAAM,WAAW,UAAA,CAAW,SAAA,EAAW,CAAC,EAAE,OAAA,OAAc,OAAO,CAAA;AAC/D,IAAA,MAAM,cAAA,GAAiB,IAAI,GAAA,CAAI,QAAQ,CAAA;AACvC,IAAA,MAAM,MAAA,GAAS,UAAA,CAAW,CAAC,GAAG,cAAc,CAAA,EAAG,CAAC,EAAA,KAAO,QAAA,EAAU,MAAA,CAAO,YAAA,CAAa,EAAE,CAAC,CAAA;AACxF,IAAA,OAAO,OAAO,MAAA,CAAO,CAAC,KAAA,KAAU,OAAA,CAAQ,KAAK,CAAC,CAAA;AAAA,EAClD,CAAA,EAAG,CAAC,QAAA,EAAU,SAAS,CAAC,CAAA;AAC5B;AAEA,SAAS,UAAA,CAAiB,OAAY,MAAA,EAA4C;AAC9E,EAAA,OAAO,KAAA,CAAM,OAAA,CAAQ,CAAC,OAAA,KAAY;AAC9B,IAAA,MAAM,KAAA,GAAQ,OAAO,OAAO,CAAA;AAC5B,IAAA,OAAO,KAAA,IAAS,IAAA,GAAO,CAAC,KAAK,IAAI,EAAC;AAAA,EACtC,CAAC,CAAA;AACL;;;;"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { MapModel } from "@open-pioneer/map";
|
|
2
|
-
import type { FeatureWriter } from "../../api/model/FeatureWriter";
|
|
3
2
|
import type { EditingStep } from "../../api/model/EditingStep";
|
|
3
|
+
import type { FeatureWriter } from "../../api/model/FeatureWriter";
|
|
4
4
|
export interface EditingCallbacks {
|
|
5
5
|
readonly onSave: () => Promise<void>;
|
|
6
6
|
readonly onDelete: () => Promise<void>;
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { createLogger } from '@open-pioneer/core';
|
|
2
|
+
import { useEvent } from '@open-pioneer/react-utils';
|
|
2
3
|
import { useReactiveSnapshot } from '@open-pioneer/reactivity';
|
|
3
4
|
import { useService, useIntl } from '../../_virtual/hooks.js';
|
|
4
5
|
import { sourceId } from '../../_virtual/source-info.js';
|
|
5
6
|
import { useMemo, useCallback } from 'react';
|
|
6
|
-
import { useEvent } from '@open-pioneer/react-utils';
|
|
7
7
|
|
|
8
8
|
const LOG = createLogger(sourceId);
|
|
9
9
|
const INITIAL = { id: "initial" };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useEditingCallbacks.js","sources":["useEditingCallbacks.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2023-2025 Open Pioneer project (https://github.com/open-pioneer)\n// SPDX-License-Identifier: Apache-2.0\nimport { createLogger } from \"@open-pioneer/core\";\nimport type { MapModel } from \"@open-pioneer/map\";\nimport type { NotificationService } from \"@open-pioneer/notifier\";\nimport { useReactiveSnapshot } from \"@open-pioneer/reactivity\";\nimport { useIntl, useService } from \"open-pioneer:react-hooks\";\nimport { sourceId } from \"open-pioneer:source-info\";\nimport { useCallback, useMemo } from \"react\";\nimport type {
|
|
1
|
+
{"version":3,"file":"useEditingCallbacks.js","sources":["useEditingCallbacks.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2023-2025 Open Pioneer project (https://github.com/open-pioneer)\n// SPDX-License-Identifier: Apache-2.0\n\nimport { createLogger } from \"@open-pioneer/core\";\nimport type { MapModel } from \"@open-pioneer/map\";\nimport type { NotificationService } from \"@open-pioneer/notifier\";\nimport { useEvent } from \"@open-pioneer/react-utils\";\nimport { useReactiveSnapshot } from \"@open-pioneer/reactivity\";\nimport { useIntl, useService } from \"open-pioneer:react-hooks\";\nimport { sourceId } from \"open-pioneer:source-info\";\nimport { useCallback, useMemo } from \"react\";\nimport type { EditingStep, InitialStep } from \"../../api/model/EditingStep\";\nimport type { FeatureWriter, StorageResult } from \"../../api/model/FeatureWriter\";\n\nconst LOG = createLogger(sourceId);\n\nconst INITIAL: InitialStep = { id: \"initial\" };\n\nexport interface EditingCallbacks {\n readonly onSave: () => Promise<void>;\n readonly onDelete: () => Promise<void>;\n readonly onCancel: () => void;\n}\n\n// oxlint-disable-next-line max-params\nexport function useEditingCallbacks(\n mapModel: MapModel,\n editingStep: EditingStep,\n writer: FeatureWriter,\n setEditingStep: (newEditingStep: EditingStep) => void,\n successNotifierDisplayDuration: number | false | undefined,\n failureNotifierDisplayDuration: number | false | undefined\n): EditingCallbacks {\n const projection = useReactiveSnapshot(() => mapModel.projection, [mapModel]);\n\n const showNotifier = useShowNotifier(\n successNotifierDisplayDuration,\n failureNotifierDisplayDuration\n );\n\n const onSave = useEvent(async () => {\n if (editingStep.id === \"creation\") {\n const { feature, template } = editingStep;\n\n let result: StorageResult;\n try {\n result = await writer.addFeature({ feature, template, projection });\n setEditingStep(INITIAL);\n } catch (error) {\n LOG.error(\"Error creating feature\", feature, error);\n result = { kind: \"error\" };\n }\n showNotifier(\"create\", result);\n } else if (editingStep.id === \"update\") {\n const { feature, layer } = editingStep;\n\n let result: StorageResult;\n try {\n result = await writer.updateFeature({ feature, layer, projection });\n setEditingStep(INITIAL);\n } catch (error) {\n LOG.error(\"Error updating feature\", feature, error);\n result = { kind: \"error\" };\n }\n showNotifier(\"update\", result);\n }\n });\n const onDelete = useEvent(async () => {\n if (editingStep.id === \"update\") {\n const { feature, layer } = editingStep;\n\n let result: StorageResult;\n try {\n result = await writer.deleteFeature({ feature, layer, projection });\n setEditingStep(INITIAL);\n } catch (error) {\n LOG.error(\"Error deleting feature\", feature, error);\n result = { kind: \"error\" };\n }\n showNotifier(\"delete\", result);\n }\n });\n const onCancel = useEvent(async () => {\n setEditingStep(INITIAL);\n });\n\n return useMemo(\n () => ({\n onSave,\n onDelete,\n onCancel\n }),\n [onSave, onDelete, onCancel]\n );\n}\n\nfunction useShowNotifier(\n successNotifierDisplayDuration: number | false | undefined,\n failureNotifierDisplayDuration: number | false | undefined\n) {\n const notifier = useService<NotificationService>(\"notifier.NotificationService\");\n const { formatMessage } = useIntl();\n\n return useCallback(\n (operation: Operation, result: StorageResult) => {\n if (!result) {\n // void, undefined --> success\n if (successNotifierDisplayDuration !== false) {\n notifier.success({\n title: formatMessage({\n id: getTitleId(operation, true)\n }),\n displayDuration: successNotifierDisplayDuration\n });\n }\n } else {\n if (failureNotifierDisplayDuration !== false) {\n notifier.error({\n title: formatMessage({\n id: getTitleId(operation, false)\n }),\n message: result.message,\n displayDuration: failureNotifierDisplayDuration\n });\n }\n }\n },\n [formatMessage, notifier, successNotifierDisplayDuration, failureNotifierDisplayDuration]\n );\n}\n\nfunction getTitleId(operation: Operation, success: boolean): TitleId {\n switch (operation) {\n case \"create\":\n return success ? TitleId.CreationSuccess : TitleId.CreationFailure;\n case \"update\":\n return success ? TitleId.UpdateSuccess : TitleId.UpdateFailure;\n case \"delete\":\n return success ? TitleId.DeletionSuccess : TitleId.DeletionFailure;\n }\n}\n\nenum TitleId {\n CreationSuccess = \"notifier.creationSuccess\",\n CreationFailure = \"notifier.creationFailure\",\n UpdateSuccess = \"notifier.updateSuccess\",\n UpdateFailure = \"notifier.updateFailure\",\n DeletionSuccess = \"notifier.deletionSuccess\",\n DeletionFailure = \"notifier.deletionFailure\"\n}\n\ntype Operation = \"create\" | \"update\" | \"delete\";\n"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DrawingSession.js","sources":["DrawingSession.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2023-2025 Open Pioneer project (https://github.com/open-pioneer)\n// SPDX-License-Identifier: Apache-2.0\nimport { reactive, synchronized, watchValue, type CleanupHandle } from \"@conterra/reactivity-core\";\nimport type { Feature } from \"ol\";\nimport type { Coordinate } from \"ol/coordinate\";\nimport { unByKey } from \"ol/Observable\";\nimport { DrawingState } from \"../useGeometryEditing\";\nimport { canBeFinished, canBeReset, getLastCoordinate, getNumberOfVertices } from \"./geometryState\";\nimport { UndoManager } from \"./UndoManager\";\n\nexport interface DrawingTracker {\n readonly trackCapabilities: (feature: Feature, actionHandler: DrawingActionHandler) => void;\n readonly untrackCapabilities: () => void;\n}\n\nexport interface DrawingActionHandler {\n readonly undo: () => void;\n readonly redo: (coordinate: Coordinate) => void;\n readonly finish: () => void;\n readonly reset: () => void;\n}\n\nexport class DrawingSession implements DrawingTracker, DrawingState {\n #ignoreNextEdit = false;\n #actionHandler: DrawingActionHandler | undefined;\n #watchHandle: CleanupHandle | undefined;\n\n readonly #canFinishSignal = reactive<boolean>();\n readonly #canResetSignal = reactive<boolean>();\n readonly #undoManager = new UndoManager<Coordinate>();\n\n trackCapabilities(feature: Feature, actionHandler: DrawingActionHandler): void {\n this.untrackCapabilities();\n\n const geometry = feature.getGeometry();\n\n if (geometry != null) {\n const numberOfVertices = synchronized(\n () => getNumberOfVertices(geometry),\n (callback) => {\n const eventsKey = geometry.on(\"change\", callback);\n return () => unByKey(eventsKey);\n }\n );\n\n this.#ignoreNextEdit = true;\n\n // TODO: When undoing the very first change (that is, removing the first vertex),\n // a \"drawabort\" event is fired causing the undo history to be reset.\n this.#watchHandle = watchValue(\n () => numberOfVertices.value,\n (numberOfVertices) => {\n this.#canFinishSignal.value = canBeFinished(geometry, numberOfVertices);\n this.#canResetSignal.value = canBeReset(geometry, numberOfVertices);\n\n if (!this.#ignoreNextEdit) {\n const lastCoordinate = getLastCoordinate(geometry);\n if (lastCoordinate != null) {\n this.#undoManager.addEdit(lastCoordinate);\n }\n } else {\n this.#ignoreNextEdit = false;\n }\n },\n { immediate: true }\n );\n\n this.#actionHandler = actionHandler;\n }\n }\n\n finish(): void {\n if (this.canFinish) {\n this.#actionHandler?.finish();\n }\n }\n\n reset(): void {\n if (this.canReset) {\n this.#actionHandler?.reset();\n }\n }\n\n undo(): void {\n if (this.canUndo && this.#actionHandler != null) {\n this.#undoManager.undo();\n this.#ignoreNextEdit = true;\n this.#actionHandler.undo();\n }\n }\n\n redo(): void {\n if (this.canRedo && this.#actionHandler != null) {\n const coordinate = this.#undoManager.redo();\n if (coordinate != null) {\n this.#ignoreNextEdit = true;\n this.#actionHandler.redo(coordinate);\n }\n }\n }\n\n untrackCapabilities(): void {\n this.#watchHandle?.destroy();\n\n this.#canFinishSignal.value = undefined;\n this.#canResetSignal.value = undefined;\n this.#undoManager.reset();\n\n this.#actionHandler = undefined;\n }\n\n get canFinish(): boolean {\n return this.#canFinishSignal.value ?? false;\n }\n\n get canReset(): boolean {\n return this.#canResetSignal.value ?? false;\n }\n\n get canUndo(): boolean {\n return this.#undoManager.canUndo;\n }\n\n get canRedo(): boolean {\n return this.#undoManager.canRedo;\n }\n}\n"],"names":["numberOfVertices"],"mappings":";;;;;
|
|
1
|
+
{"version":3,"file":"DrawingSession.js","sources":["DrawingSession.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2023-2025 Open Pioneer project (https://github.com/open-pioneer)\n// SPDX-License-Identifier: Apache-2.0\n\nimport { reactive, synchronized, watchValue, type CleanupHandle } from \"@conterra/reactivity-core\";\nimport type { Feature } from \"ol\";\nimport type { Coordinate } from \"ol/coordinate\";\nimport { unByKey } from \"ol/Observable\";\nimport { DrawingState } from \"../useGeometryEditing\";\nimport { canBeFinished, canBeReset, getLastCoordinate, getNumberOfVertices } from \"./geometryState\";\nimport { UndoManager } from \"./UndoManager\";\n\nexport interface DrawingTracker {\n readonly trackCapabilities: (feature: Feature, actionHandler: DrawingActionHandler) => void;\n readonly untrackCapabilities: () => void;\n}\n\nexport interface DrawingActionHandler {\n readonly undo: () => void;\n readonly redo: (coordinate: Coordinate) => void;\n readonly finish: () => void;\n readonly reset: () => void;\n}\n\nexport class DrawingSession implements DrawingTracker, DrawingState {\n #ignoreNextEdit = false;\n #actionHandler: DrawingActionHandler | undefined;\n #watchHandle: CleanupHandle | undefined;\n\n readonly #canFinishSignal = reactive<boolean>();\n readonly #canResetSignal = reactive<boolean>();\n readonly #undoManager = new UndoManager<Coordinate>();\n\n trackCapabilities(feature: Feature, actionHandler: DrawingActionHandler): void {\n this.untrackCapabilities();\n\n const geometry = feature.getGeometry();\n\n if (geometry != null) {\n const numberOfVertices = synchronized(\n () => getNumberOfVertices(geometry),\n (callback) => {\n const eventsKey = geometry.on(\"change\", callback);\n return () => unByKey(eventsKey);\n }\n );\n\n this.#ignoreNextEdit = true;\n\n // TODO: When undoing the very first change (that is, removing the first vertex),\n // a \"drawabort\" event is fired causing the undo history to be reset.\n this.#watchHandle = watchValue(\n () => numberOfVertices.value,\n (numberOfVertices) => {\n this.#canFinishSignal.value = canBeFinished(geometry, numberOfVertices);\n this.#canResetSignal.value = canBeReset(geometry, numberOfVertices);\n\n if (!this.#ignoreNextEdit) {\n const lastCoordinate = getLastCoordinate(geometry);\n if (lastCoordinate != null) {\n this.#undoManager.addEdit(lastCoordinate);\n }\n } else {\n this.#ignoreNextEdit = false;\n }\n },\n { immediate: true }\n );\n\n this.#actionHandler = actionHandler;\n }\n }\n\n finish(): void {\n if (this.canFinish) {\n this.#actionHandler?.finish();\n }\n }\n\n reset(): void {\n if (this.canReset) {\n this.#actionHandler?.reset();\n }\n }\n\n undo(): void {\n if (this.canUndo && this.#actionHandler != null) {\n this.#undoManager.undo();\n this.#ignoreNextEdit = true;\n this.#actionHandler.undo();\n }\n }\n\n redo(): void {\n if (this.canRedo && this.#actionHandler != null) {\n const coordinate = this.#undoManager.redo();\n if (coordinate != null) {\n this.#ignoreNextEdit = true;\n this.#actionHandler.redo(coordinate);\n }\n }\n }\n\n untrackCapabilities(): void {\n this.#watchHandle?.destroy();\n\n this.#canFinishSignal.value = undefined;\n this.#canResetSignal.value = undefined;\n this.#undoManager.reset();\n\n this.#actionHandler = undefined;\n }\n\n get canFinish(): boolean {\n return this.#canFinishSignal.value ?? false;\n }\n\n get canReset(): boolean {\n return this.#canResetSignal.value ?? false;\n }\n\n get canUndo(): boolean {\n return this.#undoManager.canUndo;\n }\n\n get canRedo(): boolean {\n return this.#undoManager.canRedo;\n }\n}\n"],"names":["numberOfVertices"],"mappings":"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"}
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import { LayerFactory, MapModel } from "@open-pioneer/map";
|
|
2
|
+
import type { Type as GeometryType } from "ol/geom/Geometry";
|
|
2
3
|
import type { Vector as VectorSource } from "ol/source";
|
|
4
|
+
import { ReactNode } from "react";
|
|
3
5
|
import type { InteractionOptions } from "../../../api/model/InteractionOptions";
|
|
4
6
|
import { type DrawingParameters } from "../interactions/DrawingInteraction";
|
|
5
7
|
import { type ModificationParameters } from "../interactions/ModificationInteraction";
|
|
6
8
|
import { type SelectionParameters } from "../interactions/SelectionInteraction";
|
|
7
9
|
import { DrawingSession } from "./DrawingSession";
|
|
8
|
-
import type { Type as GeometryType } from "ol/geom/Geometry";
|
|
9
|
-
import { ReactNode } from "react";
|
|
10
10
|
type StartDrawingFeatureOptions = Required<Omit<DrawingParameters, "tracker" | "layerFactory" | "tooltipMessages">>;
|
|
11
11
|
type StartSelectingFeatureOptions = Pick<SelectionParameters, "layers" | "completionHandler">;
|
|
12
12
|
type StartModifyingFeatureOptions = Pick<ModificationParameters, "feature" | "drawLayer">;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"EditingController.js","sources":["EditingController.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2023-2025 Open Pioneer project (https://github.com/open-pioneer)\n// SPDX-License-Identifier: Apache-2.0\nimport { LayerFactory, MapModel } from \"@open-pioneer/map\";\nimport type { Vector as VectorSource } from \"ol/source\";\nimport type { InteractionOptions } from \"../../../api/model/InteractionOptions\";\nimport { BaseInteraction } from \"../interactions/BaseInteraction\";\nimport { DoubleClickInteraction } from \"../interactions/DoubleClickInteraction\";\nimport { DrawingInteraction, type DrawingParameters } from \"../interactions/DrawingInteraction\";\nimport { HighlightingInteraction } from \"../interactions/HighlightingInteraction\";\nimport { KeyboardInteraction } from \"../interactions/KeyboardInteraction\";\nimport {\n ModificationInteraction,\n type ModificationParameters\n} from \"../interactions/ModificationInteraction\";\nimport {\n SelectionInteraction,\n type SelectionParameters\n} from \"../interactions/SelectionInteraction\";\nimport { SnappingInteraction } from \"../interactions/SnappingInteraction\";\nimport { DrawingSession } from \"./DrawingSession\";\
|
|
1
|
+
{"version":3,"file":"EditingController.js","sources":["EditingController.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2023-2025 Open Pioneer project (https://github.com/open-pioneer)\n// SPDX-License-Identifier: Apache-2.0\n\nimport { LayerFactory, MapModel } from \"@open-pioneer/map\";\nimport type { Type as GeometryType } from \"ol/geom/Geometry\";\nimport type { Vector as VectorSource } from \"ol/source\";\nimport { ReactNode } from \"react\";\nimport type { InteractionOptions } from \"../../../api/model/InteractionOptions\";\nimport { BaseInteraction } from \"../interactions/BaseInteraction\";\nimport { DoubleClickInteraction } from \"../interactions/DoubleClickInteraction\";\nimport { DrawingInteraction, type DrawingParameters } from \"../interactions/DrawingInteraction\";\nimport { HighlightingInteraction } from \"../interactions/HighlightingInteraction\";\nimport { KeyboardInteraction } from \"../interactions/KeyboardInteraction\";\nimport {\n ModificationInteraction,\n type ModificationParameters\n} from \"../interactions/ModificationInteraction\";\nimport {\n SelectionInteraction,\n type SelectionParameters\n} from \"../interactions/SelectionInteraction\";\nimport { SnappingInteraction } from \"../interactions/SnappingInteraction\";\nimport { DrawingSession } from \"./DrawingSession\";\n\ntype StartDrawingFeatureOptions = Required<\n Omit<DrawingParameters, \"tracker\" | \"layerFactory\" | \"tooltipMessages\">\n>;\ntype StartSelectingFeatureOptions = Pick<SelectionParameters, \"layers\" | \"completionHandler\">;\ntype StartModifyingFeatureOptions = Pick<ModificationParameters, \"feature\" | \"drawLayer\">;\n\nexport interface TooltipMessages {\n getSelectionMessage(): ReactNode;\n getDrawingMessages(): Map<GeometryType, ReactNode>;\n getModificationMessages(): Map<string, ReactNode>;\n}\n\nexport class EditingController {\n #currentInteractions: BaseInteraction<unknown, unknown>[] = [];\n #snappingSources: VectorSource[] = [];\n #interactionOptions: InteractionOptions = {};\n\n readonly drawingSession = new DrawingSession();\n\n readonly #mapModel: MapModel;\n readonly #layerFactory: LayerFactory;\n readonly #tooltipMessages: TooltipMessages;\n\n constructor(mapModel: MapModel, layerFactory: LayerFactory, tooltipMessages: TooltipMessages) {\n this.#mapModel = mapModel;\n this.#layerFactory = layerFactory;\n this.#tooltipMessages = tooltipMessages;\n }\n\n startDrawingFeature({\n geometryType,\n drawingOptions,\n completionHandler\n }: StartDrawingFeatureOptions): void {\n this.#replaceInteractions(\n new DrawingInteraction(this.#mapModel, {\n geometryType,\n tracker: this.drawingSession,\n drawingOptions: { ...this.#interactionOptions.drawingOptions, ...drawingOptions },\n completionHandler,\n layerFactory: this.#layerFactory,\n tooltipMessages: this.#tooltipMessages\n }),\n new KeyboardInteraction(this.#mapModel, {\n actions: this.drawingSession\n }),\n new SnappingInteraction(this.#mapModel, {\n snappingSources: this.#snappingSources,\n snappingOptions: this.#interactionOptions.snappingOptions\n }),\n new DoubleClickInteraction(this.#mapModel)\n );\n }\n\n startSelectingFeature({ layers, completionHandler }: StartSelectingFeatureOptions): void {\n this.#replaceInteractions(\n new SelectionInteraction(this.#mapModel, {\n layers,\n selectionOptions: this.#interactionOptions.selectionOptions,\n completionHandler,\n tooltipMessages: this.#tooltipMessages\n })\n );\n }\n\n startModifyingFeature({ feature, drawLayer }: StartModifyingFeatureOptions): void {\n this.#replaceInteractions(\n new ModificationInteraction(this.#mapModel, {\n feature,\n drawLayer,\n modificationOptions: this.#interactionOptions.modificationOptions,\n tooltipMessages: this.#tooltipMessages\n }),\n new HighlightingInteraction(this.#mapModel, {\n feature,\n highlightOptions: this.#interactionOptions.highlightingOptions\n }),\n new SnappingInteraction(this.#mapModel, {\n snappingSources: this.#snappingSources,\n snappingOptions: this.#interactionOptions.snappingOptions\n })\n );\n }\n\n setSnappingSources(sources: VectorSource[] | undefined): void {\n this.#snappingSources = sources ?? [];\n }\n\n setInteractionOptions(options: InteractionOptions): void {\n this.#interactionOptions = options;\n }\n\n stopCurrentInteractions(): void {\n this.#currentInteractions.forEach((interaction) => {\n interaction.stop();\n });\n this.#currentInteractions = [];\n }\n\n #replaceInteractions(...interactions: BaseInteraction<unknown, unknown>[]): void {\n this.stopCurrentInteractions();\n this.#currentInteractions = interactions;\n this.#currentInteractions.forEach((interaction) => {\n interaction.start();\n });\n }\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"UndoManager.js","sources":["UndoManager.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2023-2025 Open Pioneer project (https://github.com/open-pioneer)\n// SPDX-License-Identifier: Apache-2.0\nimport { computed, reactiveArray } from \"@conterra/reactivity-core\";\n\nexport class UndoManager<T> {\n addEdit(edit: T): void {\n this.#undoStack.push(edit);\n this.#redoStack.splice(0);\n }\n\n undo(): T | undefined {\n const edit = this.#undoStack.pop();\n if (edit != null) {\n this.#redoStack.push(edit);\n }\n return edit;\n }\n\n redo(): T | undefined {\n const edit = this.#redoStack.pop();\n if (edit != null) {\n this.#undoStack.push(edit);\n }\n return edit;\n }\n\n reset(): void {\n this.#undoStack.splice(0);\n this.#redoStack.splice(0);\n }\n\n get canUndo(): boolean {\n return this.#canUndoSignal.value;\n }\n\n get canRedo(): boolean {\n return this.#canRedoSignal.value;\n }\n\n #undoStack = reactiveArray<T>();\n #redoStack = reactiveArray<T>();\n\n #canUndoSignal = computed(() => this.#undoStack.length >= 1);\n #canRedoSignal = computed(() => this.#redoStack.length >= 1);\n}\n"],"names":[],"mappings":";;
|
|
1
|
+
{"version":3,"file":"UndoManager.js","sources":["UndoManager.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2023-2025 Open Pioneer project (https://github.com/open-pioneer)\n// SPDX-License-Identifier: Apache-2.0\n\nimport { computed, reactiveArray } from \"@conterra/reactivity-core\";\n\nexport class UndoManager<T> {\n addEdit(edit: T): void {\n this.#undoStack.push(edit);\n this.#redoStack.splice(0);\n }\n\n undo(): T | undefined {\n const edit = this.#undoStack.pop();\n if (edit != null) {\n this.#redoStack.push(edit);\n }\n return edit;\n }\n\n redo(): T | undefined {\n const edit = this.#redoStack.pop();\n if (edit != null) {\n this.#undoStack.push(edit);\n }\n return edit;\n }\n\n reset(): void {\n this.#undoStack.splice(0);\n this.#redoStack.splice(0);\n }\n\n get canUndo(): boolean {\n return this.#canUndoSignal.value;\n }\n\n get canRedo(): boolean {\n return this.#canRedoSignal.value;\n }\n\n #undoStack = reactiveArray<T>();\n #redoStack = reactiveArray<T>();\n\n #canUndoSignal = computed(() => this.#undoStack.length >= 1);\n #canRedoSignal = computed(() => this.#redoStack.length >= 1);\n}\n"],"names":[],"mappings":";;AAKO,MAAM,WAAA,CAAe;AAAA,EACxB,QAAQ,IAAA,EAAe;AACnB,IAAA,IAAA,CAAK,UAAA,CAAW,KAAK,IAAI,CAAA;AACzB,IAAA,IAAA,CAAK,UAAA,CAAW,OAAO,CAAC,CAAA;AAAA,EAC5B;AAAA,EAEA,IAAA,GAAsB;AAClB,IAAA,MAAM,IAAA,GAAO,IAAA,CAAK,UAAA,CAAW,GAAA,EAAI;AACjC,IAAA,IAAI,QAAQ,IAAA,EAAM;AACd,MAAA,IAAA,CAAK,UAAA,CAAW,KAAK,IAAI,CAAA;AAAA,IAC7B;AACA,IAAA,OAAO,IAAA;AAAA,EACX;AAAA,EAEA,IAAA,GAAsB;AAClB,IAAA,MAAM,IAAA,GAAO,IAAA,CAAK,UAAA,CAAW,GAAA,EAAI;AACjC,IAAA,IAAI,QAAQ,IAAA,EAAM;AACd,MAAA,IAAA,CAAK,UAAA,CAAW,KAAK,IAAI,CAAA;AAAA,IAC7B;AACA,IAAA,OAAO,IAAA;AAAA,EACX;AAAA,EAEA,KAAA,GAAc;AACV,IAAA,IAAA,CAAK,UAAA,CAAW,OAAO,CAAC,CAAA;AACxB,IAAA,IAAA,CAAK,UAAA,CAAW,OAAO,CAAC,CAAA;AAAA,EAC5B;AAAA,EAEA,IAAI,OAAA,GAAmB;AACnB,IAAA,OAAO,KAAK,cAAA,CAAe,KAAA;AAAA,EAC/B;AAAA,EAEA,IAAI,OAAA,GAAmB;AACnB,IAAA,OAAO,KAAK,cAAA,CAAe,KAAA;AAAA,EAC/B;AAAA,EAEA,aAAa,aAAA,EAAiB;AAAA,EAC9B,aAAa,aAAA,EAAiB;AAAA,EAE9B,iBAAiB,QAAA,CAAS,MAAM,IAAA,CAAK,UAAA,CAAW,UAAU,CAAC,CAAA;AAAA,EAC3D,iBAAiB,QAAA,CAAS,MAAM,IAAA,CAAK,UAAA,CAAW,UAAU,CAAC,CAAA;AAC/D;;;;"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"geometryState.js","sources":["geometryState.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2023-2025 Open Pioneer project (https://github.com/open-pioneer)\n// SPDX-License-Identifier: Apache-2.0\nimport type { Coordinate } from \"ol/coordinate\";\nimport type { Geometry, LineString, Polygon } from \"ol/geom\";\n\nexport function canBeFinished(\n geometry: Geometry,\n numberOfVertices: number | undefined\n): boolean | undefined {\n if (isLineString(geometry) && numberOfVertices != null) {\n return numberOfVertices >= 3;\n } else if (isPolygon(geometry) && numberOfVertices != null) {\n return numberOfVertices >= 4;\n } else {\n return undefined;\n }\n}\n\nexport function canBeReset(\n geometry: Geometry,\n numberOfVertices: number | undefined\n): boolean | undefined {\n if ((isLineString(geometry) || isPolygon(geometry)) && numberOfVertices != null) {\n return numberOfVertices >= 1;\n } else {\n return undefined;\n }\n}\n\nexport function getNumberOfVertices(geometry: Geometry): number | undefined {\n if (isLineString(geometry)) {\n return geometry.getCoordinates().length;\n } else if (isPolygon(geometry)) {\n return geometry.getFlatCoordinates().length / 2 - 1;\n } else {\n return undefined;\n }\n}\n\nexport function getLastCoordinate(geometry: Geometry): Coordinate | undefined {\n if (isLineString(geometry)) {\n const lastCoordinate = geometry.getLastCoordinate();\n return lastCoordinate.length >= 2 ? lastCoordinate : undefined;\n } else if (isPolygon(geometry)) {\n const coordinates = geometry.getLinearRing(0)?.getCoordinates();\n return coordinates?.[coordinates.length - 2] ?? undefined;\n } else {\n return undefined;\n }\n}\n\nfunction isLineString(geometry: Geometry): geometry is LineString {\n return geometry.getType() === \"LineString\";\n}\n\nfunction isPolygon(geometry: Geometry): geometry is Polygon {\n return geometry.getType() === \"Polygon\";\n}\n"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"geometryState.js","sources":["geometryState.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2023-2025 Open Pioneer project (https://github.com/open-pioneer)\n// SPDX-License-Identifier: Apache-2.0\n\nimport type { Coordinate } from \"ol/coordinate\";\nimport type { Geometry, LineString, Polygon } from \"ol/geom\";\n\nexport function canBeFinished(\n geometry: Geometry,\n numberOfVertices: number | undefined\n): boolean | undefined {\n if (isLineString(geometry) && numberOfVertices != null) {\n return numberOfVertices >= 3;\n } else if (isPolygon(geometry) && numberOfVertices != null) {\n return numberOfVertices >= 4;\n } else {\n return undefined;\n }\n}\n\nexport function canBeReset(\n geometry: Geometry,\n numberOfVertices: number | undefined\n): boolean | undefined {\n if ((isLineString(geometry) || isPolygon(geometry)) && numberOfVertices != null) {\n return numberOfVertices >= 1;\n } else {\n return undefined;\n }\n}\n\nexport function getNumberOfVertices(geometry: Geometry): number | undefined {\n if (isLineString(geometry)) {\n return geometry.getCoordinates().length;\n } else if (isPolygon(geometry)) {\n return geometry.getFlatCoordinates().length / 2 - 1;\n } else {\n return undefined;\n }\n}\n\nexport function getLastCoordinate(geometry: Geometry): Coordinate | undefined {\n if (isLineString(geometry)) {\n const lastCoordinate = geometry.getLastCoordinate();\n return lastCoordinate.length >= 2 ? lastCoordinate : undefined;\n } else if (isPolygon(geometry)) {\n const coordinates = geometry.getLinearRing(0)?.getCoordinates();\n return coordinates?.[coordinates.length - 2] ?? undefined;\n } else {\n return undefined;\n }\n}\n\nfunction isLineString(geometry: Geometry): geometry is LineString {\n return geometry.getType() === \"LineString\";\n}\n\nfunction isPolygon(geometry: Geometry): geometry is Polygon {\n return geometry.getType() === \"Polygon\";\n}\n"],"names":[],"mappings":"AAMO,SAAS,aAAA,CACZ,UACA,gBAAA,EACmB;AACnB,EAAA,IAAI,YAAA,CAAa,QAAQ,CAAA,IAAK,gBAAA,IAAoB,IAAA,EAAM;AACpD,IAAA,OAAO,gBAAA,IAAoB,CAAA;AAAA,EAC/B,CAAA,MAAA,IAAW,SAAA,CAAU,QAAQ,CAAA,IAAK,oBAAoB,IAAA,EAAM;AACxD,IAAA,OAAO,gBAAA,IAAoB,CAAA;AAAA,EAC/B,CAAA,MAAO;AACH,IAAA,OAAO,MAAA;AAAA,EACX;AACJ;AAEO,SAAS,UAAA,CACZ,UACA,gBAAA,EACmB;AACnB,EAAA,IAAA,CAAK,aAAa,QAAQ,CAAA,IAAK,UAAU,QAAQ,CAAA,KAAM,oBAAoB,IAAA,EAAM;AAC7E,IAAA,OAAO,gBAAA,IAAoB,CAAA;AAAA,EAC/B,CAAA,MAAO;AACH,IAAA,OAAO,MAAA;AAAA,EACX;AACJ;AAEO,SAAS,oBAAoB,QAAA,EAAwC;AACxE,EAAA,IAAI,YAAA,CAAa,QAAQ,CAAA,EAAG;AACxB,IAAA,OAAO,QAAA,CAAS,gBAAe,CAAE,MAAA;AAAA,EACrC,CAAA,MAAA,IAAW,SAAA,CAAU,QAAQ,CAAA,EAAG;AAC5B,IAAA,OAAO,QAAA,CAAS,kBAAA,EAAmB,CAAE,MAAA,GAAS,CAAA,GAAI,CAAA;AAAA,EACtD,CAAA,MAAO;AACH,IAAA,OAAO,MAAA;AAAA,EACX;AACJ;AAEO,SAAS,kBAAkB,QAAA,EAA4C;AAC1E,EAAA,IAAI,YAAA,CAAa,QAAQ,CAAA,EAAG;AACxB,IAAA,MAAM,cAAA,GAAiB,SAAS,iBAAA,EAAkB;AAClD,IAAA,OAAO,cAAA,CAAe,MAAA,IAAU,CAAA,GAAI,cAAA,GAAiB,MAAA;AAAA,EACzD,CAAA,MAAA,IAAW,SAAA,CAAU,QAAQ,CAAA,EAAG;AAC5B,IAAA,MAAM,WAAA,GAAc,QAAA,CAAS,aAAA,CAAc,CAAC,GAAG,cAAA,EAAe;AAC9D,IAAA,OAAO,WAAA,GAAc,WAAA,CAAY,MAAA,GAAS,CAAC,CAAA,IAAK,MAAA;AAAA,EACpD,CAAA,MAAO;AACH,IAAA,OAAO,MAAA;AAAA,EACX;AACJ;AAEA,SAAS,aAAa,QAAA,EAA4C;AAC9D,EAAA,OAAO,QAAA,CAAS,SAAQ,KAAM,YAAA;AAClC;AAEA,SAAS,UAAU,QAAA,EAAyC;AACxD,EAAA,OAAO,QAAA,CAAS,SAAQ,KAAM,SAAA;AAClC;;;;"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"BaseInteraction.js","sources":["BaseInteraction.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2023-2025 Open Pioneer project (https://github.com/open-pioneer)\n// SPDX-License-Identifier: Apache-2.0\nimport type { MapModel } from \"@open-pioneer/map\";\nimport type { Map } from \"ol\";\n\ntype EditingWorkflowState<T> = IdleState | ActiveState<T>;\n\ninterface IdleState {\n readonly type: \"idle\";\n}\n\ninterface ActiveState<T> {\n readonly type: \"active\";\n readonly data: T;\n}\n\nexport abstract class BaseInteraction<Params, Data> {\n #state: EditingWorkflowState<Data> = { type: \"idle\" };\n\n readonly #mapModelInstance: MapModel;\n readonly #parameters: Params;\n\n constructor(mapModelInstance: MapModel, parameters: Params) {\n this.#mapModelInstance = mapModelInstance;\n this.#parameters = parameters;\n }\n\n start(): void {\n if (this.#state.type === \"idle\") {\n const data = this.startInteraction(this.#parameters);\n this.#state = { type: \"active\", data };\n }\n }\n\n stop(): void {\n if (this.#state.type === \"active\") {\n this.stopInteraction(this.#state.data);\n this.#state = { type: \"idle\" };\n }\n }\n\n protected get map(): Map {\n return this.mapModel.olMap;\n }\n\n protected get mapModel(): MapModel {\n return this.#mapModelInstance;\n }\n\n protected abstract startInteraction(parameters: Params): Data;\n protected abstract stopInteraction(interactionData: Data): void;\n}\n"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"BaseInteraction.js","sources":["BaseInteraction.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2023-2025 Open Pioneer project (https://github.com/open-pioneer)\n// SPDX-License-Identifier: Apache-2.0\n\nimport type { MapModel } from \"@open-pioneer/map\";\nimport type { Map } from \"ol\";\n\ntype EditingWorkflowState<T> = IdleState | ActiveState<T>;\n\ninterface IdleState {\n readonly type: \"idle\";\n}\n\ninterface ActiveState<T> {\n readonly type: \"active\";\n readonly data: T;\n}\n\nexport abstract class BaseInteraction<Params, Data> {\n #state: EditingWorkflowState<Data> = { type: \"idle\" };\n\n readonly #mapModelInstance: MapModel;\n readonly #parameters: Params;\n\n constructor(mapModelInstance: MapModel, parameters: Params) {\n this.#mapModelInstance = mapModelInstance;\n this.#parameters = parameters;\n }\n\n start(): void {\n if (this.#state.type === \"idle\") {\n const data = this.startInteraction(this.#parameters);\n this.#state = { type: \"active\", data };\n }\n }\n\n stop(): void {\n if (this.#state.type === \"active\") {\n this.stopInteraction(this.#state.data);\n this.#state = { type: \"idle\" };\n }\n }\n\n protected get map(): Map {\n return this.mapModel.olMap;\n }\n\n protected get mapModel(): MapModel {\n return this.#mapModelInstance;\n }\n\n protected abstract startInteraction(parameters: Params): Data;\n protected abstract stopInteraction(interactionData: Data): void;\n}\n"],"names":[],"mappings":"AAiBO,MAAe,eAAA,CAA8B;AAAA,EAChD,MAAA,GAAqC,EAAE,IAAA,EAAM,MAAA,EAAO;AAAA,EAE3C,iBAAA;AAAA,EACA,WAAA;AAAA,EAET,WAAA,CAAY,kBAA4B,UAAA,EAAoB;AACxD,IAAA,IAAA,CAAK,iBAAA,GAAoB,gBAAA;AACzB,IAAA,IAAA,CAAK,WAAA,GAAc,UAAA;AAAA,EACvB;AAAA,EAEA,KAAA,GAAc;AACV,IAAA,IAAI,IAAA,CAAK,MAAA,CAAO,IAAA,KAAS,MAAA,EAAQ;AAC7B,MAAA,MAAM,IAAA,GAAO,IAAA,CAAK,gBAAA,CAAiB,IAAA,CAAK,WAAW,CAAA;AACnD,MAAA,IAAA,CAAK,MAAA,GAAS,EAAE,IAAA,EAAM,QAAA,EAAU,IAAA,EAAK;AAAA,IACzC;AAAA,EACJ;AAAA,EAEA,IAAA,GAAa;AACT,IAAA,IAAI,IAAA,CAAK,MAAA,CAAO,IAAA,KAAS,QAAA,EAAU;AAC/B,MAAA,IAAA,CAAK,eAAA,CAAgB,IAAA,CAAK,MAAA,CAAO,IAAI,CAAA;AACrC,MAAA,IAAA,CAAK,MAAA,GAAS,EAAE,IAAA,EAAM,MAAA,EAAO;AAAA,IACjC;AAAA,EACJ;AAAA,EAEA,IAAc,GAAA,GAAW;AACrB,IAAA,OAAO,KAAK,QAAA,CAAS,KAAA;AAAA,EACzB;AAAA,EAEA,IAAc,QAAA,GAAqB;AAC/B,IAAA,OAAO,IAAA,CAAK,iBAAA;AAAA,EAChB;AAIJ;;;;"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DoubleClickInteraction.js","sources":["DoubleClickInteraction.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2023-2025 Open Pioneer project (https://github.com/open-pioneer)\n// SPDX-License-Identifier: Apache-2.0\nimport type { MapModel } from \"@open-pioneer/map\";\nimport { DoubleClickZoom, type Interaction } from \"ol/interaction\";\nimport { BaseInteraction } from \"./BaseInteraction\";\n\ninterface DoubleClickData {\n readonly doubleClickZoom: Interaction | undefined;\n readonly wasActive: boolean;\n}\n\n// A double-click is used to finish drawing a feature. Hence, disable the double-click zoom\n// interaction, which would otherwise be triggered along with it.\nexport class DoubleClickInteraction extends BaseInteraction<{}, DoubleClickData> {\n constructor(mapModel: MapModel) {\n super(mapModel, {});\n }\n\n protected startInteraction(): DoubleClickData {\n const doubleClickZoom = this.#getDoubleClickZoom();\n const wasActive = doubleClickZoom?.getActive() ?? false;\n\n doubleClickZoom?.setActive(false);\n\n return { doubleClickZoom, wasActive };\n }\n\n protected stopInteraction({ doubleClickZoom, wasActive }: DoubleClickData): void {\n doubleClickZoom?.setActive(wasActive);\n }\n\n #getDoubleClickZoom(): Interaction | undefined {\n return this.map\n .getInteractions()\n .getArray()\n .find((interaction) => interaction instanceof DoubleClickZoom);\n }\n}\n"],"names":[],"mappings":";;;
|
|
1
|
+
{"version":3,"file":"DoubleClickInteraction.js","sources":["DoubleClickInteraction.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2023-2025 Open Pioneer project (https://github.com/open-pioneer)\n// SPDX-License-Identifier: Apache-2.0\n\nimport type { MapModel } from \"@open-pioneer/map\";\nimport { DoubleClickZoom, type Interaction } from \"ol/interaction\";\nimport { BaseInteraction } from \"./BaseInteraction\";\n\ninterface DoubleClickData {\n readonly doubleClickZoom: Interaction | undefined;\n readonly wasActive: boolean;\n}\n\n// A double-click is used to finish drawing a feature. Hence, disable the double-click zoom\n// interaction, which would otherwise be triggered along with it.\nexport class DoubleClickInteraction extends BaseInteraction<{}, DoubleClickData> {\n constructor(mapModel: MapModel) {\n super(mapModel, {});\n }\n\n protected startInteraction(): DoubleClickData {\n const doubleClickZoom = this.#getDoubleClickZoom();\n const wasActive = doubleClickZoom?.getActive() ?? false;\n\n doubleClickZoom?.setActive(false);\n\n return { doubleClickZoom, wasActive };\n }\n\n protected stopInteraction({ doubleClickZoom, wasActive }: DoubleClickData): void {\n doubleClickZoom?.setActive(wasActive);\n }\n\n #getDoubleClickZoom(): Interaction | undefined {\n return this.map\n .getInteractions()\n .getArray()\n .find((interaction) => interaction instanceof DoubleClickZoom);\n }\n}\n"],"names":[],"mappings":";;;AAcO,MAAM,+BAA+B,eAAA,CAAqC;AAAA,EAC7E,YAAY,QAAA,EAAoB;AAC5B,IAAA,KAAA,CAAM,QAAA,EAAU,EAAE,CAAA;AAAA,EACtB;AAAA,EAEU,gBAAA,GAAoC;AAC1C,IAAA,MAAM,eAAA,GAAkB,KAAK,mBAAA,EAAoB;AACjD,IAAA,MAAM,SAAA,GAAY,eAAA,EAAiB,SAAA,EAAU,IAAK,KAAA;AAElD,IAAA,eAAA,EAAiB,UAAU,KAAK,CAAA;AAEhC,IAAA,OAAO,EAAE,iBAAiB,SAAA,EAAU;AAAA,EACxC;AAAA,EAEU,eAAA,CAAgB,EAAE,eAAA,EAAiB,SAAA,EAAU,EAA0B;AAC7E,IAAA,eAAA,EAAiB,UAAU,SAAS,CAAA;AAAA,EACxC;AAAA,EAEA,mBAAA,GAA+C;AAC3C,IAAA,OAAO,IAAA,CAAK,GAAA,CACP,eAAA,EAAgB,CAChB,QAAA,GACA,IAAA,CAAK,CAAC,WAAA,KAAgB,WAAA,YAAuB,eAAe,CAAA;AAAA,EACrE;AACJ;;;;"}
|
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { LayerFactory, SimpleLayer } from "@open-pioneer/map";
|
|
2
2
|
import type { Feature } from "ol";
|
|
3
3
|
import type { EventsKey } from "ol/events";
|
|
4
4
|
import type { Type as GeometryType } from "ol/geom/Geometry";
|
|
5
|
-
import {
|
|
6
|
-
import type { DrawingTracker } from "../controller/DrawingSession";
|
|
5
|
+
import { Draw } from "ol/interaction";
|
|
7
6
|
import type { DrawingOptions } from "../../../api/model/InteractionOptions";
|
|
8
|
-
import {
|
|
7
|
+
import type { DrawingTracker } from "../controller/DrawingSession";
|
|
9
8
|
import { TooltipMessages } from "../controller/EditingController";
|
|
9
|
+
import { BaseInteraction } from "./BaseInteraction";
|
|
10
10
|
export interface DrawingParameters {
|
|
11
11
|
readonly geometryType: GeometryType;
|
|
12
12
|
readonly tracker: DrawingTracker;
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
+
import { destroyResource } from '@open-pioneer/core';
|
|
2
|
+
import { SimpleLayer } from '@open-pioneer/map';
|
|
1
3
|
import { Draw } from 'ol/interaction.js';
|
|
2
4
|
import { Vector as Vector$1 } from 'ol/layer.js';
|
|
3
5
|
import { unByKey } from 'ol/Observable.js';
|
|
4
6
|
import { Vector } from 'ol/source.js';
|
|
5
7
|
import { BaseInteraction } from './BaseInteraction.js';
|
|
6
|
-
import { SimpleLayer } from '@open-pioneer/map';
|
|
7
|
-
import { destroyResource } from '@open-pioneer/core';
|
|
8
8
|
|
|
9
9
|
class DrawingInteraction extends BaseInteraction {
|
|
10
10
|
#tooltip;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DrawingInteraction.js","sources":["DrawingInteraction.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2023-2025 Open Pioneer project (https://github.com/open-pioneer)\n// SPDX-License-Identifier: Apache-2.0\nimport {
|
|
1
|
+
{"version":3,"file":"DrawingInteraction.js","sources":["DrawingInteraction.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2023-2025 Open Pioneer project (https://github.com/open-pioneer)\n// SPDX-License-Identifier: Apache-2.0\n\nimport { destroyResource } from \"@open-pioneer/core\";\nimport { LayerFactory, MapModel, Overlay, SimpleLayer } from \"@open-pioneer/map\";\nimport type { Feature } from \"ol\";\nimport type { EventsKey } from \"ol/events\";\nimport type { Type as GeometryType } from \"ol/geom/Geometry\";\nimport { Draw } from \"ol/interaction\";\nimport { Vector as VectorLayer } from \"ol/layer\";\nimport { unByKey } from \"ol/Observable\";\nimport { Vector as VectorSource } from \"ol/source\";\nimport type { DrawingOptions } from \"../../../api/model/InteractionOptions\";\nimport type { DrawingTracker, DrawingActionHandler } from \"../controller/DrawingSession\";\nimport { TooltipMessages } from \"../controller/EditingController\";\nimport { BaseInteraction } from \"./BaseInteraction\";\n\nexport interface DrawingParameters {\n readonly geometryType: GeometryType;\n readonly tracker: DrawingTracker;\n readonly drawingOptions?: DrawingOptions;\n /** The completion handler takes ownership of the drawLayer and needs to destroy it if it is no longer needed. */\n readonly completionHandler: (feature: Feature, drawLayer: SimpleLayer) => void;\n readonly layerFactory: LayerFactory;\n readonly tooltipMessages: TooltipMessages;\n}\n\ninterface DrawingData {\n readonly draw: Draw;\n readonly eventsKeys: EventsKey[];\n readonly tracker: DrawingTracker;\n}\n\nexport class DrawingInteraction extends BaseInteraction<DrawingParameters, DrawingData> {\n #tooltip?: Overlay;\n #drawLayer: SimpleLayer | undefined;\n\n protected override startInteraction(parameters: DrawingParameters): DrawingData {\n const {\n geometryType,\n tracker,\n drawingOptions,\n completionHandler,\n layerFactory,\n tooltipMessages\n } = parameters;\n\n const source = new VectorSource();\n const drawLayer = (this.#drawLayer = layerFactory.create({\n type: SimpleLayer,\n internal: true,\n title: \"editing-draw-layer\",\n olLayer: new VectorLayer<VectorSource, Feature>({\n source: source\n })\n }));\n const draw = new Draw({ source, type: geometryType, ...drawingOptions });\n\n const handler: DrawingActionHandler = {\n undo: () => draw.removeLastPoint(),\n redo: (coordinate) => draw.appendCoordinates([coordinate]),\n finish: () => draw.finishDrawing(),\n reset: () => draw.abortDrawing()\n };\n\n const eventsKeys = [\n draw.on(\"drawstart\", ({ feature }) => tracker.trackCapabilities(feature, handler)),\n draw.on(\"drawabort\", () => tracker.untrackCapabilities()),\n draw.once(\"drawend\", ({ feature }) => {\n const drawLayer = this.#drawLayer;\n if (!drawLayer) {\n return;\n }\n\n // Remove from map but DO NOT destroy: completionHandler takes ownership\n this.mapModel.layers.removeLayer(drawLayer);\n this.#drawLayer = undefined;\n completionHandler(feature, drawLayer);\n })\n ];\n\n this.#tooltip = this.#createHelpTooltip(this.mapModel, tooltipMessages, geometryType);\n\n this.mapModel.layers.addLayer(drawLayer, { at: \"topmost\" });\n\n this.map.addInteraction(draw);\n\n return { draw, eventsKeys, tracker };\n }\n\n protected override stopInteraction(data: DrawingData): void {\n const { draw, eventsKeys, tracker } = data;\n\n this.map.removeInteraction(draw);\n\n // Cleanup draw layer if it wasn't passed to the completionHandler\n if (this.#drawLayer) {\n this.mapModel.layers.removeLayer(this.#drawLayer);\n this.#drawLayer = destroyResource(this.#drawLayer);\n }\n this.#tooltip?.destroy();\n unByKey(eventsKeys);\n tracker.untrackCapabilities();\n }\n\n #createHelpTooltip(\n mapModel: MapModel,\n tooltipMessages: TooltipMessages,\n geometryType: GeometryType\n ): Overlay | undefined {\n const message = tooltipMessages.getDrawingMessages().get(geometryType);\n if (!message) {\n return undefined;\n }\n\n const helpOverlay = mapModel.overlays.add({\n className: \"editing-tooltip printing-hide\",\n position: \"follow-pointer\",\n tag: \"editing-draw-overlay\",\n offset: [15, 0],\n positioning: \"center-left\",\n ariaRole: \"tooltip\",\n content: message\n });\n\n return helpOverlay;\n }\n}\n"],"names":["VectorSource","VectorLayer","drawLayer"],"mappings":"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"}
|