@jupytergis/base 0.11.1 → 0.12.1
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 -0
- package/lib/commands/BaseCommandIDs.js +1 -0
- package/lib/commands/index.js +52 -0
- package/lib/constants.d.ts +3 -2
- package/lib/constants.js +3 -0
- package/lib/dialogs/symbology/hooks/useGetBandInfo.d.ts +0 -6
- package/lib/dialogs/symbology/hooks/useGetBandInfo.js +2 -2
- package/lib/dialogs/symbology/tiff_layer/types/MultibandColor.js +4 -4
- package/lib/formbuilder/objectform/StoryEditorForm.d.ts +3 -2
- package/lib/formbuilder/objectform/StoryEditorForm.js +24 -1
- package/lib/mainview/mainView.d.ts +18 -0
- package/lib/mainview/mainView.js +243 -18
- package/lib/panelview/{components/filter-panel → filter-panel}/Filter.js +1 -1
- package/lib/panelview/leftpanel.js +26 -17
- package/lib/panelview/rightpanel.d.ts +2 -0
- package/lib/panelview/rightpanel.js +22 -14
- package/lib/panelview/{components/story-maps → story-maps}/PreviewModeSwitch.js +3 -2
- package/lib/panelview/story-maps/StoryEditorPanel.d.ts +9 -0
- package/lib/panelview/story-maps/StoryEditorPanel.js +34 -0
- package/lib/panelview/{components/story-maps → story-maps}/StoryNavBar.d.ts +2 -1
- package/lib/panelview/{components/story-maps → story-maps}/StoryNavBar.js +3 -3
- package/lib/panelview/story-maps/StoryViewerPanel.d.ts +13 -0
- package/lib/panelview/{components/story-maps → story-maps}/StoryViewerPanel.js +37 -24
- package/lib/panelview/story-maps/components/StoryContentSection.d.ts +6 -0
- package/lib/panelview/story-maps/components/StoryContentSection.js +10 -0
- package/lib/panelview/story-maps/components/StoryImageSection.d.ts +15 -0
- package/lib/panelview/story-maps/components/StoryImageSection.js +13 -0
- package/lib/panelview/story-maps/components/StorySubtitleSection.d.ts +11 -0
- package/lib/panelview/story-maps/components/StorySubtitleSection.js +9 -0
- package/lib/panelview/story-maps/components/StoryTitleSection.d.ts +12 -0
- package/lib/panelview/story-maps/components/StoryTitleSection.js +8 -0
- package/lib/shared/components/Combobox.d.ts +21 -0
- package/lib/shared/components/Combobox.js +32 -0
- package/lib/shared/components/Command.js +10 -10
- package/lib/shared/components/Input.d.ts +3 -0
- package/lib/shared/components/Input.js +18 -0
- package/lib/shared/components/Pagination.js +3 -2
- package/lib/shared/components/Select.d.ts +19 -0
- package/lib/shared/components/Select.js +28 -0
- package/lib/shared/components/SingleDatePicker.d.ts +11 -0
- package/lib/shared/components/SingleDatePicker.js +16 -0
- package/lib/stacBrowser/components/StacPanel.d.ts +9 -1
- package/lib/stacBrowser/components/StacPanel.js +53 -9
- package/lib/stacBrowser/components/filter-extension/QueryableComboBox.d.ts +9 -0
- package/lib/stacBrowser/components/filter-extension/QueryableComboBox.js +179 -0
- package/lib/stacBrowser/components/filter-extension/QueryableRow.d.ts +16 -0
- package/lib/stacBrowser/components/filter-extension/QueryableRow.js +16 -0
- package/lib/stacBrowser/components/filter-extension/StacFilterExtensionPanel.d.ts +7 -0
- package/lib/stacBrowser/components/filter-extension/StacFilterExtensionPanel.js +49 -0
- package/lib/stacBrowser/components/filter-extension/StacQueryableFilters.d.ts +11 -0
- package/lib/stacBrowser/components/filter-extension/StacQueryableFilters.js +19 -0
- package/lib/stacBrowser/components/{StacFilterSection.d.ts → geodes/StacFilterSection.d.ts} +1 -1
- package/lib/stacBrowser/components/{StacFilterSection.js → geodes/StacFilterSection.js} +3 -3
- package/lib/stacBrowser/components/geodes/StacGeodesFilterPanel.d.ts +7 -0
- package/lib/stacBrowser/components/geodes/StacGeodesFilterPanel.js +69 -0
- package/lib/stacBrowser/components/shared/StacPanelResults.d.ts +3 -0
- package/lib/stacBrowser/components/shared/StacPanelResults.js +68 -0
- package/lib/stacBrowser/components/shared/StacSpatialExtent.d.ts +8 -0
- package/lib/stacBrowser/components/shared/StacSpatialExtent.js +10 -0
- package/lib/stacBrowser/components/shared/StacTemporalExtent.d.ts +9 -0
- package/lib/stacBrowser/components/shared/StacTemporalExtent.js +9 -0
- package/lib/stacBrowser/context/StacResultsContext.d.ts +33 -0
- package/lib/stacBrowser/context/StacResultsContext.js +269 -0
- package/lib/stacBrowser/hooks/useGeodesSearch.d.ts +24 -0
- package/lib/stacBrowser/hooks/useGeodesSearch.js +178 -0
- package/lib/stacBrowser/hooks/useStacFilterExtension.d.ts +30 -0
- package/lib/stacBrowser/hooks/useStacFilterExtension.js +262 -0
- package/lib/stacBrowser/hooks/useStacSearch.d.ts +5 -16
- package/lib/stacBrowser/hooks/useStacSearch.js +30 -184
- package/lib/stacBrowser/types/types.d.ts +86 -3
- package/lib/toolbar/widget.d.ts +5 -0
- package/lib/toolbar/widget.js +23 -2
- package/lib/tools.d.ts +2 -8
- package/lib/tools.js +67 -18
- package/package.json +2 -3
- package/style/base.css +54 -11
- package/style/shared/button.css +5 -4
- package/style/shared/calendar.css +7 -1
- package/style/shared/combobox.css +75 -0
- package/style/shared/command.css +178 -0
- package/style/shared/input.css +59 -0
- package/style/shared/pagination.css +1 -1
- package/style/shared/popover.css +1 -0
- package/style/shared/tabs.css +1 -7
- package/style/shared/toggle.css +1 -1
- package/style/stacBrowser.css +169 -16
- package/style/statusBar.css +1 -0
- package/style/storyPanel.css +122 -3
- package/style/tabPanel.css +0 -86
- package/lib/panelview/components/story-maps/StoryEditorPanel.d.ts +0 -7
- package/lib/panelview/components/story-maps/StoryEditorPanel.js +0 -29
- package/lib/panelview/components/story-maps/StoryViewerPanel.d.ts +0 -7
- package/lib/stacBrowser/components/StacPanelFilters.d.ts +0 -14
- package/lib/stacBrowser/components/StacPanelFilters.js +0 -81
- package/lib/stacBrowser/components/StacPanelResults.d.ts +0 -13
- package/lib/stacBrowser/components/StacPanelResults.js +0 -48
- /package/lib/panelview/{components/filter-panel → filter-panel}/Filter.d.ts +0 -0
- /package/lib/panelview/{components/filter-panel → filter-panel}/FilterRow.d.ts +0 -0
- /package/lib/panelview/{components/filter-panel → filter-panel}/FilterRow.js +0 -0
- /package/lib/panelview/{components/identify-panel → identify-panel}/IdentifyPanel.d.ts +0 -0
- /package/lib/panelview/{components/identify-panel → identify-panel}/IdentifyPanel.js +0 -0
- /package/lib/panelview/{components/story-maps → story-maps}/PreviewModeSwitch.d.ts +0 -0
|
@@ -41,3 +41,4 @@ export declare const showObjectPropertiesTab = "jupytergis:showObjectPropertiesT
|
|
|
41
41
|
export declare const showAnnotationsTab = "jupytergis:showAnnotationsTab";
|
|
42
42
|
export declare const showIdentifyPanelTab = "jupytergis:showIdentifyPanelTab";
|
|
43
43
|
export declare const addStorySegment = "jupytergis:addStorySegment";
|
|
44
|
+
export declare const toggleStoryPresentationMode = "jupytergis:toggleStoryPresentationMode";
|
|
@@ -57,3 +57,4 @@ export const showAnnotationsTab = 'jupytergis:showAnnotationsTab';
|
|
|
57
57
|
export const showIdentifyPanelTab = 'jupytergis:showIdentifyPanelTab';
|
|
58
58
|
// Story maps
|
|
59
59
|
export const addStorySegment = 'jupytergis:addStorySegment';
|
|
60
|
+
export const toggleStoryPresentationMode = 'jupytergis:toggleStoryPresentationMode';
|
package/lib/commands/index.js
CHANGED
|
@@ -28,6 +28,31 @@ export function addCommands(app, tracker, translator, formSchemaRegistry, layerB
|
|
|
28
28
|
var _a;
|
|
29
29
|
const trans = translator.load('jupyterlab');
|
|
30
30
|
const { commands } = app;
|
|
31
|
+
/**
|
|
32
|
+
* Wraps a command definition to automatically disable it in Specta mode
|
|
33
|
+
*/
|
|
34
|
+
const createSpectaAwareCommand = (command) => {
|
|
35
|
+
const originalIsEnabled = command.isEnabled;
|
|
36
|
+
return Object.assign(Object.assign({}, command), { isEnabled: (args) => {
|
|
37
|
+
var _a;
|
|
38
|
+
// First check if we're in Specta mode
|
|
39
|
+
const currentModel = (_a = tracker.currentWidget) === null || _a === void 0 ? void 0 : _a.model;
|
|
40
|
+
if (currentModel === null || currentModel === void 0 ? void 0 : currentModel.isSpectaMode()) {
|
|
41
|
+
return false;
|
|
42
|
+
}
|
|
43
|
+
// Then check the original isEnabled if it exists
|
|
44
|
+
if (originalIsEnabled) {
|
|
45
|
+
return originalIsEnabled(args !== null && args !== void 0 ? args : {});
|
|
46
|
+
}
|
|
47
|
+
// Default to enabled if no original check
|
|
48
|
+
return true;
|
|
49
|
+
} });
|
|
50
|
+
};
|
|
51
|
+
// Override addCommand to automatically wrap all commands
|
|
52
|
+
const originalAddCommand = commands.addCommand.bind(commands);
|
|
53
|
+
commands.addCommand = (id, options) => {
|
|
54
|
+
return originalAddCommand(id, createSpectaAwareCommand(options));
|
|
55
|
+
};
|
|
31
56
|
commands.addCommand(CommandIDs.symbology, Object.assign({ label: trans.__('Edit Symbology'), isEnabled: () => {
|
|
32
57
|
var _a, _b;
|
|
33
58
|
const model = (_a = tracker.currentWidget) === null || _a === void 0 ? void 0 : _a.model;
|
|
@@ -356,6 +381,7 @@ export function addCommands(app, tracker, translator, formSchemaRegistry, layerB
|
|
|
356
381
|
Private.removeSelectedItems(model, 'layer', selection => {
|
|
357
382
|
model === null || model === void 0 ? void 0 : model.removeLayer(selection);
|
|
358
383
|
});
|
|
384
|
+
commands.notifyCommandChanged(CommandIDs.toggleStoryPresentationMode);
|
|
359
385
|
},
|
|
360
386
|
});
|
|
361
387
|
commands.addCommand(CommandIDs.renameGroup, {
|
|
@@ -831,7 +857,33 @@ export function addCommands(app, tracker, translator, formSchemaRegistry, layerB
|
|
|
831
857
|
return;
|
|
832
858
|
}
|
|
833
859
|
current.model.addStorySegment();
|
|
860
|
+
commands.notifyCommandChanged(CommandIDs.toggleStoryPresentationMode);
|
|
834
861
|
} }, icons.get(CommandIDs.addStorySegment)));
|
|
862
|
+
commands.addCommand(CommandIDs.toggleStoryPresentationMode, Object.assign({ label: trans.__('Toggle Story Presentation Mode'), isToggled: () => {
|
|
863
|
+
const current = tracker.currentWidget;
|
|
864
|
+
if (!current) {
|
|
865
|
+
return false;
|
|
866
|
+
}
|
|
867
|
+
const { storyMapPresentationMode } = current.model.getOptions();
|
|
868
|
+
return storyMapPresentationMode !== null && storyMapPresentationMode !== void 0 ? storyMapPresentationMode : false;
|
|
869
|
+
}, isEnabled: () => {
|
|
870
|
+
var _a, _b, _c;
|
|
871
|
+
const storySegments = (_b = (_a = tracker.currentWidget) === null || _a === void 0 ? void 0 : _a.model.getSelectedStory().story) === null || _b === void 0 ? void 0 : _b.storySegments;
|
|
872
|
+
if (((_c = tracker.currentWidget) === null || _c === void 0 ? void 0 : _c.model.jgisSettings.storyMapsDisabled) ||
|
|
873
|
+
!storySegments ||
|
|
874
|
+
storySegments.length < 1) {
|
|
875
|
+
return false;
|
|
876
|
+
}
|
|
877
|
+
return true;
|
|
878
|
+
}, execute: args => {
|
|
879
|
+
const current = tracker.currentWidget;
|
|
880
|
+
if (!current) {
|
|
881
|
+
return;
|
|
882
|
+
}
|
|
883
|
+
const currentOptions = current.model.getOptions();
|
|
884
|
+
current.model.setOptions(Object.assign(Object.assign({}, currentOptions), { storyMapPresentationMode: !currentOptions.storyMapPresentationMode }));
|
|
885
|
+
commands.notifyCommandChanged(CommandIDs.toggleStoryPresentationMode);
|
|
886
|
+
} }, icons.get(CommandIDs.toggleStoryPresentationMode)));
|
|
835
887
|
loadKeybindings(commands, keybindings);
|
|
836
888
|
}
|
|
837
889
|
var Private;
|
package/lib/constants.d.ts
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { ProcessingCommandIDs } from '@jupytergis/schema';
|
|
2
2
|
import { LabIcon } from '@jupyterlab/ui-components';
|
|
3
|
+
import * as BaseCommandIDs from './commands/BaseCommandIDs';
|
|
3
4
|
/**
|
|
4
5
|
* The command IDs.
|
|
5
6
|
*/
|
|
6
|
-
export declare const CommandIDs:
|
|
7
|
+
export declare const CommandIDs: typeof BaseCommandIDs & typeof ProcessingCommandIDs;
|
|
7
8
|
interface IRegisteredIcon {
|
|
8
9
|
icon?: LabIcon;
|
|
9
10
|
iconClass?: string;
|
package/lib/constants.js
CHANGED
|
@@ -36,6 +36,9 @@ const iconObject = {
|
|
|
36
36
|
[CommandIDs.temporalController]: { icon: clockIcon },
|
|
37
37
|
[CommandIDs.addMarker]: { icon: markerIcon },
|
|
38
38
|
[CommandIDs.addStorySegment]: { iconClass: 'fa fa-link' },
|
|
39
|
+
[CommandIDs.toggleStoryPresentationMode]: {
|
|
40
|
+
iconClass: 'fa fa-book jgis-icon-adjust',
|
|
41
|
+
},
|
|
39
42
|
};
|
|
40
43
|
/**
|
|
41
44
|
* The registered icons
|
|
@@ -10,7 +10,6 @@ const useGetBandInfo = (model, layer) => {
|
|
|
10
10
|
setLoading(true);
|
|
11
11
|
setError(null);
|
|
12
12
|
try {
|
|
13
|
-
const bandsArr = [];
|
|
14
13
|
const source = model.getSource((_a = layer === null || layer === void 0 ? void 0 : layer.parameters) === null || _a === void 0 ? void 0 : _a.source);
|
|
15
14
|
const sourceInfo = (_b = source === null || source === void 0 ? void 0 : source.parameters) === null || _b === void 0 ? void 0 : _b.urls[0];
|
|
16
15
|
if (!(sourceInfo === null || sourceInfo === void 0 ? void 0 : sourceInfo.url)) {
|
|
@@ -40,9 +39,10 @@ const useGetBandInfo = (model, layer) => {
|
|
|
40
39
|
}
|
|
41
40
|
const image = await tiff.getImage();
|
|
42
41
|
const numberOfBands = image.getSamplesPerPixel();
|
|
42
|
+
const bandsArr = [];
|
|
43
43
|
for (let i = 0; i < numberOfBands; i++) {
|
|
44
44
|
bandsArr.push({
|
|
45
|
-
band: i,
|
|
45
|
+
band: i + 1,
|
|
46
46
|
stats: {
|
|
47
47
|
minimum: (_c = sourceInfo.min) !== null && _c !== void 0 ? _c : 0,
|
|
48
48
|
maximum: (_d = sourceInfo.max) !== null && _d !== void 0 ? _d : 100,
|
|
@@ -87,9 +87,9 @@ const MultibandColor = ({ model, okSignalPromise, cancel, layerId, }) => {
|
|
|
87
87
|
return (React.createElement("div", { className: "jp-gis-layer-symbology-container" },
|
|
88
88
|
React.createElement("div", { className: "jp-gis-band-container" },
|
|
89
89
|
React.createElement(LoadingOverlay, { loading: loading }),
|
|
90
|
-
React.createElement(BandRow, { label: "Red Band", index: selectedBands.red - 1, bandRow: bandRows[selectedBands.red - 1], bandRows: bandRows, setSelectedBand: val => updateBand('red', val >= 0 ? val
|
|
91
|
-
React.createElement(BandRow, { label: "Green Band", index: selectedBands.green - 1, bandRow: bandRows[selectedBands.green - 1], bandRows: bandRows, setSelectedBand: val => updateBand('green', val >= 0 ? val
|
|
92
|
-
React.createElement(BandRow, { label: "Blue Band", index: selectedBands.blue - 1, bandRow: bandRows[selectedBands.blue - 1], bandRows: bandRows, setSelectedBand: val => updateBand('blue', val >= 0 ? val
|
|
93
|
-
React.createElement(BandRow, { label: "Alpha Band", index: selectedBands.alpha - 1, bandRow: bandRows[selectedBands.alpha - 1], bandRows: bandRows, setSelectedBand: val => updateBand('alpha', val >= 0 ? val
|
|
90
|
+
React.createElement(BandRow, { label: "Red Band", index: selectedBands.red - 1, bandRow: bandRows[selectedBands.red - 1], bandRows: bandRows, setSelectedBand: val => updateBand('red', val >= 0 ? val : 0), setBandRows: setBandRows, isMultibandColor: true }),
|
|
91
|
+
React.createElement(BandRow, { label: "Green Band", index: selectedBands.green - 1, bandRow: bandRows[selectedBands.green - 1], bandRows: bandRows, setSelectedBand: val => updateBand('green', val >= 0 ? val : 0), setBandRows: setBandRows, isMultibandColor: true }),
|
|
92
|
+
React.createElement(BandRow, { label: "Blue Band", index: selectedBands.blue - 1, bandRow: bandRows[selectedBands.blue - 1], bandRows: bandRows, setSelectedBand: val => updateBand('blue', val >= 0 ? val : 0), setBandRows: setBandRows, isMultibandColor: true }),
|
|
93
|
+
React.createElement(BandRow, { label: "Alpha Band", index: selectedBands.alpha - 1, bandRow: bandRows[selectedBands.alpha - 1], bandRows: bandRows, setSelectedBand: val => updateBand('alpha', val >= 0 ? val : 0), setBandRows: setBandRows, isMultibandColor: true }))));
|
|
94
94
|
};
|
|
95
95
|
export default MultibandColor;
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { IDict } from '@jupytergis/schema';
|
|
2
|
+
import { RJSFSchema, UiSchema } from '@rjsf/utils';
|
|
2
3
|
import { BaseForm } from './baseform';
|
|
3
4
|
/**
|
|
4
|
-
* The form to modify
|
|
5
|
+
* The form to modify story map properties.
|
|
5
6
|
*/
|
|
6
7
|
export declare class StoryEditorPropertiesForm extends BaseForm {
|
|
7
|
-
protected processSchema(data: IDict<any> | undefined, schema:
|
|
8
|
+
protected processSchema(data: IDict<any> | undefined, schema: RJSFSchema, uiSchema: UiSchema): void;
|
|
8
9
|
}
|
|
@@ -1,10 +1,33 @@
|
|
|
1
1
|
import { BaseForm } from './baseform';
|
|
2
|
+
import { getCssVarAsColor } from "../../tools";
|
|
2
3
|
/**
|
|
3
|
-
* The form to modify
|
|
4
|
+
* The form to modify story map properties.
|
|
4
5
|
*/
|
|
5
6
|
export class StoryEditorPropertiesForm extends BaseForm {
|
|
6
7
|
processSchema(data, schema, uiSchema) {
|
|
7
8
|
super.processSchema(data, schema, uiSchema);
|
|
8
9
|
this.removeFormEntry('storySegments', data, schema, uiSchema);
|
|
10
|
+
uiSchema.presentationBgColor = {
|
|
11
|
+
'ui:widget': 'color',
|
|
12
|
+
};
|
|
13
|
+
uiSchema.presentaionTextColor = {
|
|
14
|
+
'ui:widget': 'color',
|
|
15
|
+
};
|
|
16
|
+
// Set default values from theme CSS variables when not already in data
|
|
17
|
+
const schemaProps = schema.properties;
|
|
18
|
+
if ((schemaProps === null || schemaProps === void 0 ? void 0 : schemaProps.presentationBgColor) &&
|
|
19
|
+
(data === null || data === void 0 ? void 0 : data.presentationBgColor) === undefined) {
|
|
20
|
+
const defaultBg = getCssVarAsColor('--jp-layout-color0');
|
|
21
|
+
if (defaultBg) {
|
|
22
|
+
schemaProps.presentationBgColor.default = defaultBg;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
if ((schemaProps === null || schemaProps === void 0 ? void 0 : schemaProps.presentaionTextColor) &&
|
|
26
|
+
(data === null || data === void 0 ? void 0 : data.presentaionTextColor) === undefined) {
|
|
27
|
+
const defaultText = getCssVarAsColor('--jp-ui-font-color0');
|
|
28
|
+
if (defaultText) {
|
|
29
|
+
schemaProps.presentaionTextColor.default = defaultText;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
9
32
|
}
|
|
10
33
|
}
|
|
@@ -31,10 +31,12 @@ interface IStates {
|
|
|
31
31
|
}>;
|
|
32
32
|
displayTemporalController: boolean;
|
|
33
33
|
filterStates: IDict<IJGISFilterItem | undefined>;
|
|
34
|
+
isSpectaPresentation: boolean;
|
|
34
35
|
}
|
|
35
36
|
export declare class MainView extends React.Component<IProps, IStates> {
|
|
36
37
|
constructor(props: IProps);
|
|
37
38
|
componentDidMount(): Promise<void>;
|
|
39
|
+
componentDidUpdate(prevProps: IProps, prevState: IStates): void;
|
|
38
40
|
componentWillUnmount(): void;
|
|
39
41
|
generateMap(center: number[], zoom: number): Promise<void>;
|
|
40
42
|
updateCenter: () => void;
|
|
@@ -134,6 +136,7 @@ export declare class MainView extends React.Component<IProps, IStates> {
|
|
|
134
136
|
removeLayer(id: string): void;
|
|
135
137
|
private _onClientSharedStateChanged;
|
|
136
138
|
private _onSharedOptionsChanged;
|
|
139
|
+
private _onSettingsChanged;
|
|
137
140
|
private updateOptions;
|
|
138
141
|
private _onViewChanged;
|
|
139
142
|
/**
|
|
@@ -167,6 +170,15 @@ export declare class MainView extends React.Component<IProps, IStates> {
|
|
|
167
170
|
private _onLayerTreeChange;
|
|
168
171
|
private _onSourcesChange;
|
|
169
172
|
private _onSharedModelStateChange;
|
|
173
|
+
/**
|
|
174
|
+
* Handler for when story maps change in the model.
|
|
175
|
+
* Updates specta state and presentation colors when story data becomes available.
|
|
176
|
+
*/
|
|
177
|
+
private _setupSpectaMode;
|
|
178
|
+
private _removeAllInteractions;
|
|
179
|
+
private _setupStoryScrollListener;
|
|
180
|
+
private _cleanupStoryScrollListener;
|
|
181
|
+
private _updateSpectaPresentationColors;
|
|
170
182
|
private _onSharedMetadataChanged;
|
|
171
183
|
private _computeAnnotationPosition;
|
|
172
184
|
private _updateAnnotation;
|
|
@@ -187,7 +199,11 @@ export declare class MainView extends React.Component<IProps, IStates> {
|
|
|
187
199
|
private _commands;
|
|
188
200
|
private _isPositionInitialized;
|
|
189
201
|
private divRef;
|
|
202
|
+
private controlsToolbarRef;
|
|
203
|
+
private spectaContainerRef;
|
|
204
|
+
private storyViewerPanelRef;
|
|
190
205
|
private _Map;
|
|
206
|
+
private _zoomControl?;
|
|
191
207
|
private _model;
|
|
192
208
|
private _mainViewModel;
|
|
193
209
|
private _ready;
|
|
@@ -203,5 +219,7 @@ export declare class MainView extends React.Component<IProps, IStates> {
|
|
|
203
219
|
private _formSchemaRegistry?;
|
|
204
220
|
private _annotationModel?;
|
|
205
221
|
private _featurePropertyCache;
|
|
222
|
+
private _isSpectaPresentationInitialized;
|
|
223
|
+
private _storyScrollHandler;
|
|
206
224
|
}
|
|
207
225
|
export {};
|
package/lib/mainview/mainView.js
CHANGED
|
@@ -16,12 +16,12 @@ import { UUID } from '@lumino/coreutils';
|
|
|
16
16
|
import { ContextMenu } from '@lumino/widgets';
|
|
17
17
|
import { Collection, Map as OlMap, View, getUid, } from 'ol';
|
|
18
18
|
import Feature from 'ol/Feature';
|
|
19
|
-
import { FullScreen, ScaleLine } from 'ol/control';
|
|
19
|
+
import { FullScreen, ScaleLine, Zoom } from 'ol/control';
|
|
20
20
|
import { singleClick } from 'ol/events/condition';
|
|
21
21
|
import { getCenter } from 'ol/extent';
|
|
22
22
|
import { GeoJSON, MVT } from 'ol/format';
|
|
23
23
|
import { Point } from 'ol/geom';
|
|
24
|
-
import { DragAndDrop, Select } from 'ol/interaction';
|
|
24
|
+
import { DragAndDrop, DragPan, DragRotate, DragZoom, KeyboardPan, KeyboardZoom, MouseWheelZoom, PinchRotate, PinchZoom, DoubleClickZoom, Select, } from 'ol/interaction';
|
|
25
25
|
import { Heatmap as HeatmapLayer, Image as ImageLayer, Layer, Vector as VectorLayer, VectorTile as VectorTileLayer, WebGLTile as WebGlTileLayer, } from 'ol/layer';
|
|
26
26
|
import TileLayer from 'ol/layer/Tile';
|
|
27
27
|
import { fromLonLat, get as getProjection, toLonLat, transformExtent, } from 'ol/proj';
|
|
@@ -44,8 +44,10 @@ import { debounce, isLightTheme, loadFile, throttle } from "../tools";
|
|
|
44
44
|
import CollaboratorPointers from './CollaboratorPointers';
|
|
45
45
|
import { FollowIndicator } from './FollowIndicator';
|
|
46
46
|
import TemporalSlider from './TemporalSlider';
|
|
47
|
+
import { hexToRgb } from '../dialogs/symbology/colorRampUtils';
|
|
47
48
|
import { markerIcon } from '../icons';
|
|
48
49
|
import { LeftPanel, RightPanel } from '../panelview';
|
|
50
|
+
import StoryViewerPanel from '../panelview/story-maps/StoryViewerPanel';
|
|
49
51
|
export class MainView extends React.Component {
|
|
50
52
|
constructor(props) {
|
|
51
53
|
super(props);
|
|
@@ -406,6 +408,138 @@ export class MainView extends React.Component {
|
|
|
406
408
|
}
|
|
407
409
|
}
|
|
408
410
|
};
|
|
411
|
+
/**
|
|
412
|
+
* Handler for when story maps change in the model.
|
|
413
|
+
* Updates specta state and presentation colors when story data becomes available.
|
|
414
|
+
*/
|
|
415
|
+
this._setupSpectaMode = () => {
|
|
416
|
+
this._removeAllInteractions();
|
|
417
|
+
this._setupStoryScrollListener();
|
|
418
|
+
// Update colors CSS variables with colors from story
|
|
419
|
+
this._updateSpectaPresentationColors();
|
|
420
|
+
};
|
|
421
|
+
this._removeAllInteractions = () => {
|
|
422
|
+
// Remove all default interactions
|
|
423
|
+
const interactions = this._Map.getInteractions();
|
|
424
|
+
const interactionArray = interactions.getArray();
|
|
425
|
+
// Remove each interaction type
|
|
426
|
+
const interactionsToRemove = [
|
|
427
|
+
DragPan,
|
|
428
|
+
DragRotate,
|
|
429
|
+
DragZoom,
|
|
430
|
+
KeyboardPan,
|
|
431
|
+
KeyboardZoom,
|
|
432
|
+
MouseWheelZoom,
|
|
433
|
+
PinchRotate,
|
|
434
|
+
PinchZoom,
|
|
435
|
+
DoubleClickZoom,
|
|
436
|
+
DragAndDrop,
|
|
437
|
+
Select,
|
|
438
|
+
];
|
|
439
|
+
this._zoomControl && this._Map.removeControl(this._zoomControl);
|
|
440
|
+
interactionsToRemove.forEach(InteractionClass => {
|
|
441
|
+
const interaction = interactionArray.find(interaction => interaction instanceof InteractionClass);
|
|
442
|
+
if (interaction) {
|
|
443
|
+
this._Map.removeInteraction(interaction);
|
|
444
|
+
}
|
|
445
|
+
});
|
|
446
|
+
};
|
|
447
|
+
this._setupStoryScrollListener = () => {
|
|
448
|
+
const segmentNavigationThrottle = 750; // Minimum time between segment changes (ms)
|
|
449
|
+
const SCROLL_EDGE_THRESHOLD = 0; // Pixels from top/bottom to trigger segment change
|
|
450
|
+
// Create throttled functions that call the current panel handle dynamically
|
|
451
|
+
const throttledHandleNext = throttle(() => {
|
|
452
|
+
const panelHandle = this.storyViewerPanelRef.current;
|
|
453
|
+
panelHandle === null || panelHandle === void 0 ? void 0 : panelHandle.handleNext();
|
|
454
|
+
}, segmentNavigationThrottle);
|
|
455
|
+
const throttledHandlePrev = throttle(() => {
|
|
456
|
+
const panelHandle = this.storyViewerPanelRef.current;
|
|
457
|
+
panelHandle === null || panelHandle === void 0 ? void 0 : panelHandle.handlePrev();
|
|
458
|
+
}, segmentNavigationThrottle);
|
|
459
|
+
const handleScroll = (e) => {
|
|
460
|
+
const currentPanelHandle = this.storyViewerPanelRef.current;
|
|
461
|
+
if (!currentPanelHandle || !currentPanelHandle.canNavigate) {
|
|
462
|
+
return;
|
|
463
|
+
}
|
|
464
|
+
const wheelEvent = e;
|
|
465
|
+
const target = wheelEvent.target;
|
|
466
|
+
// Find the story viewer panel
|
|
467
|
+
const storyViewerPanel = document.querySelector('.jgis-story-viewer-panel');
|
|
468
|
+
// If no panel found, change segments normally
|
|
469
|
+
if (!storyViewerPanel) {
|
|
470
|
+
wheelEvent.preventDefault();
|
|
471
|
+
wheelEvent.deltaY > 0 ? throttledHandleNext() : throttledHandlePrev();
|
|
472
|
+
return;
|
|
473
|
+
}
|
|
474
|
+
const hasOverflow = storyViewerPanel.scrollHeight > storyViewerPanel.clientHeight;
|
|
475
|
+
// If panel has no overflow, change segments normally
|
|
476
|
+
if (!hasOverflow) {
|
|
477
|
+
wheelEvent.preventDefault();
|
|
478
|
+
wheelEvent.deltaY > 0 ? throttledHandleNext() : throttledHandlePrev();
|
|
479
|
+
return;
|
|
480
|
+
}
|
|
481
|
+
// Panel has overflow - handle scroll forwarding and edge detection
|
|
482
|
+
const scrollTop = storyViewerPanel.scrollTop;
|
|
483
|
+
const scrollHeight = storyViewerPanel.scrollHeight;
|
|
484
|
+
const clientHeight = storyViewerPanel.clientHeight;
|
|
485
|
+
const isAtBottom = scrollTop + clientHeight >= scrollHeight - SCROLL_EDGE_THRESHOLD;
|
|
486
|
+
const isAtTop = scrollTop <= SCROLL_EDGE_THRESHOLD;
|
|
487
|
+
const isScrollingDown = wheelEvent.deltaY > 0;
|
|
488
|
+
const isScrollingUp = wheelEvent.deltaY < 0;
|
|
489
|
+
// At edges: change segments
|
|
490
|
+
if ((isScrollingDown && isAtBottom) || (isScrollingUp && isAtTop)) {
|
|
491
|
+
wheelEvent.preventDefault();
|
|
492
|
+
isScrollingDown ? throttledHandleNext() : throttledHandlePrev();
|
|
493
|
+
return;
|
|
494
|
+
}
|
|
495
|
+
// If scrolling inside the panel, let it scroll naturally
|
|
496
|
+
if (target.closest('.jgis-story-viewer-panel')) {
|
|
497
|
+
return;
|
|
498
|
+
}
|
|
499
|
+
// Scrolling outside the panel: forward scroll to panel (no throttling for smooth scrolling)
|
|
500
|
+
wheelEvent.preventDefault();
|
|
501
|
+
const newScrollTop = Math.max(0, Math.min(scrollHeight - clientHeight, scrollTop + wheelEvent.deltaY));
|
|
502
|
+
storyViewerPanel.scrollTop = newScrollTop;
|
|
503
|
+
};
|
|
504
|
+
this._storyScrollHandler = handleScroll;
|
|
505
|
+
// Attach wheel event listener to the main container
|
|
506
|
+
const containerElement = document.querySelector('.jGIS-Mainview-Container');
|
|
507
|
+
if (containerElement) {
|
|
508
|
+
containerElement.addEventListener('wheel', handleScroll, {
|
|
509
|
+
passive: false,
|
|
510
|
+
});
|
|
511
|
+
}
|
|
512
|
+
};
|
|
513
|
+
this._cleanupStoryScrollListener = () => {
|
|
514
|
+
if (this._storyScrollHandler) {
|
|
515
|
+
const containerElement = document.querySelector('.jGIS-Mainview-Container');
|
|
516
|
+
if (containerElement) {
|
|
517
|
+
containerElement.removeEventListener('wheel', this._storyScrollHandler);
|
|
518
|
+
}
|
|
519
|
+
this._storyScrollHandler = null;
|
|
520
|
+
}
|
|
521
|
+
};
|
|
522
|
+
this._updateSpectaPresentationColors = () => {
|
|
523
|
+
var _a;
|
|
524
|
+
// Try ref first, fallback to querySelector if ref not available yet
|
|
525
|
+
const container = this.spectaContainerRef.current ||
|
|
526
|
+
((_a = this.divRef.current) === null || _a === void 0 ? void 0 : _a.querySelector('.jgis-specta-story-panel-container'));
|
|
527
|
+
if (!container) {
|
|
528
|
+
return;
|
|
529
|
+
}
|
|
530
|
+
const story = this._model.getSelectedStory().story;
|
|
531
|
+
const bgColor = story === null || story === void 0 ? void 0 : story.presentationBgColor;
|
|
532
|
+
const textColor = story === null || story === void 0 ? void 0 : story.presentaionTextColor;
|
|
533
|
+
// Set background color
|
|
534
|
+
if (bgColor) {
|
|
535
|
+
const rgb = hexToRgb(bgColor);
|
|
536
|
+
container.style.setProperty('--jgis-specta-bg-color', `rgba(${rgb[0]}, ${rgb[1]}, ${rgb[2]})`);
|
|
537
|
+
}
|
|
538
|
+
// Set text color
|
|
539
|
+
if (textColor) {
|
|
540
|
+
container.style.setProperty('--jgis-specta-text-color', textColor);
|
|
541
|
+
}
|
|
542
|
+
};
|
|
409
543
|
this._onSharedMetadataChanged = (_, changes) => {
|
|
410
544
|
const newState = Object.assign({}, this.state.annotations);
|
|
411
545
|
changes.forEach((val, key) => {
|
|
@@ -451,10 +585,15 @@ export class MainView extends React.Component {
|
|
|
451
585
|
};
|
|
452
586
|
this._isPositionInitialized = false;
|
|
453
587
|
this.divRef = React.createRef(); // Reference of render div
|
|
588
|
+
this.controlsToolbarRef = React.createRef();
|
|
589
|
+
this.spectaContainerRef = React.createRef();
|
|
590
|
+
this.storyViewerPanelRef = React.createRef();
|
|
454
591
|
this._ready = false;
|
|
455
592
|
this._sourceToLayerMap = new Map();
|
|
456
593
|
this._originalFeatures = {};
|
|
457
594
|
this._featurePropertyCache = new Map();
|
|
595
|
+
this._isSpectaPresentationInitialized = false;
|
|
596
|
+
this._storyScrollHandler = null;
|
|
458
597
|
this._state = props.state;
|
|
459
598
|
this._formSchemaRegistry = props.formSchemaRegistry;
|
|
460
599
|
this._annotationModel = props.annotationModel;
|
|
@@ -489,6 +628,7 @@ export class MainView extends React.Component {
|
|
|
489
628
|
this._model.sharedModel.changed.connect(this._onSharedModelStateChange);
|
|
490
629
|
this._model.sharedMetadataChanged.connect(this._onSharedMetadataChanged, this);
|
|
491
630
|
this._model.zoomToPositionSignal.connect(this._onZoomToPosition, this);
|
|
631
|
+
this._model.settingsChanged.connect(this._onSettingsChanged, this);
|
|
492
632
|
this._model.updateLayerSignal.connect(this._triggerLayerUpdate, this);
|
|
493
633
|
this._model.addFeatureAsMsSignal.connect(this._convertFeatureToMs, this);
|
|
494
634
|
this._model.geolocationChanged.connect(this._handleGeolocationChanged, this);
|
|
@@ -513,6 +653,7 @@ export class MainView extends React.Component {
|
|
|
513
653
|
loadingErrors: [],
|
|
514
654
|
displayTemporalController: false,
|
|
515
655
|
filterStates: {},
|
|
656
|
+
isSpectaPresentation: false,
|
|
516
657
|
};
|
|
517
658
|
this._sources = [];
|
|
518
659
|
this._loadingLayers = new Set();
|
|
@@ -530,12 +671,19 @@ export class MainView extends React.Component {
|
|
|
530
671
|
: [0, 0];
|
|
531
672
|
const zoom = options.zoom !== undefined ? options.zoom : 1;
|
|
532
673
|
await this.generateMap(center, zoom);
|
|
533
|
-
this.addContextMenu();
|
|
534
674
|
this._mainViewModel.initSignal();
|
|
535
675
|
if (window.jupytergisMaps !== undefined && this._documentPath) {
|
|
536
676
|
window.jupytergisMaps[this._documentPath] = this._Map;
|
|
537
677
|
}
|
|
538
678
|
}
|
|
679
|
+
componentDidUpdate(prevProps, prevState) {
|
|
680
|
+
// Run setup when isSpectaPresentation changes from false/undefined to true
|
|
681
|
+
if (this.state.isSpectaPresentation &&
|
|
682
|
+
!this._isSpectaPresentationInitialized) {
|
|
683
|
+
this._setupSpectaMode();
|
|
684
|
+
this._isSpectaPresentationInitialized = true;
|
|
685
|
+
}
|
|
686
|
+
}
|
|
539
687
|
componentWillUnmount() {
|
|
540
688
|
if (window.jupytergisMaps !== undefined && this._documentPath) {
|
|
541
689
|
delete window.jupytergisMaps[this._documentPath];
|
|
@@ -543,20 +691,37 @@ export class MainView extends React.Component {
|
|
|
543
691
|
window.removeEventListener('resize', this._handleWindowResize);
|
|
544
692
|
this._mainViewModel.viewSettingChanged.disconnect(this._onViewChanged, this);
|
|
545
693
|
this._model.themeChanged.disconnect(this._handleThemeChange, this);
|
|
694
|
+
this._model.settingsChanged.disconnect(this._onSettingsChanged, this);
|
|
546
695
|
this._model.sharedOptionsChanged.disconnect(this._onSharedOptionsChanged, this);
|
|
547
696
|
this._model.clientStateChanged.disconnect(this._onClientSharedStateChanged, this);
|
|
697
|
+
// Clean up story scroll listener
|
|
698
|
+
this._cleanupStoryScrollListener();
|
|
548
699
|
this._mainViewModel.dispose();
|
|
549
700
|
}
|
|
550
701
|
async generateMap(center, zoom) {
|
|
702
|
+
const scaleLine = new ScaleLine({
|
|
703
|
+
target: this.controlsToolbarRef.current || undefined,
|
|
704
|
+
});
|
|
705
|
+
const fullScreen = new FullScreen({
|
|
706
|
+
target: this.controlsToolbarRef.current || undefined,
|
|
707
|
+
});
|
|
708
|
+
const controls = [scaleLine, fullScreen];
|
|
709
|
+
if (this._model.jgisSettings.zoomButtonsEnabled) {
|
|
710
|
+
this._zoomControl = new Zoom({
|
|
711
|
+
target: this.controlsToolbarRef.current || undefined,
|
|
712
|
+
});
|
|
713
|
+
controls.push(this._zoomControl);
|
|
714
|
+
}
|
|
551
715
|
if (this.divRef.current) {
|
|
552
716
|
this._Map = new OlMap({
|
|
553
717
|
target: this.divRef.current,
|
|
718
|
+
keyboardEventTarget: document,
|
|
554
719
|
layers: [],
|
|
555
720
|
view: new View({
|
|
556
721
|
center,
|
|
557
722
|
zoom,
|
|
558
723
|
}),
|
|
559
|
-
controls
|
|
724
|
+
controls,
|
|
560
725
|
});
|
|
561
726
|
// Add map interactions
|
|
562
727
|
const dragAndDropInteraction = new DragAndDrop({
|
|
@@ -1379,12 +1544,42 @@ export class MainView extends React.Component {
|
|
|
1379
1544
|
}
|
|
1380
1545
|
}
|
|
1381
1546
|
_onSharedOptionsChanged() {
|
|
1547
|
+
// ! would prefer a model ready signal or something, this feels hacky
|
|
1548
|
+
const enableSpectaPresentation = this._model.isSpectaMode();
|
|
1549
|
+
// Handle initialization based on specta presentation state
|
|
1550
|
+
if (!this._isSpectaPresentationInitialized) {
|
|
1551
|
+
if (enableSpectaPresentation) {
|
|
1552
|
+
// _setupSpectaMode will be called in componentDidUpdate when state changes
|
|
1553
|
+
this.setState(old => (Object.assign(Object.assign({}, old), { isSpectaPresentation: true })));
|
|
1554
|
+
}
|
|
1555
|
+
else {
|
|
1556
|
+
// Add context menu when not in specta mode
|
|
1557
|
+
this.addContextMenu();
|
|
1558
|
+
this._isSpectaPresentationInitialized = true;
|
|
1559
|
+
}
|
|
1560
|
+
}
|
|
1382
1561
|
if (!this._isPositionInitialized) {
|
|
1383
1562
|
const options = this._model.getOptions();
|
|
1384
1563
|
this.updateOptions(options);
|
|
1385
1564
|
this._isPositionInitialized = true;
|
|
1386
1565
|
}
|
|
1387
1566
|
}
|
|
1567
|
+
_onSettingsChanged(sender, key) {
|
|
1568
|
+
if (key !== 'zoomButtonsEnabled' || !this._Map) {
|
|
1569
|
+
return;
|
|
1570
|
+
}
|
|
1571
|
+
const enabled = this._model.jgisSettings.zoomButtonsEnabled;
|
|
1572
|
+
if (!enabled && this._zoomControl) {
|
|
1573
|
+
this._Map.removeControl(this._zoomControl);
|
|
1574
|
+
this._zoomControl = undefined;
|
|
1575
|
+
}
|
|
1576
|
+
if (enabled && !this._zoomControl) {
|
|
1577
|
+
this._zoomControl = new Zoom({
|
|
1578
|
+
target: this.controlsToolbarRef.current || undefined,
|
|
1579
|
+
});
|
|
1580
|
+
this._Map.addControl(this._zoomControl);
|
|
1581
|
+
}
|
|
1582
|
+
}
|
|
1388
1583
|
async updateOptions(options) {
|
|
1389
1584
|
const { projection, extent, useExtent, latitude, longitude, zoom, bearing, } = options;
|
|
1390
1585
|
let view = this._Map.getView();
|
|
@@ -1555,7 +1750,7 @@ export class MainView extends React.Component {
|
|
|
1555
1750
|
}
|
|
1556
1751
|
// TODO this and flyToPosition need a rework
|
|
1557
1752
|
_onZoomToPosition(_, id) {
|
|
1558
|
-
var _a, _b;
|
|
1753
|
+
var _a, _b, _c;
|
|
1559
1754
|
// Check if the id is an annotation
|
|
1560
1755
|
const annotation = (_a = this._model.annotationModel) === null || _a === void 0 ? void 0 : _a.getAnnotation(id);
|
|
1561
1756
|
if (annotation) {
|
|
@@ -1566,17 +1761,44 @@ export class MainView extends React.Component {
|
|
|
1566
1761
|
let extent;
|
|
1567
1762
|
const layer = this.getLayer(id);
|
|
1568
1763
|
const source = layer === null || layer === void 0 ? void 0 : layer.getSource();
|
|
1569
|
-
|
|
1570
|
-
|
|
1764
|
+
const jgisLayer = this._model.getLayer(id);
|
|
1765
|
+
/**
|
|
1766
|
+
* Layer may be undefined in two cases:
|
|
1767
|
+
* 1. StorySegmentLayer: These layers don't have an associated OpenLayers layer
|
|
1768
|
+
* 2. StacLayer: When centerOnPosition is called immediately after adding the layer,
|
|
1769
|
+
* the OpenLayers layer hasn't been created yet, so we use the bbox from the
|
|
1770
|
+
* layer model's STAC data directly.
|
|
1771
|
+
*/
|
|
1571
1772
|
if (!layer) {
|
|
1572
|
-
|
|
1573
|
-
|
|
1574
|
-
|
|
1575
|
-
|
|
1576
|
-
|
|
1577
|
-
|
|
1578
|
-
|
|
1579
|
-
|
|
1773
|
+
// Handle StacLayer that hasn't been added to the map yet
|
|
1774
|
+
if ((jgisLayer === null || jgisLayer === void 0 ? void 0 : jgisLayer.type) === 'StacLayer') {
|
|
1775
|
+
const layerParams = jgisLayer.parameters;
|
|
1776
|
+
const stacBbox = (_b = layerParams.data) === null || _b === void 0 ? void 0 : _b.bbox;
|
|
1777
|
+
if (stacBbox && stacBbox.length === 4) {
|
|
1778
|
+
// STAC bbox format: [west, south, east, north] in EPSG:4326
|
|
1779
|
+
const [west, south, east, north] = stacBbox;
|
|
1780
|
+
const bboxExtent = [west, south, east, north];
|
|
1781
|
+
// Convert from EPSG:4326 to view projection
|
|
1782
|
+
const viewProjection = this._Map.getView().getProjection();
|
|
1783
|
+
const transformedExtent = viewProjection.getCode() !== 'EPSG:4326'
|
|
1784
|
+
? transformExtent(bboxExtent, 'EPSG:4326', viewProjection)
|
|
1785
|
+
: bboxExtent;
|
|
1786
|
+
this._Map.getView().fit(transformedExtent, {
|
|
1787
|
+
size: this._Map.getSize(),
|
|
1788
|
+
duration: 500,
|
|
1789
|
+
padding: [250, 250, 250, 250],
|
|
1790
|
+
});
|
|
1791
|
+
return;
|
|
1792
|
+
}
|
|
1793
|
+
}
|
|
1794
|
+
// Handle StorySegmentLayer
|
|
1795
|
+
if ((jgisLayer === null || jgisLayer === void 0 ? void 0 : jgisLayer.type) === 'StorySegmentLayer') {
|
|
1796
|
+
const layerParams = jgisLayer.parameters;
|
|
1797
|
+
const coords = getCenter(layerParams.extent);
|
|
1798
|
+
this._flyToPosition({ x: coords[0], y: coords[1] }, layerParams.zoom, ((_c = layerParams.transition.time) !== null && _c !== void 0 ? _c : 1) * 1000, // seconds -> ms
|
|
1799
|
+
layerParams.transition.type);
|
|
1800
|
+
return;
|
|
1801
|
+
}
|
|
1580
1802
|
}
|
|
1581
1803
|
if (source instanceof VectorSource) {
|
|
1582
1804
|
extent = source.getExtent();
|
|
@@ -1829,7 +2051,7 @@ export class MainView extends React.Component {
|
|
|
1829
2051
|
}),
|
|
1830
2052
|
React.createElement("div", { className: "jGIS-Mainview-Container" },
|
|
1831
2053
|
this.state.displayTemporalController && (React.createElement(TemporalSlider, { model: this._model, filterStates: this.state.filterStates })),
|
|
1832
|
-
React.createElement("div", { className: "jGIS-Mainview data-jgis-keybinding", tabIndex:
|
|
2054
|
+
React.createElement("div", { className: "jGIS-Mainview data-jgis-keybinding", tabIndex: 0, style: {
|
|
1833
2055
|
border: this.state.remoteUser
|
|
1834
2056
|
? `solid 3px ${this.state.remoteUser.color}`
|
|
1835
2057
|
: 'unset',
|
|
@@ -1841,9 +2063,12 @@ export class MainView extends React.Component {
|
|
|
1841
2063
|
width: '100%',
|
|
1842
2064
|
height: '100%',
|
|
1843
2065
|
} },
|
|
1844
|
-
React.createElement("div", { className: "jgis-panels-wrapper" },
|
|
2066
|
+
React.createElement("div", { className: "jgis-panels-wrapper" }, !this.state.isSpectaPresentation ? (React.createElement(React.Fragment, null,
|
|
1845
2067
|
this._state && (React.createElement(LeftPanel, { model: this._model, commands: this._mainViewModel.commands, state: this._state })),
|
|
1846
|
-
this._formSchemaRegistry && this._annotationModel && (React.createElement(RightPanel, { model: this._model, formSchemaRegistry: this._formSchemaRegistry, annotationModel: this._annotationModel }))))
|
|
2068
|
+
this._formSchemaRegistry && this._annotationModel && (React.createElement(RightPanel, { model: this._model, commands: this._mainViewModel.commands, formSchemaRegistry: this._formSchemaRegistry, annotationModel: this._annotationModel })))) : (React.createElement("div", { className: "jgis-specta-right-panel-container-mod jgis-right-panel-container" },
|
|
2069
|
+
React.createElement("div", { ref: this.spectaContainerRef, className: "jgis-specta-story-panel-container" },
|
|
2070
|
+
React.createElement(StoryViewerPanel, { ref: this.storyViewerPanelRef, model: this._model, isSpecta: this.state.isSpectaPresentation }))))),
|
|
2071
|
+
React.createElement("div", { ref: this.controlsToolbarRef, className: "jgis-controls-toolbar" }))),
|
|
1847
2072
|
React.createElement(StatusBar, { jgisModel: this._model, loading: this.state.loadingLayer, projection: this.state.viewProjection, scale: this.state.scale }))));
|
|
1848
2073
|
}
|
|
1849
2074
|
}
|