@jupytergis/base 0.13.2 → 0.14.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/lib/commands/BaseCommandIDs.d.ts +14 -13
- package/lib/commands/BaseCommandIDs.js +14 -14
- package/lib/commands/index.js +528 -130
- package/lib/commands/operationCommands.d.ts +22 -0
- package/lib/commands/operationCommands.js +305 -0
- package/lib/constants.js +11 -9
- package/lib/dialogs/ProcessingFormDialog.d.ts +1 -1
- package/lib/dialogs/ProcessingFormDialog.js +2 -2
- package/lib/dialogs/layerBrowserDialog.d.ts +2 -0
- package/lib/dialogs/layerBrowserDialog.js +12 -5
- package/lib/dialogs/layerCreationFormDialog.d.ts +7 -0
- package/lib/dialogs/layerCreationFormDialog.js +10 -2
- package/lib/dialogs/symbology/components/color_ramp/ColorRampControls.d.ts +2 -1
- package/lib/dialogs/symbology/components/color_ramp/ColorRampControls.js +21 -19
- package/lib/dialogs/symbology/components/color_ramp/ColorRampSelector.d.ts +3 -1
- package/lib/dialogs/symbology/components/color_ramp/ColorRampSelector.js +13 -5
- package/lib/dialogs/symbology/tiff_layer/types/SingleBandPseudoColor.js +6 -4
- package/lib/dialogs/symbology/vector_layer/types/Categorized.js +7 -11
- package/lib/dialogs/symbology/vector_layer/types/Graduated.js +7 -10
- package/lib/dialogs/symbology/vector_layer/types/Heatmap.js +7 -8
- package/lib/formbuilder/creationform.d.ts +8 -8
- package/lib/formbuilder/creationform.js +130 -85
- package/lib/formbuilder/editform.d.ts +1 -7
- package/lib/formbuilder/editform.js +64 -52
- package/lib/formbuilder/formselectors.d.ts +5 -4
- package/lib/formbuilder/index.d.ts +1 -1
- package/lib/formbuilder/index.js +1 -1
- package/lib/formbuilder/objectform/SchemaForm.d.ts +36 -0
- package/lib/formbuilder/objectform/SchemaForm.js +77 -0
- package/lib/formbuilder/objectform/StoryEditorForm.d.ts +3 -9
- package/lib/formbuilder/objectform/StoryEditorForm.js +20 -14
- package/lib/formbuilder/objectform/components/LayerSelect.js +3 -8
- package/lib/formbuilder/objectform/components/SegmentFormSymbology.js +23 -10
- package/lib/formbuilder/objectform/components/SourcePropertiesField.d.ts +7 -0
- package/lib/formbuilder/objectform/components/SourcePropertiesField.js +29 -0
- package/lib/formbuilder/objectform/components/StorySegmentReset.js +1 -1
- package/lib/formbuilder/objectform/fileselectorwidget.js +1 -1
- package/lib/formbuilder/objectform/layer/heatmapLayerForm.d.ts +3 -12
- package/lib/formbuilder/objectform/layer/heatmapLayerForm.js +87 -55
- package/lib/formbuilder/objectform/layer/hillshadeLayerForm.d.ts +3 -8
- package/lib/formbuilder/objectform/layer/hillshadeLayerForm.js +36 -10
- package/lib/formbuilder/objectform/layer/layerform.d.ts +7 -9
- package/lib/formbuilder/objectform/layer/layerform.js +33 -20
- package/lib/formbuilder/objectform/layer/storySegmentLayerForm.d.ts +3 -5
- package/lib/formbuilder/objectform/layer/storySegmentLayerForm.js +73 -29
- package/lib/formbuilder/objectform/layer/vectorlayerform.d.ts +3 -14
- package/lib/formbuilder/objectform/layer/vectorlayerform.js +36 -29
- package/lib/formbuilder/objectform/layer/webGlLayerForm.d.ts +3 -10
- package/lib/formbuilder/objectform/layer/webGlLayerForm.js +37 -13
- package/lib/formbuilder/objectform/process/dissolveProcessForm.d.ts +8 -18
- package/lib/formbuilder/objectform/process/dissolveProcessForm.js +68 -56
- package/lib/formbuilder/objectform/processingForm.d.ts +12 -0
- package/lib/formbuilder/objectform/processingForm.js +33 -0
- package/lib/formbuilder/objectform/schemaUtils.d.ts +16 -0
- package/lib/formbuilder/objectform/schemaUtils.js +59 -0
- package/lib/formbuilder/objectform/source/geojsonsource.d.ts +3 -19
- package/lib/formbuilder/objectform/source/geojsonsource.js +94 -53
- package/lib/formbuilder/objectform/source/geotiffsource.d.ts +3 -20
- package/lib/formbuilder/objectform/source/geotiffsource.js +73 -74
- package/lib/formbuilder/objectform/source/pathbasedsource.d.ts +3 -19
- package/lib/formbuilder/objectform/source/pathbasedsource.js +76 -75
- package/lib/formbuilder/objectform/source/sourceform.d.ts +7 -8
- package/lib/formbuilder/objectform/source/sourceform.js +28 -11
- package/lib/formbuilder/objectform/source/tilesourceform.d.ts +3 -7
- package/lib/formbuilder/objectform/source/tilesourceform.js +63 -53
- package/lib/formbuilder/objectform/useSchemaFormState.d.ts +48 -0
- package/lib/formbuilder/objectform/useSchemaFormState.js +35 -0
- package/lib/index.d.ts +0 -1
- package/lib/index.js +0 -1
- package/lib/keybindings.json +10 -10
- package/lib/mainview/mainView.d.ts +11 -7
- package/lib/mainview/mainView.js +63 -36
- package/lib/mainview/mainviewmodel.js +2 -2
- package/lib/menus.js +8 -8
- package/lib/panelview/components/layers.js +5 -2
- package/lib/panelview/objectproperties.js +2 -2
- package/lib/panelview/rightpanel.js +17 -2
- package/lib/panelview/story-maps/SpectaPanel.d.ts +15 -0
- package/lib/panelview/story-maps/SpectaPanel.js +35 -0
- package/lib/panelview/story-maps/StoryViewerPanel.d.ts +24 -9
- package/lib/panelview/story-maps/StoryViewerPanel.js +22 -268
- package/lib/panelview/story-maps/{PreviewModeSwitch.js → components/PreviewModeSwitch.js} +1 -1
- package/lib/panelview/story-maps/components/SpectaDesktopView.d.ts +21 -0
- package/lib/panelview/story-maps/components/SpectaDesktopView.js +49 -0
- package/lib/panelview/story-maps/components/SpectaMobileView.d.ts +17 -0
- package/lib/panelview/story-maps/{MobileSpectaPanel.js → components/SpectaMobileView.js} +8 -22
- package/lib/panelview/story-maps/{StoryNavBar.d.ts → components/StoryNavBar.d.ts} +1 -1
- package/lib/panelview/story-maps/{StoryNavBar.js → components/StoryNavBar.js} +2 -4
- package/lib/panelview/story-maps/hooks/useStoryMap.d.ts +39 -0
- package/lib/panelview/story-maps/hooks/useStoryMap.js +252 -0
- package/lib/processing/index.d.ts +2 -2
- package/lib/processing/index.js +62 -35
- package/lib/processing/processingCommands.d.ts +1 -1
- package/lib/processing/processingCommands.js +26 -6
- package/lib/shared/components/Collapsible.d.ts +6 -0
- package/lib/shared/components/Collapsible.js +26 -0
- package/lib/statusbar/SpectaPresentationProgressBar.d.ts +7 -0
- package/lib/statusbar/SpectaPresentationProgressBar.js +40 -0
- package/lib/toolbar/widget.js +4 -2
- package/lib/tools.d.ts +6 -0
- package/lib/tools.js +9 -0
- package/lib/types.d.ts +29 -2
- package/lib/widget.js +14 -2
- package/package.json +2 -4
- package/style/base.css +23 -1
- package/style/dialog.css +5 -0
- package/style/leftPanel.css +14 -37
- package/style/shared/button.css +0 -10
- package/style/shared/switch.css +8 -7
- package/style/spectaProgressBar.css +144 -0
- package/style/storyPanel.css +33 -0
- package/style/symbologyDialog.css +2 -2
- package/lib/formbuilder/objectform/baseform.d.ts +0 -91
- package/lib/formbuilder/objectform/baseform.js +0 -231
- package/lib/panelview/story-maps/MobileSpectaPanel.d.ts +0 -7
- /package/lib/panelview/story-maps/{PreviewModeSwitch.d.ts → components/PreviewModeSwitch.d.ts} +0 -0
|
@@ -2,65 +2,77 @@ import { Signal } from '@lumino/signaling';
|
|
|
2
2
|
import * as React from 'react';
|
|
3
3
|
import { deepCopy } from "../tools";
|
|
4
4
|
import { getLayerTypeForm, getSourceTypeForm } from './formselectors';
|
|
5
|
+
function syncObjectProperties(model, id, properties) {
|
|
6
|
+
if (!id) {
|
|
7
|
+
return;
|
|
8
|
+
}
|
|
9
|
+
model.sharedModel.updateObjectParameters(id, properties);
|
|
10
|
+
}
|
|
5
11
|
/**
|
|
6
12
|
* Form for editing a source, a layer or both at the same time
|
|
7
13
|
*/
|
|
8
|
-
export
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
14
|
+
export function EditForm(props) {
|
|
15
|
+
const { layer: layerId, source: sourceId, formSchemaRegistry, model } = props;
|
|
16
|
+
const sourceFormChangedSignalRef = React.useRef(null);
|
|
17
|
+
if (!sourceFormChangedSignalRef.current) {
|
|
18
|
+
sourceFormChangedSignalRef.current = new Signal({});
|
|
12
19
|
}
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
20
|
+
const sourceFormChangedSignal = sourceFormChangedSignalRef.current;
|
|
21
|
+
let layer;
|
|
22
|
+
let LayerForm;
|
|
23
|
+
let layerData;
|
|
24
|
+
let layerSchema;
|
|
25
|
+
if (layerId) {
|
|
26
|
+
layer = model.getLayer(layerId);
|
|
27
|
+
if (!layer) {
|
|
28
|
+
return null;
|
|
29
|
+
}
|
|
30
|
+
LayerForm = getLayerTypeForm(layer.type || 'RasterLayer');
|
|
31
|
+
layerData = deepCopy(layer.parameters || {});
|
|
32
|
+
layerSchema = deepCopy(formSchemaRegistry.getSchemas().get(layer.type));
|
|
33
|
+
if (!layerSchema) {
|
|
34
|
+
console.error(`Cannot find schema for ${layer.type}`);
|
|
35
|
+
return null;
|
|
16
36
|
}
|
|
17
|
-
this.props.model.sharedModel.updateObjectParameters(id, properties);
|
|
18
37
|
}
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
console.error(`Cannot find schema for ${layer.type}`);
|
|
34
|
-
return;
|
|
35
|
-
}
|
|
38
|
+
else {
|
|
39
|
+
layer = undefined;
|
|
40
|
+
LayerForm = undefined;
|
|
41
|
+
layerData = undefined;
|
|
42
|
+
layerSchema = undefined;
|
|
43
|
+
}
|
|
44
|
+
let source;
|
|
45
|
+
let SourceForm;
|
|
46
|
+
let sourceData;
|
|
47
|
+
let sourceSchema;
|
|
48
|
+
if (sourceId) {
|
|
49
|
+
source = model.getSource(sourceId);
|
|
50
|
+
if (!source) {
|
|
51
|
+
return null;
|
|
36
52
|
}
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
if (!source) {
|
|
44
|
-
return;
|
|
45
|
-
}
|
|
46
|
-
SourceForm = getSourceTypeForm((source === null || source === void 0 ? void 0 : source.type) || 'RasterSource');
|
|
47
|
-
sourceData = deepCopy((source === null || source === void 0 ? void 0 : source.parameters) || {});
|
|
48
|
-
sourceSchema = deepCopy(this.props.formSchemaRegistry.getSchemas().get(source.type));
|
|
49
|
-
if (!sourceSchema) {
|
|
50
|
-
console.error(`Cannot find schema for ${source.type}`);
|
|
51
|
-
return;
|
|
52
|
-
}
|
|
53
|
+
SourceForm = getSourceTypeForm(source.type || 'RasterSource');
|
|
54
|
+
sourceData = deepCopy(source.parameters || {});
|
|
55
|
+
sourceSchema = deepCopy(formSchemaRegistry.getSchemas().get(source.type));
|
|
56
|
+
if (!sourceSchema) {
|
|
57
|
+
console.error(`Cannot find schema for ${source.type}`);
|
|
58
|
+
return null;
|
|
53
59
|
}
|
|
54
|
-
return (React.createElement("div", null,
|
|
55
|
-
this.props.layer && LayerForm && (React.createElement("div", null,
|
|
56
|
-
React.createElement("h3", { style: { paddingLeft: '5px' } }, "Layer Properties"),
|
|
57
|
-
React.createElement(LayerForm, { key: `${this.props.layer}-${source === null || source === void 0 ? void 0 : source.type}`, formContext: "update", sourceType: (source === null || source === void 0 ? void 0 : source.type) || 'RasterSource', model: this.props.model, filePath: this.props.model.filePath, schema: layerSchema, sourceData: layerData, syncData: (properties) => {
|
|
58
|
-
this.syncObjectProperties(this.props.layer, properties);
|
|
59
|
-
} }))),
|
|
60
|
-
this.props.source && SourceForm && (React.createElement("div", null,
|
|
61
|
-
React.createElement("h3", { style: { paddingLeft: '5px' } }, "Source Properties"),
|
|
62
|
-
React.createElement(SourceForm, { key: `${this.props.source}-${layer === null || layer === void 0 ? void 0 : layer.type}`, formContext: "update", model: this.props.model, filePath: this.props.model.filePath, schema: sourceSchema, sourceData: sourceData, syncData: (properties) => {
|
|
63
|
-
this.syncObjectProperties(this.props.source, properties);
|
|
64
|
-
}, formChangedSignal: this.sourceFormChangedSignal, sourceType: (source === null || source === void 0 ? void 0 : source.type) || 'RasterSource' })))));
|
|
65
60
|
}
|
|
61
|
+
else {
|
|
62
|
+
source = undefined;
|
|
63
|
+
SourceForm = undefined;
|
|
64
|
+
sourceData = undefined;
|
|
65
|
+
sourceSchema = undefined;
|
|
66
|
+
}
|
|
67
|
+
return (React.createElement("div", null,
|
|
68
|
+
layerId && LayerForm && layerSchema && layerData !== undefined && (React.createElement("div", null,
|
|
69
|
+
React.createElement("h3", { style: { paddingLeft: '5px' } }, "Layer Properties"),
|
|
70
|
+
React.createElement(LayerForm, { key: `${layerId}-${source === null || source === void 0 ? void 0 : source.type}`, formContext: "update", sourceType: (source === null || source === void 0 ? void 0 : source.type) || 'RasterSource', model: model, filePath: model.filePath, schema: layerSchema, sourceData: layerData, syncData: (properties) => {
|
|
71
|
+
syncObjectProperties(model, layerId, properties);
|
|
72
|
+
}, formSchemaRegistry: formSchemaRegistry }))),
|
|
73
|
+
sourceId && SourceForm && sourceSchema && sourceData !== undefined && (React.createElement("div", null,
|
|
74
|
+
React.createElement("h3", { style: { paddingLeft: '5px' } }, "Source Properties"),
|
|
75
|
+
React.createElement(SourceForm, { key: `${sourceId}-${layer === null || layer === void 0 ? void 0 : layer.type}`, formContext: "update", model: model, filePath: model.filePath, schema: sourceSchema, sourceData: sourceData, syncData: (properties) => {
|
|
76
|
+
syncObjectProperties(model, sourceId, properties);
|
|
77
|
+
}, formChangedSignal: sourceFormChangedSignal, sourceType: (source === null || source === void 0 ? void 0 : source.type) || 'RasterSource', formSchemaRegistry: formSchemaRegistry })))));
|
|
66
78
|
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { LayerType, SourceType } from '@jupytergis/schema';
|
|
2
|
-
import
|
|
3
|
-
import {
|
|
4
|
-
|
|
5
|
-
export declare function
|
|
2
|
+
import * as React from 'react';
|
|
3
|
+
import type { ILayerProps } from './objectform/layer/layerform';
|
|
4
|
+
import type { ISourceFormProps } from './objectform/source/sourceform';
|
|
5
|
+
export declare function getLayerTypeForm(layerType: LayerType): React.ComponentType<ILayerProps>;
|
|
6
|
+
export declare function getSourceTypeForm(sourceType: SourceType): React.ComponentType<ISourceFormProps>;
|
package/lib/formbuilder/index.js
CHANGED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import type { Signal } from '@lumino/signaling';
|
|
2
|
+
import { RegistryFieldsType, UiSchema } from '@rjsf/utils';
|
|
3
|
+
import React from 'react';
|
|
4
|
+
import { IDict, type IJupyterGISFormContext } from "../../types";
|
|
5
|
+
export interface ISchemaFormProps {
|
|
6
|
+
/** JSON Schema for the form. */
|
|
7
|
+
schema: IDict;
|
|
8
|
+
/** Current form data (controlled). */
|
|
9
|
+
formData: IDict | undefined;
|
|
10
|
+
/** Called when form data changes. */
|
|
11
|
+
onChange: (data: IDict) => void;
|
|
12
|
+
/** Called when form is submitted (e.g. submit button or Enter). */
|
|
13
|
+
onSubmit: (data: IDict) => void;
|
|
14
|
+
/** Context for custom fields (e.g. LayerSelect) that need model and formData. */
|
|
15
|
+
formContext: IJupyterGISFormContext;
|
|
16
|
+
/** Path to the file; used for data-path on the panel. */
|
|
17
|
+
filePath?: string;
|
|
18
|
+
/** Enable live validation. Default true. */
|
|
19
|
+
liveValidate?: boolean;
|
|
20
|
+
/** Additional custom fields to register (merged with opacity, layerSelect). */
|
|
21
|
+
additionalFields?: RegistryFieldsType;
|
|
22
|
+
/** Optional pre-built uiSchema (e.g. from processBaseSchema). When provided, merged with additionalProperties hidden field. */
|
|
23
|
+
uiSchema?: UiSchema;
|
|
24
|
+
/** Optional extra validation errors (RJSF extraErrors format). */
|
|
25
|
+
extraErrors?: IDict;
|
|
26
|
+
/** Optional ref to the hidden submit button; when provided, parent can trigger submit (e.g. on ok signal). */
|
|
27
|
+
submitButtonRef?: React.MutableRefObject<HTMLButtonElement | null>;
|
|
28
|
+
/** When provided, emit(true) when there are validation/extra errors, emit(false) when clear (e.g. to disable dialog OK). */
|
|
29
|
+
formErrorSignal?: Signal<any, boolean>;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Renders a JSON Schema form (RJSF) for layer, source, and other object properties.
|
|
33
|
+
* The parent is responsible for state (formData), syncing to the model, and dialog
|
|
34
|
+
* behaviour; this component only renders the form and calls onChange/onSubmit.
|
|
35
|
+
*/
|
|
36
|
+
export declare function SchemaForm(props: ISchemaFormProps): React.ReactElement;
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import { FormComponent } from '@jupyterlab/ui-components';
|
|
2
|
+
import validatorAjv8 from '@rjsf/validator-ajv8';
|
|
3
|
+
import React, { useCallback, useEffect, useMemo, useRef } from 'react';
|
|
4
|
+
import { LayerSelect } from './components/LayerSelect';
|
|
5
|
+
import OpacitySlider from './components/OpacitySlider';
|
|
6
|
+
const defaultFields = {
|
|
7
|
+
opacity: OpacitySlider,
|
|
8
|
+
layerSelect: LayerSelect,
|
|
9
|
+
};
|
|
10
|
+
/** True if extraErrors has a non-empty __errors array. */
|
|
11
|
+
function hasExtraErrors(extraErrors) {
|
|
12
|
+
if (!extraErrors || typeof extraErrors !== 'object') {
|
|
13
|
+
return false;
|
|
14
|
+
}
|
|
15
|
+
for (const key of Object.keys(extraErrors)) {
|
|
16
|
+
const value = extraErrors[key];
|
|
17
|
+
const errorList = value && typeof value === 'object'
|
|
18
|
+
? value.__errors
|
|
19
|
+
: undefined;
|
|
20
|
+
if (Array.isArray(errorList) && errorList.length > 0) {
|
|
21
|
+
return true;
|
|
22
|
+
}
|
|
23
|
+
if (value && typeof value === 'object' && !Array.isArray(value)) {
|
|
24
|
+
if (hasExtraErrors(value)) {
|
|
25
|
+
return true;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
return false;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Renders a JSON Schema form (RJSF) for layer, source, and other object properties.
|
|
33
|
+
* The parent is responsible for state (formData), syncing to the model, and dialog
|
|
34
|
+
* behaviour; this component only renders the form and calls onChange/onSubmit.
|
|
35
|
+
*/
|
|
36
|
+
export function SchemaForm(props) {
|
|
37
|
+
const { schema, formData, onChange, onSubmit, formContext, filePath = '', liveValidate = true, additionalFields, uiSchema: uiSchemaProp, extraErrors, submitButtonRef, formErrorSignal, } = props;
|
|
38
|
+
const schemaWithExtra = useMemo(() => (Object.assign(Object.assign({}, schema), { additionalProperties: true })), [schema]);
|
|
39
|
+
const defaultUiSchema = useMemo(() => ({
|
|
40
|
+
additionalProperties: {
|
|
41
|
+
'ui:label': false,
|
|
42
|
+
classNames: 'jGIS-hidden-field',
|
|
43
|
+
},
|
|
44
|
+
}), []);
|
|
45
|
+
const uiSchema = useMemo(() => uiSchemaProp ? Object.assign(Object.assign({}, defaultUiSchema), uiSchemaProp) : defaultUiSchema, [uiSchemaProp, defaultUiSchema]);
|
|
46
|
+
const fields = useMemo(() => (Object.assign(Object.assign({}, defaultFields), additionalFields)), [additionalFields]);
|
|
47
|
+
const contextForForm = formContext;
|
|
48
|
+
useEffect(() => {
|
|
49
|
+
if (formErrorSignal) {
|
|
50
|
+
formErrorSignal.emit(hasExtraErrors(extraErrors !== null && extraErrors !== void 0 ? extraErrors : undefined));
|
|
51
|
+
}
|
|
52
|
+
}, [formErrorSignal, extraErrors]);
|
|
53
|
+
const handleChange = useCallback((e) => {
|
|
54
|
+
var _a;
|
|
55
|
+
onChange(((_a = e.formData) !== null && _a !== void 0 ? _a : {}));
|
|
56
|
+
}, [onChange]);
|
|
57
|
+
const handleSubmit = useCallback((e) => {
|
|
58
|
+
var _a;
|
|
59
|
+
onSubmit(((_a = e.formData) !== null && _a !== void 0 ? _a : {}));
|
|
60
|
+
}, [onSubmit]);
|
|
61
|
+
const handleKeyUp = useCallback((e, submitRef) => {
|
|
62
|
+
var _a;
|
|
63
|
+
if (e.key === 'Enter') {
|
|
64
|
+
e.preventDefault();
|
|
65
|
+
(_a = submitRef.current) === null || _a === void 0 ? void 0 : _a.click();
|
|
66
|
+
}
|
|
67
|
+
}, []);
|
|
68
|
+
const submitRef = useRef(null);
|
|
69
|
+
return (React.createElement("div", { className: "jGIS-property-panel", "data-path": filePath },
|
|
70
|
+
React.createElement("div", { className: "jGIS-property-outer", onKeyUp: e => handleKeyUp(e, submitRef) },
|
|
71
|
+
React.createElement(FormComponent, Object.assign({ schema: schemaWithExtra, uiSchema: uiSchema, formData: formData !== null && formData !== void 0 ? formData : {}, formContext: contextForForm, onChange: handleChange, onSubmit: handleSubmit, validator: validatorAjv8, fields: fields, liveValidate: liveValidate, extraErrors: extraErrors, children: React.createElement("button", { ref: el => {
|
|
72
|
+
submitRef.current = el;
|
|
73
|
+
if (submitButtonRef) {
|
|
74
|
+
submitButtonRef.current = el;
|
|
75
|
+
}
|
|
76
|
+
}, type: "submit", style: { display: 'none' } }) }, {})))));
|
|
77
|
+
}
|
|
@@ -1,9 +1,3 @@
|
|
|
1
|
-
import
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* The form to modify story map properties.
|
|
6
|
-
*/
|
|
7
|
-
export declare class StoryEditorPropertiesForm extends BaseForm {
|
|
8
|
-
protected processSchema(data: IDict<any> | undefined, schema: RJSFSchema, uiSchema: UiSchema): void;
|
|
9
|
-
}
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import type { IBaseFormProps } from "../../types";
|
|
3
|
+
export declare function StoryEditorPropertiesForm(props: IBaseFormProps): React.ReactElement | null;
|
|
@@ -1,16 +1,22 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
};
|
|
1
|
+
import React, { useMemo } from 'react';
|
|
2
|
+
import { deepCopy } from "../../tools";
|
|
3
|
+
import { SchemaForm } from './SchemaForm';
|
|
4
|
+
import { processBaseSchema, removeFormEntry } from './schemaUtils';
|
|
5
|
+
import { useSchemaFormState } from './useSchemaFormState';
|
|
6
|
+
export function StoryEditorPropertiesForm(props) {
|
|
7
|
+
const { schema: schemaProp, sourceData, syncData, model, filePath, formContext, cancel, } = props;
|
|
8
|
+
const { formData, schema, formContextValue, hasSchema, handleChangeBase, handleSubmitBase, } = useSchemaFormState({ sourceData, schemaProp, model, syncData, cancel });
|
|
9
|
+
const uiSchema = useMemo(() => {
|
|
10
|
+
const builtUiSchema = {};
|
|
11
|
+
const dataCopy = deepCopy(formData);
|
|
12
|
+
removeFormEntry('storySegments', dataCopy, schema, builtUiSchema);
|
|
13
|
+
processBaseSchema(dataCopy, schema, builtUiSchema, formContext, removeFormEntry);
|
|
14
|
+
builtUiSchema.presentationBgColor = { 'ui:widget': 'color' };
|
|
15
|
+
builtUiSchema.presentationTextColor = { 'ui:widget': 'color' };
|
|
16
|
+
return builtUiSchema;
|
|
17
|
+
}, [schema, formData, formContext]);
|
|
18
|
+
if (!hasSchema) {
|
|
19
|
+
return null;
|
|
15
20
|
}
|
|
21
|
+
return (React.createElement(SchemaForm, { schema: schema, formData: formData, onChange: handleChangeBase, onSubmit: handleSubmitBase, formContext: formContextValue, filePath: filePath, uiSchema: uiSchema }));
|
|
16
22
|
}
|
|
@@ -1,10 +1,5 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
|
|
3
|
-
var _a;
|
|
4
|
-
const id = (_a = idSchema === null || idSchema === void 0 ? void 0 : idSchema.$id) !== null && _a !== void 0 ? _a : '';
|
|
5
|
-
const match = id.match(/layerOverride_(\d+)/);
|
|
6
|
-
return match ? parseInt(match[1], 10) : undefined;
|
|
7
|
-
}
|
|
2
|
+
import { extractLayerOverrideIndex } from "../../../tools";
|
|
8
3
|
/**
|
|
9
4
|
* Simple select populated with layers (valid types only).
|
|
10
5
|
* Used as the targetLayer field inside layerOverride array items.
|
|
@@ -15,7 +10,7 @@ export function LayerSelect(props) {
|
|
|
15
10
|
const context = formContext;
|
|
16
11
|
const model = context === null || context === void 0 ? void 0 : context.model;
|
|
17
12
|
const fullFormData = (_a = context === null || context === void 0 ? void 0 : context.formData) !== null && _a !== void 0 ? _a : formData;
|
|
18
|
-
const arrayIndex =
|
|
13
|
+
const arrayIndex = extractLayerOverrideIndex(idSchema !== null && idSchema !== void 0 ? idSchema : {});
|
|
19
14
|
const value = arrayIndex !== undefined && ((_b = fullFormData === null || fullFormData === void 0 ? void 0 : fullFormData.layerOverride) === null || _b === void 0 ? void 0 : _b[arrayIndex])
|
|
20
15
|
? ((_c = fullFormData.layerOverride[arrayIndex].targetLayer) !== null && _c !== void 0 ? _c : '')
|
|
21
16
|
: '';
|
|
@@ -32,7 +27,7 @@ export function LayerSelect(props) {
|
|
|
32
27
|
.filter(id => id !== undefined && id !== '')
|
|
33
28
|
.filter(id => id !== currentTargetLayer));
|
|
34
29
|
const availableLayers = model.getLayers();
|
|
35
|
-
const optionsList = Object.entries(availableLayers).filter(([layerId]) => !usedTargetLayerIds.has(layerId));
|
|
30
|
+
const optionsList = Object.entries(availableLayers).filter(([layerId, layer]) => !usedTargetLayerIds.has(layerId) && layer.type !== 'StorySegmentLayer');
|
|
36
31
|
const handleChange = (e) => {
|
|
37
32
|
const newValue = e.target.value;
|
|
38
33
|
onChange(newValue === '' ? undefined : newValue);
|
|
@@ -1,8 +1,10 @@
|
|
|
1
|
+
import { ChevronRightIcon } from 'lucide-react';
|
|
1
2
|
import React from 'react';
|
|
2
3
|
import { SymbologyWidget } from "../../../dialogs/symbology/symbologyDialog";
|
|
3
4
|
import { Button } from "../../../shared/components/Button";
|
|
5
|
+
import { Collapsible, CollapsibleContent, CollapsibleTrigger, } from "../../../shared/components/Collapsible";
|
|
4
6
|
import { GlobalStateDbManager } from "../../../store";
|
|
5
|
-
import { SYMBOLOGY_VALID_LAYER_TYPES } from "../../../types";
|
|
7
|
+
import { SYMBOLOGY_VALID_LAYER_TYPES, } from "../../../types";
|
|
6
8
|
const SELECTION_SETTLE_MS = 100;
|
|
7
9
|
function LayerOverrideItem({ item, formContext }) {
|
|
8
10
|
var _a, _b;
|
|
@@ -46,14 +48,25 @@ function LayerOverrideItem({ item, formContext }) {
|
|
|
46
48
|
item.hasRemove && (React.createElement(Button, { variant: "destructive", onClick: item.onDropIndexClick(item.index), title: "Remove item" }, "Remove")))));
|
|
47
49
|
}
|
|
48
50
|
export function ArrayFieldTemplate(props) {
|
|
51
|
+
const { formData, formContext } = props;
|
|
52
|
+
const model = formContext.model;
|
|
49
53
|
return (React.createElement(React.Fragment, null,
|
|
50
|
-
React.createElement("div",
|
|
51
|
-
React.createElement("div", {
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
54
|
+
React.createElement("div", { style: { paddingBottom: '1rem' } }, "Symbology Overrides"),
|
|
55
|
+
React.createElement("div", { className: "jgis-symbology-override-list" }, props.items.map(item => {
|
|
56
|
+
var _a, _b;
|
|
57
|
+
const overrideData = formData === null || formData === void 0 ? void 0 : formData[item.index];
|
|
58
|
+
const layerName = (_b = (_a = model.getLayer(overrideData === null || overrideData === void 0 ? void 0 : overrideData.targetLayer)) === null || _a === void 0 ? void 0 : _a.name) !== null && _b !== void 0 ? _b : 'Layer';
|
|
59
|
+
return (React.createElement(Collapsible, { key: item.key },
|
|
60
|
+
React.createElement(CollapsibleTrigger, { asChild: true },
|
|
61
|
+
React.createElement("div", { className: "jgis-symbology-override-collapsible-trigger" },
|
|
62
|
+
React.createElement(Button, { size: "icon-sm", variant: "icon", className: "jgis-rotate-90 jgis-bg-transparent" },
|
|
63
|
+
React.createElement(ChevronRightIcon, null)),
|
|
64
|
+
React.createElement("span", null,
|
|
65
|
+
layerName,
|
|
66
|
+
" Override"))),
|
|
67
|
+
React.createElement(CollapsibleContent, null,
|
|
68
|
+
React.createElement(LayerOverrideItem, { key: item.key, item: item, formContext: props.formContext }))));
|
|
69
|
+
})),
|
|
70
|
+
props.canAdd && (React.createElement("div", { className: "jgis-center-content", style: { paddingTop: '1rem' } },
|
|
71
|
+
React.createElement(Button, { onClick: props.onAddClick }, "Add Layer Override")))));
|
|
59
72
|
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { FieldProps } from '@rjsf/core';
|
|
2
|
+
import * as React from 'react';
|
|
3
|
+
/**
|
|
4
|
+
* RJSF custom field for layerOverride[].sourceProperties: renders the
|
|
5
|
+
* appropriate source form for the target layer's source type.
|
|
6
|
+
*/
|
|
7
|
+
export declare function SourcePropertiesField(props: FieldProps): React.ReactElement;
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { deepCopy, extractLayerOverrideIndex } from "../../../tools";
|
|
3
|
+
import { getSourceTypeForm } from '../../formselectors';
|
|
4
|
+
/**
|
|
5
|
+
* RJSF custom field for layerOverride[].sourceProperties: renders the
|
|
6
|
+
* appropriate source form for the target layer's source type.
|
|
7
|
+
*/
|
|
8
|
+
export function SourcePropertiesField(props) {
|
|
9
|
+
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
10
|
+
const context = props.formContext;
|
|
11
|
+
const fullFormData = context === null || context === void 0 ? void 0 : context.formData;
|
|
12
|
+
const formSchemaRegistry = context === null || context === void 0 ? void 0 : context.formSchemaRegistry;
|
|
13
|
+
// const docManager = context?.docManager;
|
|
14
|
+
const index = extractLayerOverrideIndex((_a = props.idSchema) !== null && _a !== void 0 ? _a : {});
|
|
15
|
+
const model = (_b = props.formContext) === null || _b === void 0 ? void 0 : _b.model;
|
|
16
|
+
const layerId = (_d = (_c = fullFormData === null || fullFormData === void 0 ? void 0 : fullFormData.layerOverride) === null || _c === void 0 ? void 0 : _c[index !== null && index !== void 0 ? index : 0]) === null || _d === void 0 ? void 0 : _d.targetLayer;
|
|
17
|
+
const layer = model === null || model === void 0 ? void 0 : model.getLayer(layerId);
|
|
18
|
+
const sourceID = (_e = layer === null || layer === void 0 ? void 0 : layer.parameters) === null || _e === void 0 ? void 0 : _e.source;
|
|
19
|
+
const source = model === null || model === void 0 ? void 0 : model.getSource(sourceID);
|
|
20
|
+
/* Use form value so edits persist; fall back to live source for initial display */
|
|
21
|
+
const sourceProperties = (_f = props.formData) !== null && _f !== void 0 ? _f : source === null || source === void 0 ? void 0 : source.parameters;
|
|
22
|
+
const sourceSchema = (source === null || source === void 0 ? void 0 : source.type) && formSchemaRegistry
|
|
23
|
+
? deepCopy(formSchemaRegistry.getSchemas().get(source.type))
|
|
24
|
+
: undefined;
|
|
25
|
+
const SourceForm = getSourceTypeForm((_g = source === null || source === void 0 ? void 0 : source.type) !== null && _g !== void 0 ? _g : 'GeoJSONSource');
|
|
26
|
+
return (React.createElement(React.Fragment, null,
|
|
27
|
+
React.createElement("div", { id: "jgis-source-properties-field" }, "Source Parameters"),
|
|
28
|
+
React.createElement(SourceForm, { formContext: "update", model: model, filePath: model === null || model === void 0 ? void 0 : model.filePath, schema: sourceSchema, sourceData: sourceProperties !== null && sourceProperties !== void 0 ? sourceProperties : undefined, syncData: (properties) => props.onChange(properties), sourceType: (_h = source === null || source === void 0 ? void 0 : source.type) !== null && _h !== void 0 ? _h : 'GeoJSONSource', formSchemaRegistry: formSchemaRegistry })));
|
|
29
|
+
}
|
|
@@ -16,7 +16,7 @@ function StorySegmentReset({ model, layerId }) {
|
|
|
16
16
|
extent }) });
|
|
17
17
|
model.sharedModel.updateLayer(layerId, updatedLayer);
|
|
18
18
|
};
|
|
19
|
-
return (React.createElement("div",
|
|
19
|
+
return (React.createElement("div", { className: "jgis-center-content" },
|
|
20
20
|
React.createElement(Button, { title: "Set story segment to current viewport", onClick: handleSetStorySegmentToCurrentView },
|
|
21
21
|
React.createElement(LabIcon.resolveReact, { icon: targetWithCenterIcon, className: "jp-gis-layerIcon", tag: "span" }),
|
|
22
22
|
"Set Story Segment Extent")));
|
|
@@ -80,7 +80,7 @@ export const FileSelectorWidget = props => {
|
|
|
80
80
|
};
|
|
81
81
|
return (React.createElement("div", null,
|
|
82
82
|
React.createElement("div", { className: "file-container" },
|
|
83
|
-
React.createElement("button", { className: "jp-mod-styled", onClick: handleBrowseServerFiles }, "Browse Server Files"),
|
|
83
|
+
React.createElement("button", { type: "button", className: "jp-mod-styled", onClick: handleBrowseServerFiles }, "Browse Server Files"),
|
|
84
84
|
React.createElement("p", null, serverFilePath || '')),
|
|
85
85
|
React.createElement("div", null,
|
|
86
86
|
React.createElement("h3", { className: "jp-FormGroup-fieldLabel jp-FormGroup-contentItem" }, "Or enter external URL"),
|
|
@@ -1,12 +1,3 @@
|
|
|
1
|
-
import
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
export declare class HeatmapLayerPropertiesForm extends LayerPropertiesForm {
|
|
5
|
-
protected currentFormData: IHeatmapLayer;
|
|
6
|
-
private features;
|
|
7
|
-
constructor(props: ILayerProps);
|
|
8
|
-
protected onFormSubmit(e: ISubmitEvent<any>): void;
|
|
9
|
-
protected onFormChange(e: IChangeEvent): void;
|
|
10
|
-
protected processSchema(data: IDict<any> | undefined, schema: IDict, uiSchema: IDict): void;
|
|
11
|
-
private fetchFeatureNames;
|
|
12
|
-
}
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import type { ILayerProps } from './layerform';
|
|
3
|
+
export declare function HeatmapLayerPropertiesForm(props: ILayerProps): React.ReactElement | null;
|