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:
31 files changed
+288
-33
No files matched your search
@@ -1,6 +1,5 @@
|
||||
import PropTypes from 'prop-types';
|
||||
import React, { useCallback, useEffect, useRef, useState } from 'react';
|
||||
import { LoadingIndicatorTotalPercent } from '@ohif/ui';
|
||||
import { useViewportGrid } from '@ohif/ui-next';
|
||||
|
||||
function OHIFCornerstonePMAPViewport(props: withAppTypes) {
|
||||
@@ -13,7 +12,7 @@ function OHIFCornerstonePMAPViewport(props: withAppTypes) {
|
||||
extensionManager,
|
||||
} = props;
|
||||
const viewportId = viewportOptions.viewportId;
|
||||
const { displaySetService, segmentationService, uiNotificationService } =
|
||||
const { displaySetService, segmentationService, uiNotificationService, customizationService } =
|
||||
servicesManager.services;
|
||||
|
||||
// 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');
|
||||
}
|
||||
|
||||
const LoadingIndicatorTotalPercent = customizationService.getCustomization(
|
||||
'ui.loadingIndicatorTotalPercent'
|
||||
);
|
||||
|
||||
const pmapDisplaySet = displaySets[0];
|
||||
const [viewportGrid, viewportGridService] = useViewportGrid();
|
||||
const referencedDisplaySetRef = useRef(null);
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import React, { useCallback, useEffect, useRef, useState } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { LoadingIndicatorTotalPercent, ViewportActionArrows } from '@ohif/ui';
|
||||
import { ViewportActionArrows } from '@ohif/ui';
|
||||
import { useViewportGrid } from '@ohif/ui-next';
|
||||
|
||||
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');
|
||||
}
|
||||
|
||||
const LoadingIndicatorTotalPercent = customizationService.getCustomization(
|
||||
'ui.loadingIndicatorTotalPercent'
|
||||
);
|
||||
|
||||
const rtDisplaySet = displaySets[0];
|
||||
|
||||
const [viewportGrid, viewportGridService] = useViewportGrid();
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import React, { useCallback, useEffect, useRef, useState } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { LoadingIndicatorTotalPercent, ViewportActionArrows } from '@ohif/ui';
|
||||
import { ViewportActionArrows } from '@ohif/ui';
|
||||
import { useViewportGrid } from '@ohif/ui-next';
|
||||
import createSEGToolGroupAndAddTools from '../utils/initSEGToolGroup';
|
||||
import promptHydrateSEG from '../utils/promptHydrateSEG';
|
||||
@@ -31,6 +31,10 @@ function OHIFCornerstoneSEGViewport(props: withAppTypes) {
|
||||
viewportActionCornersService,
|
||||
} = servicesManager.services;
|
||||
|
||||
const LoadingIndicatorTotalPercent = customizationService.getCustomization(
|
||||
'ui.loadingIndicatorTotalPercent'
|
||||
);
|
||||
|
||||
const toolGroupId = `${SEG_TOOLGROUP_BASE_NAME}-${viewportId}`;
|
||||
|
||||
// SEG viewport will always have a single display set
|
||||
|
||||
@@ -208,8 +208,9 @@ function commandsModule({
|
||||
*/
|
||||
setMeasurementLabel: ({ uid }) => {
|
||||
const labelConfig = customizationService.getCustomization('measurementLabels');
|
||||
const renderContent = customizationService.getCustomization('ui.labellingComponent');
|
||||
const measurement = measurementService.getMeasurement(uid);
|
||||
showLabelAnnotationPopup(measurement, uiDialogService, labelConfig).then(
|
||||
showLabelAnnotationPopup(measurement, uiDialogService, labelConfig, renderContent).then(
|
||||
(val: Map<any, any>) => {
|
||||
measurementService.update(
|
||||
uid,
|
||||
@@ -325,16 +326,19 @@ function commandsModule({
|
||||
|
||||
renameMeasurement: ({ uid }) => {
|
||||
const labelConfig = customizationService.getCustomization('measurementLabels');
|
||||
const renderContent = customizationService.getCustomization('ui.labellingComponent');
|
||||
const measurement = measurementService.getMeasurement(uid);
|
||||
showLabelAnnotationPopup(measurement, uiDialogService, labelConfig).then(val => {
|
||||
measurementService.update(
|
||||
uid,
|
||||
{
|
||||
...val,
|
||||
},
|
||||
true
|
||||
);
|
||||
});
|
||||
showLabelAnnotationPopup(measurement, uiDialogService, labelConfig, renderContent).then(
|
||||
val => {
|
||||
measurementService.update(
|
||||
uid,
|
||||
{
|
||||
...val,
|
||||
},
|
||||
true
|
||||
);
|
||||
}
|
||||
);
|
||||
},
|
||||
|
||||
toggleLockMeasurement: ({ uid }) => {
|
||||
@@ -376,7 +380,8 @@ function commandsModule({
|
||||
},
|
||||
arrowTextCallback: ({ callback, data, uid }) => {
|
||||
const labelConfig = customizationService.getCustomization('measurementLabels');
|
||||
callLabelAutocompleteDialog(uiDialogService, callback, {}, labelConfig);
|
||||
const renderContent = customizationService.getCustomization('ui.labellingComponent');
|
||||
callLabelAutocompleteDialog(uiDialogService, callback, {}, labelConfig, renderContent);
|
||||
},
|
||||
toggleCine: () => {
|
||||
const { viewports } = viewportGridService.getState();
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import React, { useCallback, useEffect, useRef, useState, ReactElement } from 'react';
|
||||
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 DicomFileUploader, {
|
||||
EVENTS,
|
||||
@@ -40,6 +41,11 @@ function DicomUploadProgress({
|
||||
dicomFileUploaderArr,
|
||||
onComplete,
|
||||
}: DicomUploadProgressProps): ReactElement {
|
||||
const { servicesManager } = useSystem();
|
||||
|
||||
const ProgressLoadingBar =
|
||||
servicesManager.services.customizationService.getCustomization('ui.progressLoadingBar');
|
||||
|
||||
const [totalUploadSize] = useState(
|
||||
dicomFileUploaderArr.reduce((acc, fileUploader) => acc + fileUploader.getFileSize(), 0)
|
||||
);
|
||||
|
||||
@@ -1,14 +1,16 @@
|
||||
import React from 'react';
|
||||
import { useViewportActionCornersContext } from '../contextProviders/ViewportActionCornersProvider';
|
||||
import { ViewportActionCorners } from '@ohif/ui';
|
||||
import { useSystem } from '@ohif/core';
|
||||
|
||||
export type OHIFViewportActionCornersProps = {
|
||||
viewportId: string;
|
||||
};
|
||||
|
||||
function OHIFViewportActionCorners({ viewportId }: OHIFViewportActionCornersProps) {
|
||||
const { servicesManager } = useSystem();
|
||||
const [viewportActionCornersState] = useViewportActionCornersContext();
|
||||
|
||||
const ViewportActionCorners =
|
||||
servicesManager.services.customizationService.getCustomization('ui.viewportActionCorner');
|
||||
if (!viewportActionCornersState[viewportId]) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
import classNames from 'classnames';
|
||||
import React, { ReactElement, useEffect, useState } from 'react';
|
||||
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 { Types } from '@ohif/core';
|
||||
|
||||
@@ -16,6 +17,7 @@ function ItemListComponent({
|
||||
itemList,
|
||||
onItemClicked,
|
||||
}: ItemListComponentProps): ReactElement {
|
||||
const { servicesManager } = useSystem();
|
||||
const { t } = useTranslation('DataSourceConfiguration');
|
||||
const [filterValue, setFilterValue] = useState('');
|
||||
|
||||
@@ -23,6 +25,10 @@ function ItemListComponent({
|
||||
setFilterValue('');
|
||||
}, [itemList]);
|
||||
|
||||
const LoadingIndicatorProgress = servicesManager.services.customizationService.getCustomization(
|
||||
'ui.loadingIndicatorProgress'
|
||||
);
|
||||
|
||||
return (
|
||||
<div className="flex min-h-[1px] grow flex-col gap-4">
|
||||
<div className="flex items-center justify-between">
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import * as ContextMenuItemsBuilder from './ContextMenuItemsBuilder';
|
||||
import ContextMenu from '../../../../platform/ui/src/components/ContextMenu/ContextMenu';
|
||||
import { CommandsManager } from '@ohif/core';
|
||||
import { annotation as CsAnnotation } from '@cornerstonejs/tools';
|
||||
import { Menu, MenuItem, Point, ContextMenuProps } from './types';
|
||||
@@ -72,6 +71,8 @@ export default class ContextMenuController {
|
||||
menuId
|
||||
);
|
||||
|
||||
const ContextMenu = this.services.customizationService.getCustomization('ui.contextMenu');
|
||||
|
||||
this.services.uiDialogService.dismiss({ id: 'context-menu' });
|
||||
this.services.uiDialogService.create({
|
||||
id: 'context-menu',
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import React, { useEffect, useState, useCallback } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
import { LoadingIndicatorProgress, InvestigationalUseDialog } from '@ohif/ui';
|
||||
import { InvestigationalUseDialog } from '@ohif/ui';
|
||||
import { HangingProtocolService, CommandsManager } from '@ohif/core';
|
||||
import { useAppConfig } from '@state';
|
||||
import ViewerHeader from './ViewerHeader';
|
||||
@@ -27,7 +27,7 @@ function ViewerLayout({
|
||||
}: withAppTypes): React.FunctionComponent {
|
||||
const [appConfig] = useAppConfig();
|
||||
|
||||
const { panelService, hangingProtocolService } = servicesManager.services;
|
||||
const { panelService, hangingProtocolService, customizationService } = servicesManager.services;
|
||||
const [showLoadingIndicator, setShowLoadingIndicator] = useState(appConfig.showLoadingIndicator);
|
||||
|
||||
const hasPanels = useCallback(
|
||||
@@ -55,6 +55,10 @@ function ViewerLayout({
|
||||
setRightPanelClosed
|
||||
);
|
||||
|
||||
const LoadingIndicatorProgress = customizationService.getCustomization(
|
||||
'ui.loadingIndicatorProgress'
|
||||
);
|
||||
|
||||
/**
|
||||
* Set body classes (tailwindcss) that don't allow vertical
|
||||
* 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 overlayItemCustomization from './customizations/overlayItemCustomization';
|
||||
import contextMenuCustomization from './customizations/contextMenuCustomization';
|
||||
import contextMenuUICustomization from './customizations/contextMenuUICustomization';
|
||||
import menuContentCustomization from './customizations/menuContentCustomization';
|
||||
import getDataSourceConfigurationCustomization from './customizations/dataSourceConfigurationCustomization';
|
||||
import progressDropdownCustomization from './customizations/progressDropdownCustomization';
|
||||
import sortingCriteriaCustomization from './customizations/sortingCriteriaCustomization';
|
||||
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,
|
||||
...defaultContextMenuCustomization,
|
||||
...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 dropDownItems = labelConfig ? labelConfig.items : [];
|
||||
|
||||
@@ -112,7 +118,7 @@ export function callLabelAutocompleteDialog(uiDialogService, callback, dialogCon
|
||||
centralize: true,
|
||||
isDraggable: false,
|
||||
showOverlay: true,
|
||||
content: LabellingFlow,
|
||||
content: renderContent,
|
||||
contentProps: {
|
||||
labellingDoneCallback: labellingDoneCallback,
|
||||
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 dropDownItems = labelConfig ? labelConfig.items : [];
|
||||
return new Promise<Map<any, any>>((resolve, reject) => {
|
||||
@@ -139,7 +150,7 @@ export function showLabelAnnotationPopup(measurement, uiDialogService, labelConf
|
||||
id: 'select-annotation',
|
||||
isDraggable: false,
|
||||
showOverlay: true,
|
||||
content: LabellingFlow,
|
||||
content: renderContent,
|
||||
defaultPosition: {
|
||||
x: window.innerWidth / 2,
|
||||
y: window.innerHeight / 2,
|
||||
|
||||
@@ -5,11 +5,13 @@ function promptLabelAnnotation({ servicesManager }, ctx, evt) {
|
||||
const { viewportId, StudyInstanceUID, SeriesInstanceUID, measurementId } = evt;
|
||||
return new Promise(async function (resolve) {
|
||||
const labelConfig = customizationService.getCustomization('measurementLabels');
|
||||
const renderContent = customizationService.getCustomization('ui.labellingComponent');
|
||||
const measurement = measurementService.getMeasurement(measurementId);
|
||||
const value = await showLabelAnnotationPopup(
|
||||
measurement,
|
||||
servicesManager.services.uiDialogService,
|
||||
labelConfig
|
||||
labelConfig,
|
||||
renderContent
|
||||
);
|
||||
|
||||
measurementService.update(
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import React, { Component } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { LoadingIndicatorProgress } from '@ohif/ui';
|
||||
import { cleanDenaturalizedDataset } from '@ohif/extension-default';
|
||||
|
||||
import './DicomMicroscopyViewport.css';
|
||||
@@ -8,6 +7,7 @@ import ViewportOverlay from './components/ViewportOverlay';
|
||||
import getDicomWebClient from './utils/dicomWebClient';
|
||||
import dcmjs from 'dcmjs';
|
||||
import MicroscopyService from './services/MicroscopyService';
|
||||
import { CustomizationService } from '@ohif/core';
|
||||
|
||||
class DicomMicroscopyViewport extends Component {
|
||||
state = {
|
||||
@@ -16,6 +16,7 @@ class DicomMicroscopyViewport extends Component {
|
||||
};
|
||||
|
||||
microscopyService: MicroscopyService;
|
||||
customizationService: CustomizationService;
|
||||
viewer: any = null; // dicom-microscopy-viewer instance
|
||||
managedViewer: any = null; // managed wrapper of microscopy-dicom extension
|
||||
|
||||
@@ -25,8 +26,9 @@ class DicomMicroscopyViewport extends Component {
|
||||
constructor(props: any) {
|
||||
super(props);
|
||||
|
||||
const { microscopyService } = this.props.servicesManager.services;
|
||||
const { microscopyService, customizationService } = this.props.servicesManager.services;
|
||||
this.microscopyService = microscopyService;
|
||||
this.customizationService = customizationService;
|
||||
}
|
||||
|
||||
static propTypes = {
|
||||
@@ -49,7 +51,6 @@ class DicomMicroscopyViewport extends Component {
|
||||
resizeRef: PropTypes.oneOfType([PropTypes.func, PropTypes.shape({ current: PropTypes.any })]),
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Get the nearest ROI from the mouse click point
|
||||
*
|
||||
@@ -272,6 +273,9 @@ class DicomMicroscopyViewport extends Component {
|
||||
const style = { width: '100%', height: '100%' };
|
||||
const displaySet = this.props.displaySets[0];
|
||||
const firstInstance = displaySet.firstInstance || displaySet.instance;
|
||||
const LoadingIndicatorProgress = this.customizationService.getCustomization(
|
||||
'ui.loadingIndicatorProgress'
|
||||
);
|
||||
|
||||
return (
|
||||
<div
|
||||
|
||||
Reference in new issue
Block a user