feat: Add customization support for more UI components (#4634)
Co-authored-by: ashikcn <ashik@L1140.trenser.com> Co-authored-by: Devu Jayalekshmi <devu.jayalekshmi@trenser.com> Co-authored-by: Arul Mozhi <arul.mozhi@trenser.com>
This commit is contained in:
parent
8f79ebafd9
commit
f15eb44b4c
@ -1,6 +1,5 @@
|
|||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import React, { useCallback, useEffect, useRef, useState } from 'react';
|
import React, { useCallback, useEffect, useRef, useState } from 'react';
|
||||||
import { LoadingIndicatorTotalPercent } from '@ohif/ui';
|
|
||||||
import { useViewportGrid } from '@ohif/ui-next';
|
import { useViewportGrid } from '@ohif/ui-next';
|
||||||
|
|
||||||
function OHIFCornerstonePMAPViewport(props: withAppTypes) {
|
function OHIFCornerstonePMAPViewport(props: withAppTypes) {
|
||||||
@ -13,7 +12,7 @@ function OHIFCornerstonePMAPViewport(props: withAppTypes) {
|
|||||||
extensionManager,
|
extensionManager,
|
||||||
} = props;
|
} = props;
|
||||||
const viewportId = viewportOptions.viewportId;
|
const viewportId = viewportOptions.viewportId;
|
||||||
const { displaySetService, segmentationService, uiNotificationService } =
|
const { displaySetService, segmentationService, uiNotificationService, customizationService } =
|
||||||
servicesManager.services;
|
servicesManager.services;
|
||||||
|
|
||||||
// PMAP viewport will always have a single display set
|
// PMAP viewport will always have a single display set
|
||||||
@ -21,6 +20,10 @@ function OHIFCornerstonePMAPViewport(props: withAppTypes) {
|
|||||||
throw new Error('PMAP viewport must have a single display set');
|
throw new Error('PMAP viewport must have a single display set');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const LoadingIndicatorTotalPercent = customizationService.getCustomization(
|
||||||
|
'ui.loadingIndicatorTotalPercent'
|
||||||
|
);
|
||||||
|
|
||||||
const pmapDisplaySet = displaySets[0];
|
const pmapDisplaySet = displaySets[0];
|
||||||
const [viewportGrid, viewportGridService] = useViewportGrid();
|
const [viewportGrid, viewportGridService] = useViewportGrid();
|
||||||
const referencedDisplaySetRef = useRef(null);
|
const referencedDisplaySetRef = useRef(null);
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
import React, { useCallback, useEffect, useRef, useState } from 'react';
|
import React, { useCallback, useEffect, useRef, useState } from 'react';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import { LoadingIndicatorTotalPercent, ViewportActionArrows } from '@ohif/ui';
|
import { ViewportActionArrows } from '@ohif/ui';
|
||||||
import { useViewportGrid } from '@ohif/ui-next';
|
import { useViewportGrid } from '@ohif/ui-next';
|
||||||
|
|
||||||
import promptHydrateRT from '../utils/promptHydrateRT';
|
import promptHydrateRT from '../utils/promptHydrateRT';
|
||||||
@ -39,6 +39,10 @@ function OHIFCornerstoneRTViewport(props: withAppTypes) {
|
|||||||
throw new Error('RT viewport should only have a single display set');
|
throw new Error('RT viewport should only have a single display set');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const LoadingIndicatorTotalPercent = customizationService.getCustomization(
|
||||||
|
'ui.loadingIndicatorTotalPercent'
|
||||||
|
);
|
||||||
|
|
||||||
const rtDisplaySet = displaySets[0];
|
const rtDisplaySet = displaySets[0];
|
||||||
|
|
||||||
const [viewportGrid, viewportGridService] = useViewportGrid();
|
const [viewportGrid, viewportGridService] = useViewportGrid();
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
import React, { useCallback, useEffect, useRef, useState } from 'react';
|
import React, { useCallback, useEffect, useRef, useState } from 'react';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import { LoadingIndicatorTotalPercent, ViewportActionArrows } from '@ohif/ui';
|
import { ViewportActionArrows } from '@ohif/ui';
|
||||||
import { useViewportGrid } from '@ohif/ui-next';
|
import { useViewportGrid } from '@ohif/ui-next';
|
||||||
import createSEGToolGroupAndAddTools from '../utils/initSEGToolGroup';
|
import createSEGToolGroupAndAddTools from '../utils/initSEGToolGroup';
|
||||||
import promptHydrateSEG from '../utils/promptHydrateSEG';
|
import promptHydrateSEG from '../utils/promptHydrateSEG';
|
||||||
@ -31,6 +31,10 @@ function OHIFCornerstoneSEGViewport(props: withAppTypes) {
|
|||||||
viewportActionCornersService,
|
viewportActionCornersService,
|
||||||
} = servicesManager.services;
|
} = servicesManager.services;
|
||||||
|
|
||||||
|
const LoadingIndicatorTotalPercent = customizationService.getCustomization(
|
||||||
|
'ui.loadingIndicatorTotalPercent'
|
||||||
|
);
|
||||||
|
|
||||||
const toolGroupId = `${SEG_TOOLGROUP_BASE_NAME}-${viewportId}`;
|
const toolGroupId = `${SEG_TOOLGROUP_BASE_NAME}-${viewportId}`;
|
||||||
|
|
||||||
// SEG viewport will always have a single display set
|
// SEG viewport will always have a single display set
|
||||||
|
|||||||
@ -208,8 +208,9 @@ function commandsModule({
|
|||||||
*/
|
*/
|
||||||
setMeasurementLabel: ({ uid }) => {
|
setMeasurementLabel: ({ uid }) => {
|
||||||
const labelConfig = customizationService.getCustomization('measurementLabels');
|
const labelConfig = customizationService.getCustomization('measurementLabels');
|
||||||
|
const renderContent = customizationService.getCustomization('ui.labellingComponent');
|
||||||
const measurement = measurementService.getMeasurement(uid);
|
const measurement = measurementService.getMeasurement(uid);
|
||||||
showLabelAnnotationPopup(measurement, uiDialogService, labelConfig).then(
|
showLabelAnnotationPopup(measurement, uiDialogService, labelConfig, renderContent).then(
|
||||||
(val: Map<any, any>) => {
|
(val: Map<any, any>) => {
|
||||||
measurementService.update(
|
measurementService.update(
|
||||||
uid,
|
uid,
|
||||||
@ -325,16 +326,19 @@ function commandsModule({
|
|||||||
|
|
||||||
renameMeasurement: ({ uid }) => {
|
renameMeasurement: ({ uid }) => {
|
||||||
const labelConfig = customizationService.getCustomization('measurementLabels');
|
const labelConfig = customizationService.getCustomization('measurementLabels');
|
||||||
|
const renderContent = customizationService.getCustomization('ui.labellingComponent');
|
||||||
const measurement = measurementService.getMeasurement(uid);
|
const measurement = measurementService.getMeasurement(uid);
|
||||||
showLabelAnnotationPopup(measurement, uiDialogService, labelConfig).then(val => {
|
showLabelAnnotationPopup(measurement, uiDialogService, labelConfig, renderContent).then(
|
||||||
measurementService.update(
|
val => {
|
||||||
uid,
|
measurementService.update(
|
||||||
{
|
uid,
|
||||||
...val,
|
{
|
||||||
},
|
...val,
|
||||||
true
|
},
|
||||||
);
|
true
|
||||||
});
|
);
|
||||||
|
}
|
||||||
|
);
|
||||||
},
|
},
|
||||||
|
|
||||||
toggleLockMeasurement: ({ uid }) => {
|
toggleLockMeasurement: ({ uid }) => {
|
||||||
@ -376,7 +380,8 @@ function commandsModule({
|
|||||||
},
|
},
|
||||||
arrowTextCallback: ({ callback, data, uid }) => {
|
arrowTextCallback: ({ callback, data, uid }) => {
|
||||||
const labelConfig = customizationService.getCustomization('measurementLabels');
|
const labelConfig = customizationService.getCustomization('measurementLabels');
|
||||||
callLabelAutocompleteDialog(uiDialogService, callback, {}, labelConfig);
|
const renderContent = customizationService.getCustomization('ui.labellingComponent');
|
||||||
|
callLabelAutocompleteDialog(uiDialogService, callback, {}, labelConfig, renderContent);
|
||||||
},
|
},
|
||||||
toggleCine: () => {
|
toggleCine: () => {
|
||||||
const { viewports } = viewportGridService.getState();
|
const { viewports } = viewportGridService.getState();
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
import React, { useCallback, useEffect, useRef, useState, ReactElement } from 'react';
|
import React, { useCallback, useEffect, useRef, useState, ReactElement } from 'react';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import { Button, ProgressLoadingBar } from '@ohif/ui';
|
import { useSystem } from '@ohif/core';
|
||||||
|
import { Button } from '@ohif/ui';
|
||||||
import { Icons } from '@ohif/ui-next';
|
import { Icons } from '@ohif/ui-next';
|
||||||
import DicomFileUploader, {
|
import DicomFileUploader, {
|
||||||
EVENTS,
|
EVENTS,
|
||||||
@ -40,6 +41,11 @@ function DicomUploadProgress({
|
|||||||
dicomFileUploaderArr,
|
dicomFileUploaderArr,
|
||||||
onComplete,
|
onComplete,
|
||||||
}: DicomUploadProgressProps): ReactElement {
|
}: DicomUploadProgressProps): ReactElement {
|
||||||
|
const { servicesManager } = useSystem();
|
||||||
|
|
||||||
|
const ProgressLoadingBar =
|
||||||
|
servicesManager.services.customizationService.getCustomization('ui.progressLoadingBar');
|
||||||
|
|
||||||
const [totalUploadSize] = useState(
|
const [totalUploadSize] = useState(
|
||||||
dicomFileUploaderArr.reduce((acc, fileUploader) => acc + fileUploader.getFileSize(), 0)
|
dicomFileUploaderArr.reduce((acc, fileUploader) => acc + fileUploader.getFileSize(), 0)
|
||||||
);
|
);
|
||||||
|
|||||||
@ -1,14 +1,16 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { useViewportActionCornersContext } from '../contextProviders/ViewportActionCornersProvider';
|
import { useViewportActionCornersContext } from '../contextProviders/ViewportActionCornersProvider';
|
||||||
import { ViewportActionCorners } from '@ohif/ui';
|
import { useSystem } from '@ohif/core';
|
||||||
|
|
||||||
export type OHIFViewportActionCornersProps = {
|
export type OHIFViewportActionCornersProps = {
|
||||||
viewportId: string;
|
viewportId: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
function OHIFViewportActionCorners({ viewportId }: OHIFViewportActionCornersProps) {
|
function OHIFViewportActionCorners({ viewportId }: OHIFViewportActionCornersProps) {
|
||||||
|
const { servicesManager } = useSystem();
|
||||||
const [viewportActionCornersState] = useViewportActionCornersContext();
|
const [viewportActionCornersState] = useViewportActionCornersContext();
|
||||||
|
const ViewportActionCorners =
|
||||||
|
servicesManager.services.customizationService.getCustomization('ui.viewportActionCorner');
|
||||||
if (!viewportActionCornersState[viewportId]) {
|
if (!viewportActionCornersState[viewportId]) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,7 +1,8 @@
|
|||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
import React, { ReactElement, useEffect, useState } from 'react';
|
import React, { ReactElement, useEffect, useState } from 'react';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import { Button, InputFilterText, LoadingIndicatorProgress } from '@ohif/ui';
|
import { useSystem } from '@ohif/core';
|
||||||
|
import { Button, InputFilterText } from '@ohif/ui';
|
||||||
import { Icons } from '@ohif/ui-next';
|
import { Icons } from '@ohif/ui-next';
|
||||||
import { Types } from '@ohif/core';
|
import { Types } from '@ohif/core';
|
||||||
|
|
||||||
@ -16,6 +17,7 @@ function ItemListComponent({
|
|||||||
itemList,
|
itemList,
|
||||||
onItemClicked,
|
onItemClicked,
|
||||||
}: ItemListComponentProps): ReactElement {
|
}: ItemListComponentProps): ReactElement {
|
||||||
|
const { servicesManager } = useSystem();
|
||||||
const { t } = useTranslation('DataSourceConfiguration');
|
const { t } = useTranslation('DataSourceConfiguration');
|
||||||
const [filterValue, setFilterValue] = useState('');
|
const [filterValue, setFilterValue] = useState('');
|
||||||
|
|
||||||
@ -23,6 +25,10 @@ function ItemListComponent({
|
|||||||
setFilterValue('');
|
setFilterValue('');
|
||||||
}, [itemList]);
|
}, [itemList]);
|
||||||
|
|
||||||
|
const LoadingIndicatorProgress = servicesManager.services.customizationService.getCustomization(
|
||||||
|
'ui.loadingIndicatorProgress'
|
||||||
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="flex min-h-[1px] grow flex-col gap-4">
|
<div className="flex min-h-[1px] grow flex-col gap-4">
|
||||||
<div className="flex items-center justify-between">
|
<div className="flex items-center justify-between">
|
||||||
|
|||||||
@ -1,5 +1,4 @@
|
|||||||
import * as ContextMenuItemsBuilder from './ContextMenuItemsBuilder';
|
import * as ContextMenuItemsBuilder from './ContextMenuItemsBuilder';
|
||||||
import ContextMenu from '../../../../platform/ui/src/components/ContextMenu/ContextMenu';
|
|
||||||
import { CommandsManager } from '@ohif/core';
|
import { CommandsManager } from '@ohif/core';
|
||||||
import { annotation as CsAnnotation } from '@cornerstonejs/tools';
|
import { annotation as CsAnnotation } from '@cornerstonejs/tools';
|
||||||
import { Menu, MenuItem, Point, ContextMenuProps } from './types';
|
import { Menu, MenuItem, Point, ContextMenuProps } from './types';
|
||||||
@ -72,6 +71,8 @@ export default class ContextMenuController {
|
|||||||
menuId
|
menuId
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const ContextMenu = this.services.customizationService.getCustomization('ui.contextMenu');
|
||||||
|
|
||||||
this.services.uiDialogService.dismiss({ id: 'context-menu' });
|
this.services.uiDialogService.dismiss({ id: 'context-menu' });
|
||||||
this.services.uiDialogService.create({
|
this.services.uiDialogService.create({
|
||||||
id: 'context-menu',
|
id: 'context-menu',
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
import React, { useEffect, useState, useCallback } from 'react';
|
import React, { useEffect, useState, useCallback } from 'react';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
|
|
||||||
import { LoadingIndicatorProgress, InvestigationalUseDialog } from '@ohif/ui';
|
import { InvestigationalUseDialog } from '@ohif/ui';
|
||||||
import { HangingProtocolService, CommandsManager } from '@ohif/core';
|
import { HangingProtocolService, CommandsManager } from '@ohif/core';
|
||||||
import { useAppConfig } from '@state';
|
import { useAppConfig } from '@state';
|
||||||
import ViewerHeader from './ViewerHeader';
|
import ViewerHeader from './ViewerHeader';
|
||||||
@ -27,7 +27,7 @@ function ViewerLayout({
|
|||||||
}: withAppTypes): React.FunctionComponent {
|
}: withAppTypes): React.FunctionComponent {
|
||||||
const [appConfig] = useAppConfig();
|
const [appConfig] = useAppConfig();
|
||||||
|
|
||||||
const { panelService, hangingProtocolService } = servicesManager.services;
|
const { panelService, hangingProtocolService, customizationService } = servicesManager.services;
|
||||||
const [showLoadingIndicator, setShowLoadingIndicator] = useState(appConfig.showLoadingIndicator);
|
const [showLoadingIndicator, setShowLoadingIndicator] = useState(appConfig.showLoadingIndicator);
|
||||||
|
|
||||||
const hasPanels = useCallback(
|
const hasPanels = useCallback(
|
||||||
@ -55,6 +55,10 @@ function ViewerLayout({
|
|||||||
setRightPanelClosed
|
setRightPanelClosed
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const LoadingIndicatorProgress = customizationService.getCustomization(
|
||||||
|
'ui.loadingIndicatorProgress'
|
||||||
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set body classes (tailwindcss) that don't allow vertical
|
* Set body classes (tailwindcss) that don't allow vertical
|
||||||
* or horizontal overflow (no scrolling). Also guarantee window
|
* or horizontal overflow (no scrolling). Also guarantee window
|
||||||
|
|||||||
@ -0,0 +1,5 @@
|
|||||||
|
import { ContextMenu } from '@ohif/ui';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
'ui.contextMenu': ContextMenu,
|
||||||
|
};
|
||||||
@ -0,0 +1,5 @@
|
|||||||
|
import { LabellingFlow } from '@ohif/ui';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
'ui.labellingComponent': LabellingFlow,
|
||||||
|
};
|
||||||
@ -0,0 +1,5 @@
|
|||||||
|
import { LoadingIndicatorProgress } from '@ohif/ui';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
'ui.loadingIndicatorProgress': LoadingIndicatorProgress,
|
||||||
|
};
|
||||||
@ -0,0 +1,5 @@
|
|||||||
|
import { LoadingIndicatorTotalPercent } from '@ohif/ui';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
'ui.loadingIndicatorTotalPercent': LoadingIndicatorTotalPercent,
|
||||||
|
};
|
||||||
@ -0,0 +1,5 @@
|
|||||||
|
import { ProgressLoadingBar } from '@ohif/ui';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
'ui.progressLoadingBar': ProgressLoadingBar,
|
||||||
|
};
|
||||||
@ -0,0 +1,5 @@
|
|||||||
|
import { ViewportActionCorners } from '@ohif/ui';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
'ui.viewportActionCorner': ViewportActionCorners,
|
||||||
|
};
|
||||||
@ -6,11 +6,17 @@ import customRoutesCustomization from './customizations/customRoutesCustomizatio
|
|||||||
import studyBrowserCustomization from './customizations/studyBrowserCustomization';
|
import studyBrowserCustomization from './customizations/studyBrowserCustomization';
|
||||||
import overlayItemCustomization from './customizations/overlayItemCustomization';
|
import overlayItemCustomization from './customizations/overlayItemCustomization';
|
||||||
import contextMenuCustomization from './customizations/contextMenuCustomization';
|
import contextMenuCustomization from './customizations/contextMenuCustomization';
|
||||||
|
import contextMenuUICustomization from './customizations/contextMenuUICustomization';
|
||||||
import menuContentCustomization from './customizations/menuContentCustomization';
|
import menuContentCustomization from './customizations/menuContentCustomization';
|
||||||
import getDataSourceConfigurationCustomization from './customizations/dataSourceConfigurationCustomization';
|
import getDataSourceConfigurationCustomization from './customizations/dataSourceConfigurationCustomization';
|
||||||
import progressDropdownCustomization from './customizations/progressDropdownCustomization';
|
import progressDropdownCustomization from './customizations/progressDropdownCustomization';
|
||||||
import sortingCriteriaCustomization from './customizations/sortingCriteriaCustomization';
|
import sortingCriteriaCustomization from './customizations/sortingCriteriaCustomization';
|
||||||
import onDropHandlerCustomization from './customizations/onDropHandlerCustomization';
|
import onDropHandlerCustomization from './customizations/onDropHandlerCustomization';
|
||||||
|
import loadingIndicatorProgressCustomization from './customizations/loadingIndicatorProgressCustomization';
|
||||||
|
import loadingIndicatorTotalPercentCustomization from './customizations/loadingIndicatorTotalPercentCustomization';
|
||||||
|
import progressLoadingBarCustomization from './customizations/progressLoadingBarCustomization';
|
||||||
|
import viewportActionCornersCustomization from './customizations/viewportActionCornersCustomization';
|
||||||
|
import labellingFlowCustomization from './customizations/labellingFlowCustomization';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
@ -48,6 +54,12 @@ export default function getCustomizationModule({ servicesManager, extensionManag
|
|||||||
...sortingCriteriaCustomization,
|
...sortingCriteriaCustomization,
|
||||||
...defaultContextMenuCustomization,
|
...defaultContextMenuCustomization,
|
||||||
...onDropHandlerCustomization,
|
...onDropHandlerCustomization,
|
||||||
|
...loadingIndicatorProgressCustomization,
|
||||||
|
...loadingIndicatorTotalPercentCustomization,
|
||||||
|
...progressLoadingBarCustomization,
|
||||||
|
...viewportActionCornersCustomization,
|
||||||
|
...labellingFlowCustomization,
|
||||||
|
...contextMenuUICustomization,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|||||||
@ -89,7 +89,13 @@ export function callInputDialog(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function callLabelAutocompleteDialog(uiDialogService, callback, dialogConfig, labelConfig) {
|
export function callLabelAutocompleteDialog(
|
||||||
|
uiDialogService,
|
||||||
|
callback,
|
||||||
|
dialogConfig,
|
||||||
|
labelConfig,
|
||||||
|
renderContent = LabellingFlow
|
||||||
|
) {
|
||||||
const exclusive = labelConfig ? labelConfig.exclusive : false;
|
const exclusive = labelConfig ? labelConfig.exclusive : false;
|
||||||
const dropDownItems = labelConfig ? labelConfig.items : [];
|
const dropDownItems = labelConfig ? labelConfig.items : [];
|
||||||
|
|
||||||
@ -112,7 +118,7 @@ export function callLabelAutocompleteDialog(uiDialogService, callback, dialogCon
|
|||||||
centralize: true,
|
centralize: true,
|
||||||
isDraggable: false,
|
isDraggable: false,
|
||||||
showOverlay: true,
|
showOverlay: true,
|
||||||
content: LabellingFlow,
|
content: renderContent,
|
||||||
contentProps: {
|
contentProps: {
|
||||||
labellingDoneCallback: labellingDoneCallback,
|
labellingDoneCallback: labellingDoneCallback,
|
||||||
measurementData: { label: '' },
|
measurementData: { label: '' },
|
||||||
@ -123,7 +129,12 @@ export function callLabelAutocompleteDialog(uiDialogService, callback, dialogCon
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
export function showLabelAnnotationPopup(measurement, uiDialogService, labelConfig) {
|
export function showLabelAnnotationPopup(
|
||||||
|
measurement,
|
||||||
|
uiDialogService,
|
||||||
|
labelConfig,
|
||||||
|
renderContent = LabellingFlow
|
||||||
|
) {
|
||||||
const exclusive = labelConfig ? labelConfig.exclusive : false;
|
const exclusive = labelConfig ? labelConfig.exclusive : false;
|
||||||
const dropDownItems = labelConfig ? labelConfig.items : [];
|
const dropDownItems = labelConfig ? labelConfig.items : [];
|
||||||
return new Promise<Map<any, any>>((resolve, reject) => {
|
return new Promise<Map<any, any>>((resolve, reject) => {
|
||||||
@ -139,7 +150,7 @@ export function showLabelAnnotationPopup(measurement, uiDialogService, labelConf
|
|||||||
id: 'select-annotation',
|
id: 'select-annotation',
|
||||||
isDraggable: false,
|
isDraggable: false,
|
||||||
showOverlay: true,
|
showOverlay: true,
|
||||||
content: LabellingFlow,
|
content: renderContent,
|
||||||
defaultPosition: {
|
defaultPosition: {
|
||||||
x: window.innerWidth / 2,
|
x: window.innerWidth / 2,
|
||||||
y: window.innerHeight / 2,
|
y: window.innerHeight / 2,
|
||||||
|
|||||||
@ -5,11 +5,13 @@ function promptLabelAnnotation({ servicesManager }, ctx, evt) {
|
|||||||
const { viewportId, StudyInstanceUID, SeriesInstanceUID, measurementId } = evt;
|
const { viewportId, StudyInstanceUID, SeriesInstanceUID, measurementId } = evt;
|
||||||
return new Promise(async function (resolve) {
|
return new Promise(async function (resolve) {
|
||||||
const labelConfig = customizationService.getCustomization('measurementLabels');
|
const labelConfig = customizationService.getCustomization('measurementLabels');
|
||||||
|
const renderContent = customizationService.getCustomization('ui.labellingComponent');
|
||||||
const measurement = measurementService.getMeasurement(measurementId);
|
const measurement = measurementService.getMeasurement(measurementId);
|
||||||
const value = await showLabelAnnotationPopup(
|
const value = await showLabelAnnotationPopup(
|
||||||
measurement,
|
measurement,
|
||||||
servicesManager.services.uiDialogService,
|
servicesManager.services.uiDialogService,
|
||||||
labelConfig
|
labelConfig,
|
||||||
|
renderContent
|
||||||
);
|
);
|
||||||
|
|
||||||
measurementService.update(
|
measurementService.update(
|
||||||
|
|||||||
@ -1,6 +1,5 @@
|
|||||||
import React, { Component } from 'react';
|
import React, { Component } from 'react';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import { LoadingIndicatorProgress } from '@ohif/ui';
|
|
||||||
import { cleanDenaturalizedDataset } from '@ohif/extension-default';
|
import { cleanDenaturalizedDataset } from '@ohif/extension-default';
|
||||||
|
|
||||||
import './DicomMicroscopyViewport.css';
|
import './DicomMicroscopyViewport.css';
|
||||||
@ -8,6 +7,7 @@ import ViewportOverlay from './components/ViewportOverlay';
|
|||||||
import getDicomWebClient from './utils/dicomWebClient';
|
import getDicomWebClient from './utils/dicomWebClient';
|
||||||
import dcmjs from 'dcmjs';
|
import dcmjs from 'dcmjs';
|
||||||
import MicroscopyService from './services/MicroscopyService';
|
import MicroscopyService from './services/MicroscopyService';
|
||||||
|
import { CustomizationService } from '@ohif/core';
|
||||||
|
|
||||||
class DicomMicroscopyViewport extends Component {
|
class DicomMicroscopyViewport extends Component {
|
||||||
state = {
|
state = {
|
||||||
@ -16,6 +16,7 @@ class DicomMicroscopyViewport extends Component {
|
|||||||
};
|
};
|
||||||
|
|
||||||
microscopyService: MicroscopyService;
|
microscopyService: MicroscopyService;
|
||||||
|
customizationService: CustomizationService;
|
||||||
viewer: any = null; // dicom-microscopy-viewer instance
|
viewer: any = null; // dicom-microscopy-viewer instance
|
||||||
managedViewer: any = null; // managed wrapper of microscopy-dicom extension
|
managedViewer: any = null; // managed wrapper of microscopy-dicom extension
|
||||||
|
|
||||||
@ -25,8 +26,9 @@ class DicomMicroscopyViewport extends Component {
|
|||||||
constructor(props: any) {
|
constructor(props: any) {
|
||||||
super(props);
|
super(props);
|
||||||
|
|
||||||
const { microscopyService } = this.props.servicesManager.services;
|
const { microscopyService, customizationService } = this.props.servicesManager.services;
|
||||||
this.microscopyService = microscopyService;
|
this.microscopyService = microscopyService;
|
||||||
|
this.customizationService = customizationService;
|
||||||
}
|
}
|
||||||
|
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
@ -49,7 +51,6 @@ class DicomMicroscopyViewport extends Component {
|
|||||||
resizeRef: PropTypes.oneOfType([PropTypes.func, PropTypes.shape({ current: PropTypes.any })]),
|
resizeRef: PropTypes.oneOfType([PropTypes.func, PropTypes.shape({ current: PropTypes.any })]),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the nearest ROI from the mouse click point
|
* Get the nearest ROI from the mouse click point
|
||||||
*
|
*
|
||||||
@ -272,6 +273,9 @@ class DicomMicroscopyViewport extends Component {
|
|||||||
const style = { width: '100%', height: '100%' };
|
const style = { width: '100%', height: '100%' };
|
||||||
const displaySet = this.props.displaySets[0];
|
const displaySet = this.props.displaySets[0];
|
||||||
const firstInstance = displaySet.firstInstance || displaySet.instance;
|
const firstInstance = displaySet.firstInstance || displaySet.instance;
|
||||||
|
const LoadingIndicatorProgress = this.customizationService.getCustomization(
|
||||||
|
'ui.loadingIndicatorProgress'
|
||||||
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
|
|||||||
@ -12,6 +12,7 @@ import {
|
|||||||
CommandsManager,
|
CommandsManager,
|
||||||
HotkeysManager,
|
HotkeysManager,
|
||||||
ServiceProvidersManager,
|
ServiceProvidersManager,
|
||||||
|
SystemContextProvider,
|
||||||
} from '@ohif/core';
|
} from '@ohif/core';
|
||||||
import {
|
import {
|
||||||
DialogProvider,
|
DialogProvider,
|
||||||
@ -114,6 +115,7 @@ function App({
|
|||||||
[I18nextProvider, { i18n }],
|
[I18nextProvider, { i18n }],
|
||||||
[ThemeWrapperNext],
|
[ThemeWrapperNext],
|
||||||
[ThemeWrapper],
|
[ThemeWrapper],
|
||||||
|
[SystemContextProvider, { commandsManager, extensionManager, hotkeysManager, servicesManager }],
|
||||||
[ToolboxProvider],
|
[ToolboxProvider],
|
||||||
[ViewportGridProvider, { service: viewportGridService }],
|
[ViewportGridProvider, { service: viewportGridService }],
|
||||||
[ViewportDialogProvider, { service: uiViewportDialogService }],
|
[ViewportDialogProvider, { service: uiViewportDialogService }],
|
||||||
|
|||||||
@ -1,14 +1,14 @@
|
|||||||
import React, { useEffect, useRef } from 'react';
|
import React, { useEffect, useRef } from 'react';
|
||||||
import classnames from 'classnames';
|
import classnames from 'classnames';
|
||||||
import { useNavigate } from 'react-router-dom';
|
import { useNavigate } from 'react-router-dom';
|
||||||
import { DicomMetadataStore, MODULE_TYPES } from '@ohif/core';
|
import { DicomMetadataStore, MODULE_TYPES, useSystem } from '@ohif/core';
|
||||||
|
|
||||||
import Dropzone from 'react-dropzone';
|
import Dropzone from 'react-dropzone';
|
||||||
import filesToStudies from './filesToStudies';
|
import filesToStudies from './filesToStudies';
|
||||||
|
|
||||||
import { extensionManager } from '../../App';
|
import { extensionManager } from '../../App';
|
||||||
|
|
||||||
import { Button, LoadingIndicatorProgress } from '@ohif/ui';
|
import { Button } from '@ohif/ui';
|
||||||
import { Icons } from '@ohif/ui-next';
|
import { Icons } from '@ohif/ui-next';
|
||||||
|
|
||||||
const getLoadButton = (onDrop, text, isDir) => {
|
const getLoadButton = (onDrop, text, isDir) => {
|
||||||
@ -49,10 +49,16 @@ type LocalProps = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
function Local({ modePath }: LocalProps) {
|
function Local({ modePath }: LocalProps) {
|
||||||
|
const { servicesManager } = useSystem();
|
||||||
|
const { customizationService } = servicesManager.services;
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
const dropzoneRef = useRef();
|
const dropzoneRef = useRef();
|
||||||
const [dropInitiated, setDropInitiated] = React.useState(false);
|
const [dropInitiated, setDropInitiated] = React.useState(false);
|
||||||
|
|
||||||
|
const LoadingIndicatorProgress = customizationService.getCustomization(
|
||||||
|
'ui.loadingIndicatorProgress'
|
||||||
|
);
|
||||||
|
|
||||||
// Initializing the dicom local dataSource
|
// Initializing the dicom local dataSource
|
||||||
const dataSourceModules = extensionManager.modules[MODULE_TYPES.DATA_SOURCE];
|
const dataSourceModules = extensionManager.modules[MODULE_TYPES.DATA_SOURCE];
|
||||||
const localDataSources = dataSourceModules.reduce((acc, curr) => {
|
const localDataSources = dataSourceModules.reduce((acc, curr) => {
|
||||||
|
|||||||
@ -22,7 +22,6 @@ import {
|
|||||||
useModal,
|
useModal,
|
||||||
AboutModal,
|
AboutModal,
|
||||||
UserPreferences,
|
UserPreferences,
|
||||||
LoadingIndicatorProgress,
|
|
||||||
useSessionStorage,
|
useSessionStorage,
|
||||||
InvestigationalUseDialog,
|
InvestigationalUseDialog,
|
||||||
Button,
|
Button,
|
||||||
@ -525,6 +524,9 @@ function WorkList({
|
|||||||
}
|
}
|
||||||
|
|
||||||
const { customizationService } = servicesManager.services;
|
const { customizationService } = servicesManager.services;
|
||||||
|
const LoadingIndicatorProgress = customizationService.getCustomization(
|
||||||
|
'ui.loadingIndicatorProgress'
|
||||||
|
);
|
||||||
const DicomUploadComponent = customizationService.getCustomization('dicomUploadComponent');
|
const DicomUploadComponent = customizationService.getCustomization('dicomUploadComponent');
|
||||||
|
|
||||||
const uploadProps =
|
const uploadProps =
|
||||||
|
|||||||
33
platform/core/src/contextProviders/SystemProvider.tsx
Normal file
33
platform/core/src/contextProviders/SystemProvider.tsx
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
import React, { createContext, useContext } from 'react';
|
||||||
|
import { CommandsManager, HotkeysManager } from '../classes';
|
||||||
|
import { ExtensionManager } from '../extensions';
|
||||||
|
import { ServicesManager } from '../services';
|
||||||
|
|
||||||
|
interface SystemContextProviderProps {
|
||||||
|
children: React.ReactNode | React.ReactNode[] | ((...args: any[]) => React.ReactNode);
|
||||||
|
servicesManager: ServicesManager;
|
||||||
|
commandsManager: CommandsManager;
|
||||||
|
extensionManager: ExtensionManager;
|
||||||
|
hotkeysManager: HotkeysManager;
|
||||||
|
}
|
||||||
|
|
||||||
|
const systemContext = createContext(null);
|
||||||
|
const { Provider } = systemContext;
|
||||||
|
|
||||||
|
export const useSystem = () => useContext(systemContext);
|
||||||
|
|
||||||
|
export function SystemContextProvider({
|
||||||
|
children,
|
||||||
|
servicesManager,
|
||||||
|
commandsManager,
|
||||||
|
extensionManager,
|
||||||
|
hotkeysManager,
|
||||||
|
}: SystemContextProviderProps) {
|
||||||
|
return (
|
||||||
|
<Provider value={{ servicesManager, commandsManager, extensionManager, hotkeysManager }}>
|
||||||
|
{children}
|
||||||
|
</Provider>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default SystemContextProvider;
|
||||||
@ -1,6 +1,7 @@
|
|||||||
import { ExtensionManager, MODULE_TYPES } from './extensions';
|
import { ExtensionManager, MODULE_TYPES } from './extensions';
|
||||||
import { ServiceProvidersManager, ServicesManager } from './services';
|
import { ServiceProvidersManager, ServicesManager } from './services';
|
||||||
import classes, { CommandsManager, HotkeysManager } from './classes';
|
import classes, { CommandsManager, HotkeysManager } from './classes';
|
||||||
|
import { SystemContextProvider, useSystem } from './contextProviders/SystemProvider';
|
||||||
|
|
||||||
import DICOMWeb from './DICOMWeb';
|
import DICOMWeb from './DICOMWeb';
|
||||||
import errorHandler from './errorHandler.js';
|
import errorHandler from './errorHandler.js';
|
||||||
@ -99,6 +100,7 @@ export {
|
|||||||
HotkeysManager,
|
HotkeysManager,
|
||||||
ServicesManager,
|
ServicesManager,
|
||||||
ServiceProvidersManager,
|
ServiceProvidersManager,
|
||||||
|
SystemContextProvider,
|
||||||
//
|
//
|
||||||
defaults,
|
defaults,
|
||||||
utils,
|
utils,
|
||||||
@ -134,6 +136,7 @@ export {
|
|||||||
PanelService,
|
PanelService,
|
||||||
WorkflowStepsService,
|
WorkflowStepsService,
|
||||||
StudyPrefetcherService,
|
StudyPrefetcherService,
|
||||||
|
useSystem,
|
||||||
useToolbar,
|
useToolbar,
|
||||||
useActiveViewportDisplaySets,
|
useActiveViewportDisplaySets,
|
||||||
};
|
};
|
||||||
|
|||||||
BIN
platform/docs/docs/assets/img/Loading-Indicator.png
Normal file
BIN
platform/docs/docs/assets/img/Loading-Indicator.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 3.1 KiB |
BIN
platform/docs/docs/assets/img/context-menu.jpg
Normal file
BIN
platform/docs/docs/assets/img/context-menu.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 10 KiB |
BIN
platform/docs/docs/assets/img/labelling-flow.png
Normal file
BIN
platform/docs/docs/assets/img/labelling-flow.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 65 KiB |
BIN
platform/docs/docs/assets/img/loading-indicator-icon.png
Normal file
BIN
platform/docs/docs/assets/img/loading-indicator-icon.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 2.1 KiB |
BIN
platform/docs/docs/assets/img/loading-indicator-percent.png
Normal file
BIN
platform/docs/docs/assets/img/loading-indicator-percent.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 3.0 KiB |
BIN
platform/docs/docs/assets/img/viewport-action-corners.png
Normal file
BIN
platform/docs/docs/assets/img/viewport-action-corners.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 6.7 KiB |
@ -10,6 +10,13 @@ import segmentationTableModeImage2 from '../../../assets/img/segmentationTableMo
|
|||||||
import segmentationShowAddSegmentImage from '../../../assets/img/segmentationShowAddSegmentImage.png';
|
import segmentationShowAddSegmentImage from '../../../assets/img/segmentationShowAddSegmentImage.png';
|
||||||
import layoutSelectorCommonPresetsImage from '../../../assets/img/layoutSelectorCommonPresetsImage.png';
|
import layoutSelectorCommonPresetsImage from '../../../assets/img/layoutSelectorCommonPresetsImage.png';
|
||||||
import layoutSelectorAdvancedPresetGeneratorImage from '../../../assets/img/layoutSelectorAdvancedPresetGeneratorImage.png';
|
import layoutSelectorAdvancedPresetGeneratorImage from '../../../assets/img/layoutSelectorAdvancedPresetGeneratorImage.png';
|
||||||
|
import labellingFLow from '../../../assets/img/labelling-flow.png';
|
||||||
|
import progressLoading from '../../../assets/img/Loading-Indicator.png';
|
||||||
|
import loadingIndicatorProgress from '../../../assets/img/loading-indicator-icon.png';
|
||||||
|
import loadingIndicatorPercent from '../../../assets/img/loading-indicator-percent.png';
|
||||||
|
import viewportActionCorners from '../../../assets/img/viewport-action-corners.png';
|
||||||
|
import contextMenu from '../../../assets/img/context-menu.jpg';
|
||||||
|
|
||||||
import segDisplayEditingTrue from '../../../assets/img/segDisplayEditingTrue.png';
|
import segDisplayEditingTrue from '../../../assets/img/segDisplayEditingTrue.png';
|
||||||
import segDisplayEditingFalse from '../../../assets/img/segDisplayEditingFalse.png';
|
import segDisplayEditingFalse from '../../../assets/img/segDisplayEditingFalse.png';
|
||||||
import thumbnailMenuItemsImage from '../../../assets/img/thumbnailMenuItemsImage.png';
|
import thumbnailMenuItemsImage from '../../../assets/img/thumbnailMenuItemsImage.png';
|
||||||
@ -610,6 +617,114 @@ window.config = {
|
|||||||
};
|
};
|
||||||
`,
|
`,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
id: 'ui.loadingIndicatorTotalPercent',
|
||||||
|
description: 'Customizes the LoadingIndicatorTotalPercent component.',
|
||||||
|
image: loadingIndicatorPercent,
|
||||||
|
default: null, //use platform/ui component as default
|
||||||
|
configuration: `
|
||||||
|
window.config = {
|
||||||
|
// rest of window config
|
||||||
|
customizationService: [
|
||||||
|
{
|
||||||
|
'ui.loadingIndicatorTotalPercent': {
|
||||||
|
$set: CustomizedComponent,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
||||||
|
`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'ui.loadingIndicatorProgress',
|
||||||
|
description: 'Customizes the LoadingIndicatorProgress component.',
|
||||||
|
image: loadingIndicatorProgress,
|
||||||
|
default: null, //use platform/ui component as default
|
||||||
|
configuration: `
|
||||||
|
window.config = {
|
||||||
|
// rest of window config
|
||||||
|
customizationService: [
|
||||||
|
{
|
||||||
|
'ui.loadingIndicatorProgress': {
|
||||||
|
$set: CustomizedComponent,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
||||||
|
`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'ui.progressLoadingBar',
|
||||||
|
description: 'Customizes the ProgressLoadingBar component.',
|
||||||
|
image: progressLoading,
|
||||||
|
default: null, //use platform/ui component as default
|
||||||
|
configuration: `
|
||||||
|
window.config = {
|
||||||
|
// rest of window config
|
||||||
|
customizationService: [
|
||||||
|
{
|
||||||
|
'ui.progressLoadingBar': {
|
||||||
|
$set: CustomizedComponent,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
||||||
|
`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'ui.viewportActionCorner',
|
||||||
|
description: 'Customizes the viewportActionCorner component.',
|
||||||
|
iamge: viewportActionCorners,
|
||||||
|
default: null, //use platform/ui component as default
|
||||||
|
configuration: `
|
||||||
|
window.config = {
|
||||||
|
// rest of window config
|
||||||
|
customizationService: [
|
||||||
|
{
|
||||||
|
'ui.viewportActionCorner': {
|
||||||
|
$set: CustomizedComponent,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
||||||
|
`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'ui.contextMenu',
|
||||||
|
description: 'Customizes the Context menu component.',
|
||||||
|
image: contextMenu,
|
||||||
|
default: null, //use platform/ui component as default
|
||||||
|
configuration: `
|
||||||
|
window.config = {
|
||||||
|
// rest of window config
|
||||||
|
customizationService: [
|
||||||
|
{
|
||||||
|
'ui.contextMenu': {
|
||||||
|
$set: CustomizedComponent,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
||||||
|
`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'ui.labellingComponent',
|
||||||
|
description: 'Customizes the labelling flow component.',
|
||||||
|
image: labellingFLow,
|
||||||
|
default: null, //use platform/ui component as default
|
||||||
|
configuration: `
|
||||||
|
window.config = {
|
||||||
|
// rest of window config
|
||||||
|
customizationService: [
|
||||||
|
{
|
||||||
|
'ui.labellingComponent': {
|
||||||
|
$set: CustomizedComponent,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
||||||
|
`,
|
||||||
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
export const segmentationCustomizations = [
|
export const segmentationCustomizations = [
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user