@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
@@ -0,0 +1,22 @@
1
+ import { IRenderMime } from '@jupyterlab/rendermime';
2
+ import { CommandRegistry } from '@lumino/commands';
3
+ import { JupyterGISTracker } from '../types';
4
+ export declare namespace LayerCreationCommandIDs {
5
+ const newGeoJSONWithParams = "jupytergis:newGeoJSONWithParams";
6
+ const newRasterWithParams = "jupytergis:newRasterWithParams";
7
+ const newVectorTileWithParams = "jupytergis:newVectorTileWithParams";
8
+ const newGeoParquetWithParams = "jupytergis:newGeoParquetWithParams";
9
+ const newHillshadeWithParams = "jupytergis:newHillshadeWithParams";
10
+ const newImageWithParams = "jupytergis:newImageWithParams";
11
+ const newVideoWithParams = "jupytergis:newVideoWithParams";
12
+ const newGeoTiffWithParams = "jupytergis:newGeoTiffWithParams";
13
+ const newShapefileWithParams = "jupytergis:newShapefileWithParams";
14
+ }
15
+ /**
16
+ * Register all layer creation commands using declarative specs.
17
+ */
18
+ export declare function addLayerCreationCommands(options: {
19
+ tracker: JupyterGISTracker;
20
+ commands: CommandRegistry;
21
+ trans: IRenderMime.TranslationBundle;
22
+ }): void;
@@ -0,0 +1,305 @@
1
+ import { UUID } from '@lumino/coreutils';
2
+ export var LayerCreationCommandIDs;
3
+ (function (LayerCreationCommandIDs) {
4
+ LayerCreationCommandIDs.newGeoJSONWithParams = 'jupytergis:newGeoJSONWithParams';
5
+ LayerCreationCommandIDs.newRasterWithParams = 'jupytergis:newRasterWithParams';
6
+ LayerCreationCommandIDs.newVectorTileWithParams = 'jupytergis:newVectorTileWithParams';
7
+ LayerCreationCommandIDs.newGeoParquetWithParams = 'jupytergis:newGeoParquetWithParams';
8
+ LayerCreationCommandIDs.newHillshadeWithParams = 'jupytergis:newHillshadeWithParams';
9
+ LayerCreationCommandIDs.newImageWithParams = 'jupytergis:newImageWithParams';
10
+ LayerCreationCommandIDs.newVideoWithParams = 'jupytergis:newVideoWithParams';
11
+ LayerCreationCommandIDs.newGeoTiffWithParams = 'jupytergis:newGeoTiffWithParams';
12
+ LayerCreationCommandIDs.newShapefileWithParams = 'jupytergis:newShapefileWithParams';
13
+ })(LayerCreationCommandIDs || (LayerCreationCommandIDs = {}));
14
+ /**
15
+ * Generic command factory for layer creation.
16
+ */
17
+ function createLayerCommand(commands, tracker, trans, spec) {
18
+ commands.addCommand(spec.id, {
19
+ label: trans.__(spec.label),
20
+ caption: trans.__(spec.caption),
21
+ isEnabled: () => true,
22
+ describedBy: {
23
+ args: {
24
+ type: 'object',
25
+ required: ['filePath', 'name', 'parameters'],
26
+ properties: {
27
+ filePath: { type: 'string', description: 'Path to the .jGIS file' },
28
+ name: { type: 'string', description: 'Layer name' },
29
+ parameters: {
30
+ type: 'object',
31
+ properties: Object.assign({ source: spec.sourceSchema }, spec.layerParamsSchema),
32
+ },
33
+ },
34
+ },
35
+ },
36
+ execute: (async (args) => {
37
+ const { filePath, name, parameters } = args;
38
+ const current = tracker.find(w => w.model.filePath === filePath);
39
+ if (!current || !current.model.sharedModel.editable) {
40
+ console.warn('Invalid or non-editable document for', filePath);
41
+ return;
42
+ }
43
+ const model = current.model;
44
+ const sharedModel = model.sharedModel;
45
+ const sourceId = UUID.uuid4();
46
+ const layerId = UUID.uuid4();
47
+ const sourceModel = {
48
+ type: spec.sourceType,
49
+ name: `${name} Source`,
50
+ parameters: parameters.source,
51
+ };
52
+ sharedModel.addSource(sourceId, sourceModel);
53
+ const layerModel = {
54
+ type: spec.layerType,
55
+ name: name,
56
+ visible: true,
57
+ parameters: spec.buildParameters(parameters, sourceId),
58
+ };
59
+ model.addLayer(layerId, layerModel);
60
+ }),
61
+ });
62
+ }
63
+ /**
64
+ * Register all layer creation commands using declarative specs.
65
+ */
66
+ export function addLayerCreationCommands(options) {
67
+ const { tracker, commands, trans } = options;
68
+ const specs = [
69
+ {
70
+ id: LayerCreationCommandIDs.newGeoJSONWithParams,
71
+ label: 'New GeoJSON Layer From Parameters',
72
+ caption: 'Add a new GeoJSON vector layer (by file path or URL) and add it to the given JupyterGIS file',
73
+ sourceType: 'GeoJSONSource',
74
+ layerType: 'VectorLayer',
75
+ sourceSchema: {
76
+ type: 'object',
77
+ required: ['path'],
78
+ properties: { path: { type: 'string' } },
79
+ },
80
+ layerParamsSchema: {
81
+ color: { type: 'object' },
82
+ opacity: { type: 'number', default: 1 },
83
+ symbologyState: { type: 'object' },
84
+ },
85
+ buildParameters: (p, id) => {
86
+ var _a, _b;
87
+ return ({
88
+ source: id,
89
+ color: (_a = p.color) !== null && _a !== void 0 ? _a : {},
90
+ opacity: (_b = p.opacity) !== null && _b !== void 0 ? _b : 1,
91
+ symbologyState: p.symbologyState,
92
+ });
93
+ },
94
+ },
95
+ {
96
+ id: LayerCreationCommandIDs.newRasterWithParams,
97
+ label: 'New Raster Layer From Parameters',
98
+ caption: 'Add a new raster layer (by file path or URL) and add it to the given JupyterGIS file',
99
+ sourceType: 'RasterSource',
100
+ layerType: 'RasterLayer',
101
+ sourceSchema: {
102
+ type: 'object',
103
+ required: ['url'],
104
+ properties: { url: { type: 'string' } },
105
+ },
106
+ layerParamsSchema: { opacity: { type: 'number', default: 1 } },
107
+ buildParameters: (p, id) => {
108
+ var _a;
109
+ return ({
110
+ source: id,
111
+ opacity: (_a = p.opacity) !== null && _a !== void 0 ? _a : 1,
112
+ });
113
+ },
114
+ },
115
+ {
116
+ id: LayerCreationCommandIDs.newVectorTileWithParams,
117
+ label: 'New Vector Tile Layer From Parameters',
118
+ caption: 'Add a new vector tile layer (by URL) and add it to the given JupyterGIS file',
119
+ sourceType: 'VectorTileSource',
120
+ layerType: 'VectorTileLayer',
121
+ sourceSchema: {
122
+ type: 'object',
123
+ required: ['url'],
124
+ properties: { url: { type: 'string' } },
125
+ },
126
+ layerParamsSchema: {
127
+ color: { type: 'object' },
128
+ opacity: { type: 'number', default: 1 },
129
+ },
130
+ buildParameters: (p, id) => {
131
+ var _a, _b;
132
+ return ({
133
+ source: id,
134
+ color: (_a = p.color) !== null && _a !== void 0 ? _a : {},
135
+ opacity: (_b = p.opacity) !== null && _b !== void 0 ? _b : 1,
136
+ });
137
+ },
138
+ },
139
+ {
140
+ id: LayerCreationCommandIDs.newGeoParquetWithParams,
141
+ label: 'New GeoParquet Layer From Parameters',
142
+ caption: 'Add a new GeoParquet vector layer (by file path or URL) and add it to the given JupyterGIS file',
143
+ sourceType: 'GeoParquetSource',
144
+ layerType: 'VectorLayer',
145
+ sourceSchema: {
146
+ type: 'object',
147
+ required: ['path'],
148
+ properties: { path: { type: 'string' } },
149
+ },
150
+ layerParamsSchema: {
151
+ color: { type: 'object' },
152
+ opacity: { type: 'number', default: 1 },
153
+ symbologyState: { type: 'object' },
154
+ },
155
+ buildParameters: (p, id) => {
156
+ var _a, _b;
157
+ return ({
158
+ source: id,
159
+ color: (_a = p.color) !== null && _a !== void 0 ? _a : {},
160
+ opacity: (_b = p.opacity) !== null && _b !== void 0 ? _b : 1,
161
+ symbologyState: p.symbologyState,
162
+ });
163
+ },
164
+ },
165
+ {
166
+ id: LayerCreationCommandIDs.newHillshadeWithParams,
167
+ label: 'New Hillshade Layer From Parameters',
168
+ caption: 'Add a new hillshade layer (by DEM raster source) and add it to the given JupyterGIS file',
169
+ sourceType: 'RasterDemSource',
170
+ layerType: 'HillshadeLayer',
171
+ sourceSchema: {
172
+ type: 'object',
173
+ required: ['url'],
174
+ properties: { url: { type: 'string' } },
175
+ },
176
+ layerParamsSchema: {
177
+ shadowColor: { type: 'string', default: '#473B24' },
178
+ },
179
+ buildParameters: (p, id) => {
180
+ var _a;
181
+ return ({
182
+ source: id,
183
+ shadowColor: (_a = p.shadowColor) !== null && _a !== void 0 ? _a : '#473B24',
184
+ });
185
+ },
186
+ },
187
+ {
188
+ id: LayerCreationCommandIDs.newImageWithParams,
189
+ label: 'New Image Layer From Parameters',
190
+ caption: 'Add a new image layer (by file path or URL) and add it to the given JupyterGIS file',
191
+ sourceType: 'ImageSource',
192
+ layerType: 'ImageLayer',
193
+ sourceSchema: {
194
+ type: 'object',
195
+ required: ['path', 'coordinates'],
196
+ properties: {
197
+ path: { type: 'string' },
198
+ coordinates: {
199
+ type: 'array',
200
+ items: { type: 'array', items: { type: 'number' } },
201
+ },
202
+ },
203
+ },
204
+ layerParamsSchema: { opacity: { type: 'number', default: 1 } },
205
+ buildParameters: (p, id) => {
206
+ var _a;
207
+ return ({
208
+ source: id,
209
+ opacity: (_a = p.opacity) !== null && _a !== void 0 ? _a : 1,
210
+ });
211
+ },
212
+ },
213
+ {
214
+ id: LayerCreationCommandIDs.newVideoWithParams,
215
+ label: 'New Video Layer From Parameters',
216
+ caption: 'Add a new video layer (by file path or URL) and add it to the given JupyterGIS file',
217
+ sourceType: 'VideoSource',
218
+ layerType: 'RasterLayer',
219
+ sourceSchema: {
220
+ type: 'object',
221
+ required: ['urls', 'coordinates'],
222
+ properties: {
223
+ urls: { type: 'array', items: { type: 'string' } },
224
+ coordinates: {
225
+ type: 'array',
226
+ items: { type: 'array', items: { type: 'number' } },
227
+ },
228
+ },
229
+ },
230
+ layerParamsSchema: { opacity: { type: 'number', default: 1 } },
231
+ buildParameters: (p, id) => {
232
+ var _a;
233
+ return ({
234
+ source: id,
235
+ opacity: (_a = p.opacity) !== null && _a !== void 0 ? _a : 1,
236
+ });
237
+ },
238
+ },
239
+ {
240
+ id: LayerCreationCommandIDs.newGeoTiffWithParams,
241
+ label: 'New GeoTIFF Layer From Parameters',
242
+ caption: 'Add a new GeoTIFF layer (by file path or URL) and add it to the given JupyterGIS file',
243
+ sourceType: 'GeoTiffSource',
244
+ layerType: 'WebGlLayer',
245
+ sourceSchema: {
246
+ type: 'object',
247
+ required: ['urls'],
248
+ properties: {
249
+ urls: {
250
+ type: 'array',
251
+ items: {
252
+ type: 'object',
253
+ properties: {
254
+ url: { type: 'string' },
255
+ min: { type: 'number' },
256
+ max: { type: 'number' },
257
+ },
258
+ },
259
+ },
260
+ },
261
+ },
262
+ layerParamsSchema: {
263
+ opacity: { type: 'number', default: 1 },
264
+ color: { type: 'any' },
265
+ symbologyState: { type: 'object' },
266
+ },
267
+ buildParameters: (p, id) => {
268
+ var _a, _b;
269
+ return ({
270
+ source: id,
271
+ opacity: (_a = p.opacity) !== null && _a !== void 0 ? _a : 1,
272
+ color: p.color,
273
+ symbologyState: (_b = p.symbologyState) !== null && _b !== void 0 ? _b : { renderType: 'continuous' },
274
+ });
275
+ },
276
+ },
277
+ {
278
+ id: LayerCreationCommandIDs.newShapefileWithParams,
279
+ label: 'New Shapefile Layer From Parameters',
280
+ caption: 'Add a new Shapefile vector layer (by file path or URL) and add it to the given JupyterGIS file',
281
+ sourceType: 'ShapefileSource',
282
+ layerType: 'VectorLayer',
283
+ sourceSchema: {
284
+ type: 'object',
285
+ required: ['path'],
286
+ properties: { path: { type: 'string' } },
287
+ },
288
+ layerParamsSchema: {
289
+ color: { type: 'object' },
290
+ opacity: { type: 'number', default: 1 },
291
+ symbologyState: { type: 'object' },
292
+ },
293
+ buildParameters: (p, id) => {
294
+ var _a, _b, _c;
295
+ return ({
296
+ source: id,
297
+ color: (_a = p.color) !== null && _a !== void 0 ? _a : {},
298
+ opacity: (_b = p.opacity) !== null && _b !== void 0 ? _b : 1,
299
+ symbologyState: (_c = p.symbologyState) !== null && _c !== void 0 ? _c : { renderType: 'Single Symbol' },
300
+ });
301
+ },
302
+ },
303
+ ];
304
+ specs.forEach(spec => createLayerCommand(commands, tracker, trans, spec));
305
+ }
package/lib/constants.js CHANGED
@@ -22,15 +22,15 @@ const iconObject = {
22
22
  [CommandIDs.redo]: { icon: redoIcon },
23
23
  [CommandIDs.undo]: { icon: undoIcon },
24
24
  [CommandIDs.openLayerBrowser]: { icon: bookOpenIcon },
25
- [CommandIDs.newRasterEntry]: { icon: rasterIcon },
26
- [CommandIDs.newVectorTileEntry]: { icon: vectorSquareIcon },
27
- [CommandIDs.newGeoJSONEntry]: { icon: geoJSONIcon },
28
- [CommandIDs.newHillshadeEntry]: { icon: moundIcon },
29
- [CommandIDs.newImageEntry]: { iconClass: 'fa fa-image' },
30
- [CommandIDs.newVideoEntry]: { iconClass: 'fa fa-video' },
31
- [CommandIDs.newShapefileEntry]: { iconClass: 'fa fa-file' },
32
- [CommandIDs.newGeoTiffEntry]: { iconClass: 'fa fa-image' },
33
- [CommandIDs.newGeoParquetEntry]: { iconClass: 'fa fa-file' },
25
+ [CommandIDs.openNewRasterDialog]: { icon: rasterIcon },
26
+ [CommandIDs.openNewVectorTileDialog]: { icon: vectorSquareIcon },
27
+ [CommandIDs.openNewGeoJSONDialog]: { icon: geoJSONIcon },
28
+ [CommandIDs.openNewHillshadeDialog]: { icon: moundIcon },
29
+ [CommandIDs.openNewImageDialog]: { iconClass: 'fa fa-image' },
30
+ [CommandIDs.openNewVideoDialog]: { iconClass: 'fa fa-video' },
31
+ [CommandIDs.openNewShapefileDialog]: { iconClass: 'fa fa-file' },
32
+ [CommandIDs.openNewGeoTiffDialog]: { iconClass: 'fa fa-image' },
33
+ [CommandIDs.openNewGeoParquetDialog]: { iconClass: 'fa fa-file' },
34
34
  [CommandIDs.symbology]: { iconClass: 'fa fa-brush' },
35
35
  [CommandIDs.identify]: { icon: infoIcon },
36
36
  [CommandIDs.temporalController]: { icon: clockIcon },
@@ -39,6 +39,8 @@ const iconObject = {
39
39
  [CommandIDs.toggleStoryPresentationMode]: {
40
40
  iconClass: 'fa fa-book jgis-icon-adjust',
41
41
  },
42
+ [CommandIDs.renameSelected]: { iconClass: 'fa fa-pen' },
43
+ [CommandIDs.removeSelected]: { iconClass: 'fa fa-trash' },
42
44
  };
43
45
  /**
44
46
  * The registered icons
@@ -2,7 +2,7 @@ import { ProcessingType, IDict, IJupyterGISModel } from '@jupytergis/schema';
2
2
  import { Dialog } from '@jupyterlab/apputils';
3
3
  import { PromiseDelegate } from '@lumino/coreutils';
4
4
  import { Signal } from '@lumino/signaling';
5
- import { IBaseFormProps } from "../formbuilder/objectform/baseform";
5
+ import type { IBaseFormProps } from "../types";
6
6
  export interface IProcessingFormDialogOptions extends IBaseFormProps {
7
7
  formContext: 'update' | 'create';
8
8
  schema: IDict;
@@ -2,8 +2,8 @@ import { Dialog } from '@jupyterlab/apputils';
2
2
  import { PromiseDelegate } from '@lumino/coreutils';
3
3
  import { Signal } from '@lumino/signaling';
4
4
  import * as React from 'react';
5
- import { BaseForm, } from "../formbuilder/objectform/baseform";
6
5
  import { DissolveForm } from "../formbuilder/objectform/process";
6
+ import { DefaultProcessingForm } from "../formbuilder/objectform/processingForm";
7
7
  const ProcessingFormWrapper = props => {
8
8
  var _a;
9
9
  const [ready, setReady] = React.useState(false);
@@ -23,7 +23,7 @@ const ProcessingFormWrapper = props => {
23
23
  FormComponent = DissolveForm;
24
24
  break;
25
25
  default:
26
- FormComponent = BaseForm;
26
+ FormComponent = DefaultProcessingForm;
27
27
  }
28
28
  return (ready && (React.createElement(FormComponent, { formContext: props.formContext, filePath: props.model.filePath, model: props.model, ok: okSignal.current, sourceData: props.sourceData, schema: props.schema, syncData: props.syncData })));
29
29
  };
@@ -9,6 +9,7 @@ interface ILayerBrowserDialogProps {
9
9
  formSchemaRegistry: IJGISFormSchemaRegistry;
10
10
  okSignalPromise: PromiseDelegate<Signal<Dialog<any>, number>>;
11
11
  cancel: () => void;
12
+ registerConfirmHandler?: (fn: () => void) => void;
12
13
  }
13
14
  export declare const LayerBrowserComponent: React.FC<ILayerBrowserDialogProps>;
14
15
  export interface ILayerBrowserOptions {
@@ -19,6 +20,7 @@ export interface ILayerBrowserOptions {
19
20
  export declare class LayerBrowserWidget extends Dialog<boolean> {
20
21
  constructor(options: ILayerBrowserOptions);
21
22
  resolve(index?: number): void;
23
+ private _getConfirmHandler;
22
24
  private okSignal;
23
25
  }
24
26
  export {};
@@ -6,7 +6,7 @@ import { Signal } from '@lumino/signaling';
6
6
  import React, { useEffect, useState } from 'react';
7
7
  import { CreationFormWrapper } from './layerCreationFormDialog';
8
8
  import CUSTOM_RASTER_IMAGE from '../../layer_gallery/custom_raster.png';
9
- export const LayerBrowserComponent = ({ model, registry, formSchemaRegistry, okSignalPromise, cancel, }) => {
9
+ export const LayerBrowserComponent = ({ model, registry, formSchemaRegistry, okSignalPromise, cancel, registerConfirmHandler, }) => {
10
10
  const [searchTerm, setSearchTerm] = useState('');
11
11
  const [activeLayers, setActiveLayers] = useState([]);
12
12
  const [selectedCategory, setSelectedCategory] = useState();
@@ -78,7 +78,7 @@ export const LayerBrowserComponent = ({ model, registry, formSchemaRegistry, okS
78
78
  maxZoom: 24,
79
79
  minZoom: 0,
80
80
  attribution: '(C) OpenStreetMap contributors',
81
- }, okSignalPromise: okSignalPromise, cancel: cancel })));
81
+ }, okSignalPromise: okSignalPromise, cancel: cancel, registerConfirmHandler: registerConfirmHandler })));
82
82
  }
83
83
  // Ok is like cancel in the case of gallery item selections
84
84
  okSignalPromise.promise.then(value => {
@@ -116,25 +116,32 @@ export const LayerBrowserComponent = ({ model, registry, formSchemaRegistry, okS
116
116
  };
117
117
  export class LayerBrowserWidget extends Dialog {
118
118
  constructor(options) {
119
- let cancelCallback = undefined;
120
- cancelCallback = () => {
119
+ const cancelCallback = () => {
121
120
  this.resolve(0);
122
121
  };
122
+ let confirmHandler = null;
123
+ const registerConfirmHandler = (fn) => {
124
+ confirmHandler = fn;
125
+ };
123
126
  const okSignalPromise = new PromiseDelegate();
124
- const body = (React.createElement(LayerBrowserComponent, { model: options.model, registry: options.registry, formSchemaRegistry: options.formSchemaRegistry, okSignalPromise: okSignalPromise, cancel: cancelCallback }));
127
+ const body = (React.createElement(LayerBrowserComponent, { model: options.model, registry: options.registry, formSchemaRegistry: options.formSchemaRegistry, okSignalPromise: okSignalPromise, cancel: cancelCallback, registerConfirmHandler: registerConfirmHandler }));
125
128
  super({ body, buttons: [Dialog.cancelButton(), Dialog.okButton()] });
126
129
  this.id = 'jupytergis::layerBrowser';
130
+ this._getConfirmHandler = () => confirmHandler;
127
131
  this.okSignal = new Signal(this);
128
132
  okSignalPromise.resolve(this.okSignal);
129
133
  // Override default dialog style
130
134
  this.addClass('jGIS-layerbrowser-FormDialog');
131
135
  }
132
136
  resolve(index) {
137
+ var _a;
133
138
  if (index === 0) {
134
139
  super.resolve(index);
135
140
  }
136
141
  if (index === 1) {
142
+ (_a = this._getConfirmHandler()) === null || _a === void 0 ? void 0 : _a();
137
143
  this.okSignal.emit(1);
144
+ super.resolve(index);
138
145
  }
139
146
  }
140
147
  }
@@ -21,6 +21,12 @@ export interface ICreationFormWrapperProps extends ICreationFormProps {
21
21
  * and other form-related parameters.
22
22
  */
23
23
  dialogOptions?: any;
24
+ /**
25
+ * Optional. When provided, the form body can register a handler that the dialog
26
+ * will invoke when the user clicks OK. If no handler is
27
+ * registered, only the ok signal is emitted.
28
+ */
29
+ registerConfirmHandler?: (fn: () => void) => void;
24
30
  }
25
31
  export interface ICreationFormDialogOptions extends ICreationFormProps {
26
32
  title: string;
@@ -32,5 +38,6 @@ export declare const CreationFormWrapper: React.FC<ICreationFormWrapperProps>;
32
38
  export declare class LayerCreationFormDialog extends Dialog<IDict> {
33
39
  constructor(options: ICreationFormDialogOptions);
34
40
  resolve(index?: number): void;
41
+ private _getConfirmHandler;
35
42
  private okSignal;
36
43
  }
@@ -16,7 +16,7 @@ export const CreationFormWrapper = props => {
16
16
  formErrorSignal.current = formChanged;
17
17
  setReady(true);
18
18
  });
19
- return (ready && (React.createElement(CreationForm, { model: props.model, formSchemaRegistry: props.formSchemaRegistry, createLayer: props.createLayer, createSource: props.createSource, layerType: props.layerType, sourceType: props.sourceType, sourceData: props.sourceData, layerData: props.layerData, ok: okSignal.current, cancel: props.cancel, formErrorSignal: formErrorSignal.current, dialogOptions: props.dialogOptions })));
19
+ return (ready && (React.createElement(CreationForm, { model: props.model, formSchemaRegistry: props.formSchemaRegistry, createLayer: props.createLayer, createSource: props.createSource, layerType: props.layerType, sourceType: props.sourceType, sourceData: props.sourceData, layerData: props.layerData, cancel: props.cancel, formErrorSignal: formErrorSignal.current, dialogOptions: props.dialogOptions, registerConfirmHandler: props.registerConfirmHandler })));
20
20
  };
21
21
  /**
22
22
  * Form for creating a source, a layer or both at the same time
@@ -26,15 +26,20 @@ export class LayerCreationFormDialog extends Dialog {
26
26
  const cancelCallback = () => {
27
27
  this.resolve(0);
28
28
  };
29
+ let confirmHandler = null;
30
+ const registerConfirmHandler = (fn) => {
31
+ confirmHandler = fn;
32
+ };
29
33
  const okSignalPromise = new PromiseDelegate();
30
34
  const formErrorSignalPromise = new PromiseDelegate();
31
35
  const body = (React.createElement("div", { style: { overflow: 'auto' } },
32
- React.createElement(CreationFormWrapper, { model: options.model, formSchemaRegistry: options.formSchemaRegistry, createLayer: options.createLayer, createSource: options.createSource, layerType: options.layerType, sourceType: options.sourceType, sourceData: options.sourceData, layerData: options.layerData, okSignalPromise: okSignalPromise, cancel: cancelCallback, formErrorSignalPromise: formErrorSignalPromise, dialogOptions: options })));
36
+ React.createElement(CreationFormWrapper, { model: options.model, formSchemaRegistry: options.formSchemaRegistry, createLayer: options.createLayer, createSource: options.createSource, layerType: options.layerType, sourceType: options.sourceType, sourceData: options.sourceData, layerData: options.layerData, okSignalPromise: okSignalPromise, cancel: cancelCallback, formErrorSignalPromise: formErrorSignalPromise, dialogOptions: options, registerConfirmHandler: registerConfirmHandler })));
33
37
  super({
34
38
  title: options.title,
35
39
  body,
36
40
  buttons: [Dialog.cancelButton(), Dialog.okButton()],
37
41
  });
42
+ this._getConfirmHandler = () => confirmHandler;
38
43
  this.okSignal = new Signal(this);
39
44
  const formErrorSignal = new Signal(this);
40
45
  /**
@@ -58,11 +63,14 @@ export class LayerCreationFormDialog extends Dialog {
58
63
  this.addClass('jGIS-layer-CreationFormDialog');
59
64
  }
60
65
  resolve(index) {
66
+ var _a;
61
67
  if (index === 0) {
62
68
  super.resolve(index);
63
69
  }
64
70
  if (index === 1) {
71
+ (_a = this._getConfirmHandler()) === null || _a === void 0 ? void 0 : _a();
65
72
  this.okSignal.emit(1);
73
+ super.resolve(index);
66
74
  }
67
75
  }
68
76
  }
@@ -23,7 +23,7 @@ import { ColorRampName } from '../../colorRampUtils';
23
23
  interface IColorRampControlsProps {
24
24
  modeOptions: ClassificationMode[];
25
25
  layerParams: IDict;
26
- classifyFunc: (selectedMode: ClassificationMode, numberOfShades: number, selectedRamp: ColorRampName, setIsLoading: (isLoading: boolean) => void) => void;
26
+ classifyFunc: (selectedMode: ClassificationMode, numberOfShades: number, selectedRamp: ColorRampName, reverseRamp: boolean, setIsLoading: (isLoading: boolean) => void) => void;
27
27
  showModeRow: boolean;
28
28
  showRampSelector: boolean;
29
29
  }
@@ -31,6 +31,7 @@ export type ColorRampControlsOptions = {
31
31
  selectedRamp: ColorRampName;
32
32
  numberOfShades: number;
33
33
  selectedMode: ClassificationMode;
34
+ reverseRamp: boolean;
34
35
  };
35
36
  declare const ColorRampControls: React.FC<IColorRampControlsProps>;
36
37
  export default ColorRampControls;
@@ -28,25 +28,19 @@ const ColorRampControls = ({ layerParams, modeOptions, classifyFunc, showModeRow
28
28
  const [selectedMode, setSelectedMode] = useState('equal interval');
29
29
  const [numberOfShades, setNumberOfShades] = useState(9);
30
30
  const [isLoading, setIsLoading] = useState(false);
31
+ const [reverseRamp, setReverseRamp] = useState(false);
31
32
  const [warning, setWarning] = useState(null);
33
+ const symbologyState = layerParams.symbologyState;
32
34
  useEffect(() => {
33
- if (layerParams.symbologyState) {
35
+ if (symbologyState) {
34
36
  populateOptions();
35
37
  }
36
38
  }, [
37
- layerParams.symbologyState.nClasses,
38
- layerParams.symbologyState.mode,
39
- layerParams.symbologyState.colorRamp,
39
+ symbologyState.colorRamp,
40
+ symbologyState.nClasses,
41
+ symbologyState.mode,
42
+ symbologyState.reverseRamp,
40
43
  ]);
41
- useEffect(() => {
42
- var _a;
43
- if (!selectedRamp) {
44
- return;
45
- }
46
- const defaultClasses = (_a = COLOR_RAMP_DEFAULTS[selectedRamp]) !== null && _a !== void 0 ? _a : 9;
47
- setNumberOfShades(defaultClasses);
48
- setWarning(null);
49
- }, [selectedRamp]);
50
44
  useEffect(() => {
51
45
  if (!selectedRamp || !numberOfShades) {
52
46
  return;
@@ -65,18 +59,26 @@ const ColorRampControls = ({ layerParams, modeOptions, classifyFunc, showModeRow
65
59
  }
66
60
  }, [selectedRamp, numberOfShades]);
67
61
  const populateOptions = () => {
68
- var _a, _b, _c;
69
- const { nClasses, mode, colorRamp } = (_a = layerParams.symbologyState) !== null && _a !== void 0 ? _a : {};
62
+ var _a, _b;
63
+ const { nClasses, mode, colorRamp, reverseRamp } = symbologyState !== null && symbologyState !== void 0 ? symbologyState : {};
70
64
  setNumberOfShades(Number(nClasses !== null && nClasses !== void 0 ? nClasses : 9));
71
- setSelectedMode((_b = mode) !== null && _b !== void 0 ? _b : 'equal interval');
72
- setSelectedRamp((_c = colorRamp) !== null && _c !== void 0 ? _c : 'viridis');
65
+ setSelectedMode((_a = mode) !== null && _a !== void 0 ? _a : 'equal interval');
66
+ setSelectedRamp((_b = colorRamp) !== null && _b !== void 0 ? _b : 'viridis');
67
+ setReverseRamp(Boolean(reverseRamp !== null && reverseRamp !== void 0 ? reverseRamp : false));
68
+ };
69
+ const handleRampChange = (selectedRamp) => {
70
+ var _a;
71
+ setSelectedRamp(selectedRamp);
72
+ const defaultClasses = (_a = COLOR_RAMP_DEFAULTS[selectedRamp]) !== null && _a !== void 0 ? _a : 9;
73
+ setNumberOfShades(defaultClasses);
74
+ setWarning(null);
73
75
  };
74
76
  return (React.createElement("div", { className: "jp-gis-color-ramp-container" },
75
77
  showRampSelector && (React.createElement("div", { className: "jp-gis-symbology-row" },
76
78
  React.createElement("label", { htmlFor: "color-ramp-select" }, "Color Ramp:"),
77
- React.createElement(ColorRampSelector, { selectedRamp: selectedRamp, setSelected: setSelectedRamp }))),
79
+ React.createElement(ColorRampSelector, { selectedRamp: selectedRamp, setSelected: handleRampChange, reverse: reverseRamp, setReverse: setReverseRamp }))),
78
80
  showModeRow && (React.createElement(ModeSelectRow, { modeOptions: modeOptions, numberOfShades: numberOfShades, setNumberOfShades: setNumberOfShades, selectedMode: selectedMode, setSelectedMode: setSelectedMode })),
79
81
  warning && (React.createElement("div", { className: "jp-gis-warning", style: { color: 'orange', marginTop: 4 } }, warning)),
80
- isLoading ? (React.createElement(LoadingIcon, null)) : (React.createElement(Button, { className: "jp-Dialog-button jp-mod-accept jp-mod-styled", disabled: !isValidNumberOfShades(numberOfShades) || !selectedMode || !!warning, onClick: () => classifyFunc(selectedMode, numberOfShades, selectedRamp, setIsLoading) }, "Classify"))));
82
+ isLoading ? (React.createElement(LoadingIcon, null)) : (React.createElement(Button, { className: "jp-Dialog-button jp-mod-accept jp-mod-styled", disabled: !isValidNumberOfShades(numberOfShades) || !selectedMode || !!warning, onClick: () => classifyFunc(selectedMode, numberOfShades, selectedRamp, reverseRamp, setIsLoading) }, "Classify"))));
81
83
  };
82
84
  export default ColorRampControls;
@@ -14,7 +14,9 @@ import React from 'react';
14
14
  import { ColorRampName } from "../../colorRampUtils";
15
15
  interface IColorRampSelectorProps {
16
16
  selectedRamp: ColorRampName;
17
- setSelected: (item: any) => void;
17
+ setSelected: (value: ColorRampName) => void;
18
+ reverse: boolean;
19
+ setReverse: React.Dispatch<React.SetStateAction<boolean>>;
18
20
  }
19
21
  declare const ColorRampSelector: React.FC<IColorRampSelectorProps>;
20
22
  export default ColorRampSelector;