Skip to content

Commit 94cf081

Browse files
Embedded panels
1 parent 4767259 commit 94cf081

File tree

27 files changed

+732
-883
lines changed

27 files changed

+732
-883
lines changed

package.json

Lines changed: 71 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -1,76 +1,73 @@
11
{
2-
"name": "@jupytergis/jupytergis-root",
3-
"version": "0.6.2",
4-
"private": true,
5-
"homepage": "https://github.com/geojupyter/jupytergis",
6-
"repository": {
7-
"type": "git",
8-
"url": "https://github.com/geojupyter/jupytergis.git"
9-
},
10-
"license": "BSD-3-Clause",
11-
"description": "A JupyterLab extension for GIS.",
12-
"keywords": [
13-
"jupyter",
14-
"jupyterlab",
15-
"jupyterlab-extension"
16-
],
17-
"bugs": {
18-
"url": "https://github.com/geojupyter/jupytergis/issues"
19-
},
20-
"author": {
21-
"name": "Jupytergis contributors"
22-
},
23-
"files": [
24-
"lib/**/*.{d.ts,eot,gif,html,jpg,js,js.map,json,png,svg,woff2,ttf}",
25-
"style/**/*.{css,js,eot,gif,html,jpg,json,png,svg,woff2,ttf}"
26-
],
27-
"workspaces": [
28-
"packages/*",
29-
"python/jupytergis_core",
30-
"python/jupytergis_lab",
31-
"python/jupytergis_qgis"
32-
],
33-
"scripts": {
34-
"build": "lerna run build",
35-
"build:prod": "lerna run build:prod --skip-nx-cache",
36-
"build:test": "lerna run build:test",
37-
"build:dev": "lerna run build:dev",
38-
"bump:js:version": "lerna version --no-push --force-publish --no-git-tag-version --yes",
39-
"clean": "lerna run clean",
40-
"clean:all": "lerna run clean:all",
41-
"eslint": "eslint . --ext .ts,.tsx --cache --fix",
42-
"eslint:check": "eslint . --ext .ts,.tsx",
43-
"prettier": "prettier --write \"**/*{.ts,.tsx,.js,.jsx,.css,.json,.md,.yml}\"",
44-
"prettier:check": "prettier --check \"**/*{.ts,.tsx,.js,.jsx,.css,.json,.md,.yml}\"",
45-
"lint:check": "jlpm run prettier:check && jlpm run eslint:check",
46-
"lint": "jlpm run prettier && jlpm run eslint",
47-
"test": "lerna run test",
48-
"dev": "python scripts/dev-install.py",
49-
"build:packages": "python scripts/build_packages.py",
50-
"watch:lib": "lerna run --stream watch",
51-
"watch": "lerna watch -- lerna run build --scope=\\$LERNA_PACKAGE_NAME --include-dependents",
52-
"build:lab": "lerna run"
53-
},
54-
"resolutions": {
55-
"@jupyterlab/apputils": "^4.0.0",
56-
"@lumino/coreutils": "^2.0.0",
57-
"@jupyterlab/notebook": "^4.0.0",
58-
"@jupyterlab/services": " ^7.0.0"
59-
},
60-
"devDependencies": {
61-
"@types/webpack-env": "^1.18.5",
62-
"@typescript-eslint/eslint-plugin": "5.55.0",
63-
"@typescript-eslint/parser": "5.55.0",
64-
"copy-webpack-plugin": "^10.0.0",
65-
"eslint": "^8.36.0",
66-
"eslint-config-prettier": "^8.8.0",
67-
"eslint-plugin-import": "^2.31.0",
68-
"eslint-plugin-prettier": "^5.0.1",
69-
"lerna": "^8.1.9",
70-
"npm-run-all": "^4.1.5",
71-
"prettier": "^3.0.0",
72-
"rimraf": "^3.0.2",
73-
"typescript": "^5",
74-
"webpack": "^5.76.3"
75-
}
2+
"name": "@jupytergis/jupytergis-root",
3+
"version": "0.6.2",
4+
"private": true,
5+
"homepage": "https://github.com/geojupyter/jupytergis",
6+
"repository": {
7+
"type": "git",
8+
"url": "https://github.com/geojupyter/jupytergis.git"
9+
},
10+
"license": "BSD-3-Clause",
11+
"description": "A JupyterLab extension for GIS.",
12+
"keywords": ["jupyter", "jupyterlab", "jupyterlab-extension"],
13+
"bugs": {
14+
"url": "https://github.com/geojupyter/jupytergis/issues"
15+
},
16+
"author": {
17+
"name": "Jupytergis contributors"
18+
},
19+
"files": [
20+
"lib/**/*.{d.ts,eot,gif,html,jpg,js,js.map,json,png,svg,woff2,ttf}",
21+
"style/**/*.{css,js,eot,gif,html,jpg,json,png,svg,woff2,ttf}"
22+
],
23+
"workspaces": [
24+
"packages/*",
25+
"python/jupytergis_core",
26+
"python/jupytergis_lab",
27+
"python/jupytergis_qgis"
28+
],
29+
"scripts": {
30+
"build": "lerna run build",
31+
"build:prod": "lerna run build:prod --skip-nx-cache",
32+
"build:test": "lerna run build:test",
33+
"build:dev": "lerna run build:dev",
34+
"bump:js:version": "lerna version --no-push --force-publish --no-git-tag-version --yes",
35+
"clean": "lerna run clean",
36+
"clean:all": "lerna run clean:all",
37+
"eslint": "eslint . --ext .ts,.tsx --cache --fix",
38+
"eslint:check": "eslint . --ext .ts,.tsx",
39+
"prettier": "prettier --write \"**/*{.ts,.tsx,.js,.jsx,.css,.json,.md,.yml}\"",
40+
"prettier:check": "prettier --check \"**/*{.ts,.tsx,.js,.jsx,.css,.json,.md,.yml}\"",
41+
"lint:check": "jlpm run prettier:check && jlpm run eslint:check",
42+
"lint": "jlpm run prettier && jlpm run eslint",
43+
"test": "lerna run test",
44+
"dev": "python scripts/dev-install.py",
45+
"build:packages": "python scripts/build_packages.py",
46+
"watch:lib": "lerna run --stream watch",
47+
"watch": "lerna watch -- lerna run build --scope=\\$LERNA_PACKAGE_NAME --include-dependents",
48+
"build:lab": "lerna run"
49+
},
50+
"resolutions": {
51+
"@jupyterlab/apputils": "^4.0.0",
52+
"@lumino/coreutils": "^2.0.0",
53+
"@jupyterlab/notebook": "^4.0.0",
54+
"@jupyterlab/services": " ^7.0.0"
55+
},
56+
"devDependencies": {
57+
"@types/webpack-env": "^1.18.5",
58+
"@typescript-eslint/eslint-plugin": "5.55.0",
59+
"@typescript-eslint/parser": "5.55.0",
60+
"copy-webpack-plugin": "^10.0.0",
61+
"eslint": "^8.36.0",
62+
"eslint-config-prettier": "^8.8.0",
63+
"eslint-plugin-import": "^2.31.0",
64+
"eslint-plugin-prettier": "^5.0.1",
65+
"lerna": "^8.1.9",
66+
"npm-run-all": "^4.1.5",
67+
"prettier": "^3.0.0",
68+
"rimraf": "^3.0.2",
69+
"typescript": "^5",
70+
"webpack": "^5.76.3"
71+
},
72+
"dependencies": {}
7673
}

packages/base/src/Lumino.tsx

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
import { Widget } from '@lumino/widgets';
2+
import * as React from 'react';
3+
4+
type LuminoProps = {
5+
id?: string;
6+
height?: string | number;
7+
children: Widget;
8+
};
9+
10+
export const Lumino = (props: LuminoProps) => {
11+
const ref = React.useRef<HTMLDivElement>(null);
12+
const { children, id, height } = props;
13+
React.useEffect(() => {
14+
if (ref && ref.current) {
15+
try {
16+
Widget.attach(children, ref.current);
17+
} catch (e) {
18+
console.warn('Exception while attaching Lumino widget.', e);
19+
}
20+
return () => {
21+
try {
22+
if (children.isAttached || children.node.isConnected) {
23+
children.dispose();
24+
Widget.detach(children);
25+
}
26+
} catch (e) {
27+
// no-op.
28+
// console.debug('Exception while detaching Lumino widget.', e);
29+
}
30+
};
31+
}
32+
}, [ref, children]);
33+
return (
34+
<div id={id} ref={ref} style={{ height: height, minHeight: height }} />
35+
);
36+
};
37+
38+
Lumino.defaultProps = {
39+
id: 'lumino-id',
40+
height: '100%',
41+
};
42+
43+
export default Lumino;

packages/base/src/annotations/components/Annotation.tsx

Lines changed: 2 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,12 @@ import { showDialog, Dialog } from '@jupyterlab/apputils';
99
import { Button } from '@jupyterlab/ui-components';
1010
import React, { useMemo, useState } from 'react';
1111

12-
import { IControlPanelModel } from '@/src/types';
1312
import { Message } from './Message';
1413

1514
export interface IAnnotationProps {
1615
itemId: string;
1716
annotationModel: IAnnotationModel;
18-
rightPanelModel?: IControlPanelModel;
17+
rightPanelModel?: IJupyterGISModel;
1918
children?: JSX.Element[] | JSX.Element;
2019
}
2120

@@ -26,20 +25,10 @@ const Annotation: React.FC<IAnnotationProps> = ({
2625
children,
2726
}) => {
2827
const [messageContent, setMessageContent] = useState('');
29-
const [jgisModel, setJgisModel] = useState<IJupyterGISModel | undefined>(
30-
rightPanelModel?.jGISModel,
31-
);
32-
28+
const jgisModel = rightPanelModel;
3329
const annotation = annotationModel.getAnnotation(itemId);
3430
const contents = useMemo(() => annotation?.contents ?? [], [annotation]);
3531

36-
/**
37-
* Update the model when it changes.
38-
*/
39-
rightPanelModel?.documentChanged.connect((_, widget) => {
40-
setJgisModel(widget?.model);
41-
});
42-
4332
const handleSubmit = () => {
4433
annotationModel.addContent(itemId, messageContent);
4534
setMessageContent('');

packages/base/src/mainview/mainView.tsx

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,15 @@
11
import { MapChange } from '@jupyter/ydoc';
22
import {
33
IAnnotation,
4+
IAnnotationModel,
45
IDict,
56
IGeoTiffSource,
67
IHeatmapLayer,
78
IHillshadeLayer,
89
IImageLayer,
910
IImageSource,
1011
IJGISFilterItem,
12+
IJGISFormSchemaRegistry,
1113
IJGISLayer,
1214
IJGISLayerDocChange,
1315
IJGISLayerTreeDocChange,
@@ -34,6 +36,7 @@ import {
3436
import { showErrorMessage } from '@jupyterlab/apputils';
3537
import { IObservableMap, ObservableMap } from '@jupyterlab/observables';
3638
import { User } from '@jupyterlab/services';
39+
import { IStateDB } from '@jupyterlab/statedb';
3740
import { CommandRegistry } from '@lumino/commands';
3841
import { JSONValue, UUID } from '@lumino/coreutils';
3942
import { ContextMenu } from '@lumino/widgets';
@@ -90,6 +93,7 @@ import CollaboratorPointers, { ClientPointer } from './CollaboratorPointers';
9093
import { FollowIndicator } from './FollowIndicator';
9194
import TemporalSlider from './TemporalSlider';
9295
import { MainViewModel } from './mainviewmodel';
96+
import { LeftPanelComponent, RightPanelComponent } from '../panelview';
9397

9498
type OlLayerTypes =
9599
| TileLayer
@@ -102,6 +106,9 @@ type OlLayerTypes =
102106
| ImageLayer<any>;
103107
interface IProps {
104108
viewModel: MainViewModel;
109+
state?: IStateDB;
110+
formSchemaRegistry?: IJGISFormSchemaRegistry;
111+
annotationModel?: IAnnotationModel;
105112
}
106113

107114
interface IStates {
@@ -123,6 +130,11 @@ interface IStates {
123130
export class MainView extends React.Component<IProps, IStates> {
124131
constructor(props: IProps) {
125132
super(props);
133+
this._state = props.state;
134+
135+
this._formSchemaRegistry = props.formSchemaRegistry;
136+
137+
this._annotationModel = props.annotationModel;
126138

127139
// Enforce the map to take the full available width in the case of Jupyter Notebook viewer
128140
const el = document.getElementById('main-panel');
@@ -2220,6 +2232,21 @@ export class MainView extends React.Component<IProps, IStates> {
22202232
scale={this.state.scale}
22212233
/>
22222234
</div>
2235+
2236+
{this._state && (
2237+
<LeftPanelComponent
2238+
model={this._model}
2239+
commands={this._commands}
2240+
state={this._state}
2241+
></LeftPanelComponent>
2242+
)}
2243+
{this._formSchemaRegistry && this._annotationModel && (
2244+
<RightPanelComponent
2245+
model={this._model}
2246+
formSchemaRegistry={this._formSchemaRegistry}
2247+
annotationModel={this._annotationModel}
2248+
></RightPanelComponent>
2249+
)}
22232250
</>
22242251
);
22252252
}
@@ -2240,4 +2267,7 @@ export class MainView extends React.Component<IProps, IStates> {
22402267
private _originalFeatures: IDict<Feature<Geometry>[]> = {};
22412268
private _highlightLayer: VectorLayer<VectorSource>;
22422269
private _updateCenter: CallableFunction;
2270+
private _state?: IStateDB;
2271+
private _formSchemaRegistry?: IJGISFormSchemaRegistry;
2272+
private _annotationModel?: IAnnotationModel;
22432273
}
Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,40 @@
1+
import { IAnnotationModel, IJGISFormSchemaRegistry } from '@jupytergis/schema';
12
import { ReactWidget } from '@jupyterlab/apputils';
3+
import { IStateDB } from '@jupyterlab/statedb';
24
import * as React from 'react';
35

46
import { MainView } from './mainView';
57
import { MainViewModel } from './mainviewmodel';
68

9+
export interface IOptions {
10+
mainViewModel: MainViewModel;
11+
state?: IStateDB;
12+
formSchemaRegistry?: IJGISFormSchemaRegistry;
13+
annotationModel?: IAnnotationModel;
14+
}
15+
716
export class JupyterGISMainViewPanel extends ReactWidget {
817
/**
918
* Construct a `JupyterGISPanel`.
1019
*/
11-
constructor(options: { mainViewModel: MainViewModel }) {
20+
constructor(options: IOptions) {
1221
super();
13-
this._mainViewModel = options.mainViewModel;
22+
this._state = options.state;
1423
this.addClass('jp-jupytergis-panel');
24+
this._options = options;
1525
}
1626

1727
render(): JSX.Element {
18-
return <MainView viewModel={this._mainViewModel} />;
28+
return (
29+
<MainView
30+
state={this._state}
31+
viewModel={this._options.mainViewModel}
32+
formSchemaRegistry={this._options.formSchemaRegistry}
33+
annotationModel={this._options.annotationModel}
34+
/>
35+
);
1936
}
2037

21-
private _mainViewModel: MainViewModel;
38+
private _state?: IStateDB;
39+
private _options: IOptions;
2240
}

0 commit comments

Comments
 (0)