@jupytergis/base 0.14.0 → 0.15.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 +1 -1
- package/lib/commands/BaseCommandIDs.js +1 -1
- package/lib/commands/index.js +28 -34
- package/lib/constants.js +1 -0
- package/lib/dialogs/symbology/classificationModes.js +12 -16
- package/lib/dialogs/symbology/colorRampUtils.d.ts +47 -3
- package/lib/dialogs/symbology/colorRampUtils.js +112 -13
- package/lib/dialogs/symbology/components/color_ramp/ColorRampSelector.js +6 -14
- package/lib/dialogs/symbology/components/color_ramp/ColorRampSelectorEntry.d.ts +2 -2
- package/lib/dialogs/symbology/components/color_ramp/ColorRampSelectorEntry.js +3 -11
- package/lib/dialogs/symbology/components/color_ramp/RgbaColorPicker.d.ts +13 -0
- package/lib/dialogs/symbology/components/color_ramp/RgbaColorPicker.js +98 -0
- package/lib/dialogs/symbology/components/color_stops/StopContainer.js +3 -1
- package/lib/dialogs/symbology/components/color_stops/StopRow.d.ts +1 -1
- package/lib/dialogs/symbology/components/color_stops/StopRow.js +12 -7
- package/lib/dialogs/symbology/symbologyDialog.d.ts +2 -1
- package/lib/dialogs/symbology/symbologyUtils.d.ts +2 -2
- package/lib/dialogs/symbology/symbologyUtils.js +58 -40
- package/lib/dialogs/symbology/tiff_layer/types/SingleBandPseudoColor.js +14 -2
- package/lib/dialogs/symbology/vector_layer/VectorRendering.js +6 -5
- package/lib/dialogs/symbology/vector_layer/components/ValueSelect.js +3 -1
- package/lib/dialogs/symbology/vector_layer/types/Canonical.js +70 -5
- package/lib/dialogs/symbology/vector_layer/types/Categorized.js +81 -34
- package/lib/dialogs/symbology/vector_layer/types/Graduated.js +155 -43
- package/lib/dialogs/symbology/vector_layer/types/SimpleSymbol.js +31 -16
- package/lib/formbuilder/formselectors.js +4 -1
- package/lib/formbuilder/objectform/components/WmsTileSourceUrlInput.d.ts +3 -0
- package/lib/formbuilder/objectform/components/WmsTileSourceUrlInput.js +84 -0
- package/lib/formbuilder/objectform/source/index.d.ts +1 -0
- package/lib/formbuilder/objectform/source/index.js +1 -0
- package/lib/formbuilder/objectform/source/wmsTileSource.d.ts +4 -0
- package/lib/formbuilder/objectform/source/wmsTileSource.js +78 -0
- package/lib/formbuilder/objectform/useSchemaFormState.d.ts +1 -1
- package/lib/mainview/mainView.d.ts +3 -1
- package/lib/mainview/mainView.js +170 -23
- package/lib/menus.js +4 -0
- package/lib/panelview/components/layers.js +19 -2
- package/lib/panelview/components/legendItem.js +14 -4
- package/lib/panelview/filter-panel/Filter.d.ts +3 -0
- package/lib/panelview/filter-panel/Filter.js +9 -9
- package/lib/panelview/leftpanel.js +0 -7
- package/lib/panelview/story-maps/SpectaPanel.js +2 -2
- package/lib/panelview/story-maps/StoryViewerPanel.d.ts +1 -2
- package/lib/panelview/story-maps/StoryViewerPanel.js +1 -1
- package/lib/panelview/story-maps/components/SpectaDesktopView.d.ts +2 -1
- package/lib/panelview/story-maps/components/SpectaDesktopView.js +4 -4
- package/lib/panelview/story-maps/hooks/useStoryMap.d.ts +1 -0
- package/lib/panelview/story-maps/hooks/useStoryMap.js +3 -0
- package/lib/stacBrowser/components/filter-extension/QueryableComboBox.js +61 -20
- package/lib/stacBrowser/hooks/useStacFilterExtension.d.ts +1 -1
- package/lib/stacBrowser/hooks/useStacFilterExtension.js +195 -111
- package/lib/stacBrowser/hooks/useStacSearch.d.ts +1 -0
- package/lib/stacBrowser/hooks/useStacSearch.js +18 -10
- package/lib/tools.d.ts +1 -1
- package/lib/tools.js +3 -3
- package/lib/types.d.ts +7 -1
- package/package.json +5 -2
- package/style/shared/button.css +2 -5
- package/style/shared/input.css +2 -2
- package/style/shared/tabs.css +2 -2
- package/style/storyPanel.css +7 -0
- package/style/symbologyDialog.css +45 -1
package/lib/mainview/mainView.js
CHANGED
|
@@ -9,11 +9,11 @@ var __rest = (this && this.__rest) || function (s, e) {
|
|
|
9
9
|
}
|
|
10
10
|
return t;
|
|
11
11
|
};
|
|
12
|
-
import { JupyterGISModel, } from '@jupytergis/schema';
|
|
12
|
+
import { JupyterGISModel, DEFAULT_PROJECTION, } from '@jupytergis/schema';
|
|
13
13
|
import { showErrorMessage } from '@jupyterlab/apputils';
|
|
14
14
|
import { CommandRegistry } from '@lumino/commands';
|
|
15
15
|
import { UUID } from '@lumino/coreutils';
|
|
16
|
-
import { ContextMenu } from '@lumino/widgets';
|
|
16
|
+
import { ContextMenu, Menu } from '@lumino/widgets';
|
|
17
17
|
import { Collection, Map as OlMap, View, getUid, } from 'ol';
|
|
18
18
|
import Feature from 'ol/Feature';
|
|
19
19
|
import { FullScreen, ScaleLine, Zoom } from 'ol/control';
|
|
@@ -27,7 +27,7 @@ import TileLayer from 'ol/layer/Tile';
|
|
|
27
27
|
import { fromLonLat, get as getProjection, toLonLat, transformExtent, } from 'ol/proj';
|
|
28
28
|
import { register } from 'ol/proj/proj4.js';
|
|
29
29
|
import RenderFeature, { toGeometry } from 'ol/render/Feature';
|
|
30
|
-
import { GeoTIFF as GeoTIFFSource, ImageTile as ImageTileSource, Vector as VectorSource, VectorTile as VectorTileSource, XYZ as XYZSource, Tile as TileSource, } from 'ol/source';
|
|
30
|
+
import { GeoTIFF as GeoTIFFSource, ImageTile as ImageTileSource, TileWMS as TileWMSSource, Vector as VectorSource, VectorTile as VectorTileSource, XYZ as XYZSource, Tile as TileSource, } from 'ol/source';
|
|
31
31
|
import Static from 'ol/source/ImageStatic';
|
|
32
32
|
import { Circle, Fill, Icon, Stroke, Style } from 'ol/style';
|
|
33
33
|
//@ts-expect-error no types for ol-pmtiles
|
|
@@ -161,11 +161,54 @@ export class MainView extends React.Component {
|
|
|
161
161
|
});
|
|
162
162
|
},
|
|
163
163
|
});
|
|
164
|
+
this._commands.addCommand('Copy-Coordinates-Map-CRS', {
|
|
165
|
+
label: () => {
|
|
166
|
+
if (!this._Map || !this._clickCoords) {
|
|
167
|
+
return 'Map CRS';
|
|
168
|
+
}
|
|
169
|
+
const proj = this._Map.getView().getProjection().getCode();
|
|
170
|
+
const coord = this._clickCoords;
|
|
171
|
+
return `Map CRS — ${proj} (${coord[0].toFixed(0)}E, ${coord[1].toFixed(0)}N)`;
|
|
172
|
+
},
|
|
173
|
+
execute: async () => {
|
|
174
|
+
const coord = this._clickCoords;
|
|
175
|
+
const text = `${coord[0].toFixed(0)}, ${coord[1].toFixed(0)}`;
|
|
176
|
+
await navigator.clipboard.writeText(text);
|
|
177
|
+
},
|
|
178
|
+
});
|
|
179
|
+
this._commands.addCommand('Copy-Coordinates-LonLat', {
|
|
180
|
+
label: () => {
|
|
181
|
+
if (!this._Map || !this._clickCoords) {
|
|
182
|
+
return 'Latitude/Longitude';
|
|
183
|
+
}
|
|
184
|
+
const lonLat = toLonLat(this._clickCoords, this._Map.getView().getProjection());
|
|
185
|
+
return `Latitude/Longitude: (${lonLat[1].toFixed(6)}N, ${lonLat[0].toFixed(6)}E)`;
|
|
186
|
+
},
|
|
187
|
+
execute: async () => {
|
|
188
|
+
const lonLat = toLonLat(this._clickCoords, this._Map.getView().getProjection());
|
|
189
|
+
const text = `${lonLat[1].toFixed(6)}, ${lonLat[0].toFixed(6)}`;
|
|
190
|
+
await navigator.clipboard.writeText(text);
|
|
191
|
+
},
|
|
192
|
+
});
|
|
164
193
|
this._contextMenu.addItem({
|
|
165
194
|
command: CommandIDs.addAnnotation,
|
|
166
195
|
selector: '.ol-viewport',
|
|
167
196
|
rank: 1,
|
|
168
197
|
});
|
|
198
|
+
const copyCoordinatesMenu = new Menu({ commands: this._commands });
|
|
199
|
+
copyCoordinatesMenu.title.label = 'Copy Coordinates';
|
|
200
|
+
copyCoordinatesMenu.addItem({
|
|
201
|
+
command: 'Copy-Coordinates-Map-CRS',
|
|
202
|
+
});
|
|
203
|
+
copyCoordinatesMenu.addItem({
|
|
204
|
+
command: 'Copy-Coordinates-LonLat',
|
|
205
|
+
});
|
|
206
|
+
this._contextMenu.addItem({
|
|
207
|
+
type: 'submenu',
|
|
208
|
+
submenu: copyCoordinatesMenu,
|
|
209
|
+
selector: '.ol-viewport',
|
|
210
|
+
rank: 2,
|
|
211
|
+
});
|
|
169
212
|
};
|
|
170
213
|
this.vectorLayerStyleRuleBuilder = (layer) => {
|
|
171
214
|
var _a, _b;
|
|
@@ -213,6 +256,70 @@ export class MainView extends React.Component {
|
|
|
213
256
|
}
|
|
214
257
|
const newStyle = Object.assign(Object.assign({}, defaultStyle), layerParams.color);
|
|
215
258
|
layerStyle.style = newStyle;
|
|
259
|
+
// When fallbackColor[3] === 0, add an OL filter so features that would be
|
|
260
|
+
// drawn with a transparent color are excluded from rendering entirely.
|
|
261
|
+
// alpha === 0 is the contract: the default TRANSPARENT [0,0,0,0] triggers
|
|
262
|
+
// this automatically, and a future dedicated picker option can set it.
|
|
263
|
+
const symbologyState = layerParams.symbologyState;
|
|
264
|
+
if (Array.isArray(symbologyState === null || symbologyState === void 0 ? void 0 : symbologyState.fallbackColor) &&
|
|
265
|
+
symbologyState.fallbackColor[3] === 0) {
|
|
266
|
+
let matchFilter;
|
|
267
|
+
if (symbologyState.renderType === 'Categorized') {
|
|
268
|
+
const fillExpr = layerParams.color['fill-color'];
|
|
269
|
+
if (Array.isArray(fillExpr) &&
|
|
270
|
+
fillExpr[0] === 'case' &&
|
|
271
|
+
fillExpr.length >= 4) {
|
|
272
|
+
// Extract conditions from ['case', cond, val, cond, val, ..., fallback],
|
|
273
|
+
// skipping any whose matched output color is also fully transparent.
|
|
274
|
+
const conditions = [];
|
|
275
|
+
for (let i = 1; i < fillExpr.length - 1; i += 2) {
|
|
276
|
+
const output = fillExpr[i + 1];
|
|
277
|
+
if (Array.isArray(output) && output[3] === 0) {
|
|
278
|
+
continue;
|
|
279
|
+
}
|
|
280
|
+
conditions.push(fillExpr[i]);
|
|
281
|
+
}
|
|
282
|
+
// If every stop is transparent, use a never-true filter to hide all.
|
|
283
|
+
matchFilter =
|
|
284
|
+
conditions.length === 0
|
|
285
|
+
? ['==', 0, 1]
|
|
286
|
+
: conditions.length === 1
|
|
287
|
+
? conditions[0]
|
|
288
|
+
: ['any', ...conditions];
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
else if (symbologyState.renderType === 'Graduated') {
|
|
292
|
+
const fillExpr = layerParams.color['fill-color'];
|
|
293
|
+
// Graduated fill is ['case', ['has', field], interpolateExpr, fallback].
|
|
294
|
+
// Features missing the attribute fall through to the fallback, so filter
|
|
295
|
+
// them out with the same ['has', field] condition.
|
|
296
|
+
if (Array.isArray(fillExpr) &&
|
|
297
|
+
fillExpr[0] === 'case' &&
|
|
298
|
+
Array.isArray(fillExpr[1]) &&
|
|
299
|
+
fillExpr[1][0] === 'has') {
|
|
300
|
+
matchFilter = fillExpr[1];
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
else if (symbologyState.renderType === 'Canonical') {
|
|
304
|
+
const fillExpr = layerParams.color['fill-color'];
|
|
305
|
+
// Canonical fill is ['coalesce', ['get', field], fallback].
|
|
306
|
+
// Features missing the attribute fall through to the fallback, so filter
|
|
307
|
+
// them out with ['has', field]. Note: features that have the field but
|
|
308
|
+
// with a non-color value also get the fallback — that gap is accepted.
|
|
309
|
+
if (Array.isArray(fillExpr) &&
|
|
310
|
+
fillExpr[0] === 'coalesce' &&
|
|
311
|
+
Array.isArray(fillExpr[1]) &&
|
|
312
|
+
fillExpr[1][0] === 'get') {
|
|
313
|
+
matchFilter = ['has', fillExpr[1][1]];
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
if (matchFilter) {
|
|
317
|
+
// Combine with any existing user-applied filter.
|
|
318
|
+
layerStyle.filter = layerStyle.filter
|
|
319
|
+
? ['all', layerStyle.filter, matchFilter]
|
|
320
|
+
: matchFilter;
|
|
321
|
+
}
|
|
322
|
+
}
|
|
216
323
|
return [layerStyle];
|
|
217
324
|
};
|
|
218
325
|
/**
|
|
@@ -268,7 +375,7 @@ export class MainView extends React.Component {
|
|
|
268
375
|
* to work with the temporal controller
|
|
269
376
|
*/
|
|
270
377
|
this.handleTemporalController = (id, layer) => {
|
|
271
|
-
var _a, _b, _c, _d, _e, _f;
|
|
378
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j;
|
|
272
379
|
const selectedLayer = (_c = (_b = (_a = this._model) === null || _a === void 0 ? void 0 : _a.localState) === null || _b === void 0 ? void 0 : _b.selected) === null || _c === void 0 ? void 0 : _c.value;
|
|
273
380
|
// Temporal Controller shouldn't be active if more than one layer is selected
|
|
274
381
|
if (!selectedLayer || Object.keys(selectedLayer).length !== 1) {
|
|
@@ -286,13 +393,13 @@ export class MainView extends React.Component {
|
|
|
286
393
|
const activeFilter = layer.filters.appliedFilters[0];
|
|
287
394
|
// Save original features on first filter application
|
|
288
395
|
if (!Object.keys(this._originalFeatures).includes(id)) {
|
|
289
|
-
this._originalFeatures[id] = source.getFeatures();
|
|
396
|
+
this._originalFeatures[id] = (_e = source.getFeatures()) !== null && _e !== void 0 ? _e : [];
|
|
290
397
|
}
|
|
291
398
|
// clear current features
|
|
292
399
|
source.clear();
|
|
293
|
-
const startTime = (
|
|
294
|
-
const endTime = (
|
|
295
|
-
const filteredFeatures = this._originalFeatures[id].filter(feature => {
|
|
400
|
+
const startTime = (_f = activeFilter.betweenMin) !== null && _f !== void 0 ? _f : 0;
|
|
401
|
+
const endTime = (_g = activeFilter.betweenMax) !== null && _g !== void 0 ? _g : 1000;
|
|
402
|
+
const filteredFeatures = ((_h = this._originalFeatures[id]) !== null && _h !== void 0 ? _h : []).filter(feature => {
|
|
296
403
|
const featureTime = feature.get(activeFilter.feature);
|
|
297
404
|
return featureTime >= startTime && featureTime <= endTime;
|
|
298
405
|
});
|
|
@@ -302,7 +409,7 @@ export class MainView extends React.Component {
|
|
|
302
409
|
}
|
|
303
410
|
else {
|
|
304
411
|
// Restore original features when no filters are applied
|
|
305
|
-
source.addFeatures(this._originalFeatures[id]);
|
|
412
|
+
source.addFeatures((_j = this._originalFeatures[id]) !== null && _j !== void 0 ? _j : []);
|
|
306
413
|
delete this._originalFeatures[id];
|
|
307
414
|
}
|
|
308
415
|
};
|
|
@@ -421,6 +528,11 @@ export class MainView extends React.Component {
|
|
|
421
528
|
this._setupSpectaMode = () => {
|
|
422
529
|
this._removeAllInteractions();
|
|
423
530
|
this._setupStoryScrollListener();
|
|
531
|
+
// Ensure keybindings have a focused target in Specta mode.
|
|
532
|
+
window.requestAnimationFrame(() => {
|
|
533
|
+
var _a;
|
|
534
|
+
(_a = this.mainViewRef.current) === null || _a === void 0 ? void 0 : _a.focus();
|
|
535
|
+
});
|
|
424
536
|
};
|
|
425
537
|
this._removeAllInteractions = () => {
|
|
426
538
|
// Remove all default interactions
|
|
@@ -555,6 +667,7 @@ export class MainView extends React.Component {
|
|
|
555
667
|
});
|
|
556
668
|
this.setState(old => (Object.assign(Object.assign({}, old), { annotations: newState })));
|
|
557
669
|
};
|
|
670
|
+
this._lastPointerCoord = null;
|
|
558
671
|
this._syncPointer = throttle((coordinates) => {
|
|
559
672
|
const pointer = {
|
|
560
673
|
coordinates: { x: coordinates[0], y: coordinates[1] },
|
|
@@ -597,6 +710,7 @@ export class MainView extends React.Component {
|
|
|
597
710
|
};
|
|
598
711
|
this._isPositionInitialized = false;
|
|
599
712
|
this.divRef = React.createRef(); // Reference of render div
|
|
713
|
+
this.mainViewRef = React.createRef();
|
|
600
714
|
this.controlsToolbarRef = React.createRef();
|
|
601
715
|
this.spectaContainerRef = React.createRef();
|
|
602
716
|
this.storyViewerPanelRef = React.createRef();
|
|
@@ -683,13 +797,15 @@ export class MainView extends React.Component {
|
|
|
683
797
|
this._updateCenter = debounce(this.updateCenter, 100);
|
|
684
798
|
}
|
|
685
799
|
async componentDidMount() {
|
|
800
|
+
var _a;
|
|
686
801
|
window.addEventListener('resize', this._handleWindowResize);
|
|
687
802
|
const options = this._model.getOptions();
|
|
803
|
+
const projection = (_a = options.projection) !== null && _a !== void 0 ? _a : DEFAULT_PROJECTION;
|
|
688
804
|
const center = options.longitude !== undefined && options.latitude !== undefined
|
|
689
|
-
? fromLonLat([options.longitude, options.latitude])
|
|
805
|
+
? fromLonLat([options.longitude, options.latitude], projection)
|
|
690
806
|
: [0, 0];
|
|
691
807
|
const zoom = options.zoom !== undefined ? options.zoom : 1;
|
|
692
|
-
await this.generateMap(center, zoom);
|
|
808
|
+
await this.generateMap(center, zoom, projection);
|
|
693
809
|
this._mainViewModel.initSignal();
|
|
694
810
|
if (window.jupytergisMaps !== undefined && this._documentPath) {
|
|
695
811
|
window.jupytergisMaps[this._documentPath] = this._Map;
|
|
@@ -717,7 +833,7 @@ export class MainView extends React.Component {
|
|
|
717
833
|
this._cleanupStoryScrollListener();
|
|
718
834
|
this._mainViewModel.dispose();
|
|
719
835
|
}
|
|
720
|
-
async generateMap(center, zoom) {
|
|
836
|
+
async generateMap(center, zoom, projection = DEFAULT_PROJECTION) {
|
|
721
837
|
const layers = this._model.getLayers();
|
|
722
838
|
this._initialLayersCount = Object.values(layers).filter(layer => layer.type !== 'StorySegmentLayer').length;
|
|
723
839
|
const scaleLine = new ScaleLine({
|
|
@@ -741,6 +857,7 @@ export class MainView extends React.Component {
|
|
|
741
857
|
view: new View({
|
|
742
858
|
center,
|
|
743
859
|
zoom,
|
|
860
|
+
projection,
|
|
744
861
|
}),
|
|
745
862
|
controls,
|
|
746
863
|
});
|
|
@@ -803,11 +920,12 @@ export class MainView extends React.Component {
|
|
|
803
920
|
}
|
|
804
921
|
});
|
|
805
922
|
this._Map.on('moveend', () => {
|
|
923
|
+
var _a;
|
|
806
924
|
const currentOptions = this._model.getOptions();
|
|
807
925
|
const view = this._Map.getView();
|
|
808
926
|
const center = view.getCenter() || [0, 0];
|
|
809
927
|
const zoom = view.getZoom() || 0;
|
|
810
|
-
const projection = view.getProjection();
|
|
928
|
+
const projection = (_a = getProjection(currentOptions.projection)) !== null && _a !== void 0 ? _a : view.getProjection();
|
|
811
929
|
const latLng = toLonLat(center, projection);
|
|
812
930
|
const bearing = view.getRotation();
|
|
813
931
|
const resolution = view.getResolution();
|
|
@@ -842,14 +960,18 @@ export class MainView extends React.Component {
|
|
|
842
960
|
this._Map.getViewport().addEventListener('contextmenu', event => {
|
|
843
961
|
event.preventDefault();
|
|
844
962
|
event.stopPropagation();
|
|
845
|
-
|
|
846
|
-
|
|
963
|
+
if (this._lastPointerCoord) {
|
|
964
|
+
this._clickCoords = this._lastPointerCoord;
|
|
965
|
+
}
|
|
847
966
|
this._contextMenu.open(event);
|
|
848
967
|
});
|
|
849
|
-
this.setState(old =>
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
968
|
+
this.setState(old => {
|
|
969
|
+
var _a;
|
|
970
|
+
return (Object.assign(Object.assign({}, old), { loading: false, viewProjection: {
|
|
971
|
+
code: projection,
|
|
972
|
+
units: ((_a = getProjection(projection)) !== null && _a !== void 0 ? _a : view.getProjection()).getUnits(),
|
|
973
|
+
} }));
|
|
974
|
+
});
|
|
853
975
|
}
|
|
854
976
|
}
|
|
855
977
|
/**
|
|
@@ -859,7 +981,7 @@ export class MainView extends React.Component {
|
|
|
859
981
|
* @param source - the source object.
|
|
860
982
|
*/
|
|
861
983
|
async addSource(id, source) {
|
|
862
|
-
var _a, _b;
|
|
984
|
+
var _a, _b, _c;
|
|
863
985
|
let newSource;
|
|
864
986
|
switch (source.type) {
|
|
865
987
|
case 'RasterSource': {
|
|
@@ -1074,6 +1196,21 @@ export class MainView extends React.Component {
|
|
|
1074
1196
|
newSource = new VectorSource({
|
|
1075
1197
|
features: [marker],
|
|
1076
1198
|
});
|
|
1199
|
+
break;
|
|
1200
|
+
}
|
|
1201
|
+
case 'WmsTileSource': {
|
|
1202
|
+
const sourceParameters = source.parameters;
|
|
1203
|
+
const url = sourceParameters.url;
|
|
1204
|
+
const selectedLayer = (_c = sourceParameters === null || sourceParameters === void 0 ? void 0 : sourceParameters.params) === null || _c === void 0 ? void 0 : _c.layers;
|
|
1205
|
+
newSource = new TileWMSSource({
|
|
1206
|
+
attributions: sourceParameters === null || sourceParameters === void 0 ? void 0 : sourceParameters.attribution,
|
|
1207
|
+
url,
|
|
1208
|
+
params: {
|
|
1209
|
+
LAYERS: selectedLayer,
|
|
1210
|
+
TILED: true,
|
|
1211
|
+
},
|
|
1212
|
+
});
|
|
1213
|
+
break;
|
|
1077
1214
|
}
|
|
1078
1215
|
}
|
|
1079
1216
|
newSource.set('id', id);
|
|
@@ -1580,6 +1717,9 @@ export class MainView extends React.Component {
|
|
|
1580
1717
|
}
|
|
1581
1718
|
}
|
|
1582
1719
|
_onSharedOptionsChanged() {
|
|
1720
|
+
if (!this._Map) {
|
|
1721
|
+
return;
|
|
1722
|
+
}
|
|
1583
1723
|
// ! would prefer a model ready signal or something, this feels hacky
|
|
1584
1724
|
const enableSpectaPresentation = this._model.isSpectaMode();
|
|
1585
1725
|
// Handle initialization based on specta presentation state
|
|
@@ -1632,6 +1772,12 @@ export class MainView extends React.Component {
|
|
|
1632
1772
|
if (projection !== undefined && currentProjection !== projection) {
|
|
1633
1773
|
const newProjection = getProjection(projection);
|
|
1634
1774
|
if (newProjection) {
|
|
1775
|
+
this.setState(old => ({
|
|
1776
|
+
viewProjection: {
|
|
1777
|
+
code: newProjection.getCode(),
|
|
1778
|
+
units: newProjection.getUnits(),
|
|
1779
|
+
},
|
|
1780
|
+
}));
|
|
1635
1781
|
view = new View({ projection: newProjection });
|
|
1636
1782
|
}
|
|
1637
1783
|
else {
|
|
@@ -1639,6 +1785,8 @@ export class MainView extends React.Component {
|
|
|
1639
1785
|
return;
|
|
1640
1786
|
}
|
|
1641
1787
|
}
|
|
1788
|
+
view.setRotation(bearing || 0);
|
|
1789
|
+
this._Map.setView(view);
|
|
1642
1790
|
// Use the extent only if explicitly requested (QGIS files).
|
|
1643
1791
|
if (useExtent && extent) {
|
|
1644
1792
|
view.fit(extent);
|
|
@@ -1652,8 +1800,6 @@ export class MainView extends React.Component {
|
|
|
1652
1800
|
this._model.setOptions(options);
|
|
1653
1801
|
}
|
|
1654
1802
|
}
|
|
1655
|
-
view.setRotation(bearing || 0);
|
|
1656
|
-
this._Map.setView(view);
|
|
1657
1803
|
}
|
|
1658
1804
|
_onViewChanged(sender, change) {
|
|
1659
1805
|
// TODO SOMETHING
|
|
@@ -1932,6 +2078,7 @@ export class MainView extends React.Component {
|
|
|
1932
2078
|
_onPointerMove(e) {
|
|
1933
2079
|
const pixel = this._Map.getEventPixel(e);
|
|
1934
2080
|
const coordinates = this._Map.getCoordinateFromPixel(pixel);
|
|
2081
|
+
this._lastPointerCoord = coordinates;
|
|
1935
2082
|
this._syncPointer(coordinates);
|
|
1936
2083
|
}
|
|
1937
2084
|
async _addMarker(e) {
|
|
@@ -2107,7 +2254,7 @@ export class MainView extends React.Component {
|
|
|
2107
2254
|
}),
|
|
2108
2255
|
React.createElement("div", { className: "jGIS-Mainview-Container" },
|
|
2109
2256
|
this.state.displayTemporalController && (React.createElement(TemporalSlider, { model: this._model, filterStates: this.state.filterStates })),
|
|
2110
|
-
React.createElement("div", { className: "jGIS-Mainview data-jgis-keybinding", tabIndex: 0, style: {
|
|
2257
|
+
React.createElement("div", { ref: this.mainViewRef, className: "jGIS-Mainview data-jgis-keybinding", tabIndex: 0, style: {
|
|
2111
2258
|
border: this.state.remoteUser
|
|
2112
2259
|
? `solid 3px ${this.state.remoteUser.color}`
|
|
2113
2260
|
: 'unset',
|
package/lib/menus.js
CHANGED
|
@@ -33,6 +33,10 @@ export const rasterSubMenu = (commands) => {
|
|
|
33
33
|
type: 'command',
|
|
34
34
|
command: CommandIDs.openNewRasterDialog,
|
|
35
35
|
});
|
|
36
|
+
subMenu.addItem({
|
|
37
|
+
type: 'command',
|
|
38
|
+
command: CommandIDs.openNewWmsDialog,
|
|
39
|
+
});
|
|
36
40
|
subMenu.addItem({
|
|
37
41
|
type: 'command',
|
|
38
42
|
command: CommandIDs.openNewHillshadeDialog,
|
|
@@ -1,3 +1,14 @@
|
|
|
1
|
+
var __rest = (this && this.__rest) || function (s, e) {
|
|
2
|
+
var t = {};
|
|
3
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
|
|
4
|
+
t[p] = s[p];
|
|
5
|
+
if (s != null && typeof Object.getOwnPropertySymbols === "function")
|
|
6
|
+
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
|
|
7
|
+
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
|
|
8
|
+
t[p[i]] = s[p[i]];
|
|
9
|
+
}
|
|
10
|
+
return t;
|
|
11
|
+
};
|
|
1
12
|
import { DOMUtils } from '@jupyterlab/apputils';
|
|
2
13
|
import { Button, LabIcon, caretDownIcon, caretRightIcon, } from '@jupyterlab/ui-components';
|
|
3
14
|
import React, { useEffect, useState, } from 'react';
|
|
@@ -104,8 +115,14 @@ export const LayersBodyComponent = props => {
|
|
|
104
115
|
};
|
|
105
116
|
}
|
|
106
117
|
else {
|
|
107
|
-
// If types are the same
|
|
108
|
-
|
|
118
|
+
// If types are the same modify the selection (either add or remove to multi-selection)
|
|
119
|
+
if (item in selectedValue) {
|
|
120
|
+
const _a = selectedValue, _b = item, _ = _a[_b], rest = __rest(_a, [typeof _b === "symbol" ? _b : _b + ""]);
|
|
121
|
+
newSelection = rest;
|
|
122
|
+
}
|
|
123
|
+
else {
|
|
124
|
+
newSelection = Object.assign(Object.assign({}, selectedValue), { [item]: { type } });
|
|
125
|
+
}
|
|
109
126
|
}
|
|
110
127
|
}
|
|
111
128
|
// Set the selection
|
|
@@ -1,16 +1,18 @@
|
|
|
1
1
|
import React, { useEffect, useState } from 'react';
|
|
2
|
+
import { findExprNode } from "../../dialogs/symbology/colorRampUtils";
|
|
2
3
|
import { useGetSymbology } from "../../dialogs/symbology/hooks/useGetSymbology";
|
|
3
4
|
export const LegendItem = ({ layerId, model }) => {
|
|
4
5
|
const { symbology, isLoading, error } = useGetSymbology({ layerId, model });
|
|
5
6
|
const [content, setContent] = useState(null);
|
|
6
7
|
const parseColorStops = (expr) => {
|
|
7
|
-
|
|
8
|
+
const interpolate = findExprNode(expr, 'interpolate');
|
|
9
|
+
if (!interpolate) {
|
|
8
10
|
return [];
|
|
9
11
|
}
|
|
10
12
|
const stops = [];
|
|
11
|
-
for (let i = 3; i <
|
|
12
|
-
const value =
|
|
13
|
-
const rgba =
|
|
13
|
+
for (let i = 3; i < interpolate.length; i += 2) {
|
|
14
|
+
const value = interpolate[i];
|
|
15
|
+
const rgba = interpolate[i + 1];
|
|
14
16
|
const color = Array.isArray(rgba)
|
|
15
17
|
? `rgba(${rgba[0]},${rgba[1]},${rgba[2]},${rgba[3]})`
|
|
16
18
|
: String(rgba);
|
|
@@ -130,6 +132,14 @@ export const LegendItem = ({ layerId, model }) => {
|
|
|
130
132
|
}))));
|
|
131
133
|
return;
|
|
132
134
|
}
|
|
135
|
+
// Canonical
|
|
136
|
+
if (renderType === 'Canonical') {
|
|
137
|
+
setContent(React.createElement("div", { style: { padding: 6 } },
|
|
138
|
+
property && (React.createElement("div", { style: { fontSize: '1em' } },
|
|
139
|
+
React.createElement("strong", null, property))),
|
|
140
|
+
React.createElement("div", { style: { fontSize: '0.8em', opacity: 0.7 } }, "hex color attribute")));
|
|
141
|
+
return;
|
|
142
|
+
}
|
|
133
143
|
// Categorized
|
|
134
144
|
if (renderType === 'Categorized') {
|
|
135
145
|
const cats = parseCaseCategories(fill || stroke);
|
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
import { IJupyterGISModel } from '@jupytergis/schema';
|
|
2
|
+
import { PromiseDelegate } from '@lumino/coreutils';
|
|
3
|
+
import { Signal } from '@lumino/signaling';
|
|
2
4
|
import React from 'react';
|
|
3
5
|
interface IFilterComponentProps {
|
|
4
6
|
model: IJupyterGISModel;
|
|
7
|
+
okSignalPromise: PromiseDelegate<Signal<any, null>>;
|
|
5
8
|
}
|
|
6
9
|
declare const FilterComponent: React.FC<IFilterComponentProps>;
|
|
7
10
|
export default FilterComponent;
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import { Button } from '@jupyterlab/ui-components';
|
|
2
2
|
import { cloneDeep } from 'lodash';
|
|
3
3
|
import React, { useEffect, useRef, useState } from 'react';
|
|
4
|
+
import { useOkSignal } from "../../dialogs/symbology/hooks/useOkSignal";
|
|
4
5
|
import { debounce, loadFile } from "../../tools";
|
|
5
6
|
import FilterRow from './FilterRow';
|
|
6
|
-
const FilterComponent = ({ model }) => {
|
|
7
|
+
const FilterComponent = ({ model, okSignalPromise, }) => {
|
|
7
8
|
const featuresInLayerRef = useRef({});
|
|
8
9
|
const [logicalOp, setLogicalOp] = useState('all');
|
|
9
10
|
const [selectedLayer, setSelectedLayer] = useState('');
|
|
@@ -48,6 +49,9 @@ const FilterComponent = ({ model }) => {
|
|
|
48
49
|
model === null || model === void 0 ? void 0 : model.sharedOptionsChanged.disconnect(handleSharedOptionsChanged);
|
|
49
50
|
};
|
|
50
51
|
}, [model]);
|
|
52
|
+
useOkSignal(okSignalPromise, () => {
|
|
53
|
+
updateLayerFilters(filterRows, logicalOp);
|
|
54
|
+
});
|
|
51
55
|
useEffect(() => {
|
|
52
56
|
var _a, _b, _c, _d;
|
|
53
57
|
// Reset filter stuff for new layer
|
|
@@ -141,9 +145,6 @@ const FilterComponent = ({ model }) => {
|
|
|
141
145
|
updateLayerFilters([]);
|
|
142
146
|
setFilterRows([]);
|
|
143
147
|
};
|
|
144
|
-
const submitFilter = () => {
|
|
145
|
-
updateLayerFilters(filterRows);
|
|
146
|
-
};
|
|
147
148
|
const updateLayerFilters = (filters, op) => {
|
|
148
149
|
const layer = model === null || model === void 0 ? void 0 : model.getLayer(selectedLayer);
|
|
149
150
|
if (!layer) {
|
|
@@ -158,17 +159,16 @@ const FilterComponent = ({ model }) => {
|
|
|
158
159
|
return (React.createElement(React.Fragment, null,
|
|
159
160
|
shouldDisplay && (React.createElement("div", { className: "jp-gis-filter-main" },
|
|
160
161
|
React.createElement("div", { id: "filter-container", className: "jp-gis-filter-select-container" },
|
|
161
|
-
React.createElement("select", { className: "jp-mod-styled rjsf jp-gis-logical-select", onChange: handleLogicalOpChange },
|
|
162
|
-
React.createElement("option", {
|
|
163
|
-
React.createElement("option", {
|
|
162
|
+
React.createElement("select", { className: "jp-mod-styled rjsf jp-gis-logical-select", value: logicalOp, onChange: handleLogicalOpChange },
|
|
163
|
+
React.createElement("option", { value: "all" }, "All"),
|
|
164
|
+
React.createElement("option", { value: "any" }, "Any")),
|
|
164
165
|
filterRows.map((row, index) => (React.createElement(FilterRow, { key: index, index: index, features: featuresInLayer, filterRows: filterRows, setFilterRows: setFilterRows, deleteRow: () => deleteRow(index) })))),
|
|
165
166
|
React.createElement("div", { className: "jp-gis-filter-button-container" },
|
|
166
167
|
React.createElement("div", { style: {
|
|
167
168
|
justifyContent: 'flex-start',
|
|
168
169
|
} },
|
|
169
170
|
React.createElement(Button, { className: "jp-Dialog-button jp-mod-accept jp-mod-styled", onClick: addFilterRow, "data-testid": "add-filter-button" }, "Add"),
|
|
170
|
-
React.createElement(Button, { className: "jp-Dialog-button jp-mod-reject jp-mod-styled", onClick: clearFilters }, "Clear")),
|
|
171
|
-
React.createElement(Button, { className: "jp-Dialog-button jp-mod-accept jp-mod-styled", onClick: submitFilter }, "Submit")))),
|
|
171
|
+
React.createElement(Button, { className: "jp-Dialog-button jp-mod-reject jp-mod-styled", onClick: clearFilters }, "Clear"))))),
|
|
172
172
|
!shouldDisplay && (React.createElement("div", { style: { textAlign: 'center' } }, "No layer selected"))));
|
|
173
173
|
};
|
|
174
174
|
export default FilterComponent;
|
|
@@ -2,7 +2,6 @@ import * as React from 'react';
|
|
|
2
2
|
import Draggable from 'react-draggable';
|
|
3
3
|
import { CommandIDs } from '../constants';
|
|
4
4
|
import { LayersBodyComponent } from './components/layers';
|
|
5
|
-
import FilterComponent from './filter-panel/Filter';
|
|
6
5
|
import { PanelTabs, TabsContent, TabsList, TabsTrigger, } from '../shared/components/Tabs';
|
|
7
6
|
import StacPanel from '../stacBrowser/components/StacPanel';
|
|
8
7
|
export const LeftPanel = (props) => {
|
|
@@ -18,9 +17,6 @@ export const LeftPanel = (props) => {
|
|
|
18
17
|
!props.settings.stacBrowserDisabled && !storyMapPresentationMode
|
|
19
18
|
? { name: 'stac', title: 'Stac Browser' }
|
|
20
19
|
: false,
|
|
21
|
-
!props.settings.filtersDisabled && !storyMapPresentationMode
|
|
22
|
-
? { name: 'filters', title: 'Filters' }
|
|
23
|
-
: false,
|
|
24
20
|
!props.settings.storyMapsDisabled
|
|
25
21
|
? { name: 'segments', title: 'Segments' }
|
|
26
22
|
: false,
|
|
@@ -121,7 +117,6 @@ export const LeftPanel = (props) => {
|
|
|
121
117
|
}, [storySegmentLayerTree]);
|
|
122
118
|
const allLeftTabsDisabled = props.settings.layersDisabled &&
|
|
123
119
|
props.settings.stacBrowserDisabled &&
|
|
124
|
-
props.settings.filtersDisabled &&
|
|
125
120
|
props.settings.storyMapsDisabled;
|
|
126
121
|
const leftPanelVisible = !props.settings.leftPanelDisabled && !allLeftTabsDisabled;
|
|
127
122
|
return (React.createElement(Draggable, { handle: ".jgis-tabs-list", cancel: ".jgis-tabs-trigger", bounds: ".jGIS-Mainview-Container" },
|
|
@@ -139,8 +134,6 @@ export const LeftPanel = (props) => {
|
|
|
139
134
|
React.createElement(LayersBodyComponent, { model: props.model, commands: props.commands, state: props.state, layerTree: filteredLayerTree }))),
|
|
140
135
|
!props.settings.stacBrowserDisabled && (React.createElement(TabsContent, { value: "stac", className: "jgis-panel-tab-content jgis-panel-tab-content-stac-panel" },
|
|
141
136
|
React.createElement(StacPanel, { model: props.model }))),
|
|
142
|
-
!props.settings.filtersDisabled && (React.createElement(TabsContent, { value: "filters", className: "jgis-panel-tab-content" },
|
|
143
|
-
React.createElement(FilterComponent, { model: props.model }))),
|
|
144
137
|
!props.settings.storyMapsDisabled && (React.createElement(TabsContent, { value: "segments", className: "jgis-panel-tab-content" },
|
|
145
138
|
React.createElement(LayersBodyComponent, { model: props.model, commands: props.commands, state: props.state, layerTree: storySegmentLayerTree })))))));
|
|
146
139
|
};
|
|
@@ -5,7 +5,7 @@ import { useStoryMap } from './hooks/useStoryMap';
|
|
|
5
5
|
export function SpectaPanel({ model, isSpecta, isMobile, onSegmentTransitionEnd, containerRef, storyViewerPanelRef, addLayer, removeLayer, }) {
|
|
6
6
|
const overrideLayerEntriesRef = useRef([]);
|
|
7
7
|
const segmentContainerRef = useRef(null);
|
|
8
|
-
const { storyData, currentIndex, setIndex, handlePrev, handleNext, hasPrev, hasNext, activeSlide, layerName, } = useStoryMap({
|
|
8
|
+
const { storyData, currentIndex, setIndex, handlePrev, handleNext, hasPrev, hasNext, activeSlide, layerName, showGradient, } = useStoryMap({
|
|
9
9
|
model,
|
|
10
10
|
overrideLayerEntriesRef,
|
|
11
11
|
removeLayer,
|
|
@@ -31,5 +31,5 @@ export function SpectaPanel({ model, isSpecta, isMobile, onSegmentTransitionEnd,
|
|
|
31
31
|
if (isMobile) {
|
|
32
32
|
return (React.createElement(SpectaMobileView, { model: model, segmentContainerRef: segmentContainerRef, storyData: storyData, currentIndex: currentIndex, activeSlide: activeSlide, layerName: layerName, handlePrev: handlePrev, handleNext: handleNext, hasPrev: hasPrev, hasNext: hasNext, setIndex: setIndex }));
|
|
33
33
|
}
|
|
34
|
-
return (React.createElement(SpectaDesktopView, { model: model, isSpecta: isSpecta, containerRef: containerRef, storyViewerPanelRef: storyViewerPanelRef, segmentContainerRef: segmentContainerRef, storyData: storyData, currentIndex: currentIndex, activeSlide: activeSlide, layerName: layerName, handlePrev: handlePrev, handleNext: handleNext, hasPrev: hasPrev, hasNext: hasNext, setIndex: setIndex }));
|
|
34
|
+
return (React.createElement(SpectaDesktopView, { model: model, isSpecta: isSpecta, containerRef: containerRef, storyViewerPanelRef: storyViewerPanelRef, segmentContainerRef: segmentContainerRef, storyData: storyData, currentIndex: currentIndex, activeSlide: activeSlide, layerName: layerName, handlePrev: handlePrev, handleNext: handleNext, hasPrev: hasPrev, hasNext: hasNext, showGradient: showGradient, setIndex: setIndex }));
|
|
35
35
|
}
|
|
@@ -5,7 +5,6 @@ interface IStoryViewerPanelProps {
|
|
|
5
5
|
model: IJupyterGISModel;
|
|
6
6
|
isSpecta: boolean;
|
|
7
7
|
isMobile?: boolean;
|
|
8
|
-
className?: string;
|
|
9
8
|
/** Ref for the segment container (SpectaPanel uses it for animationend). */
|
|
10
9
|
segmentContainerRef?: RefObject<HTMLDivElement>;
|
|
11
10
|
storyData: IJGISStoryMap | null;
|
|
@@ -41,7 +40,7 @@ export type StoryNavPlacement = 'below-title' | 'over-image' | 'subtitle-specta'
|
|
|
41
40
|
* Story viewer (presentational). Receives story state and callbacks from parent.
|
|
42
41
|
* Desktop scroll/sentinel/imperative handle live in SpectaDesktopView.
|
|
43
42
|
*/
|
|
44
|
-
declare function StoryViewerPanel({ model, isSpecta, isMobile,
|
|
43
|
+
declare function StoryViewerPanel({ model, isSpecta, isMobile, segmentContainerRef, storyData, currentIndex, activeSlide, layerName, handlePrev, handleNext, hasPrev, hasNext, setIndex, }: IStoryViewerPanelProps): React.JSX.Element;
|
|
45
44
|
declare namespace StoryViewerPanel {
|
|
46
45
|
var displayName: string;
|
|
47
46
|
}
|
|
@@ -20,7 +20,7 @@ function getStoryNavPlacement(isSpecta, hasImage, storyType, isMobile) {
|
|
|
20
20
|
* Story viewer (presentational). Receives story state and callbacks from parent.
|
|
21
21
|
* Desktop scroll/sentinel/imperative handle live in SpectaDesktopView.
|
|
22
22
|
*/
|
|
23
|
-
function StoryViewerPanel({ model, isSpecta, isMobile = false,
|
|
23
|
+
function StoryViewerPanel({ model, isSpecta, isMobile = false, segmentContainerRef, storyData, currentIndex, activeSlide, layerName, handlePrev, handleNext, hasPrev, hasNext, setIndex, }) {
|
|
24
24
|
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m;
|
|
25
25
|
const [imageLoaded, setImageLoaded] = useState(false);
|
|
26
26
|
// Prefetch image when slide changes
|
|
@@ -15,7 +15,8 @@ interface ISpectaDesktopViewProps {
|
|
|
15
15
|
handleNext: () => void;
|
|
16
16
|
hasPrev: boolean;
|
|
17
17
|
hasNext: boolean;
|
|
18
|
+
showGradient: boolean;
|
|
18
19
|
setIndex: (index: number) => void;
|
|
19
20
|
}
|
|
20
|
-
export declare function SpectaDesktopView({ model, isSpecta, containerRef, storyViewerPanelRef, segmentContainerRef, storyData, currentIndex, activeSlide, layerName, handlePrev, handleNext, hasPrev, hasNext, setIndex, }: ISpectaDesktopViewProps): JSX.Element;
|
|
21
|
+
export declare function SpectaDesktopView({ model, isSpecta, containerRef, storyViewerPanelRef, segmentContainerRef, storyData, currentIndex, activeSlide, layerName, handlePrev, handleNext, hasPrev, hasNext, showGradient, setIndex, }: ISpectaDesktopViewProps): JSX.Element;
|
|
21
22
|
export {};
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import React, { useEffect, useImperativeHandle, useRef, } from 'react';
|
|
2
2
|
import StoryViewerPanel from "../StoryViewerPanel";
|
|
3
3
|
import SpectaPresentationProgressBar from "../../../statusbar/SpectaPresentationProgressBar";
|
|
4
|
-
export function SpectaDesktopView({ model, isSpecta, containerRef, storyViewerPanelRef, segmentContainerRef, storyData, currentIndex, activeSlide, layerName, handlePrev, handleNext, hasPrev, hasNext, setIndex, }) {
|
|
4
|
+
export function SpectaDesktopView({ model, isSpecta, containerRef, storyViewerPanelRef, segmentContainerRef, storyData, currentIndex, activeSlide, layerName, handlePrev, handleNext, hasPrev, hasNext, showGradient, setIndex, }) {
|
|
5
5
|
const scrollContainerRef = useRef(null);
|
|
6
6
|
const topSentinelRef = useRef(null);
|
|
7
7
|
const bottomSentinelRef = useRef(null);
|
|
@@ -39,11 +39,11 @@ export function SpectaDesktopView({ model, isSpecta, containerRef, storyViewerPa
|
|
|
39
39
|
getScrollContainer: () => scrollContainerRef.current,
|
|
40
40
|
}), [handlePrev, handleNext, isSpecta, hasPrev, hasNext]);
|
|
41
41
|
return (React.createElement(React.Fragment, null,
|
|
42
|
-
React.createElement("div", { className: "jgis-specta-right-panel-container-mod jgis-right-panel-container" },
|
|
42
|
+
React.createElement("div", { className: "jgis-specta-right-panel-container-mod jgis-right-panel-container", style: showGradient ? undefined : { width: '25%', borderRadius: 0 } },
|
|
43
43
|
React.createElement("div", { ref: containerRef, className: "jgis-specta-story-panel-container" },
|
|
44
|
-
React.createElement("div", { ref: scrollContainerRef, className: "jgis-story-viewer-panel-specta-mod", id: "jgis-story-segment-panel" },
|
|
44
|
+
React.createElement("div", { ref: scrollContainerRef, className: "jgis-story-viewer-panel-specta-mod", id: "jgis-story-segment-panel", style: showGradient ? undefined : { width: 'unset' } },
|
|
45
45
|
React.createElement("div", { ref: topSentinelRef, "aria-hidden": true, "data-story-scroll-sentinel": "top", style: { height: 1, minHeight: 1, pointerEvents: 'none' } }),
|
|
46
|
-
React.createElement(StoryViewerPanel, { model: model, isSpecta: isSpecta,
|
|
46
|
+
React.createElement(StoryViewerPanel, { model: model, isSpecta: isSpecta, segmentContainerRef: segmentContainerRef, storyData: storyData, currentIndex: currentIndex, activeSlide: activeSlide, layerName: layerName, handlePrev: handlePrev, handleNext: handleNext, hasPrev: hasPrev, hasNext: hasNext, setIndex: setIndex }),
|
|
47
47
|
React.createElement("div", { ref: bottomSentinelRef, "aria-hidden": true, "data-story-scroll-sentinel": "bottom", style: { height: 1, minHeight: 1, pointerEvents: 'none' } })))),
|
|
48
48
|
React.createElement(SpectaPresentationProgressBar, { model: model })));
|
|
49
49
|
}
|
|
@@ -22,6 +22,7 @@ export declare function useStoryMap({ model, overrideLayerEntriesRef, removeLaye
|
|
|
22
22
|
storyData: IJGISStoryMap | null;
|
|
23
23
|
storySegments: IJGISLayer[];
|
|
24
24
|
currentIndex: number;
|
|
25
|
+
showGradient: boolean;
|
|
25
26
|
clearOverrideLayers: () => void;
|
|
26
27
|
setIndex: (index: number) => void;
|
|
27
28
|
handlePrev: () => void;
|