@jupytergis/base 0.2.1 → 0.4.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 (95) hide show
  1. package/lib/annotations/components/Annotation.js +2 -2
  2. package/lib/annotations/model.d.ts +6 -7
  3. package/lib/annotations/model.js +15 -15
  4. package/lib/commands.d.ts +2 -3
  5. package/lib/commands.js +146 -62
  6. package/lib/constants.d.ts +3 -0
  7. package/lib/constants.js +5 -1
  8. package/lib/dialogs/formdialog.d.ts +5 -0
  9. package/lib/dialogs/formdialog.js +2 -2
  10. package/lib/dialogs/layerBrowserDialog.d.ts +4 -5
  11. package/lib/dialogs/layerBrowserDialog.js +9 -9
  12. package/lib/dialogs/symbology/components/color_ramp/ModeSelectRow.js +2 -1
  13. package/lib/dialogs/symbology/hooks/useGetBandInfo.d.ts +26 -0
  14. package/lib/dialogs/symbology/hooks/useGetBandInfo.js +64 -0
  15. package/lib/dialogs/symbology/hooks/useGetProperties.d.ts +1 -1
  16. package/lib/dialogs/symbology/hooks/useGetProperties.js +12 -9
  17. package/lib/dialogs/symbology/symbologyDialog.d.ts +2 -3
  18. package/lib/dialogs/symbology/symbologyDialog.js +10 -9
  19. package/lib/dialogs/symbology/tiff_layer/TiffRendering.d.ts +1 -1
  20. package/lib/dialogs/symbology/tiff_layer/TiffRendering.js +16 -3
  21. package/lib/dialogs/symbology/tiff_layer/components/BandRow.d.ts +16 -3
  22. package/lib/dialogs/symbology/tiff_layer/components/BandRow.js +21 -7
  23. package/lib/dialogs/symbology/tiff_layer/types/MultibandColor.d.ts +4 -0
  24. package/lib/dialogs/symbology/tiff_layer/types/MultibandColor.js +85 -0
  25. package/lib/dialogs/symbology/tiff_layer/types/SingleBandPseudoColor.d.ts +1 -20
  26. package/lib/dialogs/symbology/tiff_layer/types/SingleBandPseudoColor.js +25 -65
  27. package/lib/dialogs/symbology/vector_layer/VectorRendering.d.ts +1 -1
  28. package/lib/dialogs/symbology/vector_layer/VectorRendering.js +18 -13
  29. package/lib/dialogs/symbology/vector_layer/types/Categorized.d.ts +1 -1
  30. package/lib/dialogs/symbology/vector_layer/types/Categorized.js +30 -19
  31. package/lib/dialogs/symbology/vector_layer/types/Graduated.d.ts +1 -1
  32. package/lib/dialogs/symbology/vector_layer/types/Graduated.js +16 -13
  33. package/lib/dialogs/symbology/vector_layer/types/Heatmap.d.ts +4 -0
  34. package/lib/dialogs/symbology/vector_layer/types/Heatmap.js +77 -0
  35. package/lib/dialogs/symbology/vector_layer/types/SimpleSymbol.d.ts +1 -1
  36. package/lib/dialogs/symbology/vector_layer/types/SimpleSymbol.js +4 -3
  37. package/lib/formbuilder/creationform.d.ts +6 -2
  38. package/lib/formbuilder/creationform.js +6 -6
  39. package/lib/formbuilder/editform.d.ts +2 -2
  40. package/lib/formbuilder/editform.js +14 -9
  41. package/lib/formbuilder/formselectors.js +11 -1
  42. package/lib/formbuilder/objectform/baseform.d.ts +12 -3
  43. package/lib/formbuilder/objectform/baseform.js +39 -0
  44. package/lib/formbuilder/objectform/fileselectorwidget.d.ts +2 -0
  45. package/lib/formbuilder/objectform/fileselectorwidget.js +88 -0
  46. package/lib/formbuilder/objectform/geojsonsource.d.ts +5 -7
  47. package/lib/formbuilder/objectform/geojsonsource.js +8 -24
  48. package/lib/formbuilder/objectform/geotiffsource.d.ts +5 -1
  49. package/lib/formbuilder/objectform/geotiffsource.js +64 -18
  50. package/lib/formbuilder/objectform/heatmapLayerForm.d.ts +11 -0
  51. package/lib/formbuilder/objectform/heatmapLayerForm.js +60 -0
  52. package/lib/formbuilder/objectform/layerform.d.ts +2 -0
  53. package/lib/formbuilder/objectform/layerform.js +6 -0
  54. package/lib/formbuilder/objectform/pathbasedsource.d.ts +19 -0
  55. package/lib/formbuilder/objectform/pathbasedsource.js +98 -0
  56. package/lib/formbuilder/objectform/vectorlayerform.d.ts +0 -2
  57. package/lib/formbuilder/objectform/vectorlayerform.js +0 -59
  58. package/lib/icons.d.ts +1 -0
  59. package/lib/icons.js +5 -0
  60. package/lib/keybindings.json +62 -0
  61. package/lib/mainview/TemporalSlider.d.ts +8 -0
  62. package/lib/mainview/TemporalSlider.js +303 -0
  63. package/lib/mainview/mainView.d.ts +46 -8
  64. package/lib/mainview/mainView.js +431 -144
  65. package/lib/mainview/mainviewmodel.d.ts +4 -0
  66. package/lib/mainview/mainviewmodel.js +4 -0
  67. package/lib/mainview/mainviewwidget.d.ts +0 -2
  68. package/lib/mainview/mainviewwidget.js +0 -2
  69. package/lib/panelview/annotationPanel.js +5 -5
  70. package/lib/panelview/components/filter-panel/Filter.js +8 -24
  71. package/lib/panelview/components/identify-panel/IdentifyPanel.js +1 -1
  72. package/lib/panelview/components/layers.js +2 -2
  73. package/lib/panelview/components/sources.js +1 -1
  74. package/lib/panelview/leftpanel.d.ts +3 -0
  75. package/lib/panelview/leftpanel.js +5 -1
  76. package/lib/panelview/model.js +8 -8
  77. package/lib/panelview/objectproperties.js +10 -10
  78. package/lib/panelview/rightpanel.d.ts +1 -1
  79. package/lib/panelview/rightpanel.js +10 -10
  80. package/lib/statusbar/StatusBar.d.ts +13 -0
  81. package/lib/statusbar/StatusBar.js +52 -0
  82. package/lib/toolbar/widget.d.ts +1 -1
  83. package/lib/toolbar/widget.js +44 -37
  84. package/lib/tools.d.ts +50 -7
  85. package/lib/tools.js +394 -12
  86. package/lib/types.d.ts +2 -0
  87. package/lib/widget.d.ts +29 -5
  88. package/lib/widget.js +41 -7
  89. package/package.json +17 -5
  90. package/style/base.css +11 -0
  91. package/style/icons/logo_mini_qgz.svg +31 -0
  92. package/style/leftPanel.css +8 -0
  93. package/style/statusBar.css +16 -0
  94. package/style/symbologyDialog.css +7 -1
  95. package/style/temporalSlider.css +47 -0
@@ -1,5 +1,6 @@
1
1
  import { IAnnotation, IJupyterGISModel } from '@jupytergis/schema';
2
2
  import { ObservableMap } from '@jupyterlab/observables';
3
+ import { CommandRegistry } from '@lumino/commands';
3
4
  import { JSONValue } from '@lumino/coreutils';
4
5
  import { IDisposable } from '@lumino/disposable';
5
6
  export declare class MainViewModel implements IDisposable {
@@ -8,12 +9,14 @@ export declare class MainViewModel implements IDisposable {
8
9
  get id(): string;
9
10
  get jGISModel(): IJupyterGISModel;
10
11
  get viewSettingChanged(): import("@lumino/signaling").ISignal<ObservableMap<JSONValue>, import("@jupyterlab/observables").IObservableMap.IChangedArgs<JSONValue>>;
12
+ get commands(): CommandRegistry;
11
13
  dispose(): void;
12
14
  initSignal(): void;
13
15
  addAnnotation(value: IAnnotation): void;
14
16
  private _onsharedLayersChanged;
15
17
  private _jGISModel;
16
18
  private _viewSetting;
19
+ private _commands;
17
20
  private _id;
18
21
  private _isDisposed;
19
22
  }
@@ -21,5 +24,6 @@ export declare namespace MainViewModel {
21
24
  interface IOptions {
22
25
  jGISModel: IJupyterGISModel;
23
26
  viewSetting: ObservableMap<JSONValue>;
27
+ commands: CommandRegistry;
24
28
  }
25
29
  }
@@ -4,6 +4,7 @@ export class MainViewModel {
4
4
  this._isDisposed = false;
5
5
  this._jGISModel = options.jGISModel;
6
6
  this._viewSetting = options.viewSetting;
7
+ this._commands = options.commands;
7
8
  }
8
9
  get isDisposed() {
9
10
  return this._isDisposed;
@@ -17,6 +18,9 @@ export class MainViewModel {
17
18
  get viewSettingChanged() {
18
19
  return this._viewSetting.changed;
19
20
  }
21
+ get commands() {
22
+ return this._commands;
23
+ }
20
24
  dispose() {
21
25
  if (this._isDisposed) {
22
26
  return;
@@ -3,8 +3,6 @@ import { MainViewModel } from './mainviewmodel';
3
3
  export declare class JupyterGISMainViewPanel extends ReactWidget {
4
4
  /**
5
5
  * Construct a `JupyterGISPanel`.
6
- *
7
- * @param context - The documents context.
8
6
  */
9
7
  constructor(options: {
10
8
  mainViewModel: MainViewModel;
@@ -4,8 +4,6 @@ import { MainView } from './mainView';
4
4
  export class JupyterGISMainViewPanel extends ReactWidget {
5
5
  /**
6
6
  * Construct a `JupyterGISPanel`.
7
- *
8
- * @param context - The documents context.
9
7
  */
10
8
  constructor(options) {
11
9
  super();
@@ -9,12 +9,12 @@ export class AnnotationsPanel extends Component {
9
9
  };
10
10
  this._annotationModel = props.annotationModel;
11
11
  this._rightPanelModel = props.rightPanelModel;
12
- this._annotationModel.contextChanged.connect(async () => {
13
- var _a, _b, _c, _d, _e, _f, _g, _h;
14
- await ((_b = (_a = this._annotationModel) === null || _a === void 0 ? void 0 : _a.context) === null || _b === void 0 ? void 0 : _b.ready);
15
- (_e = (_d = (_c = this._annotationModel) === null || _c === void 0 ? void 0 : _c.context) === null || _d === void 0 ? void 0 : _d.model) === null || _e === void 0 ? void 0 : _e.sharedMetadataChanged.disconnect(updateCallback);
12
+ this._annotationModel.modelChanged.connect(async () => {
13
+ // await this._annotationModel?.context?.ready;
14
+ var _a, _b, _c, _d;
15
+ (_b = (_a = this._annotationModel) === null || _a === void 0 ? void 0 : _a.model) === null || _b === void 0 ? void 0 : _b.sharedMetadataChanged.disconnect(updateCallback);
16
16
  this._annotationModel = props.annotationModel;
17
- (_h = (_g = (_f = this._annotationModel) === null || _f === void 0 ? void 0 : _f.context) === null || _g === void 0 ? void 0 : _g.model) === null || _h === void 0 ? void 0 : _h.sharedMetadataChanged.connect(updateCallback);
17
+ (_d = (_c = this._annotationModel) === null || _c === void 0 ? void 0 : _c.model) === null || _d === void 0 ? void 0 : _d.sharedMetadataChanged.connect(updateCallback);
18
18
  this.forceUpdate();
19
19
  });
20
20
  }
@@ -2,7 +2,7 @@ import { Button, ReactWidget } from '@jupyterlab/ui-components';
2
2
  import { Panel } from '@lumino/widgets';
3
3
  import { cloneDeep } from 'lodash';
4
4
  import React, { useEffect, useRef, useState } from 'react';
5
- import { debounce, getLayerTileInfo } from '../../../tools';
5
+ import { debounce, loadFile } from '../../../tools';
6
6
  import FilterRow from './FilterRow';
7
7
  /**
8
8
  * The filters panel widget.
@@ -28,7 +28,7 @@ const FilterComponent = (props) => {
28
28
  const [featuresInLayer, setFeaturesInLayer] = useState({});
29
29
  const [model, setModel] = useState(props.model.jGISModel);
30
30
  (_a = props.model) === null || _a === void 0 ? void 0 : _a.documentChanged.connect((_, widget) => {
31
- setModel(widget === null || widget === void 0 ? void 0 : widget.context.model);
31
+ setModel(widget === null || widget === void 0 ? void 0 : widget.model);
32
32
  });
33
33
  // Reset state values when current widget changes
34
34
  useEffect(() => {
@@ -107,13 +107,12 @@ const FilterComponent = (props) => {
107
107
  featuresInLayerRef.current = featuresInLayer;
108
108
  }, [featuresInLayer]);
109
109
  const buildFilterObject = async (currentLayer) => {
110
- var _a, _b, _c, _d;
110
+ var _a, _b;
111
111
  if (!model) {
112
112
  return;
113
113
  }
114
114
  const layer = model.getLayer(currentLayer !== null && currentLayer !== void 0 ? currentLayer : selectedLayer);
115
115
  const source = model.getSource((_a = layer === null || layer === void 0 ? void 0 : layer.parameters) === null || _a === void 0 ? void 0 : _a.source);
116
- const { latitude, longitude, extent, zoom } = model.getOptions();
117
116
  if (!source || !layer) {
118
117
  return;
119
118
  }
@@ -130,27 +129,12 @@ const FilterComponent = (props) => {
130
129
  });
131
130
  }
132
131
  switch (source.type) {
133
- case 'VectorTileSource': {
134
- try {
135
- const tile = await getLayerTileInfo((_b = source === null || source === void 0 ? void 0 : source.parameters) === null || _b === void 0 ? void 0 : _b.url, {
136
- latitude,
137
- longitude,
138
- extent,
139
- zoom
140
- });
141
- const layerValue = tile.layers[(_c = layer.parameters) === null || _c === void 0 ? void 0 : _c.sourceLayer];
142
- for (let i = 0; i < layerValue.length; i++) {
143
- const feature = layerValue.feature(i);
144
- addFeatureValue(feature.properties, aggregatedProperties);
145
- }
146
- }
147
- catch (error) {
148
- console.warn(`Error fetching tile info: ${error}`);
149
- }
150
- break;
151
- }
152
132
  case 'GeoJSONSource': {
153
- const data = await (model === null || model === void 0 ? void 0 : model.readGeoJSON((_d = source.parameters) === null || _d === void 0 ? void 0 : _d.path));
133
+ const data = await loadFile({
134
+ filepath: (_b = source.parameters) === null || _b === void 0 ? void 0 : _b.path,
135
+ type: 'GeoJSONSource',
136
+ model: model
137
+ });
154
138
  data === null || data === void 0 ? void 0 : data.features.forEach((feature) => {
155
139
  feature.properties &&
156
140
  addFeatureValue(feature.properties, aggregatedProperties);
@@ -26,7 +26,7 @@ const IdentifyPanelComponent = ({ controlPanelModel, tracker }) => {
26
26
  * Update the model when it changes.
27
27
  */
28
28
  controlPanelModel === null || controlPanelModel === void 0 ? void 0 : controlPanelModel.documentChanged.connect((_, widget) => {
29
- setJgisModel(widget === null || widget === void 0 ? void 0 : widget.context.model);
29
+ setJgisModel(widget === null || widget === void 0 ? void 0 : widget.model);
30
30
  });
31
31
  // Reset state values when current widget changes
32
32
  useEffect(() => {
@@ -104,8 +104,8 @@ function LayersBodyComponent(props) {
104
104
  */
105
105
  (_b = props.model) === null || _b === void 0 ? void 0 : _b.documentChanged.connect((_, widget) => {
106
106
  var _a;
107
- setModel(widget === null || widget === void 0 ? void 0 : widget.context.model);
108
- setLayerTree(((_a = widget === null || widget === void 0 ? void 0 : widget.context.model) === null || _a === void 0 ? void 0 : _a.getLayerTree()) || []);
107
+ setModel(widget === null || widget === void 0 ? void 0 : widget.model);
108
+ setLayerTree(((_a = widget === null || widget === void 0 ? void 0 : widget.model) === null || _a === void 0 ? void 0 : _a.getLayerTree()) || []);
109
109
  });
110
110
  return (React.createElement("div", { id: "jp-gis-layer-tree" }, layerTree
111
111
  .slice()
@@ -55,7 +55,7 @@ function SourcesBodyComponent(props) {
55
55
  * Update the model when it changes.
56
56
  */
57
57
  (_b = props.model) === null || _b === void 0 ? void 0 : _b.documentChanged.connect((_, widget) => {
58
- setModel(widget === null || widget === void 0 ? void 0 : widget.context.model);
58
+ setModel(widget === null || widget === void 0 ? void 0 : widget.model);
59
59
  });
60
60
  return (React.createElement("div", { id: "jp-gis-sources" }, sourceIds.map(sourceId => {
61
61
  return (React.createElement(SourceComponent, { key: `source-${sourceId}`, gisModel: model, sourceId: sourceId, onClick: onItemClick }));
@@ -4,6 +4,7 @@ import { SidePanel } from '@jupyterlab/ui-components';
4
4
  import { Message } from '@lumino/messaging';
5
5
  import { MouseEvent as ReactMouseEvent } from 'react';
6
6
  import { IControlPanelModel } from '../types';
7
+ import { CommandRegistry } from '@lumino/commands';
7
8
  /**
8
9
  * Options of the left panel widget.
9
10
  */
@@ -37,12 +38,14 @@ export declare class LeftPanelWidget extends SidePanel {
37
38
  private _lastSelectedNodeId;
38
39
  private _model;
39
40
  private _state;
41
+ private _commands;
40
42
  }
41
43
  export declare namespace LeftPanelWidget {
42
44
  interface IOptions {
43
45
  model: IControlPanelModel;
44
46
  tracker: IJupyterGISTracker;
45
47
  state: IStateDB;
48
+ commands: CommandRegistry;
46
49
  }
47
50
  interface IProps {
48
51
  filePath?: string;
@@ -3,6 +3,7 @@ import { LayersPanel } from './components/layers';
3
3
  import { SourcesPanel } from './components/sources';
4
4
  import { ControlPanelHeader } from './header';
5
5
  import { FilterPanel } from './components/filter-panel/Filter';
6
+ import { CommandIDs } from '../constants';
6
7
  export class LeftPanelWidget extends SidePanel {
7
8
  constructor(options) {
8
9
  super();
@@ -50,11 +51,13 @@ export class LeftPanelWidget extends SidePanel {
50
51
  const updatedSelectedValue = Object.assign(Object.assign({}, selectedValue), { [item]: { type, selectedNodeId: nodeId } });
51
52
  this._lastSelectedNodeId = nodeId;
52
53
  jGISModel.syncSelected(updatedSelectedValue, this.id);
54
+ this._commands.notifyCommandChanged(CommandIDs.temporalController);
53
55
  }
54
56
  };
55
57
  this.addClass('jGIS-sidepanel-widget');
56
58
  this._model = options.model;
57
59
  this._state = options.state;
60
+ this._commands = options.commands;
58
61
  const header = new ControlPanelHeader();
59
62
  this.header.addWidget(header);
60
63
  const sourcesPanel = new SourcesPanel({
@@ -81,7 +84,7 @@ export class LeftPanelWidget extends SidePanel {
81
84
  this.addWidget(filterPanel);
82
85
  options.tracker.currentChanged.connect((_, changed) => {
83
86
  if (changed) {
84
- header.title.label = changed.context.localPath;
87
+ header.title.label = changed.model.filePath;
85
88
  }
86
89
  else {
87
90
  header.title.label = '-';
@@ -129,5 +132,6 @@ export class LeftPanelWidget extends SidePanel {
129
132
  this._lastSelectedNodeId = nodeId;
130
133
  }
131
134
  (_b = (_a = this._model) === null || _a === void 0 ? void 0 : _a.jGISModel) === null || _b === void 0 ? void 0 : _b.syncSelected(selection, this.id);
135
+ this._commands.notifyCommandChanged(CommandIDs.temporalController);
132
136
  }
133
137
  }
@@ -8,23 +8,23 @@ export class ControlPanelModel {
8
8
  }
9
9
  get filePath() {
10
10
  var _a;
11
- return (_a = this._tracker.currentWidget) === null || _a === void 0 ? void 0 : _a.context.localPath;
11
+ return (_a = this._tracker.currentWidget) === null || _a === void 0 ? void 0 : _a.model.filePath;
12
12
  }
13
13
  get jGISModel() {
14
14
  var _a;
15
- return (_a = this._tracker.currentWidget) === null || _a === void 0 ? void 0 : _a.context.model;
15
+ return (_a = this._tracker.currentWidget) === null || _a === void 0 ? void 0 : _a.model;
16
16
  }
17
17
  get sharedModel() {
18
18
  var _a;
19
- return (_a = this._tracker.currentWidget) === null || _a === void 0 ? void 0 : _a.context.model.sharedModel;
19
+ return (_a = this._tracker.currentWidget) === null || _a === void 0 ? void 0 : _a.model.sharedModel;
20
20
  }
21
21
  disconnect(f) {
22
22
  this._tracker.forEach(w => {
23
- w.context.model.sharedLayersChanged.disconnect(f);
24
- w.context.model.sharedSourcesChanged.disconnect(f);
25
- w.context.model.sharedOptionsChanged.disconnect(f);
23
+ w.model.sharedLayersChanged.disconnect(f);
24
+ w.model.sharedSourcesChanged.disconnect(f);
25
+ w.model.sharedOptionsChanged.disconnect(f);
26
26
  });
27
- this._tracker.forEach(w => w.context.model.themeChanged.disconnect(f));
28
- this._tracker.forEach(w => w.context.model.clientStateChanged.disconnect(f));
27
+ this._tracker.forEach(w => w.model.themeChanged.disconnect(f));
28
+ this._tracker.forEach(w => w.model.clientStateChanged.disconnect(f));
29
29
  }
30
30
  }
@@ -45,7 +45,7 @@ class ObjectPropertiesReact extends React.Component {
45
45
  }
46
46
  };
47
47
  this.state = {
48
- context: (_a = props.tracker.currentWidget) === null || _a === void 0 ? void 0 : _a.context,
48
+ model: (_a = props.tracker.currentWidget) === null || _a === void 0 ? void 0 : _a.model,
49
49
  clientId: null,
50
50
  id: uuid()
51
51
  };
@@ -55,14 +55,14 @@ class ObjectPropertiesReact extends React.Component {
55
55
  if (changed) {
56
56
  this.props.cpModel.disconnect(this._sharedJGISModelChanged);
57
57
  this.props.cpModel.disconnect(this._onClientSharedStateChanged);
58
- changed.context.model.sharedLayersChanged.connect(this._sharedJGISModelChanged);
59
- changed.context.model.sharedSourcesChanged.connect(this._sharedJGISModelChanged);
60
- changed.context.model.clientStateChanged.connect(this._onClientSharedStateChanged);
61
- this.setState(old => (Object.assign(Object.assign({}, old), { context: changed.context, filePath: changed.context.localPath, clientId: changed.context.model.getClientId() })));
58
+ changed.model.sharedLayersChanged.connect(this._sharedJGISModelChanged);
59
+ changed.model.sharedSourcesChanged.connect(this._sharedJGISModelChanged);
60
+ changed.model.clientStateChanged.connect(this._onClientSharedStateChanged);
61
+ this.setState(old => (Object.assign(Object.assign({}, old), { model: changed.model, filePath: changed.model.filePath, clientId: changed.model.getClientId() })));
62
62
  }
63
63
  else {
64
64
  this.setState({
65
- context: undefined,
65
+ model: undefined,
66
66
  selectedObject: undefined
67
67
  });
68
68
  }
@@ -71,22 +71,22 @@ class ObjectPropertiesReact extends React.Component {
71
71
  render() {
72
72
  var _a;
73
73
  const selectedObject = this.state.selectedObject;
74
- if (!selectedObject || !this.state.context) {
74
+ if (!selectedObject || !this.state.model) {
75
75
  return React.createElement("div", null);
76
76
  }
77
77
  let layerId = undefined;
78
78
  let sourceId = undefined;
79
- const layer = this.state.context.model.getLayer(selectedObject);
79
+ const layer = this.state.model.getLayer(selectedObject);
80
80
  if (layer) {
81
81
  layerId = selectedObject;
82
82
  sourceId = (_a = layer.parameters) === null || _a === void 0 ? void 0 : _a.source;
83
83
  }
84
84
  else {
85
- const source = this.state.context.model.getSource(selectedObject);
85
+ const source = this.state.model.getSource(selectedObject);
86
86
  if (source) {
87
87
  sourceId = selectedObject;
88
88
  }
89
89
  }
90
- return (React.createElement(EditForm, { layer: layerId, source: sourceId, formSchemaRegistry: this.props.formSchemaRegistry, context: this.state.context }));
90
+ return (React.createElement(EditForm, { layer: layerId, source: sourceId, formSchemaRegistry: this.props.formSchemaRegistry, model: this.state.model }));
91
91
  }
92
92
  }
@@ -4,7 +4,7 @@ import { IControlPanelModel } from '../types';
4
4
  export declare class RightPanelWidget extends SidePanel {
5
5
  constructor(options: RightPanelWidget.IOptions);
6
6
  dispose(): void;
7
- private _currentContext;
7
+ private _currentModel;
8
8
  private _model;
9
9
  private _annotationModel;
10
10
  }
@@ -31,12 +31,12 @@ export class RightPanelWidget extends SidePanel {
31
31
  this.addWidget(identifyPanel);
32
32
  this._model.documentChanged.connect((_, changed) => {
33
33
  if (changed) {
34
- if (changed.context.model.sharedModel.editable) {
35
- header.title.label = changed.context.localPath;
34
+ if (changed.model.sharedModel.editable) {
35
+ header.title.label = changed.model.filePath;
36
36
  properties.show();
37
37
  }
38
38
  else {
39
- header.title.label = `${changed.context.localPath} - Read Only`;
39
+ header.title.label = `${changed.model.filePath} - Read Only`;
40
40
  properties.hide();
41
41
  }
42
42
  }
@@ -47,16 +47,16 @@ export class RightPanelWidget extends SidePanel {
47
47
  options.tracker.currentChanged.connect(async (_, changed) => {
48
48
  var _a;
49
49
  if (changed) {
50
- this._currentContext = changed.context;
51
- header.title.label = this._currentContext.localPath;
52
- this._annotationModel.context =
53
- ((_a = options.tracker.currentWidget) === null || _a === void 0 ? void 0 : _a.context) || undefined;
54
- await changed.context.ready;
50
+ this._currentModel = changed.model;
51
+ header.title.label = this._currentModel.filePath;
52
+ this._annotationModel.model =
53
+ ((_a = options.tracker.currentWidget) === null || _a === void 0 ? void 0 : _a.model) || undefined;
54
+ // await changed.context.ready;
55
55
  }
56
56
  else {
57
57
  header.title.label = '-';
58
- this._currentContext = null;
59
- this._annotationModel.context = undefined;
58
+ this._currentModel = null;
59
+ this._annotationModel.model = undefined;
60
60
  }
61
61
  });
62
62
  }
@@ -0,0 +1,13 @@
1
+ import { IJupyterGISModel } from '@jupytergis/schema';
2
+ import React from 'react';
3
+ interface IStatusBarProps {
4
+ jgisModel: IJupyterGISModel;
5
+ loading?: boolean;
6
+ projection?: {
7
+ code: string;
8
+ units: string;
9
+ };
10
+ scale: number;
11
+ }
12
+ declare const StatusBar: ({ jgisModel, loading, projection, scale }: IStatusBarProps) => React.JSX.Element;
13
+ export default StatusBar;
@@ -0,0 +1,52 @@
1
+ import { faGlobe, faLocationDot, faRuler } from '@fortawesome/free-solid-svg-icons';
2
+ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
3
+ import { Progress } from '@jupyter/react-components';
4
+ import React, { useEffect, useState } from 'react';
5
+ import { version } from '../../package.json'; // Adjust the path as necessary
6
+ const StatusBar = ({ jgisModel, loading, projection, scale }) => {
7
+ var _a;
8
+ const [coords, setCoords] = useState({ x: 0, y: 0 });
9
+ useEffect(() => {
10
+ const handleClientStateChanged = () => {
11
+ var _a, _b;
12
+ const pointer = (_b = (_a = jgisModel === null || jgisModel === void 0 ? void 0 : jgisModel.localState) === null || _a === void 0 ? void 0 : _a.pointer) === null || _b === void 0 ? void 0 : _b.value;
13
+ if (!pointer) {
14
+ return;
15
+ }
16
+ setCoords({ x: pointer === null || pointer === void 0 ? void 0 : pointer.coordinates.x, y: pointer === null || pointer === void 0 ? void 0 : pointer.coordinates.y });
17
+ };
18
+ jgisModel.clientStateChanged.connect(handleClientStateChanged);
19
+ return () => {
20
+ jgisModel.clientStateChanged.disconnect(handleClientStateChanged);
21
+ };
22
+ }, [jgisModel]);
23
+ return (React.createElement("div", { className: "jgis-status-bar" },
24
+ loading && (React.createElement("div", { style: { width: '16%', padding: '0 6px' } },
25
+ React.createElement(Progress, { height: 14 }))),
26
+ React.createElement("div", { className: "jgis-status-bar-item" },
27
+ React.createElement("span", null,
28
+ "jgis: ",
29
+ version)),
30
+ React.createElement("div", { className: "jgis-status-bar-item jgis-status-bar-coords" },
31
+ React.createElement(FontAwesomeIcon, { icon: faLocationDot }),
32
+ React.createElement("span", null,
33
+ ' ',
34
+ "x: ",
35
+ Math.trunc(coords.x),
36
+ " y: ",
37
+ Math.trunc(coords.y))),
38
+ React.createElement("div", { className: "jgis-status-bar-item" },
39
+ React.createElement(FontAwesomeIcon, { icon: faRuler }),
40
+ ' ',
41
+ React.createElement("span", null,
42
+ "Scale: 1: ",
43
+ Math.trunc(scale))),
44
+ React.createElement("div", { className: "jgis-status-bar-item" },
45
+ React.createElement(FontAwesomeIcon, { icon: faGlobe }),
46
+ ' ',
47
+ React.createElement("span", null, (_a = projection === null || projection === void 0 ? void 0 : projection.code) !== null && _a !== void 0 ? _a : null)),
48
+ React.createElement("div", { className: "jgis-status-bar-item" },
49
+ "Units: ", projection === null || projection === void 0 ? void 0 :
50
+ projection.units)));
51
+ };
52
+ export default StatusBar;
@@ -1,5 +1,5 @@
1
1
  import { IJGISExternalCommand, JupyterGISModel } from '@jupytergis/schema';
2
- import { Toolbar, ReactiveToolbar } from '@jupyterlab/ui-components';
2
+ import { ReactiveToolbar, Toolbar } from '@jupyterlab/ui-components';
3
3
  import { CommandRegistry } from '@lumino/commands';
4
4
  import { Widget } from '@lumino/widgets';
5
5
  export declare const TOOLBAR_SEPARATOR_CLASS = "jGIS-Toolbar-Separator";
@@ -1,8 +1,9 @@
1
1
  import { CommandToolbarButton } from '@jupyterlab/apputils';
2
- import { ReactWidget, ReactiveToolbar, ToolbarButton, addIcon, redoIcon, undoIcon, terminalIcon } from '@jupyterlab/ui-components';
2
+ import { MenuSvg, ReactWidget, ReactiveToolbar, ToolbarButton, addIcon, redoIcon, terminalIcon, undoIcon } from '@jupyterlab/ui-components';
3
3
  import { Menu, Widget } from '@lumino/widgets';
4
4
  import * as React from 'react';
5
5
  import { CommandIDs } from '../constants';
6
+ import { rasterIcon } from '../icons';
6
7
  import { UsersItem } from './usertoolbaritem';
7
8
  export const TOOLBAR_SEPARATOR_CLASS = 'jGIS-Toolbar-Separator';
8
9
  export const TOOLBAR_GROUPNAME_CLASS = 'jGIS-Toolbar-GroupName';
@@ -55,57 +56,63 @@ export class ToolbarWidget extends ReactiveToolbar {
55
56
  label: '',
56
57
  commands: options.commands
57
58
  }));
58
- const NewButton = new ToolbarButton({
59
+ // vector sub menu
60
+ const vectorSubMenu = new Menu({ commands: options.commands });
61
+ vectorSubMenu.title.label = 'Add Vector Layer';
62
+ vectorSubMenu.title.iconClass = 'fa fa-vector-square';
63
+ vectorSubMenu.id = 'jp-gis-toolbar-vector-menu';
64
+ vectorSubMenu.addItem({
65
+ type: 'command',
66
+ command: CommandIDs.newGeoJSONEntry
67
+ });
68
+ vectorSubMenu.addItem({
69
+ type: 'command',
70
+ command: CommandIDs.newShapefileLayer
71
+ });
72
+ //raster submenu
73
+ const rasterSubMenu = new Menu({ commands: options.commands });
74
+ rasterSubMenu.title.label = 'Add Raster Layer';
75
+ rasterSubMenu.title.icon = rasterIcon;
76
+ rasterSubMenu.id = 'jp-gis-toolbar-raster-menu';
77
+ rasterSubMenu.addItem({
78
+ type: 'command',
79
+ command: CommandIDs.newHillshadeEntry
80
+ });
81
+ rasterSubMenu.addItem({
82
+ type: 'command',
83
+ command: CommandIDs.newImageEntry
84
+ });
85
+ rasterSubMenu.addItem({
86
+ type: 'command',
87
+ command: CommandIDs.newGeoTiffEntry
88
+ });
89
+ const NewSubMenu = new MenuSvg({ commands: options.commands });
90
+ NewSubMenu.title.label = 'Add Layer';
91
+ NewSubMenu.addItem({ type: 'submenu', submenu: rasterSubMenu });
92
+ NewSubMenu.addItem({ type: 'submenu', submenu: vectorSubMenu });
93
+ const NewEntryButton = new ToolbarButton({
59
94
  icon: addIcon,
60
95
  noFocusOnClick: false,
61
96
  onClick: () => {
62
97
  if (!options.commands) {
63
98
  return;
64
99
  }
65
- const bbox = NewButton.node.getBoundingClientRect();
66
- const NewSubMenu = new Menu({ commands: options.commands });
67
- NewSubMenu.title.label = 'New Layer';
68
- NewSubMenu.addItem({
69
- type: 'command',
70
- command: CommandIDs.newHillshadeEntry
71
- });
72
- NewSubMenu.addItem({
73
- type: 'separator'
74
- });
75
- NewSubMenu.addItem({
76
- type: 'command',
77
- command: CommandIDs.newImageEntry
78
- });
79
- NewSubMenu.addItem({
80
- type: 'separator'
81
- });
82
- NewSubMenu.addItem({
83
- type: 'command',
84
- command: CommandIDs.newShapefileLayer
85
- });
86
- NewSubMenu.addItem({
87
- type: 'command',
88
- command: CommandIDs.newGeoTiffEntry
89
- });
90
- NewSubMenu.addItem({
91
- type: 'command',
92
- command: CommandIDs.newGeoJSONEntry
93
- });
100
+ const bbox = NewEntryButton.node.getBoundingClientRect();
94
101
  NewSubMenu.open(bbox.x, bbox.bottom);
95
102
  }
96
103
  });
97
- this.addItem('New', NewButton);
104
+ this.addItem('New', NewEntryButton);
98
105
  this.addItem('separator2', new Separator());
99
106
  this.addItem('identify', new CommandToolbarButton({
100
107
  id: CommandIDs.identify,
101
108
  label: '',
102
109
  commands: options.commands
103
110
  }));
104
- options.commands.addKeyBinding({
105
- command: CommandIDs.identify,
106
- keys: ['Escape'],
107
- selector: '#main'
108
- });
111
+ this.addItem('temporalController', new CommandToolbarButton({
112
+ id: CommandIDs.temporalController,
113
+ label: '',
114
+ commands: options.commands
115
+ }));
109
116
  this.addItem('spacer', ReactiveToolbar.createSpacerItem());
110
117
  // Users
111
118
  this.addItem('users', ReactWidget.create(React.createElement(UsersItem, { model: options.model })));