@jupytergis/base 0.6.1 → 0.7.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 (56) hide show
  1. package/lib/annotations/components/Annotation.d.ts +2 -3
  2. package/lib/annotations/components/Annotation.js +2 -9
  3. package/lib/commands/BaseCommandIDs.d.ts +1 -0
  4. package/lib/commands/BaseCommandIDs.js +1 -0
  5. package/lib/commands/index.js +15 -0
  6. package/lib/constants.js +1 -0
  7. package/lib/dialogs/symbology/components/color_ramp/ColorRamp.js +1 -1
  8. package/lib/dialogs/symbology/vector_layer/types/Heatmap.js +2 -2
  9. package/lib/formbuilder/formselectors.js +3 -0
  10. package/lib/index.d.ts +1 -1
  11. package/lib/index.js +1 -1
  12. package/lib/keybindings.json +2 -2
  13. package/lib/mainview/mainView.d.ts +8 -1
  14. package/lib/mainview/mainView.js +24 -1
  15. package/lib/mainview/mainviewwidget.d.ts +11 -4
  16. package/lib/mainview/mainviewwidget.js +3 -2
  17. package/lib/menus.js +4 -0
  18. package/lib/panelview/annotationPanel.d.ts +3 -17
  19. package/lib/panelview/annotationPanel.js +5 -22
  20. package/lib/panelview/components/filter-panel/Filter.d.ts +2 -19
  21. package/lib/panelview/components/filter-panel/Filter.js +26 -59
  22. package/lib/panelview/components/identify-panel/IdentifyPanel.d.ts +6 -14
  23. package/lib/panelview/components/identify-panel/IdentifyPanel.js +14 -52
  24. package/lib/panelview/components/layers.d.ts +10 -12
  25. package/lib/panelview/components/layers.js +109 -79
  26. package/lib/panelview/index.d.ts +0 -1
  27. package/lib/panelview/index.js +0 -1
  28. package/lib/panelview/leftpanel.d.ts +8 -47
  29. package/lib/panelview/leftpanel.js +32 -154
  30. package/lib/panelview/objectproperties.d.ts +20 -15
  31. package/lib/panelview/objectproperties.js +12 -34
  32. package/lib/panelview/rightpanel.d.ts +8 -22
  33. package/lib/panelview/rightpanel.js +32 -77
  34. package/lib/processing/index.js +4 -3
  35. package/lib/shared/components/Tabs.d.ts +7 -1
  36. package/lib/shared/components/Tabs.js +6 -1
  37. package/lib/stacBrowser/components/{StacPanelView.d.ts → StacPanel.d.ts} +2 -2
  38. package/lib/stacBrowser/components/{StacPanelView.js → StacPanel.js} +3 -3
  39. package/lib/stacBrowser/index.d.ts +1 -1
  40. package/lib/stacBrowser/index.js +1 -1
  41. package/lib/tools.js +26 -0
  42. package/lib/types.d.ts +1 -9
  43. package/lib/widget.d.ts +8 -3
  44. package/lib/widget.js +8 -4
  45. package/package.json +7 -5
  46. package/style/base.css +18 -2
  47. package/style/shared/tabs.css +16 -2
  48. package/style/stacBrowser.css +0 -6
  49. package/style/tabPanel.css +91 -0
  50. package/style/temporalSlider.css +1 -0
  51. package/lib/panelview/model.d.ts +0 -19
  52. package/lib/panelview/model.js +0 -30
  53. package/lib/stacBrowser/StacBrowser.d.ts +0 -7
  54. package/lib/stacBrowser/StacBrowser.js +0 -16
  55. package/lib/stacBrowser/StacPanel.d.ts +0 -14
  56. package/lib/stacBrowser/StacPanel.js +0 -16
@@ -1,61 +1,23 @@
1
1
  import { faMagnifyingGlass } from '@fortawesome/free-solid-svg-icons';
2
2
  import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
3
- import { LabIcon, ReactWidget, caretDownIcon } from '@jupyterlab/ui-components';
4
- import { Panel } from '@lumino/widgets';
3
+ import { LabIcon, caretDownIcon } from '@jupyterlab/ui-components';
5
4
  import React, { useEffect, useRef, useState } from 'react';
6
- export class IdentifyPanel extends Panel {
7
- constructor(options) {
8
- super();
9
- this._model = options.model;
10
- this._tracker = options.tracker;
11
- this.id = 'jupytergis::identifyPanel';
12
- this.title.caption = 'Identify';
13
- this.title.label = 'Identify';
14
- this.addClass('jgis-scrollable');
15
- this.addWidget(ReactWidget.create(React.createElement(IdentifyPanelComponent, { controlPanelModel: this._model, tracker: this._tracker })));
16
- }
17
- }
18
- const IdentifyPanelComponent = ({ controlPanelModel, tracker, }) => {
5
+ export const IdentifyPanelComponent = ({ model, }) => {
19
6
  var _a;
20
- const [widgetId, setWidgetId] = useState('');
21
7
  const [features, setFeatures] = useState();
22
8
  const [visibleFeatures, setVisibleFeatures] = useState({
23
9
  0: true,
24
10
  });
25
11
  const [remoteUser, setRemoteUser] = useState(null);
26
- const [jgisModel, setJgisModel] = useState(controlPanelModel === null || controlPanelModel === void 0 ? void 0 : controlPanelModel.jGISModel);
27
12
  const featuresRef = useRef(features);
28
- /**
29
- * Update the model when it changes.
30
- */
31
- controlPanelModel === null || controlPanelModel === void 0 ? void 0 : controlPanelModel.documentChanged.connect((_, widget) => {
32
- setJgisModel(widget === null || widget === void 0 ? void 0 : widget.model);
33
- });
34
13
  // Reset state values when current widget changes
35
- useEffect(() => {
36
- const handleCurrentChanged = () => {
37
- var _a;
38
- if (((_a = tracker.currentWidget) === null || _a === void 0 ? void 0 : _a.id) === widgetId) {
39
- return;
40
- }
41
- if (tracker.currentWidget) {
42
- setWidgetId(tracker.currentWidget.id);
43
- }
44
- setFeatures({});
45
- setVisibleFeatures({ 0: true });
46
- };
47
- tracker.currentChanged.connect(handleCurrentChanged);
48
- return () => {
49
- tracker.currentChanged.disconnect(handleCurrentChanged);
50
- };
51
- }, []);
52
14
  useEffect(() => {
53
15
  featuresRef.current = features;
54
16
  }, [features]);
55
17
  useEffect(() => {
56
18
  const handleClientStateChanged = (sender, clients) => {
57
19
  var _a, _b, _c, _d, _e, _f;
58
- const remoteUserId = (_a = jgisModel === null || jgisModel === void 0 ? void 0 : jgisModel.localState) === null || _a === void 0 ? void 0 : _a.remoteUser;
20
+ const remoteUserId = (_a = model === null || model === void 0 ? void 0 : model.localState) === null || _a === void 0 ? void 0 : _a.remoteUser;
59
21
  // If following a collaborator
60
22
  if (remoteUserId) {
61
23
  const remoteState = clients.get(remoteUserId);
@@ -68,32 +30,31 @@ const IdentifyPanelComponent = ({ controlPanelModel, tracker, }) => {
68
30
  return;
69
31
  }
70
32
  // If not following a collaborator
71
- const identifiedFeatures = (_f = (_e = jgisModel === null || jgisModel === void 0 ? void 0 : jgisModel.localState) === null || _e === void 0 ? void 0 : _e.identifiedFeatures) === null || _f === void 0 ? void 0 : _f.value;
33
+ const identifiedFeatures = (_f = (_e = model === null || model === void 0 ? void 0 : model.localState) === null || _e === void 0 ? void 0 : _e.identifiedFeatures) === null || _f === void 0 ? void 0 : _f.value;
72
34
  if (!identifiedFeatures) {
73
35
  setFeatures({});
74
36
  return;
75
37
  }
76
- if (jgisModel.isIdentifying &&
77
- featuresRef.current !== identifiedFeatures) {
38
+ if (model.isIdentifying && featuresRef.current !== identifiedFeatures) {
78
39
  setFeatures(identifiedFeatures);
79
40
  }
80
41
  };
81
- jgisModel === null || jgisModel === void 0 ? void 0 : jgisModel.clientStateChanged.connect(handleClientStateChanged);
42
+ model === null || model === void 0 ? void 0 : model.clientStateChanged.connect(handleClientStateChanged);
82
43
  return () => {
83
- jgisModel === null || jgisModel === void 0 ? void 0 : jgisModel.clientStateChanged.disconnect(handleClientStateChanged);
44
+ model === null || model === void 0 ? void 0 : model.clientStateChanged.disconnect(handleClientStateChanged);
84
45
  };
85
- }, [jgisModel]);
46
+ }, [model]);
86
47
  const highlightFeatureOnMap = (feature) => {
87
48
  var _a, _b;
88
- (_a = jgisModel === null || jgisModel === void 0 ? void 0 : jgisModel.highlightFeatureSignal) === null || _a === void 0 ? void 0 : _a.emit(feature);
49
+ (_a = model === null || model === void 0 ? void 0 : model.highlightFeatureSignal) === null || _a === void 0 ? void 0 : _a.emit(feature);
89
50
  const geometry = feature.geometry || feature._geometry;
90
- (_b = jgisModel === null || jgisModel === void 0 ? void 0 : jgisModel.flyToGeometrySignal) === null || _b === void 0 ? void 0 : _b.emit(geometry);
51
+ (_b = model === null || model === void 0 ? void 0 : model.flyToGeometrySignal) === null || _b === void 0 ? void 0 : _b.emit(geometry);
91
52
  };
92
53
  const toggleFeatureVisibility = (index) => {
93
54
  setVisibleFeatures(prev => (Object.assign(Object.assign({}, prev), { [index]: !prev[index] })));
94
55
  };
95
56
  return (React.createElement("div", { className: "jgis-identify-wrapper", style: {
96
- border: ((_a = jgisModel === null || jgisModel === void 0 ? void 0 : jgisModel.localState) === null || _a === void 0 ? void 0 : _a.remoteUser)
57
+ border: ((_a = model === null || model === void 0 ? void 0 : model.localState) === null || _a === void 0 ? void 0 : _a.remoteUser)
97
58
  ? `solid 3px ${remoteUser === null || remoteUser === void 0 ? void 0 : remoteUser.color}`
98
59
  : 'unset',
99
60
  } }, features &&
@@ -125,6 +86,7 @@ const IdentifyPanelComponent = ({ controlPanelModel, tracker, }) => {
125
86
  key,
126
87
  ":"),
127
88
  typeof value === 'string' &&
128
- /<\/?[a-z][\s\S]*>/i.test(value) ? (React.createElement("span", { dangerouslySetInnerHTML: { __html: `${value}` } })) : (React.createElement("span", null, String(value)))))))))))));
89
+ /<\/?[a-z][\s\S]*>/i.test(value) ? (React.createElement("span", { dangerouslySetInnerHTML: {
90
+ __html: `${value}`,
91
+ } })) : (React.createElement("span", null, String(value)))))))))))));
129
92
  };
130
- export default IdentifyPanel;
@@ -1,13 +1,11 @@
1
- import { Panel } from '@lumino/widgets';
2
- import { ILayerPanelOptions } from "../leftpanel";
3
- /**
4
- * The layers panel widget.
5
- */
6
- export declare class LayersPanel extends Panel {
7
- constructor(options: ILayerPanelOptions);
8
- private _onDragOver;
9
- private _onDrop;
10
- private _model;
11
- private _state;
12
- private _onSelect;
1
+ import { IJupyterGISModel } from '@jupytergis/schema';
2
+ import { IStateDB } from '@jupyterlab/statedb';
3
+ import { CommandRegistry } from '@lumino/commands';
4
+ import React from 'react';
5
+ interface IBodyProps {
6
+ model: IJupyterGISModel;
7
+ commands: CommandRegistry;
8
+ state: IStateDB;
13
9
  }
10
+ export declare const LayersBodyComponent: React.FC<IBodyProps>;
11
+ export {};
@@ -1,10 +1,9 @@
1
1
  import { DOMUtils } from '@jupyterlab/apputils';
2
- import { Button, LabIcon, ReactWidget, caretDownIcon, } from '@jupyterlab/ui-components';
3
- import { Panel } from '@lumino/widgets';
2
+ import { Button, LabIcon, caretDownIcon } from '@jupyterlab/ui-components';
3
+ import { UUID } from '@lumino/coreutils';
4
4
  import React, { useEffect, useState, } from 'react';
5
- import { icons } from "../../constants";
5
+ import { CommandIDs, icons } from "../../constants";
6
6
  import { nonVisibilityIcon, visibilityIcon } from "../../icons";
7
- const LAYERS_PANEL_CLASS = 'jp-gis-layerPanel';
8
7
  const LAYER_GROUP_CLASS = 'jp-gis-layerGroup';
9
8
  const LAYER_GROUP_HEADER_CLASS = 'jp-gis-layerGroupHeader';
10
9
  const LAYER_GROUP_COLLAPSER_CLASS = 'jp-gis-layerGroupCollapser';
@@ -13,77 +12,111 @@ const LAYER_CLASS = 'jp-gis-layer';
13
12
  const LAYER_TITLE_CLASS = 'jp-gis-layerTitle';
14
13
  const LAYER_ICON_CLASS = 'jp-gis-layerIcon';
15
14
  const LAYER_TEXT_CLASS = 'jp-gis-layerText data-jgis-keybinding';
16
- /**
17
- * The layers panel widget.
18
- */
19
- export class LayersPanel extends Panel {
20
- constructor(options) {
21
- super();
22
- // This happens when dragging over empty space below the tree.
23
- this._onDragOver = (e) => {
24
- e.stopPropagation();
25
- e.preventDefault();
26
- this.node.appendChild(Private.dragIndicator);
27
- Private.dragInfo.dragOverElement = null;
28
- Private.dragInfo.dragOverPosition = null;
29
- };
30
- this._onDrop = (e) => {
31
- Private.dragIndicator.style.display = 'none';
32
- if (this._model === undefined) {
33
- return;
34
- }
35
- const { jGISModel: model } = this._model;
36
- const { draggedElement, dragOverElement, dragOverPosition } = Private.dragInfo;
37
- if (dragOverElement === 'error') {
38
- return;
39
- }
40
- if (!draggedElement) {
41
- return;
42
- }
43
- const draggedId = draggedElement.dataset.id;
44
- if (!draggedId) {
45
- return;
46
- }
47
- // Element has been dropped in the empty zone below the tree.
48
- if (dragOverElement === null) {
49
- model === null || model === void 0 ? void 0 : model.moveItemsToGroup([draggedId], '', 0);
50
- return;
51
- }
52
- const dragOverId = dragOverElement.dataset.id;
53
- if (!dragOverId) {
54
- return;
55
- }
56
- // Handle the special case where we want to drop the element on top of the first
57
- // element of a group.
58
- if (dragOverElement.classList.contains(LAYER_GROUP_HEADER_CLASS) &&
59
- dragOverPosition === 'below') {
60
- model === null || model === void 0 ? void 0 : model.moveItemsToGroup([draggedId], dragOverId);
15
+ export const LayersBodyComponent = props => {
16
+ const model = props.model;
17
+ const id = UUID.uuid4();
18
+ const [layerTree, setLayerTree] = useState((model === null || model === void 0 ? void 0 : model.getLayerTree()) || []);
19
+ const notifyCommands = () => {
20
+ // Notify commands that need updating
21
+ props.commands.notifyCommandChanged(CommandIDs.identify);
22
+ props.commands.notifyCommandChanged(CommandIDs.temporalController);
23
+ };
24
+ const _onDragOver = (e) => {
25
+ e.stopPropagation();
26
+ e.preventDefault();
27
+ Private.dragInfo.dragOverElement = null;
28
+ Private.dragInfo.dragOverPosition = null;
29
+ };
30
+ const _onDrop = (e) => {
31
+ Private.dragIndicator.style.display = 'none';
32
+ if (model === undefined) {
33
+ return;
34
+ }
35
+ const { draggedElement, dragOverElement, dragOverPosition } = Private.dragInfo;
36
+ if (dragOverElement === 'error') {
37
+ return;
38
+ }
39
+ if (!draggedElement) {
40
+ return;
41
+ }
42
+ const draggedId = draggedElement.dataset.id;
43
+ if (!draggedId) {
44
+ return;
45
+ }
46
+ // Element has been dropped in the empty zone below the tree.
47
+ if (dragOverElement === null) {
48
+ model === null || model === void 0 ? void 0 : model.moveItemsToGroup([draggedId], '', 0);
49
+ return;
50
+ }
51
+ const dragOverId = dragOverElement.dataset.id;
52
+ if (!dragOverId) {
53
+ return;
54
+ }
55
+ // Handle the special case where we want to drop the element on top of the first
56
+ // element of a group.
57
+ if (dragOverElement.classList.contains(LAYER_GROUP_HEADER_CLASS) &&
58
+ dragOverPosition === 'below') {
59
+ model === null || model === void 0 ? void 0 : model.moveItemsToGroup([draggedId], dragOverId);
60
+ return;
61
+ }
62
+ model === null || model === void 0 ? void 0 : model.moveItemRelatedTo(draggedId, dragOverId, dragOverPosition === 'above');
63
+ };
64
+ const onSelect = ({ type, item, nodeId, event, }) => {
65
+ var _a, _b;
66
+ if (!props.model || !nodeId) {
67
+ return;
68
+ }
69
+ const selectedValue = (_b = (_a = props.model.localState) === null || _a === void 0 ? void 0 : _a.selected) === null || _b === void 0 ? void 0 : _b.value;
70
+ const node = document.getElementById(nodeId);
71
+ if (!node) {
72
+ return;
73
+ }
74
+ node.tabIndex = 0;
75
+ node.focus();
76
+ // Early return if no selection exists
77
+ if (!selectedValue) {
78
+ resetSelected(type, nodeId, item);
79
+ return;
80
+ }
81
+ // Don't want to reset selected if right clicking a selected item
82
+ if (!event.ctrlKey && event.button === 2 && item in selectedValue) {
83
+ return;
84
+ }
85
+ // Reset selection for normal left click
86
+ if (!event.ctrlKey) {
87
+ resetSelected(type, nodeId, item);
88
+ return;
89
+ }
90
+ if (nodeId) {
91
+ // Check if new selection is the same type as previous selections
92
+ const isSelectedSameType = Object.values(selectedValue).some(selection => selection.type === type);
93
+ if (!isSelectedSameType) {
94
+ // Selecting a new type, so reset selected
95
+ resetSelected(type, nodeId, item);
61
96
  return;
62
97
  }
63
- model === null || model === void 0 ? void 0 : model.moveItemRelatedTo(draggedId, dragOverId, dragOverPosition === 'above');
64
- };
65
- this._model = options.model;
66
- this._onSelect = options.onSelect;
67
- this._state = options.state;
68
- this.id = 'jupytergis::layerTree';
69
- this.addClass(LAYERS_PANEL_CLASS);
70
- this.addWidget(ReactWidget.create(React.createElement(LayersBodyComponent, { model: this._model, onSelect: this._onSelect, state: this._state })));
71
- this.node.ondragover = this._onDragOver;
72
- this.node.ondrop = this._onDrop;
73
- }
74
- }
75
- /**
76
- * The body component of the panel.
77
- */
78
- const LayersBodyComponent = props => {
79
- var _a, _b;
80
- const [model, setModel] = useState((_a = props.model) === null || _a === void 0 ? void 0 : _a.jGISModel);
81
- const [layerTree, setLayerTree] = useState((model === null || model === void 0 ? void 0 : model.getLayerTree()) || []);
98
+ // If types are the same add the selection
99
+ const updatedSelectedValue = Object.assign(Object.assign({}, selectedValue), { [item]: { type, selectedNodeId: nodeId } });
100
+ props.model.syncSelected(updatedSelectedValue, id);
101
+ notifyCommands();
102
+ }
103
+ };
104
+ const resetSelected = (type, nodeId, item) => {
105
+ const selection = {};
106
+ if (item && nodeId) {
107
+ selection[item] = {
108
+ type,
109
+ selectedNodeId: nodeId,
110
+ };
111
+ }
112
+ props.model.syncSelected(selection, id);
113
+ notifyCommands();
114
+ };
82
115
  /**
83
116
  * Propagate the layer selection.
84
117
  */
85
118
  const onItemClick = ({ type, item, nodeId, event, }) => {
86
- props.onSelect({ type, item, nodeId, event });
119
+ onSelect({ type, item, nodeId, event });
87
120
  };
88
121
  /**
89
122
  * Listen to the layers and layer tree changes.
@@ -100,15 +133,7 @@ const LayersBodyComponent = props => {
100
133
  model === null || model === void 0 ? void 0 : model.sharedModel.layerTreeChanged.disconnect(updateLayers);
101
134
  };
102
135
  }, [model]);
103
- /**
104
- * Update the model when it changes.
105
- */
106
- (_b = props.model) === null || _b === void 0 ? void 0 : _b.documentChanged.connect((_, widget) => {
107
- var _a;
108
- setModel(widget === null || widget === void 0 ? void 0 : widget.model);
109
- setLayerTree(((_a = widget === null || widget === void 0 ? void 0 : widget.model) === null || _a === void 0 ? void 0 : _a.getLayerTree()) || []);
110
- });
111
- return (React.createElement("div", { id: "jp-gis-layer-tree" }, layerTree
136
+ return (React.createElement("div", { id: "jp-gis-layer-tree", onDrop: _onDrop, onDragOver: _onDragOver }, layerTree
112
137
  .slice()
113
138
  .reverse()
114
139
  .map(layer => typeof layer === 'string' ? (React.createElement(LayerComponent, { key: layer, gisModel: model, layerId: layer, onClick: onItemClick })) : (React.createElement(LayerGroupComponent, { key: layer.name, gisModel: model, group: layer, onClick: onItemClick, state: props.state })))));
@@ -216,7 +241,12 @@ const LayerComponent = props => {
216
241
  const setSelection = (event) => {
217
242
  var _a;
218
243
  const childId = (_a = event.currentTarget.children.namedItem(id)) === null || _a === void 0 ? void 0 : _a.id;
219
- onClick({ type: 'layer', item: layerId, nodeId: childId, event });
244
+ onClick({
245
+ type: 'layer',
246
+ item: layerId,
247
+ nodeId: childId,
248
+ event,
249
+ });
220
250
  };
221
251
  return (React.createElement("div", { className: `${LAYER_ITEM_CLASS} ${LAYER_CLASS}${selected ? ' jp-mod-selected' : ''}`, draggable: true, onDragStart: Private.onDragStart, onDragOver: Private.onDragOver, onDragEnd: Private.onDragEnd, "data-id": layerId },
222
252
  React.createElement("div", { className: LAYER_TITLE_CLASS, onClick: setSelection, onContextMenu: setSelection },
@@ -1,5 +1,4 @@
1
1
  export * from './header';
2
2
  export * from './leftpanel';
3
- export * from './model';
4
3
  export * from './objectproperties';
5
4
  export * from './rightpanel';
@@ -1,5 +1,4 @@
1
1
  export * from './header';
2
2
  export * from './leftpanel';
3
- export * from './model';
4
3
  export * from './objectproperties';
5
4
  export * from './rightpanel';
@@ -1,57 +1,18 @@
1
- import { IJupyterGISTracker, JupyterGISDoc, SelectionType } from '@jupytergis/schema';
1
+ import { IJupyterGISModel, SelectionType } from '@jupytergis/schema';
2
2
  import { IStateDB } from '@jupyterlab/statedb';
3
- import { SidePanel } from '@jupyterlab/ui-components';
4
3
  import { CommandRegistry } from '@lumino/commands';
5
- import { Message } from '@lumino/messaging';
6
4
  import { MouseEvent as ReactMouseEvent } from 'react';
7
- import { IControlPanelModel } from "../types";
8
- /**
9
- * Options of the left panel widget.
10
- */
11
- export interface ILeftPanelOptions {
12
- model: IControlPanelModel;
13
- onSelect: ({ type, item, nodeId }: ILeftPanelClickHandlerParams) => void;
14
- }
15
- export interface ILayerPanelOptions extends ILeftPanelOptions {
16
- state: IStateDB;
17
- }
5
+ import * as React from 'react';
18
6
  export interface ILeftPanelClickHandlerParams {
19
7
  type: SelectionType;
20
8
  item: string;
21
9
  nodeId?: string;
22
10
  event: ReactMouseEvent;
23
11
  }
24
- export declare class LeftPanelWidget extends SidePanel {
25
- constructor(options: LeftPanelWidget.IOptions);
26
- dispose(): void;
27
- protected onAfterAttach(msg: Message): void;
28
- protected onBeforeDetach(msg: Message): void;
29
- handleEvent(event: Event): void;
30
- private _mouseUpEvent;
31
- /**
32
- * Function to call when a layer is selected from a component of the panel.
33
- *
34
- * @param item - the selected layer or group.
35
- */
36
- private _onSelect;
37
- resetSelected(type: SelectionType, nodeId?: string, item?: string): void;
38
- private _notifyCommands;
39
- private _handleFileChange;
40
- private _currentModel;
41
- private _lastSelectedNodeId;
42
- private _model;
43
- private _state;
44
- private _commands;
45
- }
46
- export declare namespace LeftPanelWidget {
47
- interface IOptions {
48
- model: IControlPanelModel;
49
- tracker: IJupyterGISTracker;
50
- state: IStateDB;
51
- commands: CommandRegistry;
52
- }
53
- interface IProps {
54
- filePath?: string;
55
- sharedModel?: JupyterGISDoc;
56
- }
12
+ interface ILeftPanelProps {
13
+ model: IJupyterGISModel;
14
+ state: IStateDB;
15
+ commands: CommandRegistry;
57
16
  }
17
+ export declare const LeftPanel: React.FC<ILeftPanelProps>;
18
+ export {};
@@ -1,154 +1,32 @@
1
- import { SidePanel } from '@jupyterlab/ui-components';
2
- import { CommandIDs } from "../constants";
3
- import StacPanel from "../stacBrowser/StacPanel";
4
- import { FilterPanel } from './components/filter-panel/Filter';
5
- import { LayersPanel } from './components/layers';
6
- import { ControlPanelHeader } from './header';
7
- export class LeftPanelWidget extends SidePanel {
8
- constructor(options) {
9
- super();
10
- /**
11
- * Function to call when a layer is selected from a component of the panel.
12
- *
13
- * @param item - the selected layer or group.
14
- */
15
- this._onSelect = ({ type, item, nodeId, event, }) => {
16
- var _a, _b;
17
- if (!this._model || !nodeId) {
18
- return;
19
- }
20
- const { jGISModel } = this._model;
21
- const selectedValue = (_b = (_a = jGISModel === null || jGISModel === void 0 ? void 0 : jGISModel.localState) === null || _a === void 0 ? void 0 : _a.selected) === null || _b === void 0 ? void 0 : _b.value;
22
- const node = document.getElementById(nodeId);
23
- if (!node) {
24
- return;
25
- }
26
- node.tabIndex = 0;
27
- node.focus();
28
- // Early return if no selection exists
29
- if (!selectedValue) {
30
- this.resetSelected(type, nodeId, item);
31
- return;
32
- }
33
- // Don't want to reset selected if right clicking a selected item
34
- if (!event.ctrlKey && event.button === 2 && item in selectedValue) {
35
- return;
36
- }
37
- // Reset selection for normal left click
38
- if (!event.ctrlKey) {
39
- this.resetSelected(type, nodeId, item);
40
- return;
41
- }
42
- if (nodeId) {
43
- // Check if new selection is the same type as previous selections
44
- const isSelectedSameType = Object.values(selectedValue).some(selection => selection.type === type);
45
- if (!isSelectedSameType) {
46
- // Selecting a new type, so reset selected
47
- this.resetSelected(type, nodeId, item);
48
- return;
49
- }
50
- // If types are the same add the selection
51
- const updatedSelectedValue = Object.assign(Object.assign({}, selectedValue), { [item]: { type, selectedNodeId: nodeId } });
52
- this._lastSelectedNodeId = nodeId;
53
- jGISModel.syncSelected(updatedSelectedValue, this.id);
54
- this._notifyCommands();
55
- }
56
- };
57
- this.addClass('jGIS-sidepanel-widget');
58
- this.addClass('data-jgis-keybinding');
59
- this.node.tabIndex = 0;
60
- this._model = options.model;
61
- this._state = options.state;
62
- this._commands = options.commands;
63
- const header = new ControlPanelHeader();
64
- this.header.addWidget(header);
65
- const layerTree = new LayersPanel({
66
- model: this._model,
67
- state: this._state,
68
- onSelect: this._onSelect,
69
- });
70
- layerTree.title.caption = 'Layer tree';
71
- layerTree.title.label = 'Layers';
72
- this.addWidget(layerTree);
73
- const stacPanel = new StacPanel({
74
- model: this._model,
75
- tracker: options.tracker,
76
- });
77
- stacPanel.title.caption = 'STAC';
78
- stacPanel.title.label = 'STAC';
79
- this.addWidget(stacPanel);
80
- const filterPanel = new FilterPanel({
81
- model: this._model,
82
- tracker: options.tracker,
83
- });
84
- filterPanel.title.caption = 'Filters';
85
- filterPanel.title.label = 'Filters';
86
- this.addWidget(filterPanel);
87
- this._handleFileChange = () => {
88
- var _a;
89
- header.title.label = ((_a = this._currentModel) === null || _a === void 0 ? void 0 : _a.filePath) || '-';
90
- };
91
- options.tracker.currentChanged.connect((_, changed) => {
92
- if (changed) {
93
- if (this._currentModel) {
94
- this._currentModel.pathChanged.disconnect(this._handleFileChange);
95
- }
96
- this._currentModel = changed.model;
97
- header.title.label = changed.model.filePath;
98
- this._currentModel.pathChanged.connect(this._handleFileChange);
99
- }
100
- else {
101
- header.title.label = '-';
102
- this._currentModel = null;
103
- }
104
- });
105
- }
106
- dispose() {
107
- super.dispose();
108
- }
109
- onAfterAttach(msg) {
110
- super.onAfterAttach(msg);
111
- const node = this.node;
112
- node.addEventListener('mouseup', this);
113
- }
114
- onBeforeDetach(msg) {
115
- super.onBeforeDetach(msg);
116
- const node = this.node;
117
- node.removeEventListener('mouseup', this);
118
- }
119
- handleEvent(event) {
120
- switch (event.type) {
121
- case 'mouseup':
122
- this._mouseUpEvent(event);
123
- break;
124
- default:
125
- break;
126
- }
127
- }
128
- _mouseUpEvent(event) {
129
- // If we click on empty space in the layer panel, keep the focus on the last selected element
130
- const node = document.getElementById(this._lastSelectedNodeId);
131
- if (!node) {
132
- return;
133
- }
134
- node.focus();
135
- }
136
- resetSelected(type, nodeId, item) {
137
- var _a, _b;
138
- const selection = {};
139
- if (item && nodeId) {
140
- selection[item] = {
141
- type,
142
- selectedNodeId: nodeId,
143
- };
144
- this._lastSelectedNodeId = nodeId;
145
- }
146
- (_b = (_a = this._model) === null || _a === void 0 ? void 0 : _a.jGISModel) === null || _b === void 0 ? void 0 : _b.syncSelected(selection, this.id);
147
- this._notifyCommands();
148
- }
149
- _notifyCommands() {
150
- // Notify commands that need updating
151
- this._commands.notifyCommandChanged(CommandIDs.identify);
152
- this._commands.notifyCommandChanged(CommandIDs.temporalController);
153
- }
154
- }
1
+ import * as React from 'react';
2
+ import { LayersBodyComponent } from './components/layers';
3
+ import { PanelTabs, TabsContent, TabsList, TabsTrigger, } from '../shared/components/Tabs';
4
+ import StacPanel from '../stacBrowser/components/StacPanel';
5
+ import FilterComponent from './components/filter-panel/Filter';
6
+ export const LeftPanel = (props) => {
7
+ const tabInfo = [
8
+ { name: 'layers', title: 'Layers' },
9
+ { name: 'stac', title: 'Stac Browser' },
10
+ { name: 'filters', title: 'Filters' },
11
+ ];
12
+ const [curTab, setCurTab] = React.useState(tabInfo[0].name);
13
+ return (React.createElement("div", { className: "jgis-left-panel-container" },
14
+ React.createElement(PanelTabs, { curTab: curTab, className: "jgis-panel-tabs" },
15
+ React.createElement(TabsList, null, tabInfo.map(e => {
16
+ return (React.createElement(TabsTrigger, { className: "jGIS-layer-browser-category", value: e.name, onClick: () => {
17
+ if (curTab !== e.name) {
18
+ setCurTab(e.name);
19
+ }
20
+ else {
21
+ setCurTab('');
22
+ }
23
+ } }, e.title));
24
+ })),
25
+ React.createElement(TabsContent, { value: "layers", className: "jgis-panel-tab-content jp-gis-layerPanel" },
26
+ React.createElement(LayersBodyComponent, { model: props.model, commands: props.commands, state: props.state })),
27
+ React.createElement(TabsContent, { value: "stac" },
28
+ React.createElement(StacPanel, { model: props.model })),
29
+ React.createElement(TabsContent, { value: "filters", className: "jgis-panel-tab-content" },
30
+ React.createElement(FilterComponent, { model: props.model }),
31
+ ","))));
32
+ };