From 43226d9191cbf9b056d2f9653cadbceda96ee03c Mon Sep 17 00:00:00 2001 From: Alireza Date: Fri, 10 Jul 2026 18:52:06 -0400 Subject: [PATCH] fix(app): appearance modal provider scope, worklist preview persistence, and tag browser label overflow (#6136) - Insert ServiceProvidersManager providers ahead of the dialog/modal providers in App.tsx: modal content renders as a sibling of the provider's children, so contexts registered via the manager (e.g. ActiveThemeProvider) were out of scope and the appearance modal crashed with 'useActiveTheme must be used within an ActiveThemeProvider'. - Persist the worklist preview panel open/closed state in sessionStorage so it survives navigating into a study and back. - Keep the DICOM tag browser instance number label on one line: the words truncate, the (n of total) digits never clip. --- .../src/DicomTagBrowser/DicomTagBrowser.tsx | 7 +++++-- platform/app/src/App.tsx | 15 ++++++++++----- platform/app/src/routes/WorkList/WorkList.tsx | 15 ++++++++++++++- 3 files changed, 29 insertions(+), 8 deletions(-) diff --git a/extensions/default/src/DicomTagBrowser/DicomTagBrowser.tsx b/extensions/default/src/DicomTagBrowser/DicomTagBrowser.tsx index 7e5b91418..50e43d292 100644 --- a/extensions/default/src/DicomTagBrowser/DicomTagBrowser.tsx +++ b/extensions/default/src/DicomTagBrowser/DicomTagBrowser.tsx @@ -165,8 +165,11 @@ const DicomTagBrowser = ({ {shouldShowInstanceList && (
- - Instance Number ({instanceNumber} of {activeDisplaySet?.images?.length}) + + Instance Number + +  ({instanceNumber} of {activeDisplaySet?.images?.length}) + [provider, { service: servicesManager.services[serviceName] }] + ); if (providersFromManager.length > 0) { - providersFromManager.forEach(([serviceName, provider]) => { - providers.push([provider, { service: servicesManager.services[serviceName] }]); - }); + const dialogIndex = providers.findIndex(([component]) => component === DialogProvider); + providers.splice(dialogIndex, 0, ...providersFromManager); } const CombinedProviders = ({ children }) => Compose({ components: providers, children }); diff --git a/platform/app/src/routes/WorkList/WorkList.tsx b/platform/app/src/routes/WorkList/WorkList.tsx index 7288c5f00..62a34c386 100644 --- a/platform/app/src/routes/WorkList/WorkList.tsx +++ b/platform/app/src/routes/WorkList/WorkList.tsx @@ -9,6 +9,7 @@ import { StudyList, Icons, InvestigationalUseDialog, + useSessionStorage, type StudyRow, type OnStudyDoubleClick, } from '@ohif/ui-next'; @@ -53,7 +54,19 @@ export default function WorkList({ const defaultSorting = useMemo(() => [{ id: 'studyDateTime', desc: true }], []); const [selected, setSelected] = useState(null); - const [isPreviewOpen, setPreviewOpen] = useState(true); + + // Persist the preview panel open/closed state so it survives navigating + // into a study and back. The hook only handles objects, hence the wrapper. + const [previewState, updatePreviewState] = useSessionStorage({ + key: 'studyList.previewOpen', + defaultValue: { open: true }, + clearOnUnload: false, + }); + const isPreviewOpen = previewState.open !== false; + const setPreviewOpen = useCallback( + (open: boolean) => updatePreviewState({ open }), + [updatePreviewState] + ); // `workList.onStudyDoubleClick` is the command (or command list) run when a // study row is double-clicked — by default `launchDefaultMode`, which