ui(components): migrates to new toolbar ui components and Numeric for Input InputRange and InputDoubleRange (#4728)
Co-authored-by: sedghi <ar.sedghi@gmail.com>
This commit is contained in:
1 parent
ac5ae4a29e
commit
a8d84443a9
116 files changed
+2930
-1038
No files matched your search
@@ -3,6 +3,7 @@ import {
|
||||
DropdownMenu,
|
||||
DropdownMenuContent,
|
||||
DropdownMenuTrigger,
|
||||
DropdownMenuItem,
|
||||
Icons,
|
||||
Button,
|
||||
} from '@ohif/ui-next';
|
||||
@@ -18,6 +19,13 @@ const getMenuItemsDefault = ({ commandsManager, items, servicesManager, ...props
|
||||
// getMenuItems can also be replaced by providing it to the MoreDropdownMenu
|
||||
const menuContent = customizationService.getCustomization('ohif.menuContent');
|
||||
|
||||
// Default menu item component if none is provided through customization
|
||||
const DefaultMenuItem = ({ item }) => (
|
||||
<DropdownMenuItem onClick={item.onClick}>{item.label || item.title}</DropdownMenuItem>
|
||||
);
|
||||
|
||||
const MenuItemComponent = menuContent?.content || DefaultMenuItem;
|
||||
|
||||
return (
|
||||
<DropdownMenuContent
|
||||
hideWhenDetached
|
||||
@@ -27,15 +35,15 @@ const getMenuItemsDefault = ({ commandsManager, items, servicesManager, ...props
|
||||
e.preventDefault();
|
||||
}}
|
||||
>
|
||||
{items?.map((item, index) =>
|
||||
React.createElement(menuContent.content, {
|
||||
key: item.id || `menu-item-${index}`,
|
||||
item,
|
||||
commandsManager,
|
||||
servicesManager,
|
||||
...props,
|
||||
})
|
||||
)}
|
||||
{items?.map((item, index) => (
|
||||
<MenuItemComponent
|
||||
key={item.id || `menu-item-${index}`}
|
||||
item={item}
|
||||
commandsManager={commandsManager}
|
||||
servicesManager={servicesManager}
|
||||
{...props}
|
||||
/>
|
||||
))}
|
||||
</DropdownMenuContent>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
import React from 'react';
|
||||
import classNames from 'classnames';
|
||||
import { ToolButton } from '@ohif/ui-next';
|
||||
|
||||
/**
|
||||
* Wraps the ToolButtonList component to handle the OHIF toolbar button structure
|
||||
* @param props - Component props
|
||||
* @returns Component
|
||||
*/
|
||||
export function ToolBoxButtonGroupWrapper({ groupId, items, onInteraction, ...props }) {
|
||||
if (!items || !groupId) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="bg-popover flex flex-row space-x-1 rounded-md px-0 py-0">
|
||||
{items.map(item => (
|
||||
<ToolButton
|
||||
{...item}
|
||||
key={item.id}
|
||||
size="small"
|
||||
className={props.disabled && 'text-primary'}
|
||||
onInteraction={() =>
|
||||
onInteraction?.({ groupId, itemId: item.id, commands: item.commands })
|
||||
}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export function ToolBoxButtonWrapper({ onInteraction, ...props }) {
|
||||
return (
|
||||
<div className="bg-popover flex flex-row rounded-md px-0 py-0">
|
||||
<ToolButton
|
||||
{...props}
|
||||
id={props.id}
|
||||
size="small"
|
||||
className={classNames(props.disabled && 'text-primary')}
|
||||
onInteraction={() => onInteraction?.({ itemId: props.id, commands: props.commands })}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,84 @@
|
||||
import React from 'react';
|
||||
import {
|
||||
ToolButtonList,
|
||||
ToolButton,
|
||||
ToolButtonListDefault,
|
||||
ToolButtonListDropDown,
|
||||
ToolButtonListItem,
|
||||
ToolButtonListDivider,
|
||||
} from '@ohif/ui-next';
|
||||
|
||||
interface ButtonItem {
|
||||
id: string;
|
||||
icon?: string;
|
||||
label?: string;
|
||||
tooltip?: string;
|
||||
isActive?: boolean;
|
||||
disabledText?: string;
|
||||
commands?: Record<string, unknown>;
|
||||
disabled?: boolean;
|
||||
className?: string;
|
||||
}
|
||||
|
||||
interface ToolButtonListWrapperProps {
|
||||
groupId: string;
|
||||
primary: ButtonItem;
|
||||
items: ButtonItem[];
|
||||
onInteraction?: (details: {
|
||||
groupId: string;
|
||||
itemId: string;
|
||||
commands?: Record<string, unknown>;
|
||||
}) => void;
|
||||
}
|
||||
|
||||
/**
|
||||
* Wraps the ToolButtonList component to handle the OHIF toolbar button structure
|
||||
* @param props - Component props
|
||||
* @returns Component
|
||||
* // test
|
||||
*/
|
||||
export default function ToolButtonListWrapper({
|
||||
groupId,
|
||||
primary,
|
||||
items,
|
||||
onInteraction,
|
||||
}: ToolButtonListWrapperProps) {
|
||||
return (
|
||||
<ToolButtonList>
|
||||
<ToolButtonListDefault>
|
||||
<div
|
||||
data-cy={`${groupId}-split-button-primary`}
|
||||
data-tool={primary.id}
|
||||
data-active={primary.isActive}
|
||||
>
|
||||
<ToolButton
|
||||
{...primary}
|
||||
onInteraction={({ itemId }) =>
|
||||
onInteraction?.({ groupId, itemId, commands: primary.commands })
|
||||
}
|
||||
className={primary.className}
|
||||
/>
|
||||
</div>
|
||||
</ToolButtonListDefault>
|
||||
<ToolButtonListDivider className={primary.isActive ? 'opacity-0' : 'opacity-100'} />
|
||||
<div data-cy={`${groupId}-split-button-secondary`}>
|
||||
<ToolButtonListDropDown>
|
||||
{items.map(item => (
|
||||
<ToolButtonListItem
|
||||
key={item.id}
|
||||
{...item}
|
||||
data-cy={item.id}
|
||||
data-tool={item.id}
|
||||
data-active={item.isActive}
|
||||
onSelect={() =>
|
||||
onInteraction?.({ groupId, itemId: item.id, commands: item.commands })
|
||||
}
|
||||
>
|
||||
<span className="pl-1">{item.label || item.tooltip || item.id}</span>
|
||||
</ToolButtonListItem>
|
||||
))}
|
||||
</ToolButtonListDropDown>
|
||||
</div>
|
||||
</ToolButtonList>
|
||||
);
|
||||
}
|
||||
@@ -1,6 +1,4 @@
|
||||
import React from 'react';
|
||||
import { Tooltip } from '@ohif/ui';
|
||||
import classnames from 'classnames';
|
||||
import { useToolbar } from '@ohif/core';
|
||||
|
||||
export function Toolbar({ servicesManager, buttonSection = 'primary' }) {
|
||||
@@ -15,7 +13,7 @@ export function Toolbar({ servicesManager, buttonSection = 'primary' }) {
|
||||
|
||||
return (
|
||||
<>
|
||||
{toolbarButtons.map(toolDef => {
|
||||
{toolbarButtons?.map(toolDef => {
|
||||
if (!toolDef) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { ToolbarButton, ButtonGroup } from '@ohif/ui';
|
||||
import React, { useCallback } from 'react';
|
||||
import { ToolbarButton, ButtonGroup } from '@ohif/ui';
|
||||
|
||||
function ToolbarButtonGroupWithServices({ groupId, items, onInteraction, size }) {
|
||||
const getSplitButtonItems = useCallback(
|
||||
|
||||
@@ -107,18 +107,18 @@ const useResizablePanels = (
|
||||
// And by virtue of the dependency on the minimum size state variables, this code
|
||||
// is executed on the render following an update of the minimum percentage sizes
|
||||
// for a panel.
|
||||
if (!resizableLeftPanelAPIRef.current.isCollapsed()) {
|
||||
if (!resizableLeftPanelAPIRef.current?.isCollapsed()) {
|
||||
const leftSize = getPercentageSize(
|
||||
leftPanelExpandedWidth + panelGroupDefinition.shared.expandedInsideBorderSize
|
||||
);
|
||||
resizableLeftPanelAPIRef.current.resize(leftSize);
|
||||
resizableLeftPanelAPIRef.current?.resize(leftSize);
|
||||
}
|
||||
|
||||
if (!resizableRightPanelAPIRef.current.isCollapsed()) {
|
||||
if (!resizableRightPanelAPIRef?.current?.isCollapsed()) {
|
||||
const rightSize = getPercentageSize(
|
||||
rightPanelExpandedWidth + panelGroupDefinition.shared.expandedInsideBorderSize
|
||||
);
|
||||
resizableRightPanelAPIRef.current.resize(rightSize);
|
||||
resizableRightPanelAPIRef?.current?.resize(rightSize);
|
||||
}
|
||||
|
||||
// This observer kicks in when the ViewportLayout resizable panel group
|
||||
@@ -199,7 +199,7 @@ const useResizablePanels = (
|
||||
}, [setLeftPanelClosed]);
|
||||
|
||||
const onLeftPanelResize = useCallback(size => {
|
||||
if (!resizablePanelGroupElemRef?.current || resizableLeftPanelAPIRef.current.isCollapsed()) {
|
||||
if (!resizablePanelGroupElemRef?.current || resizableLeftPanelAPIRef.current?.isCollapsed()) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -228,7 +228,7 @@ const useResizablePanels = (
|
||||
}, [setRightPanelClosed]);
|
||||
|
||||
const onRightPanelResize = useCallback(size => {
|
||||
if (!resizablePanelGroupElemRef?.current || resizableRightPanelAPIRef.current.isCollapsed()) {
|
||||
if (!resizablePanelGroupElemRef?.current || resizableRightPanelAPIRef?.current?.isCollapsed()) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -248,7 +248,7 @@ const useResizablePanels = (
|
||||
* Note that the width attributed to the handles must be taken into account.
|
||||
*/
|
||||
const getPercentageSize = pixelSize => {
|
||||
const { width: panelGroupWidth } = resizablePanelGroupElemRef.current.getBoundingClientRect();
|
||||
const { width: panelGroupWidth } = resizablePanelGroupElemRef.current?.getBoundingClientRect();
|
||||
return (pixelSize / (panelGroupWidth - resizableHandlesWidth.current)) * 100;
|
||||
};
|
||||
|
||||
@@ -257,7 +257,7 @@ const useResizablePanels = (
|
||||
* Note that the width attributed to the handles must be taken into account.
|
||||
*/
|
||||
const getExpandedPixelWidth = percentageSize => {
|
||||
const { width: panelGroupWidth } = resizablePanelGroupElemRef.current.getBoundingClientRect();
|
||||
const { width: panelGroupWidth } = resizablePanelGroupElemRef.current?.getBoundingClientRect();
|
||||
const expandedWidth =
|
||||
(percentageSize / 100) * (panelGroupWidth - resizableHandlesWidth.current) -
|
||||
panelGroupDefinition.shared.expandedInsideBorderSize;
|
||||
|
||||
@@ -1,42 +1,61 @@
|
||||
import ToolbarDivider from './Toolbar/ToolbarDivider';
|
||||
import { ToolbarButton as ToolbarButtonLegacy } from '@ohif/ui';
|
||||
import { ToolButton, utils } from '@ohif/ui-next';
|
||||
|
||||
import ToolbarLayoutSelectorWithServices from './Toolbar/ToolbarLayoutSelector';
|
||||
import ToolbarSplitButtonWithServices from './Toolbar/ToolbarSplitButtonWithServices';
|
||||
import ToolbarButtonGroupWithServices from './Toolbar/ToolbarButtonGroupWithServices';
|
||||
import { ToolbarButton } from '@ohif/ui';
|
||||
|
||||
// legacy
|
||||
import ToolbarDividerLegacy from './Toolbar/ToolbarDivider';
|
||||
import ToolbarSplitButtonWithServicesLegacy from './Toolbar/ToolbarSplitButtonWithServices';
|
||||
import ToolbarButtonGroupWithServicesLegacy from './Toolbar/ToolbarButtonGroupWithServices';
|
||||
import { ProgressDropdownWithService } from './Components/ProgressDropdownWithService';
|
||||
|
||||
const getClassName = isToggled => {
|
||||
return {
|
||||
className: isToggled
|
||||
? '!text-primary-active'
|
||||
: '!text-common-bright hover:!bg-primary-dark hover:text-primary-light',
|
||||
};
|
||||
};
|
||||
// new
|
||||
import ToolButtonListWrapper from './Toolbar/ToolButtonListWrapper';
|
||||
import { ToolBoxButtonGroupWrapper, ToolBoxButtonWrapper } from './Toolbar/ToolBoxWrapper';
|
||||
|
||||
export default function getToolbarModule({ commandsManager, servicesManager }: withAppTypes) {
|
||||
const { cineService } = servicesManager.services;
|
||||
return [
|
||||
// new
|
||||
{
|
||||
name: 'ohif.toolButton',
|
||||
defaultComponent: ToolButton,
|
||||
},
|
||||
{
|
||||
name: 'ohif.toolButtonList',
|
||||
defaultComponent: ToolButtonListWrapper,
|
||||
},
|
||||
{
|
||||
name: 'ohif.toolBoxButtonGroup',
|
||||
defaultComponent: ToolBoxButtonGroupWrapper,
|
||||
},
|
||||
{
|
||||
name: 'ohif.toolBoxButton',
|
||||
defaultComponent: ToolBoxButtonWrapper,
|
||||
},
|
||||
// legacy
|
||||
{
|
||||
name: 'ohif.radioGroup',
|
||||
defaultComponent: ToolbarButton,
|
||||
defaultComponent: ToolbarButtonLegacy,
|
||||
},
|
||||
{
|
||||
name: 'ohif.buttonGroup',
|
||||
defaultComponent: ToolbarButtonGroupWithServicesLegacy,
|
||||
},
|
||||
{
|
||||
name: 'ohif.divider',
|
||||
defaultComponent: ToolbarDivider,
|
||||
defaultComponent: ToolbarDividerLegacy,
|
||||
},
|
||||
{
|
||||
name: 'ohif.splitButton',
|
||||
defaultComponent: ToolbarSplitButtonWithServices,
|
||||
defaultComponent: ToolbarSplitButtonWithServicesLegacy,
|
||||
},
|
||||
// others
|
||||
{
|
||||
name: 'ohif.layoutSelector',
|
||||
defaultComponent: props =>
|
||||
ToolbarLayoutSelectorWithServices({ ...props, commandsManager, servicesManager }),
|
||||
},
|
||||
{
|
||||
name: 'ohif.buttonGroup',
|
||||
defaultComponent: ToolbarButtonGroupWithServices,
|
||||
},
|
||||
{
|
||||
name: 'ohif.progressDropdown',
|
||||
defaultComponent: ProgressDropdownWithService,
|
||||
@@ -66,7 +85,9 @@ export default function getToolbarModule({ commandsManager, servicesManager }: w
|
||||
name: 'evaluate.cine',
|
||||
evaluate: () => {
|
||||
const isToggled = cineService.getState().isCineEnabled;
|
||||
return getClassName(isToggled);
|
||||
return {
|
||||
className: utils.getToggledClassName(isToggled),
|
||||
};
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
@@ -13,9 +13,8 @@ function usePatientInfo(servicesManager: AppTypes.ServicesManager) {
|
||||
PatientDOB: '',
|
||||
});
|
||||
const [isMixedPatients, setIsMixedPatients] = useState(false);
|
||||
const displaySets = displaySetService.getActiveDisplaySets();
|
||||
|
||||
const checkMixedPatients = PatientID => {
|
||||
const checkMixedPatients = (PatientID: string) => {
|
||||
const displaySets = displaySetService.getActiveDisplaySets();
|
||||
let isMixedPatients = false;
|
||||
displaySets.forEach(displaySet => {
|
||||
@@ -30,8 +29,11 @@ function usePatientInfo(servicesManager: AppTypes.ServicesManager) {
|
||||
setIsMixedPatients(isMixedPatients);
|
||||
};
|
||||
|
||||
const updatePatientInfo = () => {
|
||||
const displaySet = displaySets[0];
|
||||
const updatePatientInfo = ({ displaySetsAdded }) => {
|
||||
if (!displaySetsAdded.length) {
|
||||
return;
|
||||
}
|
||||
const displaySet = displaySetsAdded[0];
|
||||
const instance = displaySet?.instances?.[0] || displaySet?.instance;
|
||||
if (!instance) {
|
||||
return;
|
||||
@@ -39,7 +41,7 @@ function usePatientInfo(servicesManager: AppTypes.ServicesManager) {
|
||||
|
||||
setPatientInfo({
|
||||
PatientID: instance.PatientID || null,
|
||||
PatientName: instance.PatientName ? formatPN(instance.PatientName ) : null,
|
||||
PatientName: instance.PatientName ? formatPN(instance.PatientName) : null,
|
||||
PatientSex: instance.PatientSex || null,
|
||||
PatientDOB: formatDate(instance.PatientBirthDate) || null,
|
||||
});
|
||||
@@ -49,15 +51,11 @@ function usePatientInfo(servicesManager: AppTypes.ServicesManager) {
|
||||
useEffect(() => {
|
||||
const subscription = displaySetService.subscribe(
|
||||
displaySetService.EVENTS.DISPLAY_SETS_ADDED,
|
||||
() => updatePatientInfo()
|
||||
props => updatePatientInfo(props)
|
||||
);
|
||||
return () => subscription.unsubscribe();
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
updatePatientInfo();
|
||||
}, [displaySets]);
|
||||
|
||||
return { patientInfo, isMixedPatients };
|
||||
}
|
||||
|
||||
|
||||
@@ -39,7 +39,6 @@ import { PanelStudyBrowserHeader } from './Panels/StudyBrowser/PanelStudyBrowser
|
||||
import * as utils from './utils';
|
||||
import MoreDropdownMenu from './Components/MoreDropdownMenu';
|
||||
import requestDisplaySetCreationForStudy from './Panels/requestDisplaySetCreationForStudy';
|
||||
|
||||
const defaultExtension: Types.Extensions.Extension = {
|
||||
/**
|
||||
* Only required property. Should be a unique value across all extensions.
|
||||
|
||||
Reference in new issue
Block a user