refactor(ui): Migrate components to ui-next (#4930)

Co-authored-by: Dan Rukas <dan.rukas@gmail.com>
This commit is contained in:
AlirezaandDan Rukas authored and GitHub committed 2025-04-08 12:06:07 -04:00
1 parent 1b8729dded
commit 2bdf4afa4d
80 files changed
+2196 -521

No files matched your search

@@ -1,5 +1,3 @@
import { ButtonEnums } from '@ohif/ui';
const RESPONSE = {
NO_NEVER: -1,
CANCEL: 0,
@@ -47,13 +45,13 @@ function _askHydrate(
const actions = [
{
id: 'no-hydrate',
type: ButtonEnums.type.secondary,
type: 'secondary',
text: 'No',
value: RESPONSE.CANCEL,
},
{
id: 'yes-hydrate',
type: ButtonEnums.type.primary,
type: 'primary',
text: 'Yes',
value: RESPONSE.HYDRATE_SEG,
},
@@ -15,7 +15,7 @@ export default function _getStatusComponent({ isHydrated, onStatusClick }) {
case false:
StatusIcon = () => (
<Icons.ByName
className="text-aqua-pale"
className="text-muted-foreground h-4 w-4"
name="status-untracked"
/>
);
@@ -1,5 +1,3 @@
import { ButtonEnums } from '@ohif/ui';
const RESPONSE = {
NO_NEVER: -1,
CANCEL: 0,
@@ -49,13 +47,13 @@ function _askHydrate(
const actions = [
{
id: 'no-hydrate',
type: ButtonEnums.type.secondary,
type: 'secondary',
text: 'No',
value: RESPONSE.CANCEL,
},
{
id: 'yes-hydrate',
type: ButtonEnums.type.primary,
type: 'primary',
text: 'Yes',
value: RESPONSE.HYDRATE_SEG,
},
@@ -15,7 +15,7 @@ export default function _getStatusComponent({ isHydrated, onStatusClick }) {
case false:
StatusIcon = () => (
<Icons.ByName
className="text-aqua-pale"
className="text-muted-foreground h-4 w-4"
name="status-untracked"
/>
);
@@ -427,7 +427,7 @@ function _getStatusComponent({
case 3:
StatusIcon = () => (
<Icons.ByName
className="text-aqua-pale h-4 w-4"
className="text-muted-foreground h-4 w-4"
name="status-untracked"
/>
);
@@ -1,71 +0,0 @@
import React from 'react';
import { InputDoubleRange } from '@ohif/ui';
import { Select } from '@ohif/ui';
import { Button } from '@ohif/ui';
import PropTypes from 'prop-types';
const GenerateVolume = ({
rangeValues,
handleSliderChange,
operationsUI,
options,
handleGenerateOptionsChange,
onGenerateImage,
returnTo4D,
displayingComputedVolume,
}) => {
return (
<>
<div>
<div className="mb-2 text-white">Computed Image</div>
<Select
closeMenuOnSelect={true}
className="border-primary-main mr-2 bg-black text-white "
options={operationsUI}
placeholder={operationsUI.find(option => option.value === options.Operation).placeHolder}
value={options.Operation}
onChange={({ value }) => {
handleGenerateOptionsChange({
Operation: value,
});
}}
/>
<InputDoubleRange
values={rangeValues}
onChange={handleSliderChange}
minValue={rangeValues[0] || 1}
maxValue={rangeValues[1] || 2}
showLabel={true}
step={1}
/>
<div className="flex space-x-2">
<Button
onClick={onGenerateImage}
className="w-1/2"
>
Generate
</Button>
<Button
onClick={returnTo4D}
disabled={!displayingComputedVolume}
className="w-1/2"
>
Return To 4D
</Button>
</div>
</div>
</>
);
};
GenerateVolume.propTypes = {
rangeValues: PropTypes.array.isRequired,
handleSliderChange: PropTypes.func.isRequired,
operationsUI: PropTypes.array.isRequired,
options: PropTypes.object.isRequired,
handleGenerateOptionsChange: PropTypes.func.isRequired,
onGenerateImage: PropTypes.func.isRequired,
returnTo4D: PropTypes.func.isRequired,
};
export default GenerateVolume;
@@ -4,7 +4,7 @@ import * as cs3DTools from '@cornerstonejs/tools';
import { Enums, eventTarget, getEnabledElement } from '@cornerstonejs/core';
import { MeasurementService } from '@ohif/core';
import { AllInOneMenu } from '@ohif/ui-next';
import { useViewportDialog } from '@ohif/ui';
import { useViewportDialog } from '@ohif/ui-next';
import type { Types as csTypes } from '@cornerstonejs/core';
import { setEnabledElement } from '../state';
@@ -103,7 +103,8 @@ export function Colorbar({
return (
<div
className="hover:bg-accent flex h-8 w-full flex-shrink-0 cursor-pointer items-center px-2 text-base hover:rounded"
onClick={() => {
onClick={e => {
e.stopPropagation();
onSetColorbar();
}}
>
@@ -112,7 +113,8 @@ export function Colorbar({
<Switch
className="ml-2 flex-shrink-0"
checked={showColorbar}
onCheckedChange={() => {
onClick={e => {
e.stopPropagation();
onSetColorbar();
}}
/>
@@ -360,6 +360,10 @@ const connectMeasurementServiceToTools = (
measurementService.subscribe(
MEASUREMENT_UPDATED,
({ source, measurement, notYetUpdatedAtSource }) => {
if (!source) {
return;
}
if (source.name !== CORNERSTONE_3D_TOOLS_SOURCE_NAME) {
return;
}
@@ -1,5 +1,5 @@
import React from 'react';
import { LineChart } from '@ohif/ui';
import { LineChart } from '@ohif/ui-next';
const LineChartViewport = ({ displaySets }) => {
const displaySet = displaySets[0];
@@ -1,5 +1,5 @@
import React, { useEffect, useState, useCallback, ReactElement } from 'react';
import { ProgressDropdown } from '@ohif/ui';
import { ProgressDropdown } from '@ohif/ui-next';
const workflowStepsToDropdownOptions = (steps = []) =>
steps.map(step => ({
@@ -1,4 +1,4 @@
import { Types } from '@ohif/ui';
import { Types } from '@ohif/ui-next';
import { Menu, SelectorProps, MenuItem, ContextMenuProps } from './types';
type ContextMenuItem = Types.ContextMenuItem;
@@ -1,5 +1,5 @@
import React, { useState, useEffect, useCallback } from 'react';
import { useImageViewer } from '@ohif/ui';
import { useImageViewer } from '@ohif/ui-next';
import { useSystem, utils } from '@ohif/core';
import { useNavigate } from 'react-router-dom';
import { useViewportGrid, StudyBrowser, Separator } from '@ohif/ui-next';
@@ -1,87 +0,0 @@
import React, { useEffect, useState, useCallback } from 'react';
import PropTypes from 'prop-types';
import { LayoutSelector as OHIFLayoutSelector, ToolbarButton } from '@ohif/ui';
function LegacyLayoutSelectorWithServices({
servicesManager,
rows = 3,
columns = 3,
onLayoutChange = () => {},
...props
}) {
const { toolbarService } = servicesManager.services;
const onSelection = useCallback(
props => {
toolbarService.recordInteraction({
interactionType: 'action',
commands: [
{
commandName: 'setViewportGridLayout',
commandOptions: { ...props },
context: 'DEFAULT',
},
],
});
},
[toolbarService]
);
return (
<LayoutSelector
{...props}
onSelection={onSelection}
/>
);
}
function LayoutSelector({ rows, columns, className, onSelection, ...rest }) {
const [isOpen, setIsOpen] = useState(false);
const closeOnOutsideClick = () => {
if (isOpen) {
setIsOpen(false);
}
};
useEffect(() => {
window.addEventListener('click', closeOnOutsideClick);
return () => {
window.removeEventListener('click', closeOnOutsideClick);
};
}, [isOpen]);
const onInteractionHandler = () => setIsOpen(!isOpen);
const DropdownContent = isOpen ? OHIFLayoutSelector : null;
return (
<ToolbarButton
id="Layout"
label="Grid Layout"
icon="tool-layout"
onInteraction={onInteractionHandler}
className={className}
rounded={rest.rounded}
dropdownContent={
DropdownContent !== null && (
<DropdownContent
rows={rows}
columns={columns}
onSelection={onSelection}
/>
)
}
isActive={isOpen}
type="toggle"
/>
);
}
LayoutSelector.propTypes = {
rows: PropTypes.number,
columns: PropTypes.number,
onLayoutChange: PropTypes.func,
servicesManager: PropTypes.object.isRequired,
};
export default LegacyLayoutSelectorWithServices;
@@ -1,7 +1,7 @@
import React, { useEffect, useState, useCallback, useRef } from 'react';
import React, { useEffect, useState, useCallback } from 'react';
import PropTypes from 'prop-types';
import { InvestigationalUseDialog } from '@ohif/ui';
import { InvestigationalUseDialog } from '@ohif/ui-next';
import { HangingProtocolService, CommandsManager } from '@ohif/core';
import { useAppConfig } from '@state';
import ViewerHeader from './ViewerHeader';
@@ -1,4 +1,4 @@
import { LabellingFlow } from '@ohif/ui';
import { LabellingFlow } from '@ohif/ui-next';
export default {
'ui.labellingComponent': LabellingFlow,
@@ -1,4 +1,4 @@
import { LoadingIndicatorProgress } from '@ohif/ui';
import { LoadingIndicatorProgress } from '@ohif/ui-next';
export default {
'ui.loadingIndicatorProgress': LoadingIndicatorProgress,
@@ -1,4 +1,4 @@
import { LoadingIndicatorTotalPercent } from '@ohif/ui';
import { LoadingIndicatorTotalPercent } from '@ohif/ui-next';
export default {
'ui.loadingIndicatorTotalPercent': LoadingIndicatorTotalPercent,
@@ -1,5 +1,5 @@
import i18n from '@ohif/i18n';
import { Notification } from '@ohif/ui';
import { ViewportDialog } from '@ohif/ui-next';
const beginTrackingMessage = i18n.t('MeasurementTable:Track measurements for this series?');
const trackNewSeriesMessage = i18n.t('Do you want to add this measurement to the existing report?');
@@ -16,7 +16,7 @@ const hydrateSEGMessage = i18n.t('Do you want to open this Segmentation?');
const discardDirtyMessage = i18n.t('There are unsaved measurements. Do you want to save it?');
export default {
'ui.notificationComponent': Notification,
'ui.notificationComponent': ViewportDialog,
'viewportNotification.beginTrackingMessage': beginTrackingMessage,
'viewportNotification.trackNewSeriesMessage': trackNewSeriesMessage,
'viewportNotification.discardSeriesMessage': discardSeriesMessage,
@@ -1,4 +1,4 @@
import { ProgressLoadingBar } from '@ohif/ui';
import { ProgressLoadingBar } from '@ohif/ui-next';
export default {
'ui.progressLoadingBar': ProgressLoadingBar,
+6 -1
View File
@@ -33,7 +33,12 @@ export default function getToolbarModule({ commandsManager, servicesManager }: w
name: 'ohif.toolBoxButton',
defaultComponent: ToolBoxButtonWrapper,
},
// legacy
// legacy will get removed in the future
// legacy will get removed in the future
// legacy will get removed in the future
// legacy will get removed in the future
// legacy will get removed in the future
// legacy will get removed in the future
{
name: 'ohif.radioGroup',
defaultComponent: ToolbarButtonLegacy,
-2
View File
@@ -1,8 +1,6 @@
import { addIcon as addIconUI } from '@ohif/ui';
import { Icons } from '@ohif/ui-next';
/** Adds the icon to both ui and ui-next */
export function addIcon(name, icon) {
addIconUI(name, icon);
Icons.addIcon(name, icon);
}
@@ -1,7 +1,7 @@
import React from 'react';
import { setAnnotationLabel } from '@cornerstonejs/tools/utilities';
import { annotation } from '@cornerstonejs/tools';
import { LabellingFlow } from '@ohif/ui';
import { LabellingFlow } from '@ohif/ui-next';
import { InputDialog } from '@ohif/ui-next';
interface InputDialogDefaultProps {
@@ -2,7 +2,7 @@ import React, { useState, useEffect } from 'react';
import PropTypes from 'prop-types';
import { callInputDialog } from '@ohif/extension-default';
import { ExtensionManager, CommandsManager, DicomMetadataStore } from '@ohif/core';
import { MeasurementTable } from '@ohif/ui';
import { DataRow } from '@ohif/ui-next';
import { withTranslation, WithTranslation } from 'react-i18next';
import { EVENTS as MicroscopyEvents } from '../../services/MicroscopyService';
import dcmjs from 'dcmjs';
@@ -328,14 +328,34 @@ function MicroscopyPanel(props: IMicroscopyPanelProps) {
className="ohif-scrollbar overflow-y-auto overflow-x-hidden"
data-cy={'measurements-panel'}
>
<MeasurementTable
title="Measurements"
servicesManager={props.servicesManager}
data={data}
onClick={onMeasurementItemClickHandler}
onEdit={onMeasurementItemEditHandler}
onDelete={onMeasurementDeleteHandler}
/>
<div className="flex flex-col">
{data.map(item => (
<DataRow
key={item.uid}
number={item.index + 1}
title={item.label}
isSelected={item.isActive}
onSelect={() => onMeasurementItemClickHandler({ uid: item.uid })}
details={{
primary: item.displayText,
secondary: [],
}}
isVisible={true}
onToggleVisibility={() => {}}
isLocked={false}
onToggleLocked={() => {}}
onRename={() =>
onMeasurementItemEditHandler({ uid: item.uid, isActive: item.isActive })
}
onDelete={() =>
onMeasurementDeleteHandler({ uid: item.uid, isActive: item.isActive })
}
onColor={() => {}}
disableEditing={false}
description={item.displayText.join(', ')}
/>
))}
</div>
</div>
</>
);
@@ -1,5 +0,0 @@
import { MeasurementItem } from '@ohif/ui';
export default {
'microscopyPanel.measurementItem': MeasurementItem,
};
@@ -1,12 +1,3 @@
import panelMeasurementItem from './customizations/panelMeasurementItem';
export default function getCustomizationModule() {
return [
{
name: 'default',
value: {
...panelMeasurementItem,
},
},
];
return [];
}
@@ -1,4 +1,3 @@
import { ButtonEnums } from '@ohif/ui';
import i18n from 'i18next';
const RESPONSE = {
@@ -50,19 +49,19 @@ function _askTrackMeasurements(uiViewportDialogService, customizationService, vi
const actions = [
{
id: 'prompt-begin-tracking-cancel',
type: ButtonEnums.type.secondary,
type: 'secondary',
text: i18n.t('Common:No'),
value: RESPONSE.CANCEL,
},
{
id: 'prompt-begin-tracking-no-do-not-ask-again',
type: ButtonEnums.type.secondary,
type: 'secondary',
text: i18n.t('MeasurementTable:No, do not ask again'),
value: RESPONSE.NO_NEVER,
},
{
id: 'prompt-begin-tracking-yes',
type: ButtonEnums.type.primary,
type: 'primary',
text: i18n.t('Common:Yes'),
value: RESPONSE.SET_STUDY_AND_SERIES,
},
@@ -1,5 +1,4 @@
import { hydrateStructuredReport } from '@ohif/extension-cornerstone-dicom-sr';
import { ButtonEnums } from '@ohif/ui';
import { measurementTrackingMode } from './promptBeginTracking';
const RESPONSE = {
@@ -59,13 +58,13 @@ function _askTrackMeasurements(uiViewportDialogService, customizationService, vi
const actions = [
{
id: 'no-hydrate',
type: ButtonEnums.type.secondary,
type: 'secondary',
text: 'No',
value: RESPONSE.CANCEL,
},
{
id: 'yes-hydrate',
type: ButtonEnums.type.primary,
type: 'primary',
text: 'Yes',
value: RESPONSE.HYDRATE_REPORT,
},
@@ -1,4 +1,3 @@
import { ButtonEnums } from '@ohif/ui';
import { measurementTrackingMode } from './promptBeginTracking';
const RESPONSE = {
@@ -47,17 +46,17 @@ function _askShouldAddMeasurements(uiViewportDialogService, customizationService
);
const actions = [
{
type: ButtonEnums.type.secondary,
type: 'secondary',
text: 'Cancel',
value: RESPONSE.CANCEL,
},
{
type: ButtonEnums.type.primary,
type: 'primary',
text: 'Create new report',
value: RESPONSE.CREATE_REPORT,
},
{
type: ButtonEnums.type.primary,
type: 'primary',
text: 'Add to existing report',
value: RESPONSE.ADD_SERIES,
},
@@ -88,7 +87,7 @@ function _askSaveDiscardOrCancel(UIViewportDialogService, customizationService,
);
const actions = [
{ type: 'cancel', text: 'Cancel', value: RESPONSE.CANCEL },
{ type: 'secondary', text: 'Cancel', value: RESPONSE.CANCEL },
{
type: 'secondary',
text: 'Save',
@@ -1,5 +1,4 @@
import React from 'react';
import { Dialog, ButtonEnums } from '@ohif/ui';
import { utils } from '@ohif/core';
import { AccordionTrigger, MeasurementTable, useViewportGrid } from '@ohif/ui-next';
import {