From 6c4c64b9af1a6bb011fbbe8fa3dc7a7440d124c2 Mon Sep 17 00:00:00 2001 From: arjxn-py Date: Tue, 26 Aug 2025 17:33:04 +0530 Subject: [PATCH 1/2] Automatically switch to identify panel when identifying --- packages/base/src/commands/index.ts | 5 +++++ packages/base/src/panelview/rightpanel.tsx | 6 ++++++ packages/schema/src/interfaces.ts | 1 + packages/schema/src/model.ts | 18 ++++++++++++++++++ 4 files changed, 30 insertions(+) diff --git a/packages/base/src/commands/index.ts b/packages/base/src/commands/index.ts index 8a414fe3e..1cc0af18d 100644 --- a/packages/base/src/commands/index.ts +++ b/packages/base/src/commands/index.ts @@ -207,6 +207,11 @@ export function addCommands( current.node.classList.toggle('jGIS-identify-tool'); current.model.toggleIdentify(); + + if (current.model.isIdentifying) { + current.model.activeRightPanelTab = 'identifyPanel'; + } + commands.notifyCommandChanged(CommandIDs.identify); }, ...icons.get(CommandIDs.identify), diff --git a/packages/base/src/panelview/rightpanel.tsx b/packages/base/src/panelview/rightpanel.tsx index 3b9914ab8..d775f5ab0 100644 --- a/packages/base/src/panelview/rightpanel.tsx +++ b/packages/base/src/panelview/rightpanel.tsx @@ -62,6 +62,12 @@ export const RightPanel: React.FC = props => { const [selectedObjectProperties, setSelectedObjectProperties] = React.useState(undefined); + React.useEffect(() => { + if (props.model.activeRightPanelTab) { + setCurTab(props.model.activeRightPanelTab); + } + }, [props.model.activeRightPanelTab]); + return (
(this); private _usersMap?: Map; From d58999a928ac582ac2167c68207af78910a6881e Mon Sep 17 00:00:00 2001 From: martinRenou Date: Wed, 27 Aug 2025 13:38:02 +0200 Subject: [PATCH 2/2] Introduce model.currentMode + activate tab everytime the identified features change --- packages/base/src/commands/index.ts | 13 ++--- packages/base/src/mainview/mainView.tsx | 7 +-- .../identify-panel/IdentifyPanel.tsx | 5 +- packages/base/src/panelview/rightpanel.tsx | 58 ++++++++++++------- packages/schema/src/interfaces.ts | 5 +- packages/schema/src/model.ts | 43 +++++--------- python/jupytergis_lab/src/notebookrenderer.ts | 2 +- 7 files changed, 66 insertions(+), 67 deletions(-) diff --git a/packages/base/src/commands/index.ts b/packages/base/src/commands/index.ts index 1cc0af18d..47ee758b8 100644 --- a/packages/base/src/commands/index.ts +++ b/packages/base/src/commands/index.ts @@ -160,15 +160,14 @@ export function addCommands( 'WebGlLayer', 'VectorTileLayer', ].includes(selectedLayer.type); - const isIdentifying = current.model.isIdentifying; - if (isIdentifying && !canIdentify) { - current.model.isIdentifying = false; + if (current.model.currentMode === 'identifying' && !canIdentify) { + current.model.currentMode = 'panning'; current.node.classList.remove('jGIS-identify-tool'); return false; } - return isIdentifying; + return current.model.currentMode === 'identifying'; }, isEnabled: () => { if (tracker.currentWidget?.model.jgisSettings.identifyDisabled) { @@ -198,7 +197,7 @@ export function addCommands( if (luminoEvent) { const keysPressed = luminoEvent.keys as string[] | undefined; if (keysPressed?.includes('Escape')) { - current.model.isIdentifying = false; + current.model.currentMode = 'panning'; current.node.classList.remove('jGIS-identify-tool'); commands.notifyCommandChanged(CommandIDs.identify); return; @@ -208,10 +207,6 @@ export function addCommands( current.node.classList.toggle('jGIS-identify-tool'); current.model.toggleIdentify(); - if (current.model.isIdentifying) { - current.model.activeRightPanelTab = 'identifyPanel'; - } - commands.notifyCommandChanged(CommandIDs.identify); }, ...icons.get(CommandIDs.identify), diff --git a/packages/base/src/mainview/mainView.tsx b/packages/base/src/mainview/mainView.tsx index dea1c242d..af3c7f779 100644 --- a/packages/base/src/mainview/mainView.tsx +++ b/packages/base/src/mainview/mainView.tsx @@ -211,8 +211,7 @@ export class MainView extends React.Component { // Watch isIdentifying and clear the highlight when Identify Tool is turned off this._model.sharedModel.awareness.on('change', () => { - const isIdentifying = this._model.isIdentifying; - if (!isIdentifying && this._highlightLayer) { + if (this._model.currentMode !== 'identifying' && this._highlightLayer) { this._highlightLayer.getSource()?.clear(); } }); @@ -519,7 +518,7 @@ export class MainView extends React.Component { return layer === this.getLayer(selectedLayerId); }, condition: (event: MapBrowserEvent) => { - return singleClick(event) && this._model.isIdentifying; + return singleClick(event) && this._model.currentMode === 'identifying'; }, style: styleFunction, }); @@ -2086,7 +2085,7 @@ export class MainView extends React.Component { }); private _identifyFeature(e: MapBrowserEvent) { - if (!this._model.isIdentifying) { + if (this._model.currentMode !== 'identifying') { return; } diff --git a/packages/base/src/panelview/components/identify-panel/IdentifyPanel.tsx b/packages/base/src/panelview/components/identify-panel/IdentifyPanel.tsx index e8269d75d..6add7a030 100644 --- a/packages/base/src/panelview/components/identify-panel/IdentifyPanel.tsx +++ b/packages/base/src/panelview/components/identify-panel/IdentifyPanel.tsx @@ -58,7 +58,10 @@ export const IdentifyPanelComponent: React.FC = ({ return; } - if (model.isIdentifying && featuresRef.current !== identifiedFeatures) { + if ( + model.currentMode === 'identifying' && + featuresRef.current !== identifiedFeatures + ) { setFeatures(identifiedFeatures); } }; diff --git a/packages/base/src/panelview/rightpanel.tsx b/packages/base/src/panelview/rightpanel.tsx index d775f5ab0..0dc10e62d 100644 --- a/packages/base/src/panelview/rightpanel.tsx +++ b/packages/base/src/panelview/rightpanel.tsx @@ -1,6 +1,7 @@ import { IAnnotationModel, IJGISFormSchemaRegistry, + IJupyterGISClientState, IJupyterGISModel, } from '@jupytergis/schema'; import * as React from 'react'; @@ -23,15 +24,50 @@ interface IRightPanelProps { export const RightPanel: React.FC = props => { const [settings, setSettings] = React.useState(props.model.jgisSettings); + const tabInfo = [ + !settings.objectPropertiesDisabled + ? { name: 'objectProperties', title: 'Object Properties' } + : false, + !settings.annotationsDisabled + ? { name: 'annotations', title: 'Annotations' } + : false, + !settings.identifyDisabled + ? { name: 'identifyPanel', title: 'Identified Features' } + : false, + ].filter(Boolean) as { name: string; title: string }[]; + + const [curTab, setCurTab] = React.useState( + tabInfo.length > 0 ? tabInfo[0].name : undefined, + ); React.useEffect(() => { const onSettingsChanged = () => { setSettings({ ...props.model.jgisSettings }); }; + let currentlyIdentifiedFeatures: any = undefined; + const onAwerenessChanged = ( + _: IJupyterGISModel, + clients: Map, + ) => { + const clientId = props.model.getClientId(); + const localState = clientId ? clients.get(clientId) : null; + + if ( + localState && + localState.identifiedFeatures?.value && + localState.identifiedFeatures.value !== currentlyIdentifiedFeatures + ) { + currentlyIdentifiedFeatures = localState.identifiedFeatures.value; + setCurTab('identifyPanel'); + } + }; props.model.settingsChanged.connect(onSettingsChanged); + props.model.clientStateChanged.connect(onAwerenessChanged); + return () => { props.model.settingsChanged.disconnect(onSettingsChanged); + props.model.clientStateChanged.disconnect(onAwerenessChanged); }; }, [props.model]); @@ -43,31 +79,9 @@ export const RightPanel: React.FC = props => { const rightPanelVisible = !settings.rightPanelDisabled && !allRightTabsDisabled; - const tabInfo = [ - !settings.objectPropertiesDisabled - ? { name: 'objectProperties', title: 'Object Properties' } - : false, - !settings.annotationsDisabled - ? { name: 'annotations', title: 'Annotations' } - : false, - !settings.identifyDisabled - ? { name: 'identifyPanel', title: 'Identified Features' } - : false, - ].filter(Boolean) as { name: string; title: string }[]; - - const [curTab, setCurTab] = React.useState( - tabInfo.length > 0 ? tabInfo[0].name : undefined, - ); - const [selectedObjectProperties, setSelectedObjectProperties] = React.useState(undefined); - React.useEffect(() => { - if (props.model.activeRightPanelTab) { - setCurTab(props.model.activeRightPanelTab); - } - }, [props.model.activeRightPanelTab]); - return (
; private _jgisSettings: IJupyterGISSettings; + private _currentMode: 'panning' | 'identifying'; + private _sharedModel: IJupyterGISDoc; private _filePath: string; private _contentsManager?: Contents.IManager; @@ -888,8 +878,6 @@ export class JupyterGISModel implements IJupyterGISModel { private _readOnly = false; private _isDisposed = false; - private _activeRightPanelTab: string | undefined; - private _userChanged = new Signal(this); private _usersMap?: Map; @@ -910,7 +898,6 @@ export class JupyterGISModel implements IJupyterGISModel { private _updateLayerSignal = new Signal(this); - private _isIdentifying = false; private _isTemporalControllerActive = false; static worker: Worker; diff --git a/python/jupytergis_lab/src/notebookrenderer.ts b/python/jupytergis_lab/src/notebookrenderer.ts index f34275160..f8cddf5b7 100644 --- a/python/jupytergis_lab/src/notebookrenderer.ts +++ b/python/jupytergis_lab/src/notebookrenderer.ts @@ -20,12 +20,12 @@ import { JupyterFrontEnd, JupyterFrontEndPlugin, } from '@jupyterlab/application'; -import { ISettingRegistry } from '@jupyterlab/settingregistry'; import { showErrorMessage } from '@jupyterlab/apputils'; import { ConsolePanel } from '@jupyterlab/console'; import { PathExt } from '@jupyterlab/coreutils'; import { NotebookPanel } from '@jupyterlab/notebook'; import { Contents } from '@jupyterlab/services'; +import { ISettingRegistry } from '@jupyterlab/settingregistry'; import { IStateDB } from '@jupyterlab/statedb'; import { Toolbar } from '@jupyterlab/ui-components'; import { CommandRegistry } from '@lumino/commands';