@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.
Files changed (116) hide show
  1. package/lib/commands/BaseCommandIDs.d.ts +14 -13
  2. package/lib/commands/BaseCommandIDs.js +14 -14
  3. package/lib/commands/index.js +528 -130
  4. package/lib/commands/operationCommands.d.ts +22 -0
  5. package/lib/commands/operationCommands.js +305 -0
  6. package/lib/constants.js +11 -9
  7. package/lib/dialogs/ProcessingFormDialog.d.ts +1 -1
  8. package/lib/dialogs/ProcessingFormDialog.js +2 -2
  9. package/lib/dialogs/layerBrowserDialog.d.ts +2 -0
  10. package/lib/dialogs/layerBrowserDialog.js +12 -5
  11. package/lib/dialogs/layerCreationFormDialog.d.ts +7 -0
  12. package/lib/dialogs/layerCreationFormDialog.js +10 -2
  13. package/lib/dialogs/symbology/components/color_ramp/ColorRampControls.d.ts +2 -1
  14. package/lib/dialogs/symbology/components/color_ramp/ColorRampControls.js +21 -19
  15. package/lib/dialogs/symbology/components/color_ramp/ColorRampSelector.d.ts +3 -1
  16. package/lib/dialogs/symbology/components/color_ramp/ColorRampSelector.js +13 -5
  17. package/lib/dialogs/symbology/tiff_layer/types/SingleBandPseudoColor.js +6 -4
  18. package/lib/dialogs/symbology/vector_layer/types/Categorized.js +7 -11
  19. package/lib/dialogs/symbology/vector_layer/types/Graduated.js +7 -10
  20. package/lib/dialogs/symbology/vector_layer/types/Heatmap.js +7 -8
  21. package/lib/formbuilder/creationform.d.ts +8 -8
  22. package/lib/formbuilder/creationform.js +130 -85
  23. package/lib/formbuilder/editform.d.ts +1 -7
  24. package/lib/formbuilder/editform.js +64 -52
  25. package/lib/formbuilder/formselectors.d.ts +5 -4
  26. package/lib/formbuilder/index.d.ts +1 -1
  27. package/lib/formbuilder/index.js +1 -1
  28. package/lib/formbuilder/objectform/SchemaForm.d.ts +36 -0
  29. package/lib/formbuilder/objectform/SchemaForm.js +77 -0
  30. package/lib/formbuilder/objectform/StoryEditorForm.d.ts +3 -9
  31. package/lib/formbuilder/objectform/StoryEditorForm.js +20 -14
  32. package/lib/formbuilder/objectform/components/LayerSelect.js +3 -8
  33. package/lib/formbuilder/objectform/components/SegmentFormSymbology.js +23 -10
  34. package/lib/formbuilder/objectform/components/SourcePropertiesField.d.ts +7 -0
  35. package/lib/formbuilder/objectform/components/SourcePropertiesField.js +29 -0
  36. package/lib/formbuilder/objectform/components/StorySegmentReset.js +1 -1
  37. package/lib/formbuilder/objectform/fileselectorwidget.js +1 -1
  38. package/lib/formbuilder/objectform/layer/heatmapLayerForm.d.ts +3 -12
  39. package/lib/formbuilder/objectform/layer/heatmapLayerForm.js +87 -55
  40. package/lib/formbuilder/objectform/layer/hillshadeLayerForm.d.ts +3 -8
  41. package/lib/formbuilder/objectform/layer/hillshadeLayerForm.js +36 -10
  42. package/lib/formbuilder/objectform/layer/layerform.d.ts +7 -9
  43. package/lib/formbuilder/objectform/layer/layerform.js +33 -20
  44. package/lib/formbuilder/objectform/layer/storySegmentLayerForm.d.ts +3 -5
  45. package/lib/formbuilder/objectform/layer/storySegmentLayerForm.js +73 -29
  46. package/lib/formbuilder/objectform/layer/vectorlayerform.d.ts +3 -14
  47. package/lib/formbuilder/objectform/layer/vectorlayerform.js +36 -29
  48. package/lib/formbuilder/objectform/layer/webGlLayerForm.d.ts +3 -10
  49. package/lib/formbuilder/objectform/layer/webGlLayerForm.js +37 -13
  50. package/lib/formbuilder/objectform/process/dissolveProcessForm.d.ts +8 -18
  51. package/lib/formbuilder/objectform/process/dissolveProcessForm.js +68 -56
  52. package/lib/formbuilder/objectform/processingForm.d.ts +12 -0
  53. package/lib/formbuilder/objectform/processingForm.js +33 -0
  54. package/lib/formbuilder/objectform/schemaUtils.d.ts +16 -0
  55. package/lib/formbuilder/objectform/schemaUtils.js +59 -0
  56. package/lib/formbuilder/objectform/source/geojsonsource.d.ts +3 -19
  57. package/lib/formbuilder/objectform/source/geojsonsource.js +94 -53
  58. package/lib/formbuilder/objectform/source/geotiffsource.d.ts +3 -20
  59. package/lib/formbuilder/objectform/source/geotiffsource.js +73 -74
  60. package/lib/formbuilder/objectform/source/pathbasedsource.d.ts +3 -19
  61. package/lib/formbuilder/objectform/source/pathbasedsource.js +76 -75
  62. package/lib/formbuilder/objectform/source/sourceform.d.ts +7 -8
  63. package/lib/formbuilder/objectform/source/sourceform.js +28 -11
  64. package/lib/formbuilder/objectform/source/tilesourceform.d.ts +3 -7
  65. package/lib/formbuilder/objectform/source/tilesourceform.js +63 -53
  66. package/lib/formbuilder/objectform/useSchemaFormState.d.ts +48 -0
  67. package/lib/formbuilder/objectform/useSchemaFormState.js +35 -0
  68. package/lib/index.d.ts +0 -1
  69. package/lib/index.js +0 -1
  70. package/lib/keybindings.json +10 -10
  71. package/lib/mainview/mainView.d.ts +11 -7
  72. package/lib/mainview/mainView.js +63 -36
  73. package/lib/mainview/mainviewmodel.js +2 -2
  74. package/lib/menus.js +8 -8
  75. package/lib/panelview/components/layers.js +5 -2
  76. package/lib/panelview/objectproperties.js +2 -2
  77. package/lib/panelview/rightpanel.js +17 -2
  78. package/lib/panelview/story-maps/SpectaPanel.d.ts +15 -0
  79. package/lib/panelview/story-maps/SpectaPanel.js +35 -0
  80. package/lib/panelview/story-maps/StoryViewerPanel.d.ts +24 -9
  81. package/lib/panelview/story-maps/StoryViewerPanel.js +22 -268
  82. package/lib/panelview/story-maps/{PreviewModeSwitch.js → components/PreviewModeSwitch.js} +1 -1
  83. package/lib/panelview/story-maps/components/SpectaDesktopView.d.ts +21 -0
  84. package/lib/panelview/story-maps/components/SpectaDesktopView.js +49 -0
  85. package/lib/panelview/story-maps/components/SpectaMobileView.d.ts +17 -0
  86. package/lib/panelview/story-maps/{MobileSpectaPanel.js → components/SpectaMobileView.js} +8 -22
  87. package/lib/panelview/story-maps/{StoryNavBar.d.ts → components/StoryNavBar.d.ts} +1 -1
  88. package/lib/panelview/story-maps/{StoryNavBar.js → components/StoryNavBar.js} +2 -4
  89. package/lib/panelview/story-maps/hooks/useStoryMap.d.ts +39 -0
  90. package/lib/panelview/story-maps/hooks/useStoryMap.js +252 -0
  91. package/lib/processing/index.d.ts +2 -2
  92. package/lib/processing/index.js +62 -35
  93. package/lib/processing/processingCommands.d.ts +1 -1
  94. package/lib/processing/processingCommands.js +26 -6
  95. package/lib/shared/components/Collapsible.d.ts +6 -0
  96. package/lib/shared/components/Collapsible.js +26 -0
  97. package/lib/statusbar/SpectaPresentationProgressBar.d.ts +7 -0
  98. package/lib/statusbar/SpectaPresentationProgressBar.js +40 -0
  99. package/lib/toolbar/widget.js +4 -2
  100. package/lib/tools.d.ts +6 -0
  101. package/lib/tools.js +9 -0
  102. package/lib/types.d.ts +29 -2
  103. package/lib/widget.js +14 -2
  104. package/package.json +2 -4
  105. package/style/base.css +23 -1
  106. package/style/dialog.css +5 -0
  107. package/style/leftPanel.css +14 -37
  108. package/style/shared/button.css +0 -10
  109. package/style/shared/switch.css +8 -7
  110. package/style/spectaProgressBar.css +144 -0
  111. package/style/storyPanel.css +33 -0
  112. package/style/symbologyDialog.css +2 -2
  113. package/lib/formbuilder/objectform/baseform.d.ts +0 -91
  114. package/lib/formbuilder/objectform/baseform.js +0 -231
  115. package/lib/panelview/story-maps/MobileSpectaPanel.d.ts +0 -7
  116. /package/lib/panelview/story-maps/{PreviewModeSwitch.d.ts → components/PreviewModeSwitch.d.ts} +0 -0
@@ -14,7 +14,7 @@ import { Button } from '@jupyterlab/ui-components';
14
14
  import React, { useEffect, useRef, useState } from 'react';
15
15
  import { useColorMapList, } from "../../colorRampUtils";
16
16
  import ColorRampSelectorEntry from './ColorRampSelectorEntry';
17
- const ColorRampSelector = ({ selectedRamp, setSelected, }) => {
17
+ const ColorRampSelector = ({ selectedRamp, setSelected, reverse, setReverse, }) => {
18
18
  const containerRef = useRef(null);
19
19
  const [isOpen, setIsOpen] = useState(false);
20
20
  const [colorMaps, setColorMaps] = useState([]);
@@ -25,7 +25,7 @@ const ColorRampSelector = ({ selectedRamp, setSelected, }) => {
25
25
  if (colorMaps.length > 0) {
26
26
  updateCanvas(selectedRamp);
27
27
  }
28
- }, [selectedRamp, colorMaps]);
28
+ }, [selectedRamp, colorMaps, reverse]);
29
29
  const toggleDropdown = () => {
30
30
  setIsOpen(!isOpen);
31
31
  };
@@ -53,12 +53,16 @@ const ColorRampSelector = ({ selectedRamp, setSelected, }) => {
53
53
  if (!ctx) {
54
54
  return;
55
55
  }
56
- const ramp = colorMaps.filter(c => c.name === rampName);
56
+ const ramp = colorMaps.filter(c => c.name === rampName)[0];
57
+ let colors = ramp.colors;
58
+ if (reverse) {
59
+ colors = [...colors].reverse();
60
+ }
57
61
  canvas.width = canvasWidth;
58
62
  canvas.height = canvasHeight;
59
63
  for (let i = 0; i <= 255; i++) {
60
64
  ctx.beginPath();
61
- const color = ramp[0].colors[i];
65
+ const color = colors[i];
62
66
  ctx.fillStyle = color;
63
67
  ctx.fillRect(i * 2, 0, 2, canvasHeight);
64
68
  }
@@ -75,6 +79,10 @@ const ColorRampSelector = ({ selectedRamp, setSelected, }) => {
75
79
  React.createElement("div", { className: "jp-gis-color-ramp-entry jp-gis-selected-entry" },
76
80
  React.createElement("span", { className: "jp-gis-color-label" }, selectedRamp),
77
81
  React.createElement("canvas", { id: "cv", className: "jp-gis-color-canvas-display", width: canvasWidth, height: canvasHeight }))),
78
- React.createElement("div", { className: `jp-gis-color-ramp-dropdown ${isOpen ? 'jp-gis-open' : ''}` }, colorMaps.map((item, index) => (React.createElement(ColorRampSelectorEntry, { index: index, colorMap: item, onClick: selectItem }))))));
82
+ React.createElement("div", { className: `jp-gis-color-ramp-dropdown ${isOpen ? 'jp-gis-open' : ''}` }, colorMaps.map((item, index) => (React.createElement(ColorRampSelectorEntry, { index: index, colorMap: item, onClick: selectItem })))),
83
+ React.createElement("div", { className: "jp-gis-symbology-row" },
84
+ React.createElement("label", { className: "jp-gis-inline-label" },
85
+ React.createElement("input", { type: "checkbox", checked: reverse, onChange: e => setReverse(e.target.checked) }),
86
+ "Reverse Color Ramp"))));
79
87
  };
80
88
  export default ColorRampSelector;
@@ -114,7 +114,7 @@ const SingleBandPseudoColor = ({ model, okSignalPromise, layerId, isStorySegment
114
114
  setStopRows(valueColorPairs);
115
115
  };
116
116
  const handleOk = () => {
117
- var _a, _b, _c, _d, _e, _f, _g, _h;
117
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j;
118
118
  const bandRow = bandRowsRef.current[selectedBand - 1];
119
119
  if (!bandRow) {
120
120
  return;
@@ -178,10 +178,11 @@ const SingleBandPseudoColor = ({ model, okSignalPromise, layerId, isStorySegment
178
178
  ? String(colorRampOptionsRef.current.numberOfShades)
179
179
  : undefined,
180
180
  mode: (_g = colorRampOptionsRef.current) === null || _g === void 0 ? void 0 : _g.selectedMode,
181
+ reverseRamp: (_h = colorRampOptionsRef.current) === null || _h === void 0 ? void 0 : _h.reverseRamp,
181
182
  };
182
183
  if (!isStorySegmentOverride) {
183
184
  // Update source
184
- const sourceId = (_h = layer === null || layer === void 0 ? void 0 : layer.parameters) === null || _h === void 0 ? void 0 : _h.source;
185
+ const sourceId = (_j = layer === null || layer === void 0 ? void 0 : layer.parameters) === null || _j === void 0 ? void 0 : _j.source;
185
186
  const source = model.getSource(sourceId);
186
187
  if (!source || !source.parameters) {
187
188
  return;
@@ -221,13 +222,14 @@ const SingleBandPseudoColor = ({ model, okSignalPromise, layerId, isStorySegment
221
222
  newFilters.splice(index, 1);
222
223
  setStopRows(newFilters);
223
224
  };
224
- const buildColorInfoFromClassification = async (selectedMode, numberOfShades, selectedRamp, setIsLoading) => {
225
+ const buildColorInfoFromClassification = async (selectedMode, numberOfShades, selectedRamp, reverseRamp, setIsLoading) => {
225
226
  var _a, _b;
226
227
  // Update layer state with selected options
227
228
  setColorRampOptions({
228
229
  selectedRamp,
229
230
  numberOfShades,
230
231
  selectedMode,
232
+ reverseRamp,
231
233
  });
232
234
  let stops = [];
233
235
  const currentBand = bandRows[selectedBand - 1];
@@ -250,7 +252,7 @@ const SingleBandPseudoColor = ({ model, okSignalPromise, layerId, isStorySegment
250
252
  return;
251
253
  }
252
254
  setIsLoading(false);
253
- const valueColorPairs = Utils.getValueColorPairs(stops, selectedRamp, nClasses);
255
+ const valueColorPairs = Utils.getValueColorPairs(stops, selectedRamp, nClasses, reverseRamp);
254
256
  setStopRows(valueColorPairs);
255
257
  };
256
258
  const scaleValue = (bandValue, isQuantile) => {
@@ -17,7 +17,6 @@ const Categorized = ({ model, okSignalPromise, layerId, symbologyTab, selectable
17
17
  radius: 5,
18
18
  });
19
19
  const manualStyleRef = useLatest(manualStyle);
20
- const [reverseRamp, setReverseRamp] = useState(false);
21
20
  const selectedAttributeRef = useLatest(selectedAttribute);
22
21
  const stopRowsRef = useLatest(stopRows);
23
22
  const colorRampOptionsRef = useLatest(colorRampOptions);
@@ -65,24 +64,26 @@ const Categorized = ({ model, okSignalPromise, layerId, symbologyTab, selectable
65
64
  }
66
65
  }, [layerId]);
67
66
  useEffect(() => {
68
- var _a, _b;
67
+ var _a;
69
68
  // We only want number values here
70
- const attribute = (_b = (_a = params.symbologyState) === null || _a === void 0 ? void 0 : _a.value) !== null && _b !== void 0 ? _b : Object.keys(selectableAttributesAndValues)[0];
69
+ const attribute = ((_a = params.symbologyState) === null || _a === void 0 ? void 0 : _a.value) ||
70
+ Object.keys(selectableAttributesAndValues)[0];
71
71
  setSelectedAttribute(attribute);
72
72
  }, [selectableAttributesAndValues]);
73
- const buildColorInfoFromClassification = (selectedMode, numberOfShades, selectedRamp, setIsLoading) => {
73
+ const buildColorInfoFromClassification = (selectedMode, numberOfShades, selectedRamp, reverseRamp, setIsLoading) => {
74
74
  setColorRampOptions({
75
75
  selectedFunction: '',
76
76
  selectedRamp,
77
77
  numberOfShades,
78
78
  selectedMode,
79
+ reverseRamp,
79
80
  });
80
81
  const stops = Array.from(selectableAttributesAndValues[selectedAttribute]).sort((a, b) => a - b);
81
82
  const valueColorPairs = Utils.getValueColorPairs(stops, selectedRamp, stops.length, reverseRamp);
82
83
  setStopRows(valueColorPairs);
83
84
  };
84
85
  const handleOk = () => {
85
- var _a;
86
+ var _a, _b;
86
87
  const newStyle = Object.assign({}, params.color);
87
88
  if (stopRowsRef.current && stopRowsRef.current.length > 0) {
88
89
  // Classification applied (for color)
@@ -112,7 +113,7 @@ const Categorized = ({ model, okSignalPromise, layerId, symbologyTab, selectable
112
113
  value: selectedAttributeRef.current,
113
114
  colorRamp: (_a = colorRampOptionsRef.current) === null || _a === void 0 ? void 0 : _a.selectedRamp,
114
115
  method: symbologyTab,
115
- reverse: reverseRamp,
116
+ reverseRamp: (_b = colorRampOptionsRef.current) === null || _b === void 0 ? void 0 : _b.reverseRamp,
116
117
  };
117
118
  saveSymbology({
118
119
  model,
@@ -183,12 +184,7 @@ const Categorized = ({ model, okSignalPromise, layerId, symbologyTab, selectable
183
184
  React.createElement("input", { type: "number", className: "jp-mod-styled", value: manualStyle.radius, onChange: e => {
184
185
  setManualStyle(prev => (Object.assign(Object.assign({}, prev), { radius: +e.target.value })));
185
186
  } })))),
186
- symbologyTab === 'color' && (React.createElement("div", { className: "jp-gis-symbology-row" },
187
- React.createElement("label", null,
188
- React.createElement("input", { type: "checkbox", checked: reverseRamp, onChange: e => setReverseRamp(e.target.checked) }),
189
- "Reverse Color Ramp"))),
190
187
  React.createElement("div", { className: "jp-gis-layer-symbology-container" },
191
- "//! only needs symbology state",
192
188
  React.createElement(ColorRampControls, { layerParams: params, modeOptions: [], classifyFunc: buildColorInfoFromClassification, showModeRow: false, showRampSelector: symbologyTab === 'color' }),
193
189
  React.createElement(StopContainer, { selectedMethod: '', stopRows: stopRows, setStopRows: setStopRows }))));
194
190
  }
@@ -26,7 +26,6 @@ const Graduated = ({ model, okSignalPromise, layerId, symbologyTab, selectableAt
26
26
  const [radiusManualStyle, setRadiusManualStyle] = useState({
27
27
  radius: 5,
28
28
  });
29
- const [reverseRamp, setReverseRamp] = useState(false);
30
29
  const selectableAttributeRef = useLatest(selectedAttribute);
31
30
  const symbologyTabRef = useLatest(symbologyTab);
32
31
  const colorStopRowsRef = useLatest(colorStopRows);
@@ -72,8 +71,9 @@ const Graduated = ({ model, okSignalPromise, layerId, symbologyTab, selectableAt
72
71
  }
73
72
  }, [layerId]);
74
73
  useEffect(() => {
75
- var _a, _b;
76
- const attribute = (_b = (_a = params.symbologyState) === null || _a === void 0 ? void 0 : _a.value) !== null && _b !== void 0 ? _b : Object.keys(selectableAttributesAndValues)[0];
74
+ var _a;
75
+ const attribute = ((_a = params.symbologyState) === null || _a === void 0 ? void 0 : _a.value) ||
76
+ Object.keys(selectableAttributesAndValues)[0];
77
77
  setSelectedAttribute(attribute);
78
78
  }, [selectableAttributesAndValues]);
79
79
  const updateStopRowsBasedOnLayer = () => {
@@ -84,7 +84,7 @@ const Graduated = ({ model, okSignalPromise, layerId, symbologyTab, selectableAt
84
84
  setRadiusStopRows(VectorUtils.buildRadiusInfo(layer));
85
85
  };
86
86
  const handleOk = () => {
87
- var _a, _b, _c;
87
+ var _a, _b, _c, _d;
88
88
  const newStyle = Object.assign({}, params.color);
89
89
  // Apply color symbology
90
90
  if (colorStopRowsRef.current.length > 0) {
@@ -132,7 +132,7 @@ const Graduated = ({ model, okSignalPromise, layerId, symbologyTab, selectableAt
132
132
  colorRamp: (_a = colorRampOptionsRef.current) === null || _a === void 0 ? void 0 : _a.selectedRamp,
133
133
  nClasses: (_b = colorRampOptionsRef.current) === null || _b === void 0 ? void 0 : _b.numberOfShades,
134
134
  mode: (_c = colorRampOptionsRef.current) === null || _c === void 0 ? void 0 : _c.selectedMode,
135
- reverse: reverseRamp,
135
+ reverseRamp: (_d = colorRampOptionsRef.current) === null || _d === void 0 ? void 0 : _d.reverseRamp,
136
136
  };
137
137
  saveSymbology({
138
138
  model,
@@ -151,11 +151,12 @@ const Graduated = ({ model, okSignalPromise, layerId, symbologyTab, selectableAt
151
151
  });
152
152
  };
153
153
  useOkSignal(okSignalPromise, handleOk);
154
- const buildColorInfoFromClassification = (selectedMode, numberOfShades, selectedRamp) => {
154
+ const buildColorInfoFromClassification = (selectedMode, numberOfShades, selectedRamp, reverseRamp) => {
155
155
  setColorRampOptions({
156
156
  selectedRamp,
157
157
  numberOfShades,
158
158
  selectedMode,
159
+ reverseRamp,
159
160
  });
160
161
  let stops;
161
162
  const values = Array.from(selectableAttributesAndValues[selectedAttribute]);
@@ -238,10 +239,6 @@ const Graduated = ({ model, okSignalPromise, layerId, symbologyTab, selectableAt
238
239
  handleReset('radius');
239
240
  setRadiusManualStyle(Object.assign(Object.assign({}, radiusManualStyle), { radius: +e.target.value }));
240
241
  } })))),
241
- symbologyTab === 'color' && (React.createElement("div", { className: "jp-gis-symbology-row" },
242
- React.createElement("label", null,
243
- React.createElement("input", { type: "checkbox", checked: reverseRamp, onChange: e => setReverseRamp(e.target.checked) }),
244
- "Reverse Color Ramp"))),
245
242
  React.createElement(ColorRampControls, { layerParams: params, modeOptions: modeOptions, classifyFunc: buildColorInfoFromClassification, showModeRow: true, showRampSelector: symbologyTab === 'color' }),
246
243
  React.createElement(StopContainer, { selectedMethod: symbologyTab || 'color', stopRows: symbologyTab === 'color' ? colorStopRows : radiusStopRows, setStopRows: symbologyTab === 'color' ? setColorStopRows : setRadiusStopRows })));
247
244
  }
@@ -33,12 +33,15 @@ const Heatmap = ({ model, okSignalPromise, layerId, isStorySegmentOverride, segm
33
33
  populateOptions();
34
34
  }, []);
35
35
  const populateOptions = async () => {
36
- var _a;
37
- let colorRamp;
36
+ var _a, _b;
37
+ let colorRamp = 'viridis';
38
38
  if ((_a = params.symbologyState) === null || _a === void 0 ? void 0 : _a.colorRamp) {
39
39
  colorRamp = params.symbologyState.colorRamp;
40
40
  }
41
- setSelectedRamp(colorRamp ? colorRamp : 'viridis');
41
+ if (typeof ((_b = params.symbologyState) === null || _b === void 0 ? void 0 : _b.reverse) === 'boolean') {
42
+ setReverseRamp(params.symbologyState.reverse);
43
+ }
44
+ setSelectedRamp(colorRamp);
42
45
  };
43
46
  const handleOk = () => {
44
47
  let colorMap = colormap({
@@ -75,11 +78,7 @@ const Heatmap = ({ model, okSignalPromise, layerId, isStorySegmentOverride, segm
75
78
  React.createElement("p", null, "Represent features based on their density using a heatmap."),
76
79
  React.createElement("div", { className: "jp-gis-symbology-row jp-gis-heatmap" },
77
80
  React.createElement("label", { htmlFor: "color-ramp-select" }, "Color Ramp:"),
78
- React.createElement(ColorRampSelector, { selectedRamp: selectedRamp, setSelected: setSelectedRamp })),
79
- React.createElement("div", { className: "jp-gis-symbology-row" },
80
- React.createElement("label", null,
81
- React.createElement("input", { type: "checkbox", checked: reverseRamp, onChange: e => setReverseRamp(e.target.checked) }),
82
- "Reverse Color Ramp")),
81
+ React.createElement(ColorRampSelector, { selectedRamp: selectedRamp, setSelected: setSelectedRamp, reverse: reverseRamp, setReverse: setReverseRamp })),
83
82
  React.createElement("div", { className: "jp-gis-symbology-row" },
84
83
  React.createElement("label", { htmlFor: 'vector-value-select' }, "Radius:"),
85
84
  React.createElement("input", { type: "number", value: heatmapOptions.radius, className: "jp-mod-styled", onChange: event => setHetamapOptions(prevState => (Object.assign(Object.assign({}, prevState), { radius: +event.target.value }))) })),
@@ -1,7 +1,7 @@
1
1
  import { IDict, IJGISFormSchemaRegistry, IJupyterGISModel, LayerType, SourceType } from '@jupytergis/schema';
2
2
  import { Dialog } from '@jupyterlab/apputils';
3
3
  import { Signal } from '@lumino/signaling';
4
- import * as React from 'react';
4
+ import React from 'react';
5
5
  export interface ICreationFormProps {
6
6
  /**
7
7
  * Whether or not to create a layer
@@ -47,14 +47,14 @@ export interface ICreationFormProps {
47
47
  * and other form-related parameters.
48
48
  */
49
49
  dialogOptions?: any;
50
+ /**
51
+ * When provided (e.g. by LayerCreationFormDialog), the form registers a handler
52
+ * that the dialog invokes on OK; the handler reads stored form data and runs
53
+ * addSource/addLayer. No ok signal is passed to the inner forms when using this path.
54
+ */
55
+ registerConfirmHandler?: (fn: () => void) => void;
50
56
  }
51
57
  /**
52
58
  * Form for creating a source, a layer or both at the same time
53
59
  */
54
- export declare class CreationForm extends React.Component<ICreationFormProps, any> {
55
- constructor(props: ICreationFormProps);
56
- render(): React.JSX.Element | undefined;
57
- private jGISModel;
58
- private filePath;
59
- private sourceFormChangedSignal;
60
- }
60
+ export declare function CreationForm(props: ICreationFormProps): React.JSX.Element | null;
@@ -9,109 +9,154 @@ var __rest = (this && this.__rest) || function (s, e) {
9
9
  }
10
10
  return t;
11
11
  };
12
- import { PromiseDelegate, UUID } from '@lumino/coreutils';
12
+ import { UUID } from '@lumino/coreutils';
13
13
  import { Signal } from '@lumino/signaling';
14
- import * as React from 'react';
14
+ import React, { useEffect, useMemo, useRef } from 'react';
15
15
  import { deepCopy } from "../tools";
16
16
  import { getLayerTypeForm, getSourceTypeForm } from './formselectors';
17
17
  /**
18
18
  * Form for creating a source, a layer or both at the same time
19
19
  */
20
- export class CreationForm extends React.Component {
21
- constructor(props) {
22
- super(props);
23
- this.sourceFormChangedSignal = new Signal(this);
24
- this.filePath = props.model.filePath;
25
- this.jGISModel = props.model;
20
+ export function CreationForm(props) {
21
+ const { createLayer, createSource, layerType, sourceType, layerData: initialLayerData, sourceData: initialSourceData, formSchemaRegistry, model, cancel, formErrorSignal, dialogOptions, registerConfirmHandler, } = props;
22
+ const filePath = model.filePath;
23
+ const sourceFormChangedSignalRef = useRef(null);
24
+ if (!sourceFormChangedSignalRef.current) {
25
+ sourceFormChangedSignalRef.current = new Signal({});
26
26
  }
27
- render() {
28
- var _a;
29
- const sourceId = UUID.uuid4();
30
- let layerSchema = undefined;
31
- const LayerForm = getLayerTypeForm(this.props.layerType || 'RasterLayer');
32
- const layerData = deepCopy(this.props.layerData || {});
33
- if (this.props.createLayer) {
34
- if (!this.props.layerType) {
35
- console.error('Cannot create a layer without specifying its type');
36
- return;
37
- }
38
- layerSchema = deepCopy(this.props.formSchemaRegistry.getSchemas().get(this.props.layerType));
39
- if (!layerSchema) {
40
- console.error(`Cannot find schema for ${this.props.layerType}`);
41
- return;
42
- }
43
- // If a source is created as part of this form, remove the source selection from the layer form
44
- if (this.props.createSource) {
45
- (_a = layerSchema.properties) === null || _a === void 0 ? true : delete _a.source;
46
- layerData.source = sourceId;
47
- }
48
- layerSchema['required'] = ['name', ...layerSchema['required']];
49
- layerSchema['properties'] = Object.assign({ name: { type: 'string', description: 'The name of the layer' } }, layerSchema['properties']);
50
- }
51
- let sourceSchema = undefined;
52
- const SourceForm = getSourceTypeForm(this.props.sourceType || 'RasterSource');
53
- if (this.props.sourceType) {
54
- sourceSchema = deepCopy(this.props.formSchemaRegistry.getSchemas().get(this.props.sourceType));
55
- if (!sourceSchema) {
56
- console.error(`Cannot find schema for ${this.props.sourceType}`);
57
- return;
58
- }
59
- if (!this.props.createLayer) {
60
- sourceSchema['required'] = ['name', ...sourceSchema['required']];
61
- sourceSchema['properties'] = Object.assign({ name: { type: 'string', description: 'The name of the source' } }, sourceSchema['properties']);
62
- }
63
- }
64
- const creationPromises = [];
65
- let layerCreationPromise;
66
- let sourceCreationPromise;
67
- if (this.props.createLayer) {
68
- layerCreationPromise = new PromiseDelegate();
69
- creationPromises.push(layerCreationPromise.promise);
27
+ const sourceFormChangedSignal = sourceFormChangedSignalRef.current;
28
+ const sourceIdRef = useRef(UUID.uuid4());
29
+ const sourceId = sourceIdRef.current;
30
+ const sourceFormDataRef = useRef(null);
31
+ const layerFormDataRef = useRef(null);
32
+ const initialSourceForRef = useMemo(() => deepCopy(initialSourceData !== null && initialSourceData !== void 0 ? initialSourceData : {}), [initialSourceData]);
33
+ const initialLayerForRef = useMemo(() => {
34
+ const data = deepCopy(initialLayerData || {});
35
+ if (createSource) {
36
+ data.source = sourceId;
70
37
  }
71
- if (this.props.createSource) {
72
- sourceCreationPromise = new PromiseDelegate();
73
- creationPromises.push(sourceCreationPromise.promise);
38
+ return data;
39
+ }, [initialLayerData, createSource, sourceId]);
40
+ if (sourceFormDataRef.current === null && createSource) {
41
+ sourceFormDataRef.current = initialSourceForRef;
42
+ }
43
+ if (layerFormDataRef.current === null && createLayer) {
44
+ layerFormDataRef.current = initialLayerForRef;
45
+ }
46
+ const modelRef = useRef(model);
47
+ const createLayerRef = useRef(createLayer);
48
+ const createSourceRef = useRef(createSource);
49
+ const sourceTypeRef = useRef(sourceType);
50
+ const layerTypeRef = useRef(layerType);
51
+ modelRef.current = model;
52
+ createLayerRef.current = createLayer;
53
+ createSourceRef.current = createSource;
54
+ sourceTypeRef.current = sourceType;
55
+ layerTypeRef.current = layerType;
56
+ useEffect(() => {
57
+ if (!registerConfirmHandler) {
58
+ return;
74
59
  }
75
- // Perform the layer/source creation
76
- Promise.all(creationPromises).then(async () => {
77
- if (this.props.createSource) {
78
- let actualName = '';
79
- const _a = (await (sourceCreationPromise === null || sourceCreationPromise === void 0 ? void 0 : sourceCreationPromise.promise)), { name } = _a, sourceData = __rest(_a, ["name"]);
80
- actualName =
81
- name ||
82
- (await (layerCreationPromise === null || layerCreationPromise === void 0 ? void 0 : layerCreationPromise.promise)).name + ' Source';
60
+ registerConfirmHandler(() => {
61
+ var _a, _b, _c;
62
+ const currentModel = modelRef.current;
63
+ const currentCreateSource = createSourceRef.current;
64
+ const currentCreateLayer = createLayerRef.current;
65
+ const currentSourceType = sourceTypeRef.current;
66
+ const currentLayerType = layerTypeRef.current;
67
+ const currentSourceId = sourceIdRef.current;
68
+ if (currentCreateSource) {
69
+ const sourceData = (_a = sourceFormDataRef.current) !== null && _a !== void 0 ? _a : {};
70
+ const { name } = sourceData, sourceParams = __rest(sourceData, ["name"]);
71
+ const layerData = layerFormDataRef.current;
72
+ const actualName = name ||
73
+ (currentCreateLayer && (layerData === null || layerData === void 0 ? void 0 : layerData.name)
74
+ ? `${layerData.name} Source`
75
+ : '');
83
76
  const sourceModel = {
84
- type: this.props.sourceType || 'RasterSource',
77
+ type: currentSourceType || 'RasterSource',
85
78
  name: actualName,
86
- parameters: sourceData,
79
+ parameters: sourceParams,
87
80
  };
88
- this.jGISModel.sharedModel.addSource(sourceId, sourceModel);
81
+ currentModel.sharedModel.addSource(currentSourceId, sourceModel);
89
82
  }
90
- if (this.props.createLayer) {
91
- let actualName = '';
92
- const _b = (await (layerCreationPromise === null || layerCreationPromise === void 0 ? void 0 : layerCreationPromise.promise)), { name } = _b, layerData = __rest(_b, ["name"]);
93
- actualName =
94
- name ||
95
- (await (layerCreationPromise === null || layerCreationPromise === void 0 ? void 0 : layerCreationPromise.promise)).name + ' Layer';
83
+ if (currentCreateLayer) {
84
+ const layerData = (_b = layerFormDataRef.current) !== null && _b !== void 0 ? _b : {};
85
+ const { name } = layerData, layerParams = __rest(layerData, ["name"]);
86
+ const actualName = name || `${(_c = layerData.name) !== null && _c !== void 0 ? _c : 'Layer'} Layer`;
96
87
  const layerModel = {
97
- type: this.props.layerType || 'RasterLayer',
98
- parameters: layerData,
88
+ type: currentLayerType || 'RasterLayer',
89
+ parameters: layerParams,
99
90
  visible: true,
100
91
  name: actualName,
101
92
  };
102
- this.jGISModel.addLayer(UUID.uuid4(), layerModel);
93
+ currentModel.addLayer(UUID.uuid4(), layerModel);
103
94
  }
104
95
  });
105
- return (React.createElement("div", null,
106
- this.props.createSource && (React.createElement("div", null,
107
- React.createElement("h3", null, "Source Properties"),
108
- React.createElement(SourceForm, { formContext: "create", model: this.jGISModel, filePath: this.filePath, schema: sourceSchema, sourceData: this.props.sourceData, syncData: (properties) => {
109
- sourceCreationPromise === null || sourceCreationPromise === void 0 ? void 0 : sourceCreationPromise.resolve(properties);
110
- }, ok: this.props.ok, cancel: this.props.cancel, formChangedSignal: this.sourceFormChangedSignal, formErrorSignal: this.props.formErrorSignal, dialogOptions: this.props.dialogOptions, sourceType: this.props.sourceType }))),
111
- this.props.createLayer && (React.createElement("div", null,
112
- React.createElement("h3", null, "Layer Properties"),
113
- React.createElement(LayerForm, { formContext: "create", sourceType: this.props.sourceType, model: this.jGISModel, filePath: this.filePath, schema: layerSchema, sourceData: layerData, syncData: (properties) => {
114
- layerCreationPromise === null || layerCreationPromise === void 0 ? void 0 : layerCreationPromise.resolve(properties);
115
- }, ok: this.props.ok, cancel: this.props.cancel, sourceFormChangedSignal: this.sourceFormChangedSignal, formErrorSignal: this.props.formErrorSignal, dialogOptions: this.props.dialogOptions })))));
96
+ }, [registerConfirmHandler]);
97
+ const LayerForm = useMemo(() => getLayerTypeForm(layerType || 'RasterLayer'), [layerType]);
98
+ const SourceForm = useMemo(() => getSourceTypeForm(sourceType || 'RasterSource'), [sourceType]);
99
+ const layerSchema = useMemo(() => {
100
+ var _a, _b;
101
+ if (!createLayer || !layerType) {
102
+ return undefined;
103
+ }
104
+ const raw = formSchemaRegistry.getSchemas().get(layerType);
105
+ if (!raw) {
106
+ return undefined;
107
+ }
108
+ const schema = deepCopy(raw);
109
+ if (createSource) {
110
+ (_a = schema.properties) === null || _a === void 0 ? true : delete _a.source;
111
+ }
112
+ schema['required'] = ['name', ...((_b = schema['required']) !== null && _b !== void 0 ? _b : [])];
113
+ schema['properties'] = Object.assign({ name: { type: 'string', description: 'The name of the layer' } }, schema['properties']);
114
+ return schema;
115
+ }, [createLayer, layerType, createSource, formSchemaRegistry]);
116
+ const layerData = useMemo(() => {
117
+ const data = deepCopy(initialLayerData || {});
118
+ if (createSource) {
119
+ data.source = sourceId;
120
+ }
121
+ return data;
122
+ }, [initialLayerData, createSource, sourceId]);
123
+ const sourceSchema = useMemo(() => {
124
+ var _a;
125
+ if (!sourceType) {
126
+ return undefined;
127
+ }
128
+ const raw = formSchemaRegistry.getSchemas().get(sourceType);
129
+ if (!raw) {
130
+ return undefined;
131
+ }
132
+ const schema = deepCopy(raw);
133
+ if (!createLayer) {
134
+ schema['required'] = ['name', ...((_a = schema['required']) !== null && _a !== void 0 ? _a : [])];
135
+ schema['properties'] = Object.assign({ name: { type: 'string', description: 'The name of the source' } }, schema['properties']);
136
+ }
137
+ return schema;
138
+ }, [sourceType, createLayer, formSchemaRegistry]);
139
+ if (createLayer && !layerType) {
140
+ console.error('Cannot create a layer without specifying its type');
141
+ return null;
142
+ }
143
+ if (createLayer && !layerSchema) {
144
+ console.error(`Cannot find schema for ${layerType}`);
145
+ return null;
146
+ }
147
+ if (sourceType && !sourceSchema) {
148
+ console.error(`Cannot find schema for ${sourceType}`);
149
+ return null;
116
150
  }
151
+ return (React.createElement("div", null,
152
+ createSource && sourceSchema && (React.createElement("div", null,
153
+ React.createElement("h3", null, "Source Properties"),
154
+ React.createElement(SourceForm, { formContext: "create", model: model, filePath: filePath, schema: sourceSchema, sourceData: initialSourceData, syncData: (properties) => {
155
+ sourceFormDataRef.current = properties;
156
+ }, cancel: cancel, formChangedSignal: sourceFormChangedSignal, formErrorSignal: formErrorSignal, dialogOptions: dialogOptions, sourceType: sourceType, formSchemaRegistry: formSchemaRegistry }))),
157
+ createLayer && layerSchema && (React.createElement("div", null,
158
+ React.createElement("h3", null, "Layer Properties"),
159
+ React.createElement(LayerForm, { formContext: "create", sourceType: sourceType, model: model, filePath: filePath, schema: layerSchema, sourceData: layerData, syncData: (properties) => {
160
+ layerFormDataRef.current = properties;
161
+ }, cancel: cancel, sourceFormChangedSignal: sourceFormChangedSignal, formErrorSignal: formErrorSignal, dialogOptions: dialogOptions, formSchemaRegistry: formSchemaRegistry })))));
117
162
  }
@@ -15,10 +15,4 @@ export interface IEditFormProps {
15
15
  /**
16
16
  * Form for editing a source, a layer or both at the same time
17
17
  */
18
- export declare class EditForm extends React.Component<IEditFormProps, any> {
19
- syncObjectProperties(id: string | undefined, properties: {
20
- [key: string]: any;
21
- }): Promise<void>;
22
- render(): React.JSX.Element | undefined;
23
- private sourceFormChangedSignal;
24
- }
18
+ export declare function EditForm(props: IEditFormProps): React.ReactElement | null;