@open-pioneer/feature-editing 1.4.0-dev.20260625074633 → 1.4.0-dev.20260727093741
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 +6 -2
- package/README.md +1 -3
- package/implementation/FeatureEditor.js.map +1 -1
- package/implementation/components/controls/option-hooks.js.map +1 -1
- package/implementation/context/PropertyFormContext.d.ts +0 -1
- package/implementation/context/PropertyFormContext.js +2 -2
- package/implementation/context/PropertyFormContext.js.map +1 -1
- package/implementation/geometry-editing/controller/DrawingSession.d.ts +1 -6
- package/implementation/geometry-editing/controller/DrawingSession.js +33 -33
- package/implementation/geometry-editing/controller/DrawingSession.js.map +1 -1
- package/implementation/geometry-editing/controller/EditingController.d.ts +1 -7
- package/implementation/geometry-editing/controller/EditingController.js +40 -40
- package/implementation/geometry-editing/controller/EditingController.js.map +1 -1
- package/implementation/geometry-editing/controller/UndoManager.d.ts +1 -4
- package/implementation/geometry-editing/controller/UndoManager.js +14 -14
- package/implementation/geometry-editing/controller/UndoManager.js.map +1 -1
- package/implementation/geometry-editing/interactions/BaseInteraction.d.ts +1 -3
- package/implementation/geometry-editing/interactions/BaseInteraction.js +12 -12
- package/implementation/geometry-editing/interactions/BaseInteraction.js.map +1 -1
- package/implementation/geometry-editing/interactions/DoubleClickInteraction.d.ts +1 -1
- package/implementation/geometry-editing/interactions/DoubleClickInteraction.js +2 -2
- package/implementation/geometry-editing/interactions/DoubleClickInteraction.js.map +1 -1
- package/implementation/geometry-editing/interactions/DrawingInteraction.d.ts +1 -3
- package/implementation/geometry-editing/interactions/DrawingInteraction.js +11 -11
- package/implementation/geometry-editing/interactions/DrawingInteraction.js.map +1 -1
- package/implementation/geometry-editing/interactions/HighlightingInteraction.d.ts +1 -2
- package/implementation/geometry-editing/interactions/HighlightingInteraction.js +4 -4
- package/implementation/geometry-editing/interactions/HighlightingInteraction.js.map +1 -1
- package/implementation/geometry-editing/interactions/KeyboardInteraction.d.ts +1 -5
- package/implementation/geometry-editing/interactions/KeyboardInteraction.js +10 -10
- package/implementation/geometry-editing/interactions/KeyboardInteraction.js.map +1 -1
- package/implementation/geometry-editing/interactions/ModificationInteraction.d.ts +1 -2
- package/implementation/geometry-editing/interactions/ModificationInteraction.js +4 -4
- package/implementation/geometry-editing/interactions/ModificationInteraction.js.map +1 -1
- package/implementation/geometry-editing/interactions/SelectionInteraction.d.ts +1 -5
- package/implementation/geometry-editing/interactions/SelectionInteraction.js +10 -10
- package/implementation/geometry-editing/interactions/SelectionInteraction.js.map +1 -1
- package/package.json +12 -12
package/CHANGELOG.md
CHANGED
|
@@ -1,10 +1,14 @@
|
|
|
1
1
|
# @open-pioneer/feature-editing
|
|
2
2
|
|
|
3
|
-
## 1.4.0-dev.
|
|
3
|
+
## 1.4.0-dev.20260727093741
|
|
4
4
|
|
|
5
5
|
### Minor Changes
|
|
6
6
|
|
|
7
|
-
- c30396d: Update Chakra to 3.36.
|
|
7
|
+
- c30396d: Update Chakra to 3.36.1
|
|
8
|
+
|
|
9
|
+
### Patch Changes
|
|
10
|
+
|
|
11
|
+
- 078bef5: Use private JavaScript properties (#) instead of TypeScript keyword.
|
|
8
12
|
|
|
9
13
|
## 1.3.0
|
|
10
14
|
|
package/README.md
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FeatureEditor.js","sources":["FeatureEditor.tsx"],"sourcesContent":["// SPDX-FileCopyrightText: 2023-2025 Open Pioneer project (https://github.com/open-pioneer)\n// SPDX-License-Identifier: Apache-2.0\nimport { Box } from \"@chakra-ui/react\";\nimport { useMapModelValue } from \"@open-pioneer/map\";\nimport { useCommonComponentProps } from \"@open-pioneer/react-utils\";\nimport type { Type as GeometryType } from \"ol/geom/Geometry\";\nimport { useIntl } from \"open-pioneer:react-hooks\";\nimport { type ReactElement, type ReactNode, useMemo } from \"react\";\nimport type { FeatureEditorProps } from \"../api/editor/editor\";\nimport { ActionSelector } from \"./components/action-selector/ActionSelector\";\nimport { PropertyEditor } from \"./components/property-editor/PropertyEditor\";\nimport { useEditingStep, useOnActionChange, useSnappingSources } from \"./editor/editorHooks\";\nimport { useEditingCallbacks } from \"./editor/useEditingCallbacks\";\nimport { TooltipMessages } from \"./geometry-editing/controller/EditingController\";\nimport { useGeometryEditing } from \"./geometry-editing/useGeometryEditing\";\n\nexport function FeatureEditor(props: FeatureEditorProps): ReactElement {\n const {\n map,\n templates,\n writer,\n resolveFormTemplate,\n selectableLayers,\n snappableLayers = selectableLayers,\n showActionBar = true,\n successNotifierDisplayDuration,\n failureNotifierDisplayDuration,\n onEditingStepChange,\n ...interactionOptions\n } = props;\n const { containerProps } = useCommonComponentProps(\"editor\", props);\n const mapModel = useMapModelValue(props);\n const intl = useIntl();\n\n const [editingStep, setEditingStep] = useEditingStep(onEditingStepChange);\n const snappingSources = useSnappingSources(mapModel, snappableLayers, templates);\n const onActionChange = useOnActionChange(mapModel, selectableLayers, templates, setEditingStep);\n\n const tooltipMessages = useMemo((): TooltipMessages => {\n return {\n getDrawingMessages() {\n return new Map<GeometryType, ReactNode>([\n [\"Point\", intl.formatRichMessage({ id: \"tooltips.drawingMessagePoint\" })],\n [\n \"LineString\",\n intl.formatRichMessage({ id: \"tooltips.drawingMessageLineString\" })\n ],\n [\"Polygon\", intl.formatRichMessage({ id: \"tooltips.drawingMessagePolygon\" })],\n [\"Circle\", intl.formatRichMessage({ id: \"tooltips.drawingMessageCircle\" })]\n ]);\n },\n getSelectionMessage() {\n return intl.formatRichMessage({ id: \"tooltips.selectionMessage\" });\n },\n getModificationMessages() {\n return new Map<string, ReactNode>([\n [\"Point\", intl.formatRichMessage({ id: \"tooltips.modificationMessagePoint\" })],\n [\"default\", intl.formatRichMessage({ id: \"tooltips.modificationMessage\" })]\n ]);\n }\n };\n }, [intl]);\n\n const drawingState = useGeometryEditing({\n map,\n editingStep,\n setEditingStep,\n snappingSources,\n tooltipMessages,\n ...interactionOptions\n });\n\n const editingCallbacks = useEditingCallbacks(\n mapModel,\n editingStep,\n writer,\n setEditingStep,\n successNotifierDisplayDuration,\n failureNotifierDisplayDuration\n );\n\n let content: ReactNode;\n switch (editingStep.id) {\n case \"initial\":\n case \"drawing\":\n case \"selection\":\n content = (\n <ActionSelector\n templates={templates}\n showActionBar={showActionBar}\n onActionChange={onActionChange}\n drawingState={drawingState}\n />\n );\n break;\n case \"creation\":\n case \"update\":\n content = (\n <PropertyEditor\n editingStep={editingStep}\n callbacks={editingCallbacks}\n templates={templates}\n resolveFormTemplate={resolveFormTemplate}\n />\n );\n break;\n }\n\n return (\n <Box {...containerProps} h=\"full\">\n {content}\n </Box>\n );\n}\n
|
|
1
|
+
{"version":3,"file":"FeatureEditor.js","sources":["FeatureEditor.tsx"],"sourcesContent":["// SPDX-FileCopyrightText: 2023-2025 Open Pioneer project (https://github.com/open-pioneer)\n// SPDX-License-Identifier: Apache-2.0\nimport { Box } from \"@chakra-ui/react\";\nimport { useMapModelValue } from \"@open-pioneer/map\";\nimport { useCommonComponentProps } from \"@open-pioneer/react-utils\";\nimport type { Type as GeometryType } from \"ol/geom/Geometry\";\nimport { useIntl } from \"open-pioneer:react-hooks\";\nimport { type ReactElement, type ReactNode, useMemo } from \"react\";\nimport type { FeatureEditorProps } from \"../api/editor/editor\";\nimport { ActionSelector } from \"./components/action-selector/ActionSelector\";\nimport { PropertyEditor } from \"./components/property-editor/PropertyEditor\";\nimport { useEditingStep, useOnActionChange, useSnappingSources } from \"./editor/editorHooks\";\nimport { useEditingCallbacks } from \"./editor/useEditingCallbacks\";\nimport { TooltipMessages } from \"./geometry-editing/controller/EditingController\";\nimport { useGeometryEditing } from \"./geometry-editing/useGeometryEditing\";\n\nexport function FeatureEditor(props: FeatureEditorProps): ReactElement {\n const {\n map,\n templates,\n writer,\n resolveFormTemplate,\n selectableLayers,\n snappableLayers = selectableLayers,\n showActionBar = true,\n successNotifierDisplayDuration,\n failureNotifierDisplayDuration,\n onEditingStepChange,\n ...interactionOptions\n } = props;\n const { containerProps } = useCommonComponentProps(\"editor\", props);\n const mapModel = useMapModelValue(props);\n const intl = useIntl();\n\n const [editingStep, setEditingStep] = useEditingStep(onEditingStepChange);\n const snappingSources = useSnappingSources(mapModel, snappableLayers, templates);\n const onActionChange = useOnActionChange(mapModel, selectableLayers, templates, setEditingStep);\n\n const tooltipMessages = useMemo((): TooltipMessages => {\n return {\n getDrawingMessages() {\n return new Map<GeometryType, ReactNode>([\n [\"Point\", intl.formatRichMessage({ id: \"tooltips.drawingMessagePoint\" })],\n [\n \"LineString\",\n intl.formatRichMessage({ id: \"tooltips.drawingMessageLineString\" })\n ],\n [\"Polygon\", intl.formatRichMessage({ id: \"tooltips.drawingMessagePolygon\" })],\n [\"Circle\", intl.formatRichMessage({ id: \"tooltips.drawingMessageCircle\" })]\n ]);\n },\n getSelectionMessage() {\n return intl.formatRichMessage({ id: \"tooltips.selectionMessage\" });\n },\n getModificationMessages() {\n return new Map<string, ReactNode>([\n [\"Point\", intl.formatRichMessage({ id: \"tooltips.modificationMessagePoint\" })],\n [\"default\", intl.formatRichMessage({ id: \"tooltips.modificationMessage\" })]\n ]);\n }\n };\n }, [intl]);\n\n const drawingState = useGeometryEditing({\n map,\n editingStep,\n setEditingStep,\n snappingSources,\n tooltipMessages,\n ...interactionOptions\n });\n\n const editingCallbacks = useEditingCallbacks(\n mapModel,\n editingStep,\n writer,\n setEditingStep,\n successNotifierDisplayDuration,\n failureNotifierDisplayDuration\n );\n\n let content: ReactNode;\n switch (editingStep.id) {\n case \"initial\":\n case \"drawing\":\n case \"selection\":\n content = (\n <ActionSelector\n templates={templates}\n showActionBar={showActionBar}\n onActionChange={onActionChange}\n drawingState={drawingState}\n />\n );\n break;\n case \"creation\":\n case \"update\":\n content = (\n <PropertyEditor\n editingStep={editingStep}\n callbacks={editingCallbacks}\n templates={templates}\n resolveFormTemplate={resolveFormTemplate}\n />\n );\n break;\n }\n\n return (\n <Box {...containerProps} h=\"full\">\n {content}\n </Box>\n );\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"option-hooks.js","sources":["option-hooks.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2023-2025 Open Pioneer project (https://github.com/open-pioneer)\n// SPDX-License-Identifier: Apache-2.0\nimport {\n useListCollection,\n useFilter,\n type ComboboxInputValueChangeDetails,\n type ComboboxValueChangeDetails,\n type SelectValueChangeDetails,\n type RadioGroupValueChangeDetails\n} from \"@chakra-ui/react\";\nimport { useEvent } from \"@open-pioneer/react-utils\";\nimport { useMemo } from \"react\";\nimport type { SelectConfig, ComboBoxConfig } from \"../../../api/fields/optionFieldConfigs\";\n\nexport interface OptionControlProps<T = SelectConfig | ComboBoxConfig> {\n readonly value: string | number | undefined;\n readonly field: T;\n readonly onChange: (value: unknown) => void;\n}\n\ntype ValueChangeDetails =\n
|
|
1
|
+
{"version":3,"file":"option-hooks.js","sources":["option-hooks.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2023-2025 Open Pioneer project (https://github.com/open-pioneer)\n// SPDX-License-Identifier: Apache-2.0\nimport {\n useListCollection,\n useFilter,\n type ComboboxInputValueChangeDetails,\n type ComboboxValueChangeDetails,\n type SelectValueChangeDetails,\n type RadioGroupValueChangeDetails\n} from \"@chakra-ui/react\";\nimport { useEvent } from \"@open-pioneer/react-utils\";\nimport { useMemo } from \"react\";\nimport type { SelectConfig, ComboBoxConfig } from \"../../../api/fields/optionFieldConfigs\";\n\nexport interface OptionControlProps<T = SelectConfig | ComboBoxConfig> {\n readonly value: string | number | undefined;\n readonly field: T;\n readonly onChange: (value: unknown) => void;\n}\n\ntype ValueChangeDetails =\n SelectValueChangeDetails | ComboboxValueChangeDetails | RadioGroupValueChangeDetails;\n\nexport function useOptionProps({ value, field, onChange }: OptionControlProps) {\n const selectedValue = useMemo(() => (value != undefined ? [value.toString()] : []), [value]);\n const { collection, onInputValueChange } = useCollection(field);\n const onValueChange = useOnValueChange(field.valueType, onChange);\n\n return {\n selectedValue,\n collection,\n placeholder: field.placeholder ?? field.label,\n showClearTrigger: field.showClearTrigger ?? !(field.isRequired ?? false),\n onInputValueChange,\n onValueChange\n };\n}\n\nexport function useOnValueChange(\n valueType: \"string\" | \"number\",\n onChange: (value: unknown) => void\n) {\n return useEvent((details: ValueChangeDetails) => {\n const newValue = details.value?.[0];\n if (valueType === \"number\") {\n onChange(newValue !== undefined ? parseFloat(newValue) : undefined);\n } else {\n onChange(newValue);\n }\n });\n}\n\nfunction useCollection(field: SelectConfig | ComboBoxConfig) {\n const initialItems = useMemo(() => {\n return field.options.map(({ label, value }) => ({ label, value: value.toString() }));\n }, [field.options]);\n\n const { contains } = useFilter({ sensitivity: \"base\" });\n const { collection, filter } = useListCollection({ initialItems, filter: contains });\n\n const onInputValueChange = useEvent((details: ComboboxInputValueChangeDetails) => {\n filter(details.inputValue);\n });\n\n return { collection, onInputValueChange };\n}\n"],"names":[],"mappings":";;;;AAuBO,SAAS,cAAA,CAAe,EAAE,KAAA,EAAO,KAAA,EAAO,UAAS,EAAuB;AAC3E,EAAA,MAAM,aAAA,GAAgB,OAAA,CAAQ,MAAO,KAAA,IAAS,SAAY,CAAC,KAAA,CAAM,QAAA,EAAU,CAAA,GAAI,EAAC,EAAI,CAAC,KAAK,CAAC,CAAA;AAC3F,EAAA,MAAM,EAAE,UAAA,EAAY,kBAAA,EAAmB,GAAI,cAAc,KAAK,CAAA;AAC9D,EAAA,MAAM,aAAA,GAAgB,gBAAA,CAAiB,KAAA,CAAM,SAAA,EAAW,QAAQ,CAAA;AAEhE,EAAA,OAAO;AAAA,IACH,aAAA;AAAA,IACA,UAAA;AAAA,IACA,WAAA,EAAa,KAAA,CAAM,WAAA,IAAe,KAAA,CAAM,KAAA;AAAA,IACxC,gBAAA,EAAkB,KAAA,CAAM,gBAAA,IAAoB,EAAE,MAAM,UAAA,IAAc,KAAA,CAAA;AAAA,IAClE,kBAAA;AAAA,IACA;AAAA,GACJ;AACJ;AAEO,SAAS,gBAAA,CACZ,WACA,QAAA,EACF;AACE,EAAA,OAAO,QAAA,CAAS,CAAC,OAAA,KAAgC;AAC7C,IAAA,MAAM,QAAA,GAAW,OAAA,CAAQ,KAAA,GAAQ,CAAC,CAAA;AAClC,IAAA,IAAI,cAAc,QAAA,EAAU;AACxB,MAAA,QAAA,CAAS,QAAA,KAAa,MAAA,GAAY,UAAA,CAAW,QAAQ,IAAI,MAAS,CAAA;AAAA,IACtE,CAAA,MAAO;AACH,MAAA,QAAA,CAAS,QAAQ,CAAA;AAAA,IACrB;AAAA,EACJ,CAAC,CAAA;AACL;AAEA,SAAS,cAAc,KAAA,EAAsC;AACzD,EAAA,MAAM,YAAA,GAAe,QAAQ,MAAM;AAC/B,IAAA,OAAO,KAAA,CAAM,OAAA,CAAQ,GAAA,CAAI,CAAC,EAAE,KAAA,EAAO,KAAA,EAAM,MAAO,EAAE,KAAA,EAAO,KAAA,EAAO,KAAA,CAAM,QAAA,IAAW,CAAE,CAAA;AAAA,EACvF,CAAA,EAAG,CAAC,KAAA,CAAM,OAAO,CAAC,CAAA;AAElB,EAAA,MAAM,EAAE,QAAA,EAAS,GAAI,UAAU,EAAE,WAAA,EAAa,QAAQ,CAAA;AACtD,EAAA,MAAM,EAAE,YAAY,MAAA,EAAO,GAAI,kBAAkB,EAAE,YAAA,EAAc,MAAA,EAAQ,QAAA,EAAU,CAAA;AAEnF,EAAA,MAAM,kBAAA,GAAqB,QAAA,CAAS,CAAC,OAAA,KAA6C;AAC9E,IAAA,MAAA,CAAO,QAAQ,UAAU,CAAA;AAAA,EAC7B,CAAC,CAAA;AAED,EAAA,OAAO,EAAE,YAAY,kBAAA,EAAmB;AAC5C;;;;"}
|
|
@@ -20,7 +20,6 @@ export declare abstract class BaseFormContext {
|
|
|
20
20
|
get layer(): Layer | undefined;
|
|
21
21
|
abstract get isValid(): boolean;
|
|
22
22
|
abstract get hasRequiredFields(): boolean;
|
|
23
|
-
private static getPropertyEntries;
|
|
24
23
|
}
|
|
25
24
|
export declare class DeclarativeFormContext extends BaseFormContext {
|
|
26
25
|
#private;
|
|
@@ -11,7 +11,7 @@ class BaseFormContext {
|
|
|
11
11
|
this.#modificationStep = modificationStep;
|
|
12
12
|
this.callbacks = callbacks;
|
|
13
13
|
this.#formTemplate = formTemplate;
|
|
14
|
-
const entries = BaseFormContext
|
|
14
|
+
const entries = BaseFormContext.#getPropertyEntries(modificationStep.feature);
|
|
15
15
|
this.#propertiesMap = reactiveMap(entries);
|
|
16
16
|
this.#propsAsObject = computed(() => {
|
|
17
17
|
const entries2 = this.properties.entries();
|
|
@@ -43,7 +43,7 @@ class BaseFormContext {
|
|
|
43
43
|
get layer() {
|
|
44
44
|
return this.editingStep.id === "update" ? this.editingStep.layer : void 0;
|
|
45
45
|
}
|
|
46
|
-
static getPropertyEntries(feature) {
|
|
46
|
+
static #getPropertyEntries(feature) {
|
|
47
47
|
const properties = feature.getProperties();
|
|
48
48
|
const geometryName = feature.getGeometryName();
|
|
49
49
|
return Object.entries(properties).filter(([key, _]) => key !== geometryName);
|
|
@@ -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 private 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\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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"}
|
|
@@ -12,12 +12,7 @@ export interface DrawingActionHandler {
|
|
|
12
12
|
readonly reset: () => void;
|
|
13
13
|
}
|
|
14
14
|
export declare class DrawingSession implements DrawingTracker, DrawingState {
|
|
15
|
-
private
|
|
16
|
-
private actionHandler;
|
|
17
|
-
private watchHandle;
|
|
18
|
-
private readonly canFinishSignal;
|
|
19
|
-
private readonly canResetSignal;
|
|
20
|
-
private readonly undoManager;
|
|
15
|
+
#private;
|
|
21
16
|
trackCapabilities(feature: Feature, actionHandler: DrawingActionHandler): void;
|
|
22
17
|
finish(): void;
|
|
23
18
|
reset(): void;
|
|
@@ -4,12 +4,12 @@ import { getNumberOfVertices, canBeFinished, canBeReset, getLastCoordinate } fro
|
|
|
4
4
|
import { UndoManager } from './UndoManager.js';
|
|
5
5
|
|
|
6
6
|
class DrawingSession {
|
|
7
|
-
ignoreNextEdit = false;
|
|
8
|
-
actionHandler;
|
|
9
|
-
watchHandle;
|
|
10
|
-
canFinishSignal = reactive();
|
|
11
|
-
canResetSignal = reactive();
|
|
12
|
-
undoManager = new UndoManager();
|
|
7
|
+
#ignoreNextEdit = false;
|
|
8
|
+
#actionHandler;
|
|
9
|
+
#watchHandle;
|
|
10
|
+
#canFinishSignal = reactive();
|
|
11
|
+
#canResetSignal = reactive();
|
|
12
|
+
#undoManager = new UndoManager();
|
|
13
13
|
trackCapabilities(feature, actionHandler) {
|
|
14
14
|
this.untrackCapabilities();
|
|
15
15
|
const geometry = feature.getGeometry();
|
|
@@ -21,70 +21,70 @@ class DrawingSession {
|
|
|
21
21
|
return () => unByKey(eventsKey);
|
|
22
22
|
}
|
|
23
23
|
);
|
|
24
|
-
this
|
|
25
|
-
this
|
|
24
|
+
this.#ignoreNextEdit = true;
|
|
25
|
+
this.#watchHandle = watchValue(
|
|
26
26
|
() => numberOfVertices.value,
|
|
27
27
|
(numberOfVertices2) => {
|
|
28
|
-
this
|
|
29
|
-
this
|
|
30
|
-
if (!this
|
|
28
|
+
this.#canFinishSignal.value = canBeFinished(geometry, numberOfVertices2);
|
|
29
|
+
this.#canResetSignal.value = canBeReset(geometry, numberOfVertices2);
|
|
30
|
+
if (!this.#ignoreNextEdit) {
|
|
31
31
|
const lastCoordinate = getLastCoordinate(geometry);
|
|
32
32
|
if (lastCoordinate != null) {
|
|
33
|
-
this
|
|
33
|
+
this.#undoManager.addEdit(lastCoordinate);
|
|
34
34
|
}
|
|
35
35
|
} else {
|
|
36
|
-
this
|
|
36
|
+
this.#ignoreNextEdit = false;
|
|
37
37
|
}
|
|
38
38
|
},
|
|
39
39
|
{ immediate: true }
|
|
40
40
|
);
|
|
41
|
-
this
|
|
41
|
+
this.#actionHandler = actionHandler;
|
|
42
42
|
}
|
|
43
43
|
}
|
|
44
44
|
finish() {
|
|
45
45
|
if (this.canFinish) {
|
|
46
|
-
this
|
|
46
|
+
this.#actionHandler?.finish();
|
|
47
47
|
}
|
|
48
48
|
}
|
|
49
49
|
reset() {
|
|
50
50
|
if (this.canReset) {
|
|
51
|
-
this
|
|
51
|
+
this.#actionHandler?.reset();
|
|
52
52
|
}
|
|
53
53
|
}
|
|
54
54
|
undo() {
|
|
55
|
-
if (this.canUndo && this
|
|
56
|
-
this
|
|
57
|
-
this
|
|
58
|
-
this
|
|
55
|
+
if (this.canUndo && this.#actionHandler != null) {
|
|
56
|
+
this.#undoManager.undo();
|
|
57
|
+
this.#ignoreNextEdit = true;
|
|
58
|
+
this.#actionHandler.undo();
|
|
59
59
|
}
|
|
60
60
|
}
|
|
61
61
|
redo() {
|
|
62
|
-
if (this.canRedo && this
|
|
63
|
-
const coordinate = this
|
|
62
|
+
if (this.canRedo && this.#actionHandler != null) {
|
|
63
|
+
const coordinate = this.#undoManager.redo();
|
|
64
64
|
if (coordinate != null) {
|
|
65
|
-
this
|
|
66
|
-
this
|
|
65
|
+
this.#ignoreNextEdit = true;
|
|
66
|
+
this.#actionHandler.redo(coordinate);
|
|
67
67
|
}
|
|
68
68
|
}
|
|
69
69
|
}
|
|
70
70
|
untrackCapabilities() {
|
|
71
|
-
this
|
|
72
|
-
this
|
|
73
|
-
this
|
|
74
|
-
this
|
|
75
|
-
this
|
|
71
|
+
this.#watchHandle?.destroy();
|
|
72
|
+
this.#canFinishSignal.value = void 0;
|
|
73
|
+
this.#canResetSignal.value = void 0;
|
|
74
|
+
this.#undoManager.reset();
|
|
75
|
+
this.#actionHandler = void 0;
|
|
76
76
|
}
|
|
77
77
|
get canFinish() {
|
|
78
|
-
return this
|
|
78
|
+
return this.#canFinishSignal.value ?? false;
|
|
79
79
|
}
|
|
80
80
|
get canReset() {
|
|
81
|
-
return this
|
|
81
|
+
return this.#canResetSignal.value ?? false;
|
|
82
82
|
}
|
|
83
83
|
get canUndo() {
|
|
84
|
-
return this
|
|
84
|
+
return this.#undoManager.canUndo;
|
|
85
85
|
}
|
|
86
86
|
get canRedo() {
|
|
87
|
-
return this
|
|
87
|
+
return this.#undoManager.canRedo;
|
|
88
88
|
}
|
|
89
89
|
}
|
|
90
90
|
|
|
@@ -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
|
|
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":"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"}
|
|
@@ -16,12 +16,7 @@ export interface TooltipMessages {
|
|
|
16
16
|
getModificationMessages(): Map<string, ReactNode>;
|
|
17
17
|
}
|
|
18
18
|
export declare class EditingController {
|
|
19
|
-
private
|
|
20
|
-
private readonly layerFactory;
|
|
21
|
-
private readonly tooltipMessages;
|
|
22
|
-
private currentInteractions;
|
|
23
|
-
private snappingSources;
|
|
24
|
-
private interactionOptions;
|
|
19
|
+
#private;
|
|
25
20
|
readonly drawingSession: DrawingSession;
|
|
26
21
|
constructor(mapModel: MapModel, layerFactory: LayerFactory, tooltipMessages: TooltipMessages);
|
|
27
22
|
startDrawingFeature({ geometryType, drawingOptions, completionHandler }: StartDrawingFeatureOptions): void;
|
|
@@ -30,6 +25,5 @@ export declare class EditingController {
|
|
|
30
25
|
setSnappingSources(sources: VectorSource[] | undefined): void;
|
|
31
26
|
setInteractionOptions(options: InteractionOptions): void;
|
|
32
27
|
stopCurrentInteractions(): void;
|
|
33
|
-
private replaceInteractions;
|
|
34
28
|
}
|
|
35
29
|
export {};
|
|
@@ -8,86 +8,86 @@ import { SnappingInteraction } from '../interactions/SnappingInteraction.js';
|
|
|
8
8
|
import { DrawingSession } from './DrawingSession.js';
|
|
9
9
|
|
|
10
10
|
class EditingController {
|
|
11
|
+
#currentInteractions = [];
|
|
12
|
+
#snappingSources = [];
|
|
13
|
+
#interactionOptions = {};
|
|
14
|
+
drawingSession = new DrawingSession();
|
|
15
|
+
#mapModel;
|
|
16
|
+
#layerFactory;
|
|
17
|
+
#tooltipMessages;
|
|
11
18
|
constructor(mapModel, layerFactory, tooltipMessages) {
|
|
12
|
-
this
|
|
13
|
-
this
|
|
14
|
-
this
|
|
19
|
+
this.#mapModel = mapModel;
|
|
20
|
+
this.#layerFactory = layerFactory;
|
|
21
|
+
this.#tooltipMessages = tooltipMessages;
|
|
15
22
|
}
|
|
16
|
-
mapModel;
|
|
17
|
-
layerFactory;
|
|
18
|
-
tooltipMessages;
|
|
19
|
-
currentInteractions = [];
|
|
20
|
-
snappingSources = [];
|
|
21
|
-
interactionOptions = {};
|
|
22
|
-
drawingSession = new DrawingSession();
|
|
23
23
|
startDrawingFeature({
|
|
24
24
|
geometryType,
|
|
25
25
|
drawingOptions,
|
|
26
26
|
completionHandler
|
|
27
27
|
}) {
|
|
28
|
-
this
|
|
29
|
-
new DrawingInteraction(this
|
|
28
|
+
this.#replaceInteractions(
|
|
29
|
+
new DrawingInteraction(this.#mapModel, {
|
|
30
30
|
geometryType,
|
|
31
31
|
tracker: this.drawingSession,
|
|
32
|
-
drawingOptions: { ...this
|
|
32
|
+
drawingOptions: { ...this.#interactionOptions.drawingOptions, ...drawingOptions },
|
|
33
33
|
completionHandler,
|
|
34
|
-
layerFactory: this
|
|
35
|
-
tooltipMessages: this
|
|
34
|
+
layerFactory: this.#layerFactory,
|
|
35
|
+
tooltipMessages: this.#tooltipMessages
|
|
36
36
|
}),
|
|
37
|
-
new KeyboardInteraction(this
|
|
37
|
+
new KeyboardInteraction(this.#mapModel, {
|
|
38
38
|
actions: this.drawingSession
|
|
39
39
|
}),
|
|
40
|
-
new SnappingInteraction(this
|
|
41
|
-
snappingSources: this
|
|
42
|
-
snappingOptions: this
|
|
40
|
+
new SnappingInteraction(this.#mapModel, {
|
|
41
|
+
snappingSources: this.#snappingSources,
|
|
42
|
+
snappingOptions: this.#interactionOptions.snappingOptions
|
|
43
43
|
}),
|
|
44
|
-
new DoubleClickInteraction(this
|
|
44
|
+
new DoubleClickInteraction(this.#mapModel)
|
|
45
45
|
);
|
|
46
46
|
}
|
|
47
47
|
startSelectingFeature({ layers, completionHandler }) {
|
|
48
|
-
this
|
|
49
|
-
new SelectionInteraction(this
|
|
48
|
+
this.#replaceInteractions(
|
|
49
|
+
new SelectionInteraction(this.#mapModel, {
|
|
50
50
|
layers,
|
|
51
|
-
selectionOptions: this
|
|
51
|
+
selectionOptions: this.#interactionOptions.selectionOptions,
|
|
52
52
|
completionHandler,
|
|
53
|
-
tooltipMessages: this
|
|
53
|
+
tooltipMessages: this.#tooltipMessages
|
|
54
54
|
})
|
|
55
55
|
);
|
|
56
56
|
}
|
|
57
57
|
startModifyingFeature({ feature, drawLayer }) {
|
|
58
|
-
this
|
|
59
|
-
new ModificationInteraction(this
|
|
58
|
+
this.#replaceInteractions(
|
|
59
|
+
new ModificationInteraction(this.#mapModel, {
|
|
60
60
|
feature,
|
|
61
61
|
drawLayer,
|
|
62
|
-
modificationOptions: this
|
|
63
|
-
tooltipMessages: this
|
|
62
|
+
modificationOptions: this.#interactionOptions.modificationOptions,
|
|
63
|
+
tooltipMessages: this.#tooltipMessages
|
|
64
64
|
}),
|
|
65
|
-
new HighlightingInteraction(this
|
|
65
|
+
new HighlightingInteraction(this.#mapModel, {
|
|
66
66
|
feature,
|
|
67
|
-
highlightOptions: this
|
|
67
|
+
highlightOptions: this.#interactionOptions.highlightingOptions
|
|
68
68
|
}),
|
|
69
|
-
new SnappingInteraction(this
|
|
70
|
-
snappingSources: this
|
|
71
|
-
snappingOptions: this
|
|
69
|
+
new SnappingInteraction(this.#mapModel, {
|
|
70
|
+
snappingSources: this.#snappingSources,
|
|
71
|
+
snappingOptions: this.#interactionOptions.snappingOptions
|
|
72
72
|
})
|
|
73
73
|
);
|
|
74
74
|
}
|
|
75
75
|
setSnappingSources(sources) {
|
|
76
|
-
this
|
|
76
|
+
this.#snappingSources = sources ?? [];
|
|
77
77
|
}
|
|
78
78
|
setInteractionOptions(options) {
|
|
79
|
-
this
|
|
79
|
+
this.#interactionOptions = options;
|
|
80
80
|
}
|
|
81
81
|
stopCurrentInteractions() {
|
|
82
|
-
this
|
|
82
|
+
this.#currentInteractions.forEach((interaction) => {
|
|
83
83
|
interaction.stop();
|
|
84
84
|
});
|
|
85
|
-
this
|
|
85
|
+
this.#currentInteractions = [];
|
|
86
86
|
}
|
|
87
|
-
replaceInteractions(...interactions) {
|
|
87
|
+
#replaceInteractions(...interactions) {
|
|
88
88
|
this.stopCurrentInteractions();
|
|
89
|
-
this
|
|
90
|
-
this
|
|
89
|
+
this.#currentInteractions = interactions;
|
|
90
|
+
this.#currentInteractions.forEach((interaction) => {
|
|
91
91
|
interaction.start();
|
|
92
92
|
});
|
|
93
93
|
}
|
|
@@ -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\";\nimport type { Type as GeometryType } from \"ol/geom/Geometry\";\nimport { ReactNode } from \"react\";\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
|
|
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\";\nimport type { Type as GeometryType } from \"ol/geom/Geometry\";\nimport { ReactNode } from \"react\";\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,12 +1,9 @@
|
|
|
1
1
|
export declare class UndoManager<T> {
|
|
2
|
+
#private;
|
|
2
3
|
addEdit(edit: T): void;
|
|
3
4
|
undo(): T | undefined;
|
|
4
5
|
redo(): T | undefined;
|
|
5
6
|
reset(): void;
|
|
6
7
|
get canUndo(): boolean;
|
|
7
8
|
get canRedo(): boolean;
|
|
8
|
-
private undoStack;
|
|
9
|
-
private redoStack;
|
|
10
|
-
private canUndoSignal;
|
|
11
|
-
private canRedoSignal;
|
|
12
9
|
}
|
|
@@ -2,37 +2,37 @@ import { reactiveArray, computed } from '@conterra/reactivity-core';
|
|
|
2
2
|
|
|
3
3
|
class UndoManager {
|
|
4
4
|
addEdit(edit) {
|
|
5
|
-
this
|
|
6
|
-
this
|
|
5
|
+
this.#undoStack.push(edit);
|
|
6
|
+
this.#redoStack.splice(0);
|
|
7
7
|
}
|
|
8
8
|
undo() {
|
|
9
|
-
const edit = this
|
|
9
|
+
const edit = this.#undoStack.pop();
|
|
10
10
|
if (edit != null) {
|
|
11
|
-
this
|
|
11
|
+
this.#redoStack.push(edit);
|
|
12
12
|
}
|
|
13
13
|
return edit;
|
|
14
14
|
}
|
|
15
15
|
redo() {
|
|
16
|
-
const edit = this
|
|
16
|
+
const edit = this.#redoStack.pop();
|
|
17
17
|
if (edit != null) {
|
|
18
|
-
this
|
|
18
|
+
this.#undoStack.push(edit);
|
|
19
19
|
}
|
|
20
20
|
return edit;
|
|
21
21
|
}
|
|
22
22
|
reset() {
|
|
23
|
-
this
|
|
24
|
-
this
|
|
23
|
+
this.#undoStack.splice(0);
|
|
24
|
+
this.#redoStack.splice(0);
|
|
25
25
|
}
|
|
26
26
|
get canUndo() {
|
|
27
|
-
return this
|
|
27
|
+
return this.#canUndoSignal.value;
|
|
28
28
|
}
|
|
29
29
|
get canRedo() {
|
|
30
|
-
return this
|
|
30
|
+
return this.#canRedoSignal.value;
|
|
31
31
|
}
|
|
32
|
-
undoStack = reactiveArray();
|
|
33
|
-
redoStack = reactiveArray();
|
|
34
|
-
canUndoSignal = computed(() => this
|
|
35
|
-
canRedoSignal = computed(() => this
|
|
32
|
+
#undoStack = reactiveArray();
|
|
33
|
+
#redoStack = reactiveArray();
|
|
34
|
+
#canUndoSignal = computed(() => this.#undoStack.length >= 1);
|
|
35
|
+
#canRedoSignal = computed(() => this.#redoStack.length >= 1);
|
|
36
36
|
}
|
|
37
37
|
|
|
38
38
|
export { UndoManager };
|
|
@@ -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
|
|
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":";;AAIO,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;;;;"}
|