chore(prettier): full repo linting and code reformatting once and for all (#3627)

This commit is contained in:
Alireza authored and GitHub committed 2023-09-01 16:19:39 -04:00
1 parent 01500a2d4c
commit 9045ddaedc
656 files changed
+21737 -20628

No files matched your search

@@ -7,7 +7,11 @@ import Icon from '../Icon';
const Link = ({ href, children, showIcon = false }) => {
return (
<a href={href} target="_blank" rel="noopener noreferrer">
<a
href={href}
target="_blank"
rel="noopener noreferrer"
>
<Typography
variant="subtitle"
component="p"
@@ -16,7 +20,10 @@ const Link = ({ href, children, showIcon = false }) => {
>
{children}
{!!showIcon && (
<Icon name="external-link" className="w-5 ml-2 text-white" />
<Icon
name="external-link"
className="ml-2 w-5 text-white"
/>
)}
</Typography>
</a>
@@ -25,8 +32,12 @@ const Link = ({ href, children, showIcon = false }) => {
const Row = ({ title, value, link }) => {
return (
<div className="flex mb-4">
<Typography variant="subtitle" component="p" className="w-48 text-white">
<div className="mb-4 flex">
<Typography
variant="subtitle"
component="p"
className="w-48 text-white"
>
{title}
</Typography>
@@ -50,7 +61,7 @@ const AboutModal = ({ buildNumber, versionNumber, commitHash }) => {
const browser = `${name[0].toUpperCase()}${name.substr(1)} ${version}`;
const renderRowTitle = title => (
<div className="pb-3 mb-3 border-b-2 border-black">
<div className="mb-3 border-b-2 border-black pb-3">
<Typography
variant="inherit"
color="primaryLight"
@@ -63,8 +74,11 @@ const AboutModal = ({ buildNumber, versionNumber, commitHash }) => {
return (
<div>
{renderRowTitle('Important Links')}
<div className="flex mb-8">
<Link href="https://community.ohif.org/" showIcon={true}>
<div className="mb-8 flex">
<Link
href="https://community.ohif.org/"
showIcon={true}
>
Visit the forum
</Link>
<span className="ml-4">
@@ -76,7 +90,10 @@ const AboutModal = ({ buildNumber, versionNumber, commitHash }) => {
</Link>
</span>
<span className="ml-4">
<Link href="https://ohif.org/" showIcon={true}>
<Link
href="https://ohif.org/"
showIcon={true}
>
More details
</Link>
</span>
@@ -99,11 +116,30 @@ const AboutModal = ({ buildNumber, versionNumber, commitHash }) => {
value="https://github.com/OHIF/Viewers/"
link="https://github.com/OHIF/Viewers/"
/> */}
<Row title="Version number" value={versionNumber} />
{buildNumber && <Row title="Build number" value={buildNumber} />}
{commitHash && <Row title="Commit Hash" value={commitHash} />}
<Row title="Browser" value={browser} />
<Row title="OS" value={os} />
<Row
title="Version number"
value={versionNumber}
/>
{buildNumber && (
<Row
title="Build number"
value={buildNumber}
/>
)}
{commitHash && (
<Row
title="Commit Hash"
value={commitHash}
/>
)}
<Row
title="Browser"
value={browser}
/>
<Row
title="OS"
value={os}
/>
</div>
</div>
);
@@ -10,7 +10,10 @@ export const argTypes = {
title: 'Modals/About',
};
<Meta title="Modals/About" component={AboutModal} />
<Meta
title="Modals/About"
component={AboutModal}
/>
export const aboutTemplate = args => (
<div className="bg-primary-dark">
@@ -30,8 +33,7 @@ export const aboutTemplate = args => (
## Overview
OHIF about modal component provides information about the application version
and build number
OHIF about modal component provides information about the application version and build number
<Canvas>
<Story name="Overview">{aboutTemplate.bind({})}</Story>
+3 -6
View File
@@ -11,16 +11,14 @@ const sizeClasses = {
const layoutClasses =
'box-content inline-flex flex-row items-center justify-center gap-[5px] justify center px-[10px] outline-none rounded';
const baseFontTextClasses =
'leading-[1.2] font-sans text-center whitespace-nowrap';
const baseFontTextClasses = 'leading-[1.2] font-sans text-center whitespace-nowrap';
const fontTextClasses = {
[ButtonEnums.type.primary]: classnames(baseFontTextClasses, 'font-semibold'),
[ButtonEnums.type.secondary]: classnames(baseFontTextClasses, 'font-400'),
};
const baseEnabledEffectClasses =
'transition duration-300 ease-in-out focus:outline-none';
const baseEnabledEffectClasses = 'transition duration-300 ease-in-out focus:outline-none';
const enabledEffectClasses = {
[ButtonEnums.type.primary]: classnames(
@@ -48,8 +46,7 @@ const enabledClasses = {
),
};
const disabledClasses =
'bg-inputfield-placeholder text-common-light cursor-default';
const disabledClasses = 'bg-inputfield-placeholder text-common-light cursor-default';
const defaults = {
color: 'default',
@@ -1,4 +1,4 @@
import {Button, ButtonEnums} from '../../../components';
import { Button, ButtonEnums } from '../../../components';
import { ArgsTable, Story, Canvas, Meta } from '@storybook/addon-docs';
import {
createComponentTemplate,
@@ -10,11 +10,17 @@ export const argTypes = {
title: 'Components/Button',
};
<Meta title="Components/Button" component={Button} />
<Meta
title="Components/Button"
component={Button}
/>
export const buttonTemplate = createComponentTemplate(Button);
<Heading title="Button" componentRelativePath="Button/Button.tsx" />
<Heading
title="Button"
componentRelativePath="Button/Button.tsx"
/>
- [Overview](#overview)
- [Props](#props)
@@ -23,11 +29,14 @@ export const buttonTemplate = createComponentTemplate(Button);
## Overview
You can use the button component to create a button. It can be used in different
ways, the default button is a simple button with text.
You can use the button component to create a button. It can be used in different ways, the default
button is a simple button with text.
<Canvas>
<Story name="Overview" args={{ children: 'Button', color: 'default' }}>
<Story
name="Overview"
args={{ children: 'Button', color: 'default' }}
>
{buttonTemplate.bind({})}
</Story>
</Canvas>
@@ -53,8 +62,8 @@ There can be different types of buttons: `primary`, and `secondary`.
### Sizes
There are different sizes for the button: `small`, and `medium`. The size refers
to the button's height.
There are different sizes for the button: `small`, and `medium`. The size refers to the button's
height.
<Canvas>
<Story name="Colors">
@@ -71,7 +80,10 @@ You can mix different props together to create a button.
<Canvas>
<Story name="Custom">
<Button type={ButtonEnums.type.secondary} size={ButtonEnums.size.small}>
<Button
type={ButtonEnums.type.secondary}
size={ButtonEnums.size.small}
>
Small, Secondary Button
</Button>
</Story>
@@ -143,7 +155,10 @@ End Icon is the same as start icon, but for the end of the button.
);
};
return (
<Button startIcon={<Github />} endIcon={<Github />}>
<Button
startIcon={<Github />}
endIcon={<Github />}
>
Start and End Icon Button
</Button>
);
@@ -48,8 +48,7 @@ const variantClasses = {
primary: '',
secondary: 'border border-secondary-light',
white: '',
black:
'border-primary-main group-hover:bg-primary-main group-hover:border-black',
black: 'border-primary-main group-hover:bg-primary-main group-hover:border-black',
},
contained: {
default: 'border-white',
@@ -121,9 +120,7 @@ const ButtonGroup = ({
className: classnames(
buttonClasses,
child.props.className,
!splitBorder &&
isNotFirstOrLast &&
nonFirstLastClasses[orientation],
!splitBorder && isNotFirstOrLast && nonFirstLastClasses[orientation],
!splitBorder && isLast && 'last:border-l-0'
),
disabled: child.props.disabled || disabled,
@@ -141,14 +138,7 @@ const ButtonGroup = ({
ButtonGroup.propTypes = {
children: PropTypes.node.isRequired,
className: PropTypes.string,
color: PropTypes.oneOf([
'default',
'inherit',
'primary',
'secondary',
'white',
'black',
]),
color: PropTypes.oneOf(['default', 'inherit', 'primary', 'secondary', 'white', 'black']),
disabled: PropTypes.bool,
fullWidth: PropTypes.bool,
orientation: PropTypes.oneOf(['vertical', 'horizontal']),
@@ -11,7 +11,10 @@ export const argTypes = {
title: 'Components/ButtonGroup',
};
<Meta title="Components/ButtonGroup" component={ButtonGroup} />
<Meta
title="Components/ButtonGroup"
component={ButtonGroup}
/>
export const buttonGroupTemplate = args => (
<ButtonGroup {...args}>
@@ -73,8 +76,7 @@ There are three different variants of ButtonGroup:
### Orientation
You can change the orientation of the buttons in the group by setting the
`orientation` prop.
You can change the orientation of the buttons in the group by setting the `orientation` prop.
<Canvas>
<Story name="Orientation Horizontal">
@@ -19,14 +19,7 @@ const CheckBox: React.FC<{
label: string;
labelClassName?: string;
labelVariant?: string;
}> = ({
checked,
onChange,
label,
labelClassName,
labelVariant = 'body',
className,
}) => {
}> = ({ checked, onChange, label, labelClassName, labelVariant = 'body', className }) => {
const [isChecked, setIsChecked] = useState(checked);
const handleClick = useCallback(() => {
@@ -36,16 +29,10 @@ const CheckBox: React.FC<{
return (
<div
className={`flex items-center cursor-pointer space-x-1 ${
className ? className : ''
}`}
className={`flex cursor-pointer items-center space-x-1 ${className ? className : ''}`}
onClick={handleClick}
>
{isChecked ? (
<Icon name="checkbox-checked" />
) : (
<Icon name="checkbox-unchecked" />
)}
{isChecked ? <Icon name="checkbox-checked" /> : <Icon name="checkbox-unchecked" />}
<Typography
variant={labelVariant ?? 'subtitle'}
@@ -6,11 +6,17 @@ export const argTypes = {
title: 'Components/CheckBox',
};
<Meta title="Components/CheckBox" component={CheckBox} />
<Meta
title="Components/CheckBox"
component={CheckBox}
/>
export const CheckBoxTemplate = args => <CheckBox {...args} />
export const CheckBoxTemplate = args => <CheckBox {...args} />;
<Heading title="CheckBox" componentRelativePath="CheckBox/CheckBox.tsx" />
<Heading
title="CheckBox"
componentRelativePath="CheckBox/CheckBox.tsx"
/>
- [Overview](#overview)
- [Props](#props)
@@ -26,8 +32,8 @@ CheckBox is a component that allows you to use as a boolean value
args={{
checked: false,
onChange: () => console.log('on change callback'),
label: "checkBoxLabel",
labelClassName: "text-black text-sm",
label: 'checkBoxLabel',
labelClassName: 'text-black text-sm',
}}
>
{CheckBoxTemplate.bind({})}
@@ -52,12 +52,12 @@ const CinePlayer: React.FC<CinePlayerProps> = ({
<div
className={classNames(
className,
'select-none flex items-center gap-2 px-2 py-2 rounded border border-secondary-light/60 bg-primary-dark'
'border-secondary-light/60 bg-primary-dark flex select-none items-center gap-2 rounded border px-2 py-2'
)}
>
<Icon
name={getPlayPauseIconName()}
className="cursor-pointer text-white active:text-primary-light hover:bg-customblue-300 hover:rounded"
className="active:text-primary-light hover:bg-customblue-300 cursor-pointer text-white hover:rounded"
onClick={() => onPlayPauseChange(!isPlaying)}
/>
<Tooltip
@@ -77,14 +77,14 @@ const CinePlayer: React.FC<CinePlayerProps> = ({
/>
}
>
<div className="border border-secondary-light flex h-6 items-stretch rounded gap-1">
<div className="border-secondary-light flex h-6 items-stretch gap-1 rounded border">
<div
className={`${fpsButtonClassNames} rounded-l`}
onClick={() => handleSetFrameRate(frameRate - 1)}
>
<Icon name="arrow-left-small" />
</div>
<div className="w-11 text-sm text-white text-center group-hover/fps:text-primary-light leading-[22px]">
<div className="group-hover/fps:text-primary-light w-11 text-center text-sm leading-[22px] text-white">
{`${frameRate} FPS`}
</div>
<div
@@ -97,7 +97,7 @@ const CinePlayer: React.FC<CinePlayerProps> = ({
</Tooltip>
<Icon
name="icon-close"
className="cursor-pointer text-primary-active active:text-primary-light hover:bg-customblue-300 hover:rounded"
className="text-primary-active active:text-primary-light hover:bg-customblue-300 cursor-pointer hover:rounded"
onClick={onClose}
/>
</div>
@@ -10,7 +10,7 @@ const ContextMenu = ({ items, ...props }) => {
return (
<div
data-cy="context-menu"
className="relative bg-secondary-dark rounded z-50 block w-48"
className="bg-secondary-dark relative z-50 block w-48 rounded"
onContextMenu={e => e.preventDefault()}
>
{items.map((item, index) => (
@@ -19,10 +19,15 @@ const ContextMenu = ({ items, ...props }) => {
data-cy="context-menu-item"
onClick={() => item.action(item, props)}
style={{ justifyContent: 'space-between' }}
className="flex px-4 py-3 cursor-pointer items-center transition duration-300 hover:bg-primary-dark border-b border-primary-dark last:border-b-0"
className="hover:bg-primary-dark border-primary-dark flex cursor-pointer items-center border-b px-4 py-3 transition duration-300 last:border-b-0"
>
<Typography>{item.label}</Typography>
{item.iconRight && <Icon name={item.iconRight} className="inline" />}
{item.iconRight && (
<Icon
name={item.iconRight}
className="inline"
/>
)}
</div>
))}
</div>
@@ -7,7 +7,10 @@ export const argTypes = {
title: 'Modals/ContextMenu',
};
<Meta title="Modals/ContextMenu" component={ContextMenu} />
<Meta
title="Modals/ContextMenu"
component={ContextMenu}
/>
export const contextMenueTemplate = createComponentTemplate(ContextMenu);
@@ -22,9 +25,8 @@ export const contextMenueTemplate = createComponentTemplate(ContextMenu);
## Overview
Context Menu is a component that is used to display a list of options to the
user. This component can be used for use cases such as opening a list of options
on user right click.
Context Menu is a component that is used to display a list of options to the user. This component
can be used for use cases such as opening a list of options on user right click.
<Canvas>
<Story
@@ -1,7 +1,7 @@
/** CONTAINER STYLES **/
.DateRangePickerInput {
@apply bg-transparent border-0 flex;
@apply flex border-0 bg-transparent;
}
.DateRangePicker_picker {
@@ -12,7 +12,7 @@
.DateInput {
background: transparent;
@apply flex flex-1 w-auto;
@apply flex w-auto flex-1;
}
/** INPUT FIELD COMMON STYLES **/
@@ -26,7 +26,7 @@
@apply bg-no-repeat;
}
.DateInput_input {
@apply cursor-pointer border-primary-main mt-2 bg-black shadow transition duration-300 appearance-none border-t border-l border-r border-b border-solid rounded w-full py-2 px-3 text-sm text-white leading-tight pl-8 font-light;
@apply border-primary-main mt-2 w-full cursor-pointer appearance-none rounded border-t border-l border-r border-b border-solid bg-black py-2 px-3 pl-8 text-sm font-light leading-tight text-white shadow transition duration-300;
}
.DateInput_input:hover {
@apply border-gray-500;
@@ -56,31 +56,35 @@
/* SELECT MONTH PICKER */
.DateRangePicker_select {
@apply bg-white text-secondary-active border rounded border-common-dark appearance-none cursor-pointer text-base pl-2 pr-5 py-1; /* NEEDED FOR ARROW DOWN */
@apply text-secondary-active border-common-dark cursor-pointer appearance-none rounded border bg-white py-1 pl-2 pr-5 text-base; /* NEEDED FOR ARROW DOWN */
background-image: linear-gradient(45deg, transparent 50%, gray 50%),
linear-gradient(135deg, gray 50%, transparent 50%);
background-position: calc(100% - 11px) 11px, calc(100% - 6px) calc(11px);
background-size: 5px 5px, 5px 5px;
background-position:
calc(100% - 11px) 11px,
calc(100% - 6px) calc(11px);
background-size:
5px 5px,
5px 5px;
background-repeat: no-repeat;
}
/* CALENDAR DAYS */
.CalendarDay {
@apply border-0 rounded-full;
@apply rounded-full border-0;
}
.CalendarDay:hover,
.CalendarDay__selected,
.CalendarDay__selected:active,
.CalendarDay__selected:hover {
@apply bg-primary-main text-white border-0 border-primary-main;
@apply bg-primary-main border-primary-main border-0 text-white;
}
.CalendarDay__blocked_out_of_range:hover {
@apply border-0 bg-white cursor-not-allowed text-common-dark;
@apply text-common-dark cursor-not-allowed border-0 bg-white;
}
.CalendarDay__selected_span {
@apply border-0 bg-primary-light;
@apply bg-primary-light border-0;
}
/* MONTH NAVIGATION BUTTONS */
@@ -36,7 +36,10 @@ const renderYearsOptions = () => {
for (let i = 0; i < 20; i++) {
const year = currentYear - i;
options.push(
<option key={year} value={year}>
<option
key={year}
value={year}
>
{year}
</option>
);
@@ -58,7 +61,7 @@ const DateRange = props => {
<button
key={text}
type="button"
className={`m-0 py-2 px-3 bg-primary-main border-0 rounded text-white text-base transition duration-300 hover:opacity-80`}
className={`bg-primary-main m-0 rounded border-0 py-2 px-3 text-base text-white transition duration-300 hover:opacity-80`}
onClick={() =>
onChange({
startDate: start ? start.format('YYYYMMDD') : undefined,
@@ -101,7 +104,10 @@ const DateRange = props => {
onBlur={handleOnBlur}
>
{moment.months().map((label, value) => (
<option key={value} value={value}>
<option
key={value}
value={value}
>
{label}
</option>
))}
@@ -6,7 +6,10 @@ export const argTypes = {
title: 'Components/DateRange',
};
<Meta title="Components/DateRange" component={DateRange} />
<Meta
title="Components/DateRange"
component={DateRange}
/>
export const DateRangeTemplate = args => (
<div className="h-96">
@@ -14,7 +17,10 @@ export const DateRangeTemplate = args => (
</div>
);
<Heading title="DateRange" componentRelativePath="DateRange/DateRange.tsx" />
<Heading
title="DateRange"
componentRelativePath="DateRange/DateRange.tsx"
/>
- [Overview](#overview)
- [Props](#props)
+6 -12
View File
@@ -37,17 +37,7 @@ const Dialog = ({
}, [onShow]);
return (
<div
className={classNames(
theme,
flex,
border,
outline,
position,
width,
padding
)}
>
<div className={classNames(theme, flex, border, outline, position, width, padding)}>
<HeaderComponent
title={title}
noCloseButton={noCloseButton}
@@ -55,7 +45,11 @@ const Dialog = ({
value={value}
setValue={setValue}
/>
<BodyComponent text={text} value={value} setValue={setValue} />
<BodyComponent
text={text}
value={value}
setValue={setValue}
/>
<FooterComponent
actions={actions}
onSubmit={onSubmit}
+1 -4
View File
@@ -41,10 +41,7 @@ Footer.propTypes = {
id: PropTypes.string.isRequired,
text: PropTypes.string.isRequired,
value: PropTypes.any,
type: PropTypes.oneOf([
ButtonEnums.type.primary,
ButtonEnums.type.secondary,
]).isRequired,
type: PropTypes.oneOf([ButtonEnums.type.primary, ButtonEnums.type.secondary]).isRequired,
classes: PropTypes.arrayOf(PropTypes.string),
})
).isRequired,
+6 -2
View File
@@ -11,7 +11,7 @@ const CloseButton = ({ onClick }) => {
data-cy="close-button"
onClick={onClick}
name="close"
className="cursor-pointer text-primary-active"
className="text-primary-active cursor-pointer"
/>
);
};
@@ -27,7 +27,11 @@ const Header = ({ title, noCloseButton, onClose }) => {
return (
<div className={classNames(theme, flex, padding)}>
<Typography variant="h6" color="primaryLight" className="!leading-[1.2]">
<Typography
variant="h6"
color="primaryLight"
className="!leading-[1.2]"
>
{title}
</Typography>
{!noCloseButton && <CloseButton onClick={onClose} />}
@@ -7,11 +7,17 @@ export const argTypes = {
title: 'Modals/Dialog',
};
<Meta title="Modals/Dialog" component={Dialog} />
<Meta
title="Modals/Dialog"
component={Dialog}
/>
export const DialogTemplate = createComponentTemplate(Dialog);
<Heading title="Dialog" componentRelativePath="Dialog/Dialog.tsx" />
<Heading
title="Dialog"
componentRelativePath="Dialog/Dialog.tsx"
/>
- [Overview](#overview)
- [Props](#props)
@@ -29,9 +29,9 @@ const DisplaySetMessageListTooltip = ({ messages, id }): React.ReactNode => {
arrow="center"
parent={`#${id}`}
>
<div className="bg-primary-dark border border-secondary-light text-white text-base rounded text-left max-w-64">
<div className="bg-primary-dark border-secondary-light max-w-64 rounded border text-left text-base text-white">
<div
className="break-normal text-base text-blue-300 font-bold"
className="break-normal text-base font-bold text-blue-300"
style={{
marginLeft: '12px',
marginTop: '12px',
@@ -14,7 +14,7 @@ const Dropdown = ({ id, children, showDropdownIcon, list, titleClassName }) => {
<div
key={title}
className={classnames(
'flex px-4 py-2 cursor-pointer items-center transition duration-300 hover:bg-secondary-main border-b last:border-b-0 border-secondary-main'
'hover:bg-secondary-main border-secondary-main flex cursor-pointer items-center border-b px-4 py-2 transition duration-300 last:border-b-0'
)}
onClick={() => {
setOpen(false);
@@ -22,7 +22,12 @@ const Dropdown = ({ id, children, showDropdownIcon, list, titleClassName }) => {
}}
data-cy={id}
>
{!!icon && <Icon name={icon} className="w-4 mr-2 text-white" />}
{!!icon && (
<Icon
name={icon}
className="mr-2 w-4 text-white"
/>
)}
<Typography className={titleClassName}>{title}</Typography>
</div>
);
@@ -43,7 +48,12 @@ const Dropdown = ({ id, children, showDropdownIcon, list, titleClassName }) => {
return (
<div className="flex items-center">
{children}
{showDropdownIcon && <Icon name="chevron-down" className="ml-1" />}
{showDropdownIcon && (
<Icon
name="chevron-down"
className="ml-1"
/>
)}
</div>
);
};
@@ -62,7 +72,7 @@ const Dropdown = ({ id, children, showDropdownIcon, list, titleClassName }) => {
return (
<div
className={classnames(
'absolute top-100 right-0 mt-2 z-10 origin-top-right transition duration-300 transform bg-primary-dark border border-secondary-main rounded shadow',
'top-100 bg-primary-dark border-secondary-main absolute right-0 z-10 mt-2 origin-top-right transform rounded border shadow transition duration-300',
{
'scale-0': !open,
'scale-100': open,
@@ -92,8 +102,15 @@ const Dropdown = ({ id, children, showDropdownIcon, list, titleClassName }) => {
}, [open]);
return (
<div data-cy="dropdown" ref={element} className="relative">
<div className="flex items-center cursor-pointer" onClick={toggleList}>
<div
data-cy="dropdown"
ref={element}
className="relative"
>
<div
className="flex cursor-pointer items-center"
onClick={toggleList}
>
{renderTitleElement()}
</div>
@@ -7,7 +7,10 @@ export const argTypes = {
title: 'Components/Dropdown',
};
<Meta title="Components/Dropdown" component={Dropdown} />
<Meta
title="Components/Dropdown"
component={Dropdown}
/>
export const DropdownTemplate = args => (
// Todo: this should not set a background
@@ -16,7 +19,10 @@ export const DropdownTemplate = args => (
</div>
);
<Heading title="Dropdown" componentRelativePath="Dropdown/Dropdown.tsx" />
<Heading
title="Dropdown"
componentRelativePath="Dropdown/Dropdown.tsx"
/>
- [Overview](#overview)
- [Props](#props)
@@ -28,7 +34,10 @@ export const DropdownTemplate = args => (
Dropdown is a modal Dropdown component which enabled to show a modal Dropdown.
<Canvas>
<Story name="Overview" args={{ id: 'dropdown-d', list: [] }}>
<Story
name="Overview"
args={{ id: 'dropdown-d', list: [] }}
>
{DropdownTemplate.bind({})}
</Story>
</Canvas>
@@ -8,9 +8,15 @@ import Typography from '../Typography';
// TODO: Add loading spinner to OHIF + use it here.
const EmptyStudies = ({ className }) => {
return (
<div className={classnames('flex-col inline-flex items-center', className)}>
<Icon name="magnifier" className="mb-4" />
<Typography className="text-primary-light" variant="h5">
<div className={classnames('inline-flex flex-col items-center', className)}>
<Icon
name="magnifier"
className="mb-4"
/>
<Typography
className="text-primary-light"
variant="h5"
>
{'No studies available'}
</Typography>
</div>
@@ -8,21 +8,19 @@ import IconButton from '../IconButton';
const isProduction = process.env.NODE_ENV === 'production';
const DefaultFallback = ({
error,
context,
resetErrorBoundary,
fallbackRoute,
}) => {
const DefaultFallback = ({ error, context, resetErrorBoundary, fallbackRoute }) => {
const [showDetails, setShowDetails] = useState(false);
const title = `Something went wrong${!isProduction && ` in ${context}`}.`;
const subtitle = `Sorry, something went wrong there. Try again.`;
return (
<div className="ErrorFallback bg-primary-dark w-full h-full" role="alert">
<div
className="ErrorFallback bg-primary-dark h-full w-full"
role="alert"
>
<p className="text-primary-light text-xl">{title}</p>
<p className="text-primary-light text-base">{subtitle}</p>
{!isProduction && (
<div className="rounded-md bg-secondary-dark p-5 mt-5 font-mono space-y-2">
<div className="bg-secondary-dark mt-5 space-y-2 rounded-md p-5 font-mono">
<p className="text-primary-light">Context: {context}</p>
<p className="text-primary-light">Error Message: {error.message}</p>
@@ -35,13 +33,15 @@ const DefaultFallback = ({
>
<React.Fragment>
<div>{'Stack Trace'}</div>
<Icon width="15px" height="15px" name="chevron-down" />
<Icon
width="15px"
height="15px"
name="chevron-down"
/>
</React.Fragment>
</IconButton>
{showDetails && (
<p className="px-4 text-primary-light">Stack: {error.stack}</p>
)}
{showDetails && <p className="text-primary-light px-4">Stack: {error.stack}</p>}
</div>
)}
</div>
@@ -100,7 +100,11 @@ const ErrorBoundary = ({
return (
<ReactErrorBoundary
fallbackRender={props => (
<Fallback {...props} context={context} fallbackRoute={fallbackRoute} />
<Fallback
{...props}
context={context}
fallbackRoute={fallbackRoute}
/>
)}
onReset={onResetHandler}
onError={onErrorHandler}
@@ -1,10 +1,10 @@
.ExpandableToolbarButton:hover .ExpandableToolbarButton__arrow:after {
content: "";
content: '';
position: absolute;
bottom: -10px;
border-width: 10px 10px 0;
border-style: solid;
border-color:#5acce6 transparent;
border-color: #5acce6 transparent;
}
.ExpandableToolbarButton .ExpandableToolbarButton__content {
@@ -41,7 +41,10 @@ const ExpandableToolbarButton = ({
};
return (
<div key={id} className="ExpandableToolbarButton">
<div
key={id}
className="ExpandableToolbarButton"
>
<IconButton
variant={isActive ? 'contained' : 'text'}
className={classnames(
@@ -55,13 +58,11 @@ const ExpandableToolbarButton = ({
<Icon name={icon} />
</IconButton>
<div className="absolute z-10 pt-4">
<div
className={classnames(
'ExpandableToolbarButton__content w-48',
className
)}
>
<Content {...contentProps} onClick={onChildClickHandler} />
<div className={classnames('ExpandableToolbarButton__content w-48', className)}>
<Content
{...contentProps}
onClick={onChildClickHandler}
/>
</div>
</div>
</div>
+13 -10
View File
@@ -33,33 +33,36 @@ function Header({
className="justify-between border-b-4 border-black"
isSticky={isSticky}
>
<div className="flex justify-between flex-1">
<div className="flex flex-1 justify-between">
<div className="flex items-center">
{/* // TODO: Should preserve filter/sort
// Either injected service? Or context (like react router's `useLocation`?) */}
<div
className={classNames(
'inline-flex items-center mr-3',
'mr-3 inline-flex items-center',
isReturnEnabled && 'cursor-pointer'
)}
onClick={onClickReturn}
>
{isReturnEnabled && (
<Icon name="chevron-left" className="w-8 text-primary-active" />
<Icon
name="chevron-left"
className="text-primary-active w-8"
/>
)}
<div className="ml-4">
{WhiteLabeling?.createLogoComponentFn?.(React, props) || (
<Svg name="logo-ohif" />
)}
{WhiteLabeling?.createLogoComponentFn?.(React, props) || <Svg name="logo-ohif" />}
</div>
</div>
</div>
<div className="flex items-center">{children}</div>
<div className="flex items-center">
<span className="mr-3 text-lg text-common-light">
{t('INVESTIGATIONAL USE ONLY')}
</span>
<Dropdown id="options" showDropdownIcon={false} list={menuOptions}>
<span className="text-common-light mr-3 text-lg">{t('INVESTIGATIONAL USE ONLY')}</span>
<Dropdown
id="options"
showDropdownIcon={false}
list={menuOptions}
>
<IconButton
id={'options-settings-icon'}
variant="text"
@@ -7,11 +7,17 @@ export const argTypes = {
title: 'Components/Header',
};
<Meta title="Components/Header" component={Header} />
<Meta
title="Components/Header"
component={Header}
/>
export const HeaderTemplate = createComponentTemplate(Header);
<Heading title="Header" componentRelativePath="Header/Header.tsx" />
<Heading
title="Header"
componentRelativePath="Header/Header.tsx"
/>
- [Overview](#overview)
- [Props](#props)
@@ -15,14 +15,7 @@ import { getKeys, formatKeysForInput } from './utils';
* @param {string} props.className input classes
* @param {Array[]} props.modifierKeys
*/
const HotkeyField = ({
disabled,
keys,
onChange,
className,
modifierKeys,
hotkeys,
}) => {
const HotkeyField = ({ disabled, keys, onChange, className, modifierKeys, hotkeys }) => {
const inputValue = formatKeysForInput(keys);
const onInputKeyDown = event => {
@@ -50,10 +50,13 @@ const HotkeysPreferences = ({
return (
<div className="flex flex-row justify-center">
<div className="flex flex-row w-full justify-evenly">
<div className="flex w-full flex-row justify-evenly">
{splitedHotkeys.map((hotkeys, index) => {
return (
<div key={`HotkeyGroup@${index}`} className="flex flex-row">
<div
key={`HotkeyGroup@${index}`}
className="flex flex-row"
>
<div className="flex flex-col p-2 text-right">
{hotkeys.map((hotkey, hotkeyIndex) => {
const [id, definition] = hotkey;
@@ -66,13 +69,13 @@ const HotkeysPreferences = ({
return (
<div
key={`HotkeyItem@${hotkeyIndex}`}
className="flex flex-row justify-end mb-2"
className="mb-2 flex flex-row justify-end"
>
<div className="flex flex-col items-center">
<Typography
variant="subtitle"
className={classNames(
'pr-6 w-full text-right text-primary-light',
'text-primary-light w-full pr-6 text-right',
!isFirst && 'hidden'
)}
>
@@ -81,7 +84,7 @@ const HotkeysPreferences = ({
<Typography
variant="subtitle"
className={classNames(
'pr-6 h-full flex flex-row items-center whitespace-nowrap',
'flex h-full flex-row items-center whitespace-nowrap pr-6',
isFirst && 'mt-5'
)}
>
@@ -92,18 +95,13 @@ const HotkeysPreferences = ({
<Typography
variant="subtitle"
className={classNames(
'pr-6 pl-0 text-left text-primary-light',
'text-primary-light pr-6 pl-0 text-left',
!isFirst && 'hidden'
)}
>
{t('Shortcut')}
</Typography>
<div
className={classNames(
'flex flex-col w-32',
isFirst && 'mt-5'
)}
>
<div className={classNames('flex w-32 flex-col', isFirst && 'mt-5')}>
<HotkeyField
disabled={disabled}
keys={definition.keys}
@@ -113,9 +111,7 @@ const HotkeysPreferences = ({
className="h-8 text-lg"
/>
{error && (
<span className="p-2 text-sm text-left text-red-600">
{error}
</span>
<span className="p-2 text-left text-sm text-red-600">{error}</span>
)}
</div>
</div>
@@ -10,10 +10,7 @@ const findConflictingCommand = (hotkeys, currentCommandName, pressedKeys) => {
const toolHotkeys = hotkeys[commandName].keys;
const formatedToolHotkeys = formatPressedKeys(toolHotkeys);
if (
formatedPressedHotkeys === formatedToolHotkeys &&
commandName !== currentCommandName
) {
if (formatedPressedHotkeys === formatedToolHotkeys && commandName !== currentCommandName) {
firstConflictingCommand = hotkeys[commandName];
break;
}
@@ -23,8 +20,7 @@ const findConflictingCommand = (hotkeys, currentCommandName, pressedKeys) => {
};
const ERROR_MESSAGES = {
MODIFIER:
"It's not possible to define only modifier keys (ctrl, alt and shift) as a shortcut",
MODIFIER: "It's not possible to define only modifier keys (ctrl, alt and shift) as a shortcut",
EMPTY: "Field can't be empty.",
};
@@ -46,11 +42,7 @@ const emptyValidator = ({ pressedKeys = [] }) => {
};
const conflictingValidator = ({ commandName, pressedKeys, hotkeys }) => {
const conflictingCommand = findConflictingCommand(
hotkeys,
commandName,
pressedKeys
);
const conflictingCommand = findConflictingCommand(hotkeys, commandName, pressedKeys);
if (conflictingCommand) {
return {
@@ -61,9 +53,7 @@ const conflictingValidator = ({ commandName, pressedKeys, hotkeys }) => {
const disallowedValidator = ({ pressedKeys = [] }) => {
const lastPressedKey = pressedKeys[pressedKeys.length - 1];
const modifierCommand = formatPressedKeys(
pressedKeys.slice(0, pressedKeys.length - 1)
);
const modifierCommand = formatPressedKeys(pressedKeys.slice(0, pressedKeys.length - 1));
const disallowedCombination = DISALLOWED_COMBINATIONS[modifierCommand];
const hasDisallowedCombinations = disallowedCombination
@@ -72,9 +62,7 @@ const disallowedValidator = ({ pressedKeys = [] }) => {
if (hasDisallowedCombinations) {
return {
error: `"${formatPressedKeys(
pressedKeys
)}" shortcut combination is not allowed`,
error: `"${formatPressedKeys(pressedKeys)}" shortcut combination is not allowed`,
};
}
};
@@ -13,9 +13,7 @@ const splitHotkeyDefinitionsAndCreateTuples = hotkeyDefinitions => {
if (arrayHotkeys.length) {
const halfwayThrough = Math.ceil(arrayHotkeys.length / 2);
splitedHotkeys.push(arrayHotkeys.slice(0, halfwayThrough));
splitedHotkeys.push(
arrayHotkeys.slice(halfwayThrough, arrayHotkeys.length)
);
splitedHotkeys.push(arrayHotkeys.slice(halfwayThrough, arrayHotkeys.length));
}
return splitedHotkeys;
@@ -9,16 +9,22 @@ export const argTypes = {
title: 'Components/Icon',
};
<Meta title="Components/Icon" component={Icon} />
<Meta
title="Components/Icon"
component={Icon}
/>
export const IconTemplate = args => (
// Todo: Icon colors
<div className="w-8 h-8">
<div className="h-8 w-8">
<Icon {...args} />
</div>
);
<Heading title="Icon" componentRelativePath="Icon/Icon.tsx" />
<Heading
title="Icon"
componentRelativePath="Icon/Icon.tsx"
/>
- [Overview](#overview)
- [Props](#props)
@@ -46,8 +52,7 @@ Icon is a component that renders the Icons.
## Usage
You can choose the icon from the list of icons. Here we have render all the
icons.
You can choose the icon from the list of icons. Here we have render all the icons.
<Canvas>
<Story name="All Icons">
@@ -58,8 +63,8 @@ icons.
{icons
.filter(ic => ic !== 'magnifier')
.map(icon => (
<div className="m-4 flex flex-col justify-center items-center">
<div class="w-8 h-8">
<div className="m-4 flex flex-col items-center justify-center">
<div class="h-8 w-8">
<Icon name={icon} />
</div>
<div className="text-gray-600">{icon}</div>
@@ -38,16 +38,14 @@ const variantClasses = {
'border border-primary-main text-primary-main hover:opacity-80 active:opacity-100 focus:opacity-80',
secondary:
'border border-secondary-light text-secondary-light hover:opacity-80 active:opacity-100 focus:opacity-80',
white:
'border border-white text-white hover:opacity-80 active:opacity-100 focus:opacity-80',
white: 'border border-white text-white hover:opacity-80 active:opacity-100 focus:opacity-80',
black:
'border border-primary-main text-white hover:bg-primary-main focus:bg-primary-main hover:border-black focus:border-black',
},
contained: {
default: 'text-black hover:opacity-80 active:opacity-100 focus:opacity-80',
primary: 'text-white hover:opacity-80 active:opacity-100 focus:opacity-80',
secondary:
'text-white hover:opacity-80 active:opacity-100 focus:opacity-80',
secondary: 'text-white hover:opacity-80 active:opacity-100 focus:opacity-80',
white: 'text-black hover:opacity-80 active:opacity-100 focus:opacity-80',
black: 'text-white hover:opacity-80 active:opacity-100 focus:opacity-80',
},
@@ -166,14 +164,7 @@ IconButton.propTypes = {
size: PropTypes.oneOf(['small', 'medium', 'large', 'initial', 'toolbar']),
rounded: PropTypes.oneOf(['none', 'small', 'medium', 'large', 'full']),
variant: PropTypes.oneOf(['text', 'outlined', 'contained']),
color: PropTypes.oneOf([
'default',
'primary',
'secondary',
'white',
'black',
'inherit',
]),
color: PropTypes.oneOf(['default', 'primary', 'secondary', 'white', 'black', 'inherit']),
fullWidth: PropTypes.bool,
disabled: PropTypes.bool,
type: PropTypes.string,
@@ -21,7 +21,10 @@ class ImageScrollbar extends PureComponent {
};
return (
<div className="scroll" onContextMenu={this.props.onContextMenu}>
<div
className="scroll"
onContextMenu={this.props.onContextMenu}
>
<div className="scroll-holder">
<input
// adding mousetrap let the mousetrap know about the scrollbar otherwise,
+5 -2
View File
@@ -36,8 +36,11 @@ const Input = ({
...otherProps
}) => {
return (
<div className={classnames('flex flex-col flex-1', containerClassName)}>
<Label className={labelClassName} text={label}></Label>
<div className={classnames('flex flex-1 flex-col', containerClassName)}>
<Label
className={labelClassName}
text={label}
></Label>
<input
data-cy={`input-${id}`}
className={classnames(
@@ -8,11 +8,17 @@ export const argTypes = {
title: 'Components/Input',
};
<Meta title="Components/Input" component={Input} />
<Meta
title="Components/Input"
component={Input}
/>
export const InputTemplate = createComponentTemplate(Input);
<Heading title="Input" componentRelativePath="Input/Input.tsx" />
<Heading
title="Input"
componentRelativePath="Input/Input.tsx"
/>
- [Overview](#overview)
- [Props](#props)
@@ -50,8 +50,7 @@ InputDateRange.propTypes = {
id: PropTypes.string,
label: PropTypes.string.isRequired,
isSortable: PropTypes.bool.isRequired,
sortDirection: PropTypes.oneOf(['ascending', 'descending', 'none'])
.isRequired,
sortDirection: PropTypes.oneOf(['ascending', 'descending', 'none']).isRequired,
onLabelClick: PropTypes.func.isRequired,
value: PropTypes.shape({
/** YYYYMMDD (19921022) */
@@ -1,13 +1,6 @@
import classNames from 'classnames';
import debounce from 'lodash.debounce';
import React, {
ReactElement,
useCallback,
useEffect,
useMemo,
useRef,
useState,
} from 'react';
import React, { ReactElement, useCallback, useEffect, useMemo, useRef, useState } from 'react';
import Icon from '../Icon';
@@ -68,7 +61,7 @@ const InputFilterText = ({
<input
ref={searchInputRef}
type="text"
className="block bg-black w-full shadow transition duration-300 appearance-none border border-inputfield-main focus:border-inputfield-focus focus:outline-none disabled:border-inputfield-disabled rounded-md w-full py-2 px-9 text-base leading-tight placeholder:text-inputfield-placeholder"
className="border-inputfield-main focus:border-inputfield-focus disabled:border-inputfield-disabled placeholder:text-inputfield-placeholder block w-full w-full appearance-none rounded-md border bg-black py-2 px-9 text-base leading-tight shadow transition duration-300 focus:outline-none"
placeholder={placeholder}
onChange={event => handleFilterTextChanged(event.target.value)}
autoComplete="off"
@@ -6,15 +6,21 @@ export const argTypes = {
title: 'Components/InputFilterText',
};
<Meta title="Components/InputFilterText" component={InputFilterText} />
<Meta
title="Components/InputFilterText"
component={InputFilterText}
/>
export const InputFilterTextTemplate = args => (
<div className="w-80">
<InputFilterText {...args} />
</div>
)
);
<Heading title="InputFilterText" componentRelativePath="InputFilterText/InputFilterText.tsx" />
<Heading
title="InputFilterText"
componentRelativePath="InputFilterText/InputFilterText.tsx"
/>
- [Overview](#overview)
- [Props](#props)
@@ -22,21 +28,20 @@ export const InputFilterTextTemplate = args => (
## Overview
InputFilterText is a component that is styled such that it can be used as a text input to
filter a list of textual items. It allows you to enter any text. There are two (optional)
callbacks that can be invoked as the characters of the text are entered: one
callback is invoked as each character is typed and another is debounced so that
any filtering can occur once the user has entered a significant amount of info and
pausing by a configurable amount of time in milliseconds. The component also
provides a button on the far right of the component that when clicked will clear the input
text. The button only appears when there is text in the component.
InputFilterText is a component that is styled such that it can be used as a text input to filter a
list of textual items. It allows you to enter any text. There are two (optional) callbacks that can
be invoked as the characters of the text are entered: one callback is invoked as each character is
typed and another is debounced so that any filtering can occur once the user has entered a
significant amount of info and pausing by a configurable amount of time in milliseconds. The
component also provides a button on the far right of the component that when clicked will clear the
input text. The button only appears when there is text in the component.
<Canvas>
<Story
name="Overview"
args={{
className: "w-full text-white",
placeholder: "Search for...",
className: 'w-full text-white',
placeholder: 'Search for...',
onChange: () => console.log('input text changed'),
onDebounceChange: () => console.log('debounce text changed'),
}}
@@ -36,13 +36,7 @@ const InputGroup = ({
}
};
const renderFieldInputComponent = ({
name,
displayName,
inputProps,
isSortable,
inputType,
}) => {
const renderFieldInputComponent = ({ name, displayName, inputProps, isSortable, inputType }) => {
const _isSortable = isSortable && isSortingEnabled;
const _sortDirection = sortBy !== name ? 'none' : sortDirection;
@@ -123,16 +117,13 @@ const InputGroup = ({
}
};
return (
<div className="container m-auto relative flex flex-col">
<div className="flex flex-row w-full">
<div className="container relative m-auto flex flex-col">
<div className="flex w-full flex-row">
{inputMeta.map(inputMeta => {
return (
<div
key={inputMeta.name}
className={classnames(
'pl-4 first:pl-12',
getGridWidthClass(inputMeta.gridCol)
)}
className={classnames('pl-4 first:pl-12', getGridWidthClass(inputMeta.gridCol))}
>
{renderFieldInputComponent(inputMeta)}
</div>
@@ -148,11 +139,9 @@ InputGroup.propTypes = {
PropTypes.shape({
name: PropTypes.string.isRequired,
displayName: PropTypes.string.isRequired,
inputType: PropTypes.oneOf(['Text', 'MultiSelect', 'DateRange', 'None'])
.isRequired,
inputType: PropTypes.oneOf(['Text', 'MultiSelect', 'DateRange', 'None']).isRequired,
isSortable: PropTypes.bool.isRequired,
gridCol: PropTypes.oneOf([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12])
.isRequired,
gridCol: PropTypes.oneOf([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]).isRequired,
option: PropTypes.arrayOf(
PropTypes.shape({
value: PropTypes.string,
@@ -5,10 +5,8 @@ import { useTranslation } from 'react-i18next';
import Icon from '../Icon';
const baseLabelClassName =
'flex flex-col flex-1 text-white text-lg pl-1 select-none';
const spanClassName =
'flex flex-row items-center cursor-pointer focus:outline-none';
const baseLabelClassName = 'flex flex-col flex-1 text-white text-lg pl-1 select-none';
const spanClassName = 'flex flex-row items-center cursor-pointer focus:outline-none';
const sortIconMap = {
descending: 'sorting-active-up',
ascending: 'sorting-active-down',
@@ -48,9 +46,7 @@ const InputLabelWrapper = ({
name={sortIconMap[sortDirection]}
className={classnames(
'mx-2 w-2',
sortDirection !== 'none'
? 'text-primary-light'
: 'text-primary-main'
sortDirection !== 'none' ? 'text-primary-light' : 'text-primary-main'
)}
/>
)}
@@ -67,8 +63,7 @@ InputLabelWrapper.defaultProps = {
InputLabelWrapper.propTypes = {
label: PropTypes.string.isRequired,
isSortable: PropTypes.bool.isRequired,
sortDirection: PropTypes.oneOf(['ascending', 'descending', 'none'])
.isRequired,
sortDirection: PropTypes.oneOf(['ascending', 'descending', 'none']).isRequired,
onLabelClick: PropTypes.func.isRequired,
className: PropTypes.string,
children: PropTypes.node,
@@ -60,8 +60,7 @@ InputMultiSelect.propTypes = {
id: PropTypes.string,
label: PropTypes.string.isRequired,
isSortable: PropTypes.bool.isRequired,
sortDirection: PropTypes.oneOf(['ascending', 'descending', 'none'])
.isRequired,
sortDirection: PropTypes.oneOf(['ascending', 'descending', 'none']).isRequired,
onLabelClick: PropTypes.func.isRequired,
onChange: PropTypes.func.isRequired,
placeholder: PropTypes.string,
@@ -82,10 +82,15 @@ const InputNumber: React.FC<{
);
return (
<div className={'flex flex-col flex-1'}>
{label && <Label className={labelClassName} text={label}></Label>}
<div className={'flex flex-1 flex-col'}>
{label && (
<Label
className={labelClassName}
text={label}
></Label>
)}
<div
className={`flex items-center bg-black border-2 px-1 overflow-hidden justify-center border-secondary-light rounded-md ${
className={`border-secondary-light flex items-center justify-center overflow-hidden rounded-md border-2 bg-black px-1 ${
sizesClasses[size]
} ${className ? className : ''}`}
>
@@ -94,7 +99,7 @@ const InputNumber: React.FC<{
type="text"
value={numberValue}
onChange={handleChange}
className={`bg-black text-white text-[12px] w-full text-center input-number`}
className={`input-number w-full bg-black text-center text-[12px] text-white`}
/>
<div className="up-arrowsize flex flex-col items-center justify-around">
@@ -103,7 +108,7 @@ const InputNumber: React.FC<{
variant="text"
color="inherit"
size="initial"
className="text-[#726f7e] transform rotate-180"
className="rotate-180 transform text-[#726f7e]"
onClick={handleIncrement}
>
<Icon name="ui-arrow-down" />
@@ -6,15 +6,21 @@ export const argTypes = {
title: 'Components/InputNumber',
};
<Meta title="Components/InputNumber" component={InputNumber} />
<Meta
title="Components/InputNumber"
component={InputNumber}
/>
export const InputNumberTemplate = args => (
<div className="w-16">
<InputNumber {...args} />
</div>
)
);
<Heading title="InputNumber" componentRelativePath="InputNumber/InputNumber.tsx" />
<Heading
title="InputNumber"
componentRelativePath="InputNumber/InputNumber.tsx"
/>
- [Overview](#overview)
- [Props](#props)
@@ -55,15 +55,13 @@ const InputRange: React.FC<{
[onChange, setRangeValue]
);
const rangeValuePercentage =
((rangeValue - minValue) / (maxValue - minValue)) * 100;
const rangeValuePercentage = ((rangeValue - minValue) / (maxValue - minValue)) * 100;
const rangeValueForStr =
step >= 1 ? rangeValue.toFixed(0) : rangeValue.toFixed(1);
const rangeValueForStr = step >= 1 ? rangeValue.toFixed(0) : rangeValue.toFixed(1);
return (
<div
className={`flex items-center cursor-pointer space-x-1 ${
className={`flex cursor-pointer items-center space-x-1 ${
containerClassName ? containerClassName : ''
}`}
>
@@ -82,14 +80,15 @@ const InputRange: React.FC<{
min={minValue}
max={maxValue}
value={rangeValue}
className={`appearance-none h-[3px] rounded-lg input-range-thumb-design ${
className={`input-range-thumb-design h-[3px] appearance-none rounded-lg ${
inputClassName ? inputClassName : ''
}`}
style={{
background:
trackColor ||
`linear-gradient(to right, #5acce6 0%, #5acce6 ${rangeValuePercentage -
10}%, #3a3f99 ${rangeValuePercentage + 10}%, #3a3f99 100%)`,
`linear-gradient(to right, #5acce6 0%, #5acce6 ${rangeValuePercentage - 10}%, #3a3f99 ${
rangeValuePercentage + 10
}%, #3a3f99 100%)`,
}}
onChange={handleChange}
id="myRange"
@@ -6,15 +6,21 @@ export const argTypes = {
title: 'Components/InputRange',
};
<Meta title="Components/InputRange" component={InputRange} />
<Meta
title="Components/InputRange"
component={InputRange}
/>
export const RangeInputTemplate = args => (
<div className="w-3">
<InputRange {...args} />
</div>
)
);
<Heading title="InputRange" componentRelativePath="InputRange/InputRange.tsx" />
<Heading
title="InputRange"
componentRelativePath="InputRange/InputRange.tsx"
/>
- [Overview](#overview)
- [Props](#props)
@@ -34,7 +40,7 @@ InputRange is a component that allows you to use as a boolean value
step: 10,
unit: '%',
onChange: () => console.log('input range change'),
labelClassName: 'text-black'
labelClassName: 'text-black',
}}
>
{RangeInputTemplate.bind({})}
@@ -4,15 +4,7 @@ import PropTypes from 'prop-types';
import Input from '../Input';
import InputLabelWrapper from '../InputLabelWrapper';
const InputText = ({
id,
label,
isSortable,
sortDirection,
onLabelClick,
value,
onChange,
}) => {
const InputText = ({ id, label, isSortable, sortDirection, onLabelClick, value, onChange }) => {
return (
<InputLabelWrapper
label={label}
+4 -1
View File
@@ -6,7 +6,10 @@ const Label = ({ children, className, text, ...rest }) => {
const baseClasses = '';
return (
<label className={classnames(baseClasses, className)} {...rest}>
<label
className={classnames(baseClasses, className)}
{...rest}
>
{text}
{children}
</label>
@@ -24,7 +24,7 @@ function LayoutSelector({ onSelection, rows, columns }) {
className="p-2"
>
{Array.apply(null, Array(rows * columns))
.map(function(_, i) {
.map(function (_, i) {
return i;
})
.map(index => (
@@ -8,7 +8,10 @@ export const argTypes = {
title: 'Components/LayoutSelector',
};
<Meta title="Components/LayoutSelector" component={LayoutSelector} />
<Meta
title="Components/LayoutSelector"
component={LayoutSelector}
/>
export const LayoutSelectorTemplate = createComponentTemplate(LayoutSelector);
@@ -40,32 +40,25 @@ const variants = {
outlined: {
default:
'text-primary-light hover:bg-primary-light hover:text-black focus:text-black focus:bg-primary-light active:opacity-80',
primary:
'text-primary-main hover:opacity-80 active:opacity-100 focus:opacity-80',
secondary:
'text-secondary-light hover:opacity-80 active:opacity-100 focus:opacity-80',
translucent:
'text-white hover:opacity-80 active:opacity-100 focus:opacity-80',
primary: 'text-primary-main hover:opacity-80 active:opacity-100 focus:opacity-80',
secondary: 'text-secondary-light hover:opacity-80 active:opacity-100 focus:opacity-80',
translucent: 'text-white hover:opacity-80 active:opacity-100 focus:opacity-80',
white:
'text-black hover:bg-primary-main focus:bg-primary-main hover:border-black focus:border-black',
black:
'text-white hover:bg-primary-main focus:bg-primary-main hover:border-black focus:border-black',
primaryActive:
'text-primary-active hover:opacity-80 active:opacity-100 focus:opacity-80',
primaryActive: 'text-primary-active hover:opacity-80 active:opacity-100 focus:opacity-80',
primaryLight:
'border bg-transparent border-primary-main text-white hover:opacity-80 active:opacity-100 focus:opacity-80',
},
contained: {
default: 'text-black hover:opacity-80 active:opacity-100 focus:opacity-80',
primary: 'text-white hover:opacity-80 active:opacity-100 focus:opacity-80',
primaryDark:
'text-primary-active hover:opacity-80 active:opacity-100 focus:opacity-80',
secondary:
'text-white hover:opacity-80 active:opacity-100 focus:opacity-80',
primaryDark: 'text-primary-active hover:opacity-80 active:opacity-100 focus:opacity-80',
secondary: 'text-white hover:opacity-80 active:opacity-100 focus:opacity-80',
white: 'text-black hover:opacity-80 active:opacity-100 focus:opacity-80',
black: 'text-white hover:opacity-80 active:opacity-100 focus:opacity-80',
light:
'border text-black hover:opacity-80 active:opacity-100 focus:opacity-80',
light: 'border text-black hover:opacity-80 active:opacity-100 focus:opacity-80',
},
disabled: {
default: 'cursor-not-allowed opacity-50 text-black',
@@ -10,11 +10,17 @@ export const argTypes = {
title: 'Components/LegacyButton',
};
<Meta title="Components/LegacyButton" component={LegacyButton} />
<Meta
title="Components/LegacyButton"
component={LegacyButton}
/>
export const buttonTemplate = createComponentTemplate(LegacyButton);
<Heading title="LegacyButton" componentRelativePath="LegacyButton/LegacyButton.tsx" />
<Heading
title="LegacyButton"
componentRelativePath="LegacyButton/LegacyButton.tsx"
/>
- [Overview](#overview)
- [Props](#props)
@@ -23,11 +29,14 @@ export const buttonTemplate = createComponentTemplate(LegacyButton);
## Overview
You can use the legacy button component to create a button. It can be used in different
ways, the default button is a simple button with a text.
You can use the legacy button component to create a button. It can be used in different ways, the
default button is a simple button with a text.
<Canvas>
<Story name="Overview" args={{ children: 'LegacyButton', color: 'default' }}>
<Story
name="Overview"
args={{ children: 'LegacyButton', color: 'default' }}
>
{buttonTemplate.bind({})}
</Story>
</Canvas>
@@ -40,8 +49,7 @@ ways, the default button is a simple button with a text.
### Variants
There can be different variants of buttons: `text`, `outlined`, `contained`, and
`disabled`.
There can be different variants of buttons: `text`, `outlined`, `contained`, and `disabled`.
<Canvas>
<Story name="Variants">
@@ -56,8 +64,8 @@ There can be different variants of buttons: `text`, `outlined`, `contained`, and
### Colors
There are different colors for the legacy button: `default`, `primary`, `secondary`,
`white`, `black`, `inherit`, `light`.
There are different colors for the legacy button: `default`, `primary`, `secondary`, `white`,
`black`, `inherit`, `light`.
<Canvas>
<Story name="Colors">
@@ -79,7 +87,10 @@ You can mix different props together to create a legacy button.
<Canvas>
<Story name="Custom">
<LegacyButton color="secondary" variant="outlined">
<LegacyButton
color="secondary"
variant="outlined"
>
Custom LegacyButton
</LegacyButton>
</Story>
@@ -151,7 +162,10 @@ End Icon is the same as start icon, but for the end of the legacy button.
);
};
return (
<LegacyButton startIcon={<Github />} endIcon={<Github />}>
<LegacyButton
startIcon={<Github />}
endIcon={<Github />}
>
Start and End Icon LegacyButton
</LegacyButton>
);
@@ -165,7 +179,10 @@ You can make the legacy button full width by setting the `fullWidth` prop to `tr
<Canvas>
<Story name="Full Width">
<LegacyButton fullWidth color="secondary">
<LegacyButton
fullWidth
color="secondary"
>
Full Width LegacyButton
</LegacyButton>
</Story>
@@ -34,17 +34,21 @@ const LegacyCinePlayer = ({
};
return (
<div className="flex flex-row items-center justify-center h-10 border rounded-full LegacyCinePlayer border-primary-light">
<div className="LegacyCinePlayer border-primary-light flex h-10 flex-row items-center justify-center rounded-full border">
<IconButton
variant="text"
color="inherit"
size="initial"
className="ml-4 mr-3 text-primary-active"
className="text-primary-active ml-4 mr-3"
onClick={onPlayPauseChangeHandler}
>
<Icon width="15px" height="15px" name={action[isPlaying].icon} />
<Icon
width="15px"
height="15px"
name={action[isPlaying].icon}
/>
</IconButton>
<div className="flex flex-col justify-center h-full pt-2 pl-1 pr-1 mr-3">
<div className="mr-3 flex h-full flex-col justify-center pt-2 pl-1 pr-1">
<input
type="range"
name="frameRate"
@@ -54,14 +58,12 @@ const LegacyCinePlayer = ({
value={frameRate}
onChange={onFrameRateChangeHandler}
/>
<p className="-mt-2 text-sm text-primary-light">{`${frameRate.toFixed(
1
)} fps`}</p>
<p className="text-primary-light -mt-2 text-sm">{`${frameRate.toFixed(1)} fps`}</p>
</div>
<IconButton
color="inherit"
size="initial"
className="mr-3 border rounded-full text-primary-active border-primary-active"
className="text-primary-active border-primary-active mr-3 rounded-full border"
onClick={onClose}
>
<Icon name="close" />
@@ -7,7 +7,10 @@ export const argTypes = {
title: 'Components/LegacyCinePlayer',
};
<Meta title="Components/LegacyCinePlayer" component={LegacyCinePlayer} />
<Meta
title="Components/LegacyCinePlayer"
component={LegacyCinePlayer}
/>
export const cineTemplate = createComponentTemplate(LegacyCinePlayer);
@@ -40,20 +40,21 @@ function LegacyPatientInfo({
isOpen && (
<div className="flex py-2">
<div className="flex pt-1">
<Icon name="info-link" className="w-4 text-primary-main" />
<Icon
name="info-link"
className="text-primary-main w-4"
/>
</div>
<div className="flex flex-col ml-2">
<div className="ml-2 flex flex-col">
<span
className="text-base font-bold text-white"
title={patientName}
>
{patientName}
</span>
<div className="flex pb-4 mt-4 mb-4 border-b border-secondary-main">
<div className="border-secondary-main mt-4 mb-4 flex border-b pb-4">
<div className={classnames(classes.firstRow)}>
<span className={classnames(classes.infoHeader)}>
{t('Sex')}
</span>
<span className={classnames(classes.infoHeader)}>{t('Sex')}</span>
<span
className={classnames(classes.infoText)}
title={patientSex}
@@ -62,9 +63,7 @@ function LegacyPatientInfo({
</span>
</div>
<div className={classnames(classes.row)}>
<span className={classnames(classes.infoHeader)}>
{t('Age')}
</span>
<span className={classnames(classes.infoHeader)}>{t('Age')}</span>
<span
className={classnames(classes.infoText)}
title={patientAge}
@@ -73,19 +72,18 @@ function LegacyPatientInfo({
</span>
</div>
<div className={classnames(classes.row)}>
<span className={classnames(classes.infoHeader)}>
{t('MRN')}
</span>
<span className={classnames(classes.infoText)} title={MRN}>
<span className={classnames(classes.infoHeader)}>{t('MRN')}</span>
<span
className={classnames(classes.infoText)}
title={MRN}
>
{MRN}
</span>
</div>
</div>
<div className="flex">
<div className={classnames(classes.firstRow)}>
<span className={classnames(classes.infoHeader)}>
{t('Thickness')}
</span>
<span className={classnames(classes.infoHeader)}>{t('Thickness')}</span>
<span
className={classnames(classes.infoText)}
title={thickness}
@@ -94,9 +92,7 @@ function LegacyPatientInfo({
</span>
</div>
<div className={classnames(classes.row)}>
<span className={classnames(classes.infoHeader)}>
{t('Spacing')}
</span>
<span className={classnames(classes.infoHeader)}>{t('Spacing')}</span>
<span
className={classnames(classes.infoText)}
title={spacing}
@@ -105,9 +101,7 @@ function LegacyPatientInfo({
</span>
</div>
<div className={classnames(classes.row)}>
<span className={classnames(classes.infoHeader)}>
{t('Scanner')}
</span>
<span className={classnames(classes.infoHeader)}>{t('Scanner')}</span>
<span
className={classnames(classes.infoText)}
title={scanner}
@@ -121,12 +115,15 @@ function LegacyPatientInfo({
)
}
>
<div className="relative flex justify-end cursor-pointer">
<div className="relative flex cursor-pointer justify-end">
<div className="relative">
<Icon name="profile" className="w-5 text-white" />
<Icon
name="profile"
className="w-5 text-white"
/>
<Icon
name="info-link"
className="absolute w-5 text-white bg-black"
className="absolute w-5 bg-black text-white"
style={{ right: -7, bottom: -10 }}
/>
</div>
@@ -7,7 +7,7 @@ export default {
};
export const Default = () => (
<div className="w-1/2 p-4 h-64">
<div className="h-64 w-1/2 p-4">
<LegacyViewportActionBar
onArrowsClick={direction => alert(`Series ${direction}`)}
studyData={{
@@ -22,32 +22,16 @@ const LegacyViewportActionBar = ({
}) => {
const [showPatientInfo, setShowPatientInfo] = useState(patientInfoVisibility);
const {
label,
useAltStyling,
studyDate,
currentSeries,
seriesDescription,
patientInformation,
} = studyData;
const { label, useAltStyling, studyDate, currentSeries, seriesDescription, patientInformation } =
studyData;
const {
patientName,
patientSex,
patientAge,
MRN,
thickness,
spacing,
scanner,
} = patientInformation;
const { patientName, patientSex, patientAge, MRN, thickness, spacing, scanner } =
patientInformation;
const onPatientInfoClick = () => setShowPatientInfo(!showPatientInfo);
const closePatientInfo = () => setShowPatientInfo(false);
const showPatientInfoRef = useRef(null);
const clickOutsideListener = useOnClickOutside(
showPatientInfoRef,
closePatientInfo
);
const clickOutsideListener = useOnClickOutside(showPatientInfoRef, closePatientInfo);
useEffect(() => {
if (showPatientInfo) {
@@ -68,7 +52,7 @@ const LegacyViewportActionBar = ({
return (
<div
className="flex flex-wrap items-center p-2 -mt-2 border-b select-none"
className="-mt-2 flex select-none flex-wrap items-center border-b p-2"
style={{
borderColor: borderColor,
backgroundColor: backgroundColor,
@@ -76,15 +60,15 @@ const LegacyViewportActionBar = ({
onDoubleClick={onDoubleClick}
onContextMenu={e => e.preventDefault()}
>
<div className="flex flex-1 grow mt-2 min-w-48">
<div className="min-w-48 mt-2 flex flex-1 grow">
<div className="flex items-center">
<span className="mr-2 text-white text-large">{label}</span>
<span className="text-large mr-2 text-white">{label}</span>
{showStatus && getStatusComponent && getStatusComponent()}
</div>
<div className="flex flex-col justify-start ml-4">
<div className="ml-4 flex flex-col justify-start">
<div className="flex">
<span className="text-base text-white">{studyDate}</span>
<span className="pl-2 ml-2 text-base border-l border-primary-light text-primary-light">
<span className="border-primary-light text-primary-light ml-2 border-l pl-2 text-base">
S: {currentSeries}
</span>
</div>
@@ -96,41 +80,51 @@ const LegacyViewportActionBar = ({
Can clean up by setting percentage widths + calc on parent
containers
*/}
<p className="text-base truncate max-w-40 text-primary-light">
{seriesDescription}
</p>
<p className="max-w-40 text-primary-light truncate text-base">{seriesDescription}</p>
</div>
</div>
</div>
{showNavArrows && !showCine && (
<div className="mt-2" style={{ pointerEvents: 'all' }}>
<div
className="mt-2"
style={{ pointerEvents: 'all' }}
>
{/* TODO Revisit design of ButtonGroup later - for now use LegacyButton for its children.*/}
<ButtonGroup>
<LegacyButton
size="initial"
className="px-2 py-1 bg-black"
className="bg-black px-2 py-1"
border="light"
onClick={() => onArrowsClick('left')}
>
<Icon name="chevron-left" className="w-4 text-white" />
<Icon
name="chevron-left"
className="w-4 text-white"
/>
</LegacyButton>
<LegacyButton
size="initial"
border="light"
className="px-2 py-1 bg-black"
className="bg-black px-2 py-1"
onClick={() => onArrowsClick('right')}
>
<Icon name="chevron-right" className="w-4 text-white" />
<Icon
name="chevron-right"
className="w-4 text-white"
/>
</LegacyButton>
</ButtonGroup>
</div>
)}
{showCine && !showNavArrows && (
<div className="mt-2 mr-auto min-w-48 max-w-48">
<div className="min-w-48 max-w-48 mt-2 mr-auto">
<LegacyCinePlayer {...cineProps} />
</div>
)}
<div className="flex h-8 mt-2 ml-4 mr-2" onClick={onPatientInfoClick}>
<div
className="mt-2 ml-4 mr-2 flex h-8"
onClick={onPatientInfoClick}
>
<LegacyPatientInfo
showPatientInfoRef={showPatientInfoRef}
isOpen={showPatientInfo}
@@ -29,7 +29,7 @@ const ListMenu = ({ items = [], renderer, onClick }) => {
};
return (
<div className="flex flex-col rounded-md bg-secondary-dark pt-2 pb-2">
<div className="bg-secondary-dark flex flex-col rounded-md pt-2 pb-2">
{items.map((item, index) => {
return (
<ListItem
@@ -14,11 +14,14 @@ function LoadingIndicatorProgress({ className, textBlock, progress }) {
return (
<div
className={classNames(
'absolute z-50 top-0 left-0 flex flex-col items-center justify-center space-y-5',
'absolute top-0 left-0 z-50 flex flex-col items-center justify-center space-y-5',
className
)}
>
<Icon name="loading-ohif-mark" className="text-white w-12 h-12" />
<Icon
name="loading-ohif-mark"
className="h-12 w-12 text-white"
/>
<div className="w-48">
<ProgressLoadingBar progress={progress} />
</div>
@@ -24,17 +24,15 @@ function LoadingIndicatorTotalPercent({
const progress = percentComplete;
const totalNumbersText = totalNumbers !== null ? `${totalNumbers}` : '';
const numTargetsLoadedText =
percentComplete !== null
? Math.floor((percentComplete * totalNumbers) / 100)
: '';
percentComplete !== null ? Math.floor((percentComplete * totalNumbers) / 100) : '';
const textBlock =
!totalNumbers && percentComplete === null ? (
<div className="text-white text-sm">{loadingText}</div>
<div className="text-sm text-white">{loadingText}</div>
) : !totalNumbers && percentComplete !== null ? (
<div className="text-white text-sm">Loaded {percentComplete}%</div>
<div className="text-sm text-white">Loaded {percentComplete}%</div>
) : (
<div className="text-white text-sm">
<div className="text-sm text-white">
Loaded {numTargetsLoadedText} of {totalNumbersText} {targetText}
</div>
);
@@ -4,16 +4,7 @@ import classnames from 'classnames';
import Icon from '../Icon';
const MeasurementItem = ({
uid,
index,
label,
displayText,
isActive,
onClick,
onEdit,
item,
}) => {
const MeasurementItem = ({ uid, index, label, displayText, isActive, onClick, onEdit, item }) => {
const [isHovering, setIsHovering] = useState(false);
const onEditHandler = event => {
@@ -29,9 +20,9 @@ const MeasurementItem = ({
return (
<div
className={classnames(
'group flex cursor-pointer bg-black border outline-none border-transparent transition duration-300',
'group flex cursor-pointer border border-transparent bg-black outline-none transition duration-300',
{
'rounded overflow-hidden border-primary-light': isActive,
'border-primary-light overflow-hidden rounded': isActive,
}
)}
onMouseEnter={onMouseEnter}
@@ -42,30 +33,27 @@ const MeasurementItem = ({
data-cy={'measurement-item'}
>
<div
className={classnames(
'text-center w-6 py-1 text-base transition duration-300',
{
'bg-primary-light text-black active': isActive,
'bg-primary-dark text-primary-light group-hover:bg-secondary-main': !isActive,
}
)}
className={classnames('w-6 py-1 text-center text-base transition duration-300', {
'bg-primary-light active text-black': isActive,
'bg-primary-dark text-primary-light group-hover:bg-secondary-main': !isActive,
})}
>
{index}
</div>
<div className="relative flex flex-col flex-1 px-2 py-1">
<span className="mb-1 text-base text-primary-light">{label}</span>
<div className="relative flex flex-1 flex-col px-2 py-1">
<span className="text-primary-light mb-1 text-base">{label}</span>
{displayText.map((line, i) => (
<span
key={i}
className="pl-2 text-base text-white border-l border-primary-light"
className="border-primary-light border-l pl-2 text-base text-white"
dangerouslySetInnerHTML={{ __html: line }}
></span>
))}
<Icon
className={classnames(
'text-white w-4 absolute cursor-pointer transition duration-300',
{ 'invisible opacity-0 mr-2': !isActive && !isHovering },
{ 'visible opacity-1': !isActive && isHovering }
'absolute w-4 cursor-pointer text-white transition duration-300',
{ 'invisible mr-2 opacity-0': !isActive && !isHovering },
{ 'opacity-1 visible': !isActive && isHovering }
)}
name="pencil"
style={{
@@ -81,10 +69,7 @@ const MeasurementItem = ({
};
MeasurementItem.propTypes = {
uid: PropTypes.oneOfType([
PropTypes.number.isRequired,
PropTypes.string.isRequired,
]),
uid: PropTypes.oneOfType([PropTypes.number.isRequired, PropTypes.string.isRequired]),
index: PropTypes.number.isRequired,
label: PropTypes.string,
displayText: PropTypes.array.isRequired,
@@ -5,36 +5,25 @@ import { useTranslation } from 'react-i18next';
import MeasurementItem from './MeasurementItem';
const MeasurementTable = ({
data,
title,
onClick,
onEdit,
servicesManager,
}) => {
const MeasurementTable = ({ data, title, onClick, onEdit, servicesManager }) => {
servicesManager = servicesManager as ServicesManager;
const { customizationService } = servicesManager.services;
const { t } = useTranslation('MeasurementTable');
const amount = data.length;
const itemCustomization = customizationService.getCustomization(
'MeasurementItem',
{
content: MeasurementItem,
contentProps: {},
}
);
const itemCustomization = customizationService.getCustomization('MeasurementItem', {
content: MeasurementItem,
contentProps: {},
});
const CustomMeasurementItem = itemCustomization.content;
return (
<div>
<div className="flex justify-between px-2 py-1 bg-secondary-main">
<span className="text-base font-bold tracking-widest text-white uppercase">
{t(title)}
</span>
<div className="bg-secondary-main flex justify-between px-2 py-1">
<span className="text-base font-bold uppercase tracking-widest text-white">{t(title)}</span>
<span className="text-base font-bold text-white">{amount}</span>
</div>
<div className="overflow-hidden ohif-scrollbar max-h-112">
<div className="ohif-scrollbar max-h-112 overflow-hidden">
{data.length !== 0 &&
data.map((measurementItem, index) => (
<CustomMeasurementItem
@@ -50,10 +39,10 @@ const MeasurementTable = ({
/>
))}
{data.length === 0 && (
<div className="flex transition duration-300 bg-black border border-transparent cursor-default group">
<div className="w-6 py-1 text-base text-center transition duration-300 bg-primary-dark text-primary-light group-hover:bg-secondary-main"></div>
<div className="flex items-center justify-between flex-1 px-2 py-4">
<span className="flex items-center flex-1 mb-1 text-base text-primary-light">
<div className="group flex cursor-default border border-transparent bg-black transition duration-300">
<div className="bg-primary-dark text-primary-light group-hover:bg-secondary-main w-6 py-1 text-center text-base transition duration-300"></div>
<div className="flex flex-1 items-center justify-between px-2 py-4">
<span className="text-primary-light mb-1 flex flex-1 items-center text-base">
{t('No tracked measurements')}
</span>
</div>
@@ -8,10 +8,13 @@ export const argTypes = {
title: 'Components/MeasurementTable',
};
<Meta title="Components/MeasurementTable" component={MeasurementTable} />
<Meta
title="Components/MeasurementTable"
component={MeasurementTable}
/>
export const MeasurementTableTemplate = args => (
<div className="w-64 h-64 bg-primary-dark">
<div className="bg-primary-dark h-64 w-64">
<MeasurementTable {...args} />
</div>
);
@@ -38,7 +41,7 @@ MeasurementTable is a component that renders the MeasurementTables.
services: {
customizationService: {
getCustomization: (title, data) => data.content,
}
},
},
},
}}
@@ -73,7 +76,7 @@ With data
services: {
customizationService: {
getCustomization: (title, data) => data,
}
},
},
},
}}
+5 -8
View File
@@ -30,7 +30,7 @@ const Modal = ({
const renderHeader = () => {
return (
title && (
<header className="flex items-center px-[20px] py-[13px] bg-primary-dark rounded-tl rounded-tr">
<header className="bg-primary-dark flex items-center rounded-tl rounded-tr px-[20px] py-[13px]">
<Typography
variant="h6"
color="primaryLight"
@@ -43,7 +43,7 @@ const Modal = ({
<Icon
onClick={onClose}
name="close"
className="cursor-pointer text-primary-active"
className="text-primary-active cursor-pointer"
/>
)}
</header>
@@ -53,7 +53,7 @@ const Modal = ({
return (
<ReactModal
className="relative w-11/12 lg:w-10/12 xl:w-1/2 max-h-full outline-none text-white"
className="relative max-h-full w-11/12 text-white outline-none lg:w-10/12 xl:w-1/2"
overlayClassName="fixed top-0 left-0 right-0 bottom-0 z-50 bg-overlay flex items-start justify-center py-16"
shouldCloseOnEsc={shouldCloseOnEsc}
onRequestClose={handleClose}
@@ -62,7 +62,7 @@ const Modal = ({
shouldCloseOnOverlayClick={shouldCloseOnOverlayClick}
>
{renderHeader()}
<section className="ohif-scrollbar modal-content overflow-y-auto px-[20px] pt-2 pb-[20px] rounded-bl rounded-br bg-primary-dark">
<section className="ohif-scrollbar modal-content bg-primary-dark overflow-y-auto rounded-bl rounded-br px-[20px] pt-2 pb-[20px]">
{children}
</section>
</ReactModal>
@@ -81,10 +81,7 @@ Modal.propTypes = {
title: PropTypes.string,
onClose: PropTypes.func,
/** The modal's content */
children: PropTypes.oneOfType([
PropTypes.arrayOf(PropTypes.node),
PropTypes.node,
]).isRequired,
children: PropTypes.oneOfType([PropTypes.arrayOf(PropTypes.node), PropTypes.node]).isRequired,
shouldCloseOnOverlayClick: PropTypes.bool,
};
+1 -1
View File
@@ -9,7 +9,7 @@ const NavBar = ({ className, children, isSticky }) => {
return (
<div
className={classnames(
'flex flex-row items-center bg-secondary-dark px-1 border-b-4 border-black z-20',
'bg-secondary-dark z-20 flex flex-row items-center border-b-4 border-black px-1',
isSticky && stickyClasses,
!isSticky && notStickyClasses,
className
@@ -5,19 +5,12 @@ import PropTypes from 'prop-types';
import Button, { ButtonEnums } from '../Button';
import Icon from '../Icon';
const Notification = ({
id,
type,
message,
actions,
onSubmit,
onOutsideClick,
}) => {
const Notification = ({ id, type, message, actions, onSubmit, onOutsideClick }) => {
const notificationRef = useRef(null);
useEffect(() => {
const notificationElement = notificationRef.current;
const handleClick = function(event) {
const handleClick = function (event) {
const isClickInside = notificationElement.contains(event.target);
if (!isClickInside) {
@@ -65,14 +58,17 @@ const Notification = ({
return (
<div
ref={notificationRef}
className="flex flex-col p-2 mx-2 mt-2 border-2 rounded-md border-customblue-10 bg-customblue-400"
className="border-customblue-10 bg-customblue-400 mx-2 mt-2 flex flex-col rounded-md border-2 p-2"
data-cy={id}
>
<div className="flex items-center grow">
<Icon name={icon} className={classnames('w-6 h-6', color)} />
<div className="flex grow items-center">
<Icon
name={icon}
className={classnames('h-6 w-6', color)}
/>
<span className="ml-2 text-[13px] text-black">{message}</span>
</div>
<div className="flex flex-wrap gap-2 justify-end mt-2">
<div className="mt-2 flex flex-wrap justify-end gap-2">
{actions?.map((action, index) => {
return (
<Button
@@ -105,10 +101,7 @@ Notification.propTypes = {
PropTypes.shape({
text: PropTypes.string.isRequired,
value: PropTypes.any.isRequired,
type: PropTypes.oneOf([
ButtonEnums.type.primary,
ButtonEnums.type.secondary,
]).isRequired,
type: PropTypes.oneOf([ButtonEnums.type.primary, ButtonEnums.type.secondary]).isRequired,
size: PropTypes.oneOf([ButtonEnums.size.small, ButtonEnums.size.medium]),
})
).isRequired,
@@ -8,7 +8,10 @@ export const argTypes = {
title: 'Components/Notification',
};
<Meta title="Components/Notification" component={Notification} />
<Meta
title="Components/Notification"
component={Notification}
/>
export const NotificationTemplate = createComponentTemplate(Notification);
@@ -40,20 +40,21 @@ function PatientInfo({
isOpen && (
<div className="flex py-2">
<div className="flex pt-1">
<Icon name="info-link" className="w-4 text-primary-main" />
<Icon
name="info-link"
className="text-primary-main w-4"
/>
</div>
<div className="flex flex-col ml-2">
<div className="ml-2 flex flex-col">
<span
className="text-base font-bold text-white"
title={patientName}
>
{patientName}
</span>
<div className="flex pb-4 mt-4 mb-4 border-b border-secondary-main">
<div className="border-secondary-main mt-4 mb-4 flex border-b pb-4">
<div className={classnames(classes.firstRow)}>
<span className={classnames(classes.infoHeader)}>
{t('Sex')}
</span>
<span className={classnames(classes.infoHeader)}>{t('Sex')}</span>
<span
className={classnames(classes.infoText)}
title={patientSex}
@@ -62,9 +63,7 @@ function PatientInfo({
</span>
</div>
<div className={classnames(classes.row)}>
<span className={classnames(classes.infoHeader)}>
{t('Age')}
</span>
<span className={classnames(classes.infoHeader)}>{t('Age')}</span>
<span
className={classnames(classes.infoText)}
title={patientAge}
@@ -73,32 +72,27 @@ function PatientInfo({
</span>
</div>
<div className={classnames(classes.row)}>
<span className={classnames(classes.infoHeader)}>
{t('MRN')}
</span>
<span className={classnames(classes.infoText)} title={MRN}>
<span className={classnames(classes.infoHeader)}>{t('MRN')}</span>
<span
className={classnames(classes.infoText)}
title={MRN}
>
{MRN}
</span>
</div>
</div>
<div className="flex">
<div className={classnames(classes.firstRow)}>
<span className={classnames(classes.infoHeader)}>
{t('Thickness')}
</span>
<span className={classnames(classes.infoHeader)}>{t('Thickness')}</span>
<span
className={classnames(classes.infoText)}
title={thickness}
>
{thicknessUnits
? `${thickness}${thicknessUnits}`
: `${thickness}`}
{thicknessUnits ? `${thickness}${thicknessUnits}` : `${thickness}`}
</span>
</div>
<div className={classnames(classes.row)}>
<span className={classnames(classes.infoHeader)}>
{t('Spacing')}
</span>
<span className={classnames(classes.infoHeader)}>{t('Spacing')}</span>
<span
className={classnames(classes.infoText)}
title={spacing}
@@ -107,9 +101,7 @@ function PatientInfo({
</span>
</div>
<div className={classnames(classes.row)}>
<span className={classnames(classes.infoHeader)}>
{t('Scanner')}
</span>
<span className={classnames(classes.infoHeader)}>{t('Scanner')}</span>
<span
className={classnames(classes.infoText)}
title={scanner}
@@ -124,7 +116,7 @@ function PatientInfo({
}
>
<Icon
className="cursor-pointer text-white hover:text-primary-light"
className="hover:text-primary-light cursor-pointer text-white"
name="info-action"
/>
</Tooltip>
@@ -11,9 +11,7 @@ export type ProgressLoadingBarProps = {
* If progress is provided, it will render a progress bar
* The progress text can be optionally displayed to the left of the bar.
*/
function ProgressLoadingBar({
progress,
}: ProgressLoadingBarProps): ReactElement {
function ProgressLoadingBar({ progress }: ProgressLoadingBarProps): ReactElement {
return (
<div className="loading">
{progress === undefined || progress === null ? (
@@ -15,9 +15,9 @@ const ActiveSegmentationConfig = ({
setFillAlpha,
}) => {
return (
<div className="flex justify-between text-[12px] pt-[13px] px-2">
<div className="flex justify-between px-2 pt-[13px] text-[12px]">
<div className="flex flex-col items-start">
<div className="text-white mb-[12px]">Active</div>
<div className="mb-[12px] text-white">Active</div>
<CheckBox
label="Outline"
checked={config.renderOutline}
@@ -34,8 +34,8 @@ const ActiveSegmentationConfig = ({
/>
</div>
<div className="flex flex-col items-center col-span-2">
<div className="text-[#b3b3b3] text-[10px] mb-[12px]">Opacity</div>
<div className="col-span-2 flex flex-col items-center">
<div className="mb-[12px] text-[10px] text-[#b3b3b3]">Opacity</div>
<InputRange
minValue={0}
maxValue={100}
@@ -61,7 +61,7 @@ const ActiveSegmentationConfig = ({
</div>
<div className="flex flex-col items-center">
<div className="text-[#b3b3b3] text-[10px] mb-[12px]">Size</div>
<div className="mb-[12px] text-[10px] text-[#b3b3b3]">Size</div>
<InputNumber
value={config.outlineWidthActive}
onChange={setOutlineWidthActive}
@@ -89,7 +89,7 @@ const InactiveSegmentationConfig = ({
onChange={setRenderInactiveSegmentations}
/>
<div className="flex pl-4 items-center space-x-2">
<div className="flex items-center space-x-2 pl-4">
<span className="text-[10px] text-[#b3b3b3]">Opacity</span>
<InputRange
minValue={0}
@@ -130,16 +130,11 @@ const SegmentationConfig = ({
>
<Icon
name="panel-group-open-close"
className={classNames(
'w-5 h-5 text-white transition duration-300 cursor-pointer',
{
'transform rotate-90': !isMinimized,
}
)}
className={classNames('h-5 w-5 cursor-pointer text-white transition duration-300', {
'rotate-90 transform': !isMinimized,
})}
/>
<span className="text-[#d8d8d8] text-[12px] font-[300]">
{'Segmentation Appearance'}
</span>
<span className="text-[12px] font-[300] text-[#d8d8d8]">{'Segmentation Appearance'}</span>
</div>
{/* active segmentation */}
{!isMinimized && (
@@ -153,13 +148,13 @@ const SegmentationConfig = ({
setRenderOutline={setRenderOutline}
/>
{/* A small line */}
<div className="h-[1px] bg-[#212456] mb-[8px] mx-1"></div>
<div className="mx-1 mb-[8px] h-[1px] bg-[#212456]"></div>
{/* inactive segmentation */}
<div
onClick={() => setIsMinimized(!isMinimized)}
className="flex items-center cursor-pointer pl-2 pb-[9px]"
className="flex cursor-pointer items-center pl-2 pb-[9px]"
>
<span className="text-[#d8d8d8] text-[12px] font-[300]">
<span className="text-[12px] font-[300] text-[#d8d8d8]">
{'Inactive Segmentations'}
</span>
</div>
@@ -17,10 +17,16 @@ const AddNewSegmentRow = ({
}) => {
return (
<div>
<div className="flex items-center pl-[29px] bg-black text-primary-active hover:opacity-80 cursor-pointer text-[12px] py-1">
<div className="text-primary-active flex cursor-pointer items-center bg-black py-1 pl-[29px] text-[12px] hover:opacity-80">
{showAddSegment && !disableEditing && (
<div className="flex items-center" onClick={() => onSegmentAdd()}>
<Icon name="row-add" className="w-5 h-5" />
<div
className="flex items-center"
onClick={() => onSegmentAdd()}
>
<Icon
name="row-add"
className="h-5 w-5"
/>
<div className="">Add Segment</div>
</div>
)}
@@ -32,9 +38,15 @@ const AddNewSegmentRow = ({
}}
>
{isVisible ? (
<Icon name="row-show-all" className="w-5 h-5" />
<Icon
name="row-show-all"
className="h-5 w-5"
/>
) : (
<Icon name="row-hide-all" className="w-5 h-5" />
<Icon
name="row-hide-all"
className="h-5 w-5"
/>
)}
</div>
</div>
@@ -60,7 +72,7 @@ const SegmentGroupHeader = ({
return (
<div
className={classnames(
'flex flex-static items-center pr-2 pl-[3px] h-[27px] gap-2 rounded-t-md border-b border-secondary-light cursor-pointer text-[12px]',
'flex-static border-secondary-light flex h-[27px] cursor-pointer items-center gap-2 rounded-t-md border-b pr-2 pl-[3px] text-[12px]',
{
'bg-secondary-main': isActive,
'bg-secondary-dark': !isActive,
@@ -77,14 +89,11 @@ const SegmentGroupHeader = ({
evt.stopPropagation();
onToggleMinimizeSegmentation(id);
}}
className={classnames(
'w-5 h-5 text-white transition duration-300 cursor-pointer',
{
'transform rotate-90': !isMinimized,
}
)}
className={classnames('h-5 w-5 cursor-pointer text-white transition duration-300', {
'rotate-90 transform': !isMinimized,
})}
/>
<span className="text-white w-full whitespace-nowrap text-ellipsis overflow-hidden">
<span className="w-full overflow-hidden text-ellipsis whitespace-nowrap text-white">
{label.toUpperCase()}
</span>
<div className="flex-grow" />
@@ -156,7 +165,7 @@ const SegmentationGroup = ({
onSegmentEdit,
}) => {
return (
<div className="flex flex-col flex-auto min-h-0">
<div className="flex min-h-0 flex-auto flex-col">
<SegmentGroupHeader
id={id}
label={label}
@@ -170,7 +179,7 @@ const SegmentationGroup = ({
disableEditing={disableEditing}
/>
{!isMinimized && (
<div className="flex flex-col flex-auto min-h-0">
<div className="flex min-h-0 flex-auto flex-col">
<AddNewSegmentRow
onConfigChange={onSegmentationConfigChange}
onSegmentAdd={onSegmentAdd}
@@ -180,22 +189,19 @@ const SegmentationGroup = ({
disableEditing={disableEditing}
showAddSegment={showAddSegment}
/>
<div className="flex flex-col min-h-0 ohif-scrollbar overflow-y-hidden">
<div className="ohif-scrollbar flex min-h-0 flex-col overflow-y-hidden">
{!!segments.length &&
segments.map(segment => {
if (segment === undefined || segment === null) {
return null;
}
const {
segmentIndex,
color,
label,
isVisible,
isLocked,
} = segment;
const { segmentIndex, color, label, isVisible, isLocked } = segment;
return (
<div className="mb-[1px]" key={segmentIndex}>
<div
className="mb-[1px]"
key={segmentIndex}
>
<SegmentationGroupSegment
segmentationId={id}
segmentIndex={segmentIndex}
@@ -32,7 +32,7 @@ const SegmentItem = ({
return (
<div
className={classnames(
'group relative flex cursor-pointer bg-primary-dark transition duration-300 text-[12px] overflow-hidden border',
'bg-primary-dark group relative flex cursor-pointer overflow-hidden border text-[12px] transition duration-300',
{
'border-primary-light rounded-[3px]': isActive,
},
@@ -52,14 +52,12 @@ const SegmentItem = ({
>
<div
className={classnames(
'w-[27px] flex items-center justify-center border-r border-r-black text-[12px]',
'flex w-[27px] items-center justify-center border-r border-r-black text-[12px]',
{
'bg-primary-light text-black border-l border-l-primary-light rounded-l-sm': isActive,
'bg-[#1d3c58] border-l border-l-[#1d3c58] rounded-l-sm':
!isActive && isHovering,
'bg-primary-dark text-aqua-pale':
!isActive && !isHovering && isVisible,
'bg-[#140e2e] opacity-60 text-[#537594]': !isActive && !isVisible,
'bg-primary-light border-l-primary-light rounded-l-sm border-l text-black': isActive,
'rounded-l-sm border-l border-l-[#1d3c58] bg-[#1d3c58]': !isActive && isHovering,
'bg-primary-dark text-aqua-pale': !isActive && !isHovering && isVisible,
'bg-[#140e2e] text-[#537594] opacity-60': !isActive && !isVisible,
}
)}
onMouseEnter={() => setIsSegmentIndexHovering(true)}
@@ -75,24 +73,22 @@ const SegmentItem = ({
}}
/>
) : (
<div className={classnames('flex items-center pr-2 ')}>
{segmentIndex}
</div>
<div className={classnames('flex items-center pr-2 ')}>{segmentIndex}</div>
)}
</div>
<div
className={classnames(
'flex items-center justify-between w-full pl-2 py-1 text-white border-r border-r-black relative ',
'relative flex w-full items-center justify-between border-r border-r-black py-1 pl-2 text-white ',
{
'bg-primary-dark text-primary-light': isActive,
'bg-primary-dark text-aqua-pale': !isActive && isVisible,
'bg-[#140e2e] opacity-60 text-[#3d5871]': !isVisible,
'bg-[#140e2e] text-[#3d5871] opacity-60': !isVisible,
}
)}
>
<div className={classnames('flex items-baseline gap-2')}>
<div
className={classnames('shrink-0 w-[8px] h-[8px] rounded-full')}
className={classnames('h-[8px] w-[8px] shrink-0 rounded-full')}
style={{ backgroundColor: cssColor }}
onClick={e => {
e.stopPropagation();
@@ -102,12 +98,12 @@ const SegmentItem = ({
<div className="">{label}</div>
</div>
{/* with faded background */}
<div className="absolute right-0 bg-black/15 rounded-lg pr-[7px]">
<div className="bg-black/15 absolute right-0 rounded-lg pr-[7px]">
{!isVisible && !isHovering && (
<div>
<Icon
name="row-hidden"
className={classnames('w-5 h-5 text-[#3d5871] ')}
className={classnames('h-5 w-5 text-[#3d5871] ')}
onClick={e => {
e.stopPropagation();
onToggleVisibility(segmentationId, segmentIndex);
@@ -120,7 +116,7 @@ const SegmentItem = ({
{!disableEditing && (
<Icon
name="row-edit"
className={classnames('w-5 h-5', {
className={classnames('h-5 w-5', {
'text-white': isLocked,
'text-primary-light': !isLocked,
})}
@@ -133,7 +129,7 @@ const SegmentItem = ({
{isVisible ? (
<Icon
name="row-hide"
className={classnames('w-5 h-5', {
className={classnames('h-5 w-5', {
'text-white': isLocked,
'text-primary-light': !isLocked,
})}
@@ -145,7 +141,7 @@ const SegmentItem = ({
) : (
<Icon
name="row-unhide"
className={classnames('w-5 h-5', {
className={classnames('h-5 w-5', {
'text-white': isLocked,
'text-primary-light': !isLocked,
})}
@@ -32,7 +32,7 @@ const SegmentationGroupTable = ({
setRenderOutline,
}) => {
return (
<div className="flex flex-col min-h-0 font-inter font-[300]">
<div className="font-inter flex min-h-0 flex-col font-[300]">
<SegmentationConfig
setFillAlpha={setFillAlpha}
setFillAlphaInactive={setFillAlphaInactive}
@@ -43,7 +43,7 @@ const SegmentationGroupTable = ({
setRenderOutline={setRenderOutline}
segmentationConfig={segmentationConfig}
/>
<div className="flex flex-col min-h-0 pr-[1px] mt-1">
<div className="mt-1 flex min-h-0 flex-col pr-[1px]">
{!!segmentations.length &&
segmentations.map((segmentation, index) => {
const {
@@ -86,10 +86,13 @@ const SegmentationGroupTable = ({
</div>
{showAddSegmentation && !disableEditing && (
<div
className="flex items-center cursor-pointer hover:opacity-80 text-primary-active bg-black text-[12px] pl-1 h-[45px]"
className="text-primary-active flex h-[45px] cursor-pointer items-center bg-black pl-1 text-[12px] hover:opacity-80"
onClick={() => onSegmentationAdd()}
>
<Icon name="row-add" className="w-5 h-5" />
<Icon
name="row-add"
className="h-5 w-5"
/>
<div className="pl-1">Add New Segmentation</div>
</div>
)}
@@ -14,7 +14,7 @@ export const argTypes = {
/>
export const SegmentationGroupTableTemplate = args => (
<div className="w-64 h-96 bg-primary-dark">
<div className="bg-primary-dark h-96 w-64">
<SegmentationGroupTable {...args} />
</div>
);
@@ -38,94 +38,78 @@ SegmentationGroupTable is a component that renders the SegmentationGroupTables.
args={{
activeSegmentationId: 'ed8d6f8d-4035-438d-9032-36d5912aaa3a',
showAddSegmentation: true,
isMinimized: {"4be5-b9b2-ed33-fa86970568e7": false},
isMinimized: { '4be5-b9b2-ed33-fa86970568e7': false },
showAddSegment: true,
segmentations: [
{
"id": "4be5-b9b2-ed33-fa86970568e7",
"volumeId": "a3b0f15f-4be5-b9b2-ed33-fa86970568e7",
"activeSegmentIndex": 1,
"cachedStats": {},
"label": "Segmentation",
"segmentsLocked": {},
"type": "LABELMAP",
"displayText": [],
"hydrated": true,
"segmentCount": 3,
"segments": [
null,
{
"label": "Segment 1",
"segmentIndex": 1,
"color": [
128,
174,
128
],
"opacity": 255,
"isVisible": true,
"isLocked": false,
},
{
"label": "Segment 2",
"segmentIndex": 2,
"color": [
241,
214,
145
],
"opacity": 255,
"isVisible": true,
"isLocked": false,
},
{
"label": "Segment 3",
"segmentIndex": 3,
"color": [
141,
114,
145
],
"opacity": 255,
"isVisible": false,
"isLocked": false
}
],
"isActive": false,
"colorLUTIndex": 1,
"isVisible": true
},
{
"id": "a3b0f15f-4be5-b9b2-ed33-fa86970568e7",
"volumeId": "a3b0f15f-4be5-b9b2-ed33-fa86970568e7",
"activeSegmentIndex": 1,
"cachedStats": {},
"label": "Segmentation2",
"segmentsLocked": {},
"type": "LABELMAP",
"displayText": [],
"hydrated": true,
"segmentCount": 2,
"segments": [
null,
{
"label": "Segment 1",
"segmentIndex": 1,
"color": [
228,
174,
128
],
"opacity": 255,
"isVisible": true,
"isLocked": false,
},
],
"isActive": true,
"colorLUTIndex": 1,
"isVisible": true
}
]
segmentations: [
{
id: '4be5-b9b2-ed33-fa86970568e7',
volumeId: 'a3b0f15f-4be5-b9b2-ed33-fa86970568e7',
activeSegmentIndex: 1,
cachedStats: {},
label: 'Segmentation',
segmentsLocked: {},
type: 'LABELMAP',
displayText: [],
hydrated: true,
segmentCount: 3,
segments: [
null,
{
label: 'Segment 1',
segmentIndex: 1,
color: [128, 174, 128],
opacity: 255,
isVisible: true,
isLocked: false,
},
{
label: 'Segment 2',
segmentIndex: 2,
color: [241, 214, 145],
opacity: 255,
isVisible: true,
isLocked: false,
},
{
label: 'Segment 3',
segmentIndex: 3,
color: [141, 114, 145],
opacity: 255,
isVisible: false,
isLocked: false,
},
],
isActive: false,
colorLUTIndex: 1,
isVisible: true,
},
{
id: 'a3b0f15f-4be5-b9b2-ed33-fa86970568e7',
volumeId: 'a3b0f15f-4be5-b9b2-ed33-fa86970568e7',
activeSegmentIndex: 1,
cachedStats: {},
label: 'Segmentation2',
segmentsLocked: {},
type: 'LABELMAP',
displayText: [],
hydrated: true,
segmentCount: 2,
segments: [
null,
{
label: 'Segment 1',
segmentIndex: 1,
color: [228, 174, 128],
opacity: 255,
isVisible: true,
isLocked: false,
},
],
isActive: true,
colorLUTIndex: 1,
isVisible: true,
},
],
}}
>
{SegmentationGroupTableTemplate.bind({})}
@@ -31,9 +31,9 @@ const SegmentationItem = ({
return (
<div
className={classnames(
'group relative flex cursor-pointer items-stretch bg-black border outline-none border-transparent transition duration-300',
'group relative flex cursor-pointer items-stretch border border-transparent bg-black outline-none transition duration-300',
{
'rounded overflow-hidden border-primary-light': isActive,
'border-primary-light overflow-hidden rounded': isActive,
}
)}
onMouseEnter={onMouseEnter}
@@ -45,7 +45,7 @@ const SegmentationItem = ({
>
<div
className={classnames(
'text-center flex items-center justify-center w-6 h-auto text-base transition duration-300',
'flex h-auto w-6 items-center justify-center text-center text-base transition duration-300',
{
'bg-primary-light text-black': isActive,
'bg-primary-dark text-primary-light group-hover:bg-secondary-main': !isActive,
@@ -55,13 +55,10 @@ const SegmentationItem = ({
{isHovering ? (
<Icon
name="close"
className={classnames(
'w-[10px] transition duration-500 text-center hover:opacity-80',
{
'bg-primary-light text-black': isActive,
'bg-primary-dark text-primary-light group-hover:bg-secondary-main': !isActive,
}
)}
className={classnames('w-[10px] text-center transition duration-500 hover:opacity-80', {
'bg-primary-light text-black': isActive,
'bg-primary-dark text-primary-light group-hover:bg-secondary-main': !isActive,
})}
onClick={e => {
e.stopPropagation();
onDelete(id);
@@ -71,22 +68,22 @@ const SegmentationItem = ({
<span>{index}</span>
)}
</div>
<div className="relative flex flex-col w-full p-1">
<div className="flex items-center ml-2">
<div className="flex flex-1 text-base text-primary-light">
<div className="relative flex w-full flex-col p-1">
<div className="ml-2 flex items-center">
<div className="text-primary-light flex flex-1 text-base">
<div
className="w-3 h-3 mt-1 mr-2 rounded-full"
className="mt-1 mr-2 h-3 w-3 rounded-full"
style={{ backgroundColor: 'red' }}
></div>
{label}
</div>
<div className="flex items-center w-1/4">
<div className="flex w-1/4 items-center">
<div>
<Icon
className={classnames(
'text-white w-3 absolute cursor-pointer transition duration-300 hover:opacity-80',
{ 'invisible opacity-0 mr-2': !isActive && !isHovering },
{ 'visible opacity-1': !isActive && isHovering }
'absolute w-3 cursor-pointer text-white transition duration-300 hover:opacity-80',
{ 'invisible mr-2 opacity-0': !isActive && !isHovering },
{ 'opacity-1 visible': !isActive && isHovering }
)}
name="pencil"
style={{
@@ -100,7 +97,7 @@ const SegmentationItem = ({
<div>
<Icon
className={classnames(
'text-white w-4 cursor-pointer transition duration-300 hover:opacity-80'
'w-4 cursor-pointer text-white transition duration-300 hover:opacity-80'
)}
name={isVisible ? 'eye-visible' : 'eye-hidden'}
onClick={e => {
@@ -117,7 +114,7 @@ const SegmentationItem = ({
displayText.map(line => (
<span
key={line}
className="pl-2 text-base text-white border-l border-primary-light"
className="border-primary-light border-l pl-2 text-base text-white"
>
{line}
</span>
@@ -129,10 +126,7 @@ const SegmentationItem = ({
};
SegmentationItem.propTypes = {
id: PropTypes.oneOfType([
PropTypes.number.isRequired,
PropTypes.string.isRequired,
]),
id: PropTypes.oneOfType([PropTypes.number.isRequired, PropTypes.string.isRequired]),
index: PropTypes.number.isRequired,
label: PropTypes.string,
displayText: PropTypes.arrayOf(PropTypes.string),
@@ -27,9 +27,7 @@ const SegmentationTable = ({
// if there is set all to invisible state
if (visibleSegmentationsIds.length > 0) {
// make all invisible
setHiddenSegmentationIds(
segmentations.map(segmentation => segmentation.id)
);
setHiddenSegmentationIds(segmentations.map(segmentation => segmentation.id));
// toggle those that are visible
onToggleVisibilityAll(visibleSegmentationsIds);
@@ -49,20 +47,18 @@ const SegmentationTable = ({
return (
<div>
<div className="flex justify-between px-2 py-1 bg-secondary-main">
<span className="text-base font-bold tracking-widest text-white uppercase">
{title}
</span>
<div className="bg-secondary-main flex justify-between px-2 py-1">
<span className="text-base font-bold uppercase tracking-widest text-white">{title}</span>
<div className="flex">
<span className="text-base font-bold text-white">{amount}</span>
<Icon
name="eye-hidden"
className="w-6 ml-2 text-white transition duration-300 cursor-pointer hover:opacity-80"
className="ml-2 w-6 cursor-pointer text-white transition duration-300 hover:opacity-80"
onClick={() => handleToggleAll()}
/>
</div>
</div>
<div className="overflow-x-hidden overflow-y-auto ohif-scrollbar max-h-64">
<div className="ohif-scrollbar max-h-64 overflow-y-auto overflow-x-hidden">
{!!segmentations.length &&
segmentations.map((segmentation, i) => {
const { id, label, displayText = [] } = segmentation;
@@ -8,10 +8,13 @@ export const argTypes = {
title: 'Components/SegmentationTable',
};
<Meta title="Components/SegmentationTable" component={SegmentationTable} />
<Meta
title="Components/SegmentationTable"
component={SegmentationTable}
/>
export const SegmentationTableTemplate = args => (
<div className="w-64 h-96 bg-primary-dark">
<div className="bg-primary-dark h-96 w-64">
<SegmentationTable {...args} />
</div>
);
+5 -4
View File
@@ -1,5 +1,5 @@
.customSelect__wrapper .customSelect__control {
@apply bg-black border-primary-main shadow transition duration-300 border rounded w-full text-sm text-white leading-tight;
@apply border-primary-main w-full rounded border bg-black text-sm leading-tight text-white shadow transition duration-300;
min-height: 33px;
}
.customSelect__wrapper .customSelect__control:hover {
@@ -40,11 +40,11 @@
}
.customSelect__wrapper.customSelect--is-disabled {
@apply cursor-not-allowed pointer-events-auto;
@apply pointer-events-auto cursor-not-allowed;
}
.customSelect__wrapper .customSelect__value-container--is-multi {
@apply px-3 py-2 inline-block truncate;
@apply inline-block truncate px-3 py-2;
}
.customSelect__menu {
@@ -73,7 +73,8 @@
background-color: #0944b391 !important;
}
.ohif-select .customSelect__option, .ohif-select .customSelect__option label {
.ohif-select .customSelect__option,
.ohif-select .customSelect__option label {
color: #d6d6d6;
font-size: 14px;
display: flex;
+8 -13
View File
@@ -22,14 +22,17 @@ const Option = props => {
return (
<components.Option {...props}>
<div className="flex items-center">
<div className="w-2 h-2">
<div className="h-2 w-2">
{props.isSelected ? (
<Icon name={'checkbox-active'} />
) : (
<Icon name={'checkbox-default'} />
)}
</div>
<label id={props.data.value} className="ml-3 mt-1">
<label
id={props.data.value}
className="ml-3 mt-1"
>
<span>{props.value}</span>
</label>
</div>
@@ -58,9 +61,7 @@ const Select = ({
IndicatorSeparator: () => null,
};
let _components = isMulti ? { Option, MultiValue } : {};
_components = noIcons
? { ..._components, ..._noIconComponents }
: _components;
_components = noIcons ? { ..._components, ..._noIconComponents } : _components;
const selectedOptions = [];
// Map array of values to an array of selected options
@@ -76,10 +77,7 @@ const Select = ({
return (
<ReactSelect
inputId={`input-${id}`}
className={classnames(
className,
'ohif-select flex flex-col flex-1 customSelect__wrapper'
)}
className={classnames(className, 'ohif-select customSelect__wrapper flex flex-1 flex-col')}
data-cy={`input-${id}`}
classNamePrefix="customSelect"
isDisabled={isDisabled}
@@ -134,10 +132,7 @@ Select.propTypes = {
})
),
placeholder: PropTypes.string,
value: PropTypes.oneOfType([
PropTypes.arrayOf(PropTypes.string),
PropTypes.any,
]),
value: PropTypes.oneOfType([PropTypes.arrayOf(PropTypes.string), PropTypes.any]),
};
export default Select;
@@ -2,13 +2,7 @@ import classnames from 'classnames';
import PropTypes from 'prop-types';
import React, { useCallback, useEffect, useRef, useState } from 'react';
import { useTranslation } from 'react-i18next';
import SwiperCore, {
A11y,
Controller,
Navigation,
Pagination,
Scrollbar,
} from 'swiper';
import SwiperCore, { A11y, Controller, Navigation, Pagination, Scrollbar } from 'swiper';
import { Swiper, SwiperSlide } from 'swiper/react';
import { PanelService, ServicesManager, Types } from '@ohif/core';
@@ -84,9 +78,7 @@ const SidePanel = ({
// Tracks whether this SidePanel has been opened at least once since this SidePanel was inserted into the DOM.
// Thus going to the Study List page and back to the viewer resets this flag for a SidePanel.
const [hasBeenOpened, setHasBeenOpened] = useState(
activeTabIndexProp !== null
);
const [hasBeenOpened, setHasBeenOpened] = useState(activeTabIndexProp !== null);
const [panelOpen, setPanelOpen] = useState(activeTabIndexProp !== null);
const [activeTabIndex, setActiveTabIndex] = useState(activeTabIndexProp ?? 0);
const swiperRef = useRef() as any;
@@ -136,9 +128,7 @@ const SidePanel = ({
panelService.EVENTS.ACTIVATE_PANEL,
(activatePanelEvent: Types.ActivatePanelEvent) => {
if (!hasBeenOpened || activatePanelEvent.forceActive) {
const tabIndex = tabs.findIndex(
tab => tab.id === activatePanelEvent.panelId
);
const tabIndex = tabs.findIndex(tab => tab.id === activatePanelEvent.panelId);
if (tabIndex !== -1) {
updateActiveTabIndex(tabIndex);
}
@@ -158,8 +148,8 @@ const SidePanel = ({
<>
<div
className={classnames(
'bg-secondary-dark h-[28px] flex items-center w-full rounded-md cursor-pointer',
side === 'left' ? 'pr-2 justify-end' : 'pl-2 justify-start'
'bg-secondary-dark flex h-[28px] w-full cursor-pointer items-center rounded-md',
side === 'left' ? 'justify-end pr-2' : 'justify-start pl-2'
)}
onClick={() => {
updatePanelOpen(prev => !prev);
@@ -168,13 +158,10 @@ const SidePanel = ({
>
<Icon
name={'navigation-panel-right-reveal'}
className={classnames(
'text-primary-active',
side === 'left' && 'transform rotate-180'
)}
className={classnames('text-primary-active', side === 'left' && 'rotate-180 transform')}
/>
</div>
<div className={classnames('flex flex-col space-y-3 mt-3')}>
<div className={classnames('mt-3 flex flex-col space-y-3')}>
{_childComponents.map((childComponent, index) => (
<Tooltip
position={side === 'left' ? 'right' : 'left'}
@@ -213,11 +200,7 @@ const SidePanel = ({
return (
<div
className={classnames(
className,
baseClasses,
classesMap[openStatus][side]
)}
className={classnames(className, baseClasses, classesMap[openStatus][side])}
style={style}
>
{panelOpen ? (
@@ -225,7 +208,7 @@ const SidePanel = ({
{/** Panel Header with Arrow and Close Actions */}
<div
className={classnames(
'flex flex-static px-[10px] bg-primary-dark h-9 cursor-pointer',
'flex-static bg-primary-dark flex h-9 cursor-pointer px-[10px]',
tabs.length === 1 && 'mb-1'
)}
onClick={() => {
@@ -240,7 +223,7 @@ const SidePanel = ({
color="inherit"
border="none"
rounded="none"
className="flex flex-row flex-static items-center px-3 relative w-full"
className="flex-static relative flex w-full flex-row items-center px-3"
name={tabs.length === 1 ? `${tabs[activeTabIndex].name}` : ''}
>
<Icon
@@ -270,14 +253,20 @@ const SidePanel = ({
{/** carousel navigation with the arrows */}
{/** only show carousel nav if tabs are more than 3 tabs */}
{tabs.length > 3 && (
<div className="text-primary-active w-full flex justify-end gap-2 bg-primary-dark py-1 px-2">
<button ref={prevRef} className="swiper-button-prev-custom">
<div className="text-primary-active bg-primary-dark flex w-full justify-end gap-2 py-1 px-2">
<button
ref={prevRef}
className="swiper-button-prev-custom"
>
<Icon
name={'icon-prev'}
className={classnames('text-primary-active')}
/>
</button>
<button ref={nextRef} className="swiper-button-next-custom">
<button
ref={nextRef}
className="swiper-button-next-custom"
>
<Icon
name={'icon-next'}
className={classnames('text-primary-active')}
@@ -351,10 +340,8 @@ function _getMoreThanOneTabLayout(
<SwiperSlide key={index}>
<div
className={classnames(
index === activeTabIndex
? 'bg-secondary-main text-white'
: 'text-aqua-pale',
'flex cursor-pointer px-4 py-1 rounded-[4px] flex-col justify-center items-center text-center hover:text-white'
index === activeTabIndex ? 'bg-secondary-main text-white' : 'text-aqua-pale',
'flex cursor-pointer flex-col items-center justify-center rounded-[4px] px-4 py-1 text-center hover:text-white'
)}
key={index}
onClick={() => {
@@ -366,9 +353,7 @@ function _getMoreThanOneTabLayout(
<Icon
name={obj.iconName}
className={classnames(
index === activeTabIndex
? 'text-white'
: 'text-primary-active'
index === activeTabIndex ? 'text-white' : 'text-primary-active'
)}
style={{
width: '22px',
@@ -376,7 +361,7 @@ function _getMoreThanOneTabLayout(
}}
/>
</span>
<span className="text-[10px] select-none font-medium whitespace-nowrap mt-[5px]">
<span className="mt-[5px] select-none whitespace-nowrap text-[10px] font-medium">
{obj.label}
</span>
</div>
@@ -8,7 +8,10 @@ export const argTypes = {
title: 'Components/SidePanel',
};
<Meta title="Components/SidePanel" component={SidePanel} />
<Meta
title="Components/SidePanel"
component={SidePanel}
/>
export const SidePanelTemplate = args => (
<div className="w-96">
@@ -16,7 +19,10 @@ export const SidePanelTemplate = args => (
</div>
);
<Heading title="SidePanel" componentRelativePath="SidePanel/SidePanel.tsx" />
<Heading
title="SidePanel"
componentRelativePath="SidePanel/SidePanel.tsx"
/>
- [Overview](#overview)
- [Props](#props)
@@ -40,7 +46,7 @@ SidePanel is a component that renders the SidePanels.
iconName: 'group-layers',
iconLabel: 'group-layers',
content: () => <div class="text-primary-light p-3">Hello</div>,
}
},
],
childComponents: [
{
@@ -44,9 +44,11 @@
.sb-item {
animation: fadein 1s;
box-shadow: 0 6px 10px 0 rgba(0, 0, 0, 0.2), 0 1px 18px 0 rgba(0, 0, 0, 0.12),
box-shadow:
0 6px 10px 0 rgba(0, 0, 0, 0.2),
0 1px 18px 0 rgba(0, 0, 0, 0.12),
0 3px 5px -1px rgba(0, 0, 0, 0.14);
@apply relative p-3 text-white overflow-hidden rounded-md transition-height ease-in-out duration-300;
@apply transition-height relative overflow-hidden rounded-md p-3 text-white duration-300 ease-in-out;
}
@keyframes fadein {
@@ -55,7 +57,7 @@
@apply opacity-0;
}
to {
@apply opacity-100 top-0;
@apply top-0 opacity-100;
}
}
@@ -8,7 +8,11 @@ const SnackbarContainer = () => {
const { snackbarItems, hide } = useSnackbar();
const renderItem = item => (
<SnackbarItem key={item.itemId} options={item} onClose={hide} />
<SnackbarItem
key={item.itemId}
options={item}
onClose={hide}
/>
);
const renderItems = () => {
@@ -33,7 +37,7 @@ const SnackbarContainer = () => {
return (
<div
key={pos}
className={`fixed z-50 p-6 box-border h-auto sb-${pos}`}
className={`fixed z-50 box-border h-auto p-6 sb-${pos}`}
>
{items[pos].map((item, index) => (
<div key={item.id + index}>{renderItem(item)}</div>
@@ -27,36 +27,34 @@ const SnackbarItem = ({ options, onClose }) => {
[SnackbarTypes.ERROR]: 'bg-[#dabdbe]',
};
const hidden =
'duration-300 transition-all ease-in-out h-0 opacity-0 pt-0 mb-0 pb-0';
const hidden = 'duration-300 transition-all ease-in-out h-0 opacity-0 pt-0 mb-0 pb-0';
return (
<div
className={classNames(
`${options.visible ? '' : hidden} sb-item`,
typeClasses[options.type]
)}
className={classNames(`${options.visible ? '' : hidden} sb-item`, typeClasses[options.type])}
>
<div className="flex">
<Icon name={iconClasses[options.type]} className="w-5 h-5 mt-[1px]" />
<div className="flex-col mx-2">
<Icon
name={iconClasses[options.type]}
className="mt-[1px] h-5 w-5"
/>
<div className="mx-2 flex-col">
{/* </span> */}
{options.title && (
<div className="break-normal text-lg font-bold text-black">
{options.title}
</div>
<div className="break-normal text-lg font-bold text-black">{options.title}</div>
)}
{options.message && (
<div className="break-normal text-base text-black">
{options.message}
</div>
<div className="break-normal text-base text-black">{options.message}</div>
)}
</div>
<div
onClick={handleClose}
className="w-5 h-5 rounded-full flex items-center justify-center self-start ml-auto relative left-[3px] top-[-3px] text-[#0944b3]"
className="relative left-[3px] top-[-3px] ml-auto flex h-5 w-5 items-center justify-center self-start rounded-full text-[#0944b3]"
>
<Icon name="close" className="text-black" />
<Icon
name="close"
className="text-black"
/>
</div>
</div>
</div>
@@ -10,8 +10,7 @@ import ListMenu from '../ListMenu';
import ToolbarButton from '../ToolbarButton';
const baseClasses = {
Button:
'flex items-center rounded-md border-transparent cursor-pointer group/button',
Button: 'flex items-center rounded-md border-transparent cursor-pointer group/button',
Primary:
// By default border on left, top and bottom for hover effect and only rounded on left side.
// Extra padding on right to componensate for no right border.
@@ -27,9 +26,7 @@ const classes = {
Button: ({ isExpanded, primary }) =>
classNames(
baseClasses.Button,
!isExpanded &&
!primary.isActive &&
'hover:!bg-primary-dark hover:border-primary-dark'
!isExpanded && !primary.isActive && 'hover:!bg-primary-dark hover:border-primary-dark'
),
Interface: 'h-full flex flex-row items-center',
Primary: ({ primary, isExpanded }) =>
@@ -64,19 +61,14 @@ const classes = {
SecondaryIcon: ({ isExpanded }) =>
classNames(
baseClasses.SecondaryIcon,
isExpanded
? 'text-primary-dark'
: 'text-[#348cfd] group-hover/secondary:text-primary-light'
isExpanded ? 'text-primary-dark' : 'text-[#348cfd] group-hover/secondary:text-primary-light'
),
Separator: ({ primary, isExpanded, isHovering }) =>
classNames(
baseClasses.Separator,
isHovering || isExpanded || primary.isActive
? 'border-transparent'
: 'border-primary-active'
isHovering || isExpanded || primary.isActive ? 'border-transparent' : 'border-primary-active'
),
Content: ({ isExpanded }) =>
classNames(baseClasses.Content, isExpanded ? 'block' : 'hidden'),
Content: ({ isExpanded }) => classNames(baseClasses.Content, isExpanded ? 'block' : 'hidden'),
};
const SplitButton = ({
@@ -136,12 +128,9 @@ const SplitButton = ({
const onSecondaryClickHandler = () =>
setState(state => ({ ...state, isExpanded: !state.isExpanded }));
const onMouseEnterHandler = () =>
setState(state => ({ ...state, isHovering: true }));
const onMouseLeaveHandler = () =>
setState(state => ({ ...state, isHovering: false }));
const outsideClickHandler = () =>
setState(state => ({ ...state, isExpanded: false }));
const onMouseEnterHandler = () => setState(state => ({ ...state, isHovering: true }));
const onMouseLeaveHandler = () => setState(state => ({ ...state, isHovering: false }));
const outsideClickHandler = () => setState(state => ({ ...state, isExpanded: false }));
const isPrimaryToggle = state.primary.type === 'toggle';
const isPrimaryActive =
@@ -149,8 +138,7 @@ const SplitButton = ({
(isPrimaryToggle && toggles[state.primary.id] === true);
const PrimaryButtonComponent =
toolbarService?.getButtonComponentForUIType(state.primary.uiType) ??
ToolbarButton;
toolbarService?.getButtonComponentForUIType(state.primary.uiType) ?? ToolbarButton;
const primaryButtonClassName = classes.Primary({
...state,
@@ -163,8 +151,8 @@ const SplitButton = ({
return (
<div
className={classNames(
'flex flex-row items-center p-3 h-8 w-full hover:bg-primary-dark',
'text-base whitespace-pre',
'hover:bg-primary-dark flex h-8 w-full flex-row items-center p-3',
'whitespace-pre text-base',
isActive && 'bg-primary-dark',
isActive
? 'text-[#348CFD]'
@@ -173,7 +161,10 @@ const SplitButton = ({
>
{icon && (
<span className="mr-4">
<Icon name={icon} className="w-5 h-5" />
<Icon
name={icon}
className="h-5 w-5"
/>
</span>
)}
<span className="mr-5">{t(label)}</span>
@@ -188,7 +179,10 @@ const SplitButton = ({
onOutsideClick={outsideClickHandler}
disabled={!state.isExpanded}
>
<div name="SplitButton" className="relative">
<div
name="SplitButton"
className="relative"
>
<div
className={classes.Button({
...state,
@@ -8,10 +8,13 @@ export const argTypes = {
title: 'Components/SplitButton',
};
<Meta title="Components/SplitButton" component={SplitButton} />
<Meta
title="Components/SplitButton"
component={SplitButton}
/>
export const SplitButtonTemplate = args => (
<div className="h-32 bg-primary-dark">
<div className="bg-primary-dark h-32">
<SplitButton {...args} />
</div>
);
@@ -37,14 +37,7 @@ const StudyBrowser = ({
const getTabContent = () => {
const tabData = tabs.find(tab => tab.name === activeTabName);
return tabData.studies.map(
({
studyInstanceUid,
date,
description,
numInstances,
modalities,
displaySets,
}) => {
({ studyInstanceUid, date, description, numInstances, modalities, displaySets }) => {
const isExpanded = expandedStudyInstanceUIDs.includes(studyInstanceUid);
return (
<React.Fragment key={studyInstanceUid}>
@@ -78,11 +71,15 @@ const StudyBrowser = ({
return (
<React.Fragment>
<div
className="flex flex-row items-center justify-center h-16 p-4 border-b w-100 border-secondary-light bg-primary-dark"
className="w-100 border-secondary-light bg-primary-dark flex h-16 flex-row items-center justify-center border-b p-4"
data-cy={'studyBrowser-panel'}
>
{/* TODO Revisit design of ButtonGroup later - for now use LegacyButton for its children.*/}
<ButtonGroup variant="outlined" color="secondary" splitBorder={false}>
<ButtonGroup
variant="outlined"
color="secondary"
splitBorder={false}
>
{tabs.map(tab => {
const { name, label, studies } = tab;
const isActive = activeTabName === name;
@@ -98,7 +95,7 @@ const StudyBrowser = ({
return (
<LegacyButton
key={name}
className={'text-white text-base p-2 min-w-18'}
className={'min-w-18 p-2 text-base text-white'}
size="initial"
color={color}
bgColor={isActive ? 'bg-primary-main' : 'bg-black'}
@@ -113,7 +110,7 @@ const StudyBrowser = ({
})}
</ButtonGroup>
</div>
<div className="flex flex-col flex-1 overflow-auto ohif-scrollbar invisible-scrollbar">
<div className="ohif-scrollbar invisible-scrollbar flex flex-1 flex-col overflow-auto">
{getTabContent()}
</div>
</React.Fragment>
@@ -149,11 +146,8 @@ StudyBrowser.propTypes = {
seriesNumber: StringNumber,
numInstances: PropTypes.number,
description: PropTypes.string,
componentType: PropTypes.oneOf([
'thumbnail',
'thumbnailTracked',
'thumbnailNoImage',
]).isRequired,
componentType: PropTypes.oneOf(['thumbnail', 'thumbnailTracked', 'thumbnailNoImage'])
.isRequired,
isTracked: PropTypes.bool,
viewportIdentificator: PropTypes.arrayOf(PropTypes.string),
/**
@@ -8,7 +8,10 @@ export const argTypes = {
title: 'Components/StudyBrowser',
};
<Meta title="Components/StudyBrowser" component={StudyBrowser} />
<Meta
title="Components/StudyBrowser"
component={StudyBrowser}
/>
export const StudyBrowserTemplate = args => (
<div className="w-96">
@@ -76,8 +79,7 @@ With Studies
label: 'Primary',
studies: [
{
studyInstanceUid:
'1.3.6.1.4.1.25403.345050719074.3824.20170126085406.1',
studyInstanceUid: '1.3.6.1.4.1.25403.345050719074.3824.20170126085406.1',
date: '26-Oct-2015',
description: 'CT CHEST W CONTRAST',
modalities: 'CT',
@@ -90,13 +92,11 @@ With Studies
modality: 'CT',
seriesDate: '26-Oct-2015',
numInstances: 1,
StudyInstanceUID:
'1.3.6.1.4.1.25403.345050719074.3824.20170126085406.1',
StudyInstanceUID: '1.3.6.1.4.1.25403.345050719074.3824.20170126085406.1',
componentType: 'thumbnailTracked',
dragData: {
type: 'displayset',
displaySetInstanceUID:
'0b66675a-a4e3-a718-21f4-035d2d178d62',
displaySetInstanceUID: '0b66675a-a4e3-a718-21f4-035d2d178d62',
},
isTracked: false,
viewportIdentificator: [],
@@ -19,7 +19,7 @@ const StudyItem = ({
return (
<div
className={classnames(
isActive ? 'bg-secondary-dark' : 'bg-black hover:bg-secondary-main',
isActive ? 'bg-secondary-dark' : 'hover:bg-secondary-main bg-black',
baseClasses
)}
onClick={onClick}
@@ -27,32 +27,36 @@ const StudyItem = ({
role="button"
tabIndex="0"
>
<div className="flex flex-col flex-1 px-4 pb-2">
<div className="flex flex-1 flex-col px-4 pb-2">
<div className="flex flex-row items-center justify-between pt-2 pb-2">
<div className="text-base text-white">{date}</div>
<div className="flex flex-row items-center text-base text-blue-300">
<Icon name="group-layers" className="w-4 mx-2 text-blue-300" />
<Icon
name="group-layers"
className="mx-2 w-4 text-blue-300"
/>
{numInstances}
</div>
</div>
<div className="flex flex-row py-1">
<div className="pr-5 text-xl text-blue-300">{modalities}</div>
<div className="text-base text-blue-300 break-words truncate-2-lines">
{description}
</div>
<div className="truncate-2-lines break-words text-base text-blue-300">{description}</div>
</div>
</div>
{!!trackedSeries && (
<div className="flex flex-2">
<div className="flex-2 flex">
<div
className={classnames(
'flex flex-row bg-secondary-main text-base text-white py-1 pl-2 pr-4 mt-2 ',
'bg-secondary-main mt-2 flex flex-row py-1 pl-2 pr-4 text-base text-white ',
isActive
? 'flex-1 border-t border-secondary-light justify-center'
: 'rounded-sm mx-4 mb-4'
? 'border-secondary-light flex-1 justify-center border-t'
: 'mx-4 mb-4 rounded-sm'
)}
>
<Icon name="tracked" className="w-4 mr-2 text-primary-light" />
<Icon
name="tracked"
className="text-primary-light mr-2 w-4"
/>
{trackedSeries} Tracked Series
</div>
</div>
@@ -8,7 +8,10 @@ export const argTypes = {
title: 'Components/StudyItem',
};
<Meta title="Components/StudyItem" component={StudyItem} />
<Meta
title="Components/StudyItem"
component={StudyItem}
/>
export const StudyItemTemplate = args => (
<div className="w-96">
@@ -16,7 +19,10 @@ export const StudyItemTemplate = args => (
</div>
);
<Heading title="StudyItem" componentRelativePath="StudyItem/StudyItem.tsx" />
<Heading
title="StudyItem"
componentRelativePath="StudyItem/StudyItem.tsx"
/>
- [Overview](#overview)
- [Props](#props)
@@ -8,11 +8,7 @@ import TableBody from '../TableBody';
import TableRow from '../TableRow';
import TableCell from '../TableCell';
const StudyListExpandedRow = ({
seriesTableColumns,
seriesTableDataSource,
children,
}) => {
const StudyListExpandedRow = ({ seriesTableColumns, seriesTableDataSource, children }) => {
const { t } = useTranslation('StudyList');
return (
@@ -23,11 +19,7 @@ const StudyListExpandedRow = ({
<TableHead>
<TableRow>
{Object.keys(seriesTableColumns).map(columnKey => {
return (
<TableCell key={columnKey}>
{t(seriesTableColumns[columnKey])}
</TableCell>
);
return <TableCell key={columnKey}>{t(seriesTableColumns[columnKey])}</TableCell>;
})}
</TableRow>
</TableHead>
@@ -38,7 +30,10 @@ const StudyListExpandedRow = ({
{Object.keys(row).map(cellKey => {
const content = row[cellKey];
return (
<TableCell key={cellKey} className="truncate">
<TableCell
key={cellKey}
className="truncate"
>
{content}
</TableCell>
);
@@ -13,8 +13,7 @@ export const argTypes = {
component={StudyListExpandedRow}
/>
export const StudyListExpandedRowTemplate =
createComponentTemplate(StudyListExpandedRow);
export const StudyListExpandedRowTemplate = createComponentTemplate(StudyListExpandedRow);
<Heading
title="StudyListExpandedRow"
@@ -32,17 +32,19 @@ const StudyListFilter = ({
<React.Fragment>
<div>
<div className="bg-black">
<div className="container relative flex flex-col pt-5 mx-auto">
<div className="flex flex-row justify-between mb-5">
<div className="flex flex-row items-center gap-6 shrink min-w-[1px]">
<Typography variant="h6" className="text-white">
<div className="container relative mx-auto flex flex-col pt-5">
<div className="mb-5 flex flex-row justify-between">
<div className="flex min-w-[1px] shrink flex-row items-center gap-6">
<Typography
variant="h6"
className="text-white"
>
{t('StudyList')}
</Typography>
{getDataSourceConfigurationComponent &&
getDataSourceConfigurationComponent()}
{getDataSourceConfigurationComponent && getDataSourceConfigurationComponent()}
{onUploadClick && (
<div
className="flex items-center gap-2 cursor-pointer text-primary-active text-lg self-center font-semibold"
className="text-primary-active flex cursor-pointer items-center gap-2 self-center text-lg font-semibold"
onClick={onUploadClick}
>
<Icon name="icon-upload"></Icon>
@@ -74,7 +76,7 @@ const StudyListFilter = ({
</Typography>
<Typography
variant="h6"
className="self-end pb-1 text-primary-light"
className="text-primary-light self-end pb-1"
>
{t('Studies')}
</Typography>
@@ -83,8 +85,8 @@ const StudyListFilter = ({
</div>
</div>
</div>
<div className="sticky z-10 border-b-4 border-black -top-1 mx-auto">
<div className="pt-3 pb-3 bg-primary-dark">
<div className="sticky -top-1 z-10 mx-auto border-b-4 border-black">
<div className="bg-primary-dark pt-3 pb-3">
<InputGroup
inputMeta={filtersMeta}
values={filterValues}
@@ -96,10 +98,8 @@ const StudyListFilter = ({
</div>
{numOfStudies > 100 && (
<div className="container m-auto">
<div className="py-1 text-base text-center rounded-b bg-primary-main">
<p className="text-white">
{t('NumOfStudiesHiggerThan100Message')}
</p>
<div className="bg-primary-main rounded-b py-1 text-center text-base">
<p className="text-white">{t('NumOfStudiesHiggerThan100Message')}</p>
</div>
</div>
)}
@@ -116,12 +116,10 @@ StudyListFilter.propTypes = {
/** Friendly label for filter field */
displayName: PropTypes.string.isRequired,
/** One of the supported filter field input types */
inputType: PropTypes.oneOf(['Text', 'MultiSelect', 'DateRange', 'None'])
.isRequired,
inputType: PropTypes.oneOf(['Text', 'MultiSelect', 'DateRange', 'None']).isRequired,
isSortable: PropTypes.bool.isRequired,
/** Size of filter field in a 12-grid system */
gridCol: PropTypes.oneOf([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12])
.isRequired,
gridCol: PropTypes.oneOf([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]).isRequired,
/** Options for a "MultiSelect" inputType */
option: PropTypes.arrayOf(
PropTypes.shape({
@@ -7,12 +7,7 @@ import ButtonGroup from '../ButtonGroup';
import Typography from '../Typography';
import Select from '../Select';
const StudyListPagination = ({
onChangePage,
currentPage,
perPage,
onChangePerPage,
}) => {
const StudyListPagination = ({ onChangePage, currentPage, perPage, onChangePerPage }) => {
const { t } = useTranslation('StudyList');
const navigateToPage = page => {
@@ -25,9 +20,7 @@ const StudyListPagination = ({
{ value: '50', label: '50' },
{ value: '100', label: '100' },
];
const [selectedRange, setSelectedRange] = useState(
ranges.find(r => r.value === perPage)
);
const [selectedRange, setSelectedRange] = useState(ranges.find(r => r.value === perPage));
const onSelectedRange = selectedRange => {
setSelectedRange(selectedRange);
onChangePerPage(selectedRange.value);
@@ -35,12 +28,12 @@ const StudyListPagination = ({
return (
<div className="bg-black py-10">
<div className="container m-auto relative px-8">
<div className="container relative m-auto px-8">
<div className="flex justify-between">
<div className="flex items-center">
<Select
id="rows-per-page"
className="relative mr-3 w-24 border-primary-main"
className="border-primary-main relative mr-3 w-24"
options={ranges}
value={selectedRange}
isMulti={false}
@@ -50,13 +43,11 @@ const StudyListPagination = ({
hideSelectedOptions={true}
onChange={onSelectedRange}
/>
<Typography className="text-base opacity-60">
{t('ResultsPerPage')}
</Typography>
<Typography className="text-base opacity-60">{t('ResultsPerPage')}</Typography>
</div>
<div className="">
<div className="flex items-center">
<Typography className="opacity-60 mr-4 text-base">
<Typography className="mr-4 text-base opacity-60">
{t('Page')} {currentPage}
</Typography>
{/* TODO Revisit design of ButtonGroup later - for now use LegacyButton for its children.*/}
@@ -6,11 +6,19 @@ import StudyListTableRow from './StudyListTableRow';
const StudyListTable = ({ tableDataSource, querying }) => {
return (
<div className="bg-black">
<div className="container m-auto relative">
<div className="container relative m-auto">
<table className="w-full text-white">
<tbody data-cy="study-list-results" data-querying={querying}>
<tbody
data-cy="study-list-results"
data-querying={querying}
>
{tableDataSource.map((tableData, i) => {
return <StudyListTableRow tableData={tableData} key={i} />;
return (
<StudyListTableRow
tableData={tableData}
key={i}
/>
);
})}
</tbody>
</table>
@@ -13,14 +13,15 @@ const StudyListTableRow = props => {
<tr className="select-none">
<td
className={classnames('border-0 p-0', {
'border-b border-secondary-light bg-primary-dark': isExpanded,
'border-secondary-light bg-primary-dark border-b': isExpanded,
})}
>
<div
className={classnames(
'w-full transition duration-300',
{
'border border-primary-light rounded overflow-hidden mb-2 hover:border-secondary-light': isExpanded,
'border-primary-light hover:border-secondary-light mb-2 overflow-hidden rounded border':
isExpanded,
},
{
'border-transparent': !isExpanded,
@@ -31,7 +32,7 @@ const StudyListTableRow = props => {
<tbody>
<tr
className={classnames(
'cursor-pointer hover:bg-secondary-main transition duration-300',
'hover:bg-secondary-main cursor-pointer transition duration-300',
{
'bg-primary-dark': !isExpanded,
},
@@ -45,8 +46,8 @@ const StudyListTableRow = props => {
<td
key={index}
className={classnames(
'px-4 py-2 text-base truncate',
{ 'border-b border-secondary-light': !isExpanded },
'truncate px-4 py-2 text-base',
{ 'border-secondary-light border-b': !isExpanded },
getGridWidthClass(gridCol) || ''
)}
style={{
@@ -58,18 +59,13 @@ const StudyListTableRow = props => {
{index === 0 && (
<div>
<Icon
name={
isExpanded ? 'chevron-down' : 'chevron-right'
}
name={isExpanded ? 'chevron-down' : 'chevron-right'}
className="mr-4 inline-flex"
/>
</div>
)}
<div
className={classnames(
{ 'overflow-hidden': true },
{ truncate: true }
)}
className={classnames({ 'overflow-hidden': true }, { truncate: true })}
>
{content}
</div>
@@ -79,7 +75,7 @@ const StudyListTableRow = props => {
})}
</tr>
{isExpanded && (
<tr className="w-full bg-black select-text max-h-0 overflow-hidden">
<tr className="max-h-0 w-full select-text overflow-hidden bg-black">
<td colSpan={row.length}>{expandedContent}</td>
</tr>
)}
@@ -6,11 +6,11 @@ const StudySummary = ({ date, modality, description }) => {
<div className="p-2">
<div className="leading-none">
<span className="mr-2 text-base text-white">{date}</span>
<span className="px-1 text-base font-bold text-black rounded-sm bg-common-bright">
<span className="bg-common-bright rounded-sm px-1 text-base font-bold text-black">
{modality}
</span>
</div>
<div className="pt-2 text-base leading-none truncate text-primary-light ellipse">
<div className="text-primary-light ellipse truncate pt-2 text-base leading-none">
{description || ''}
</div>
</div>
+1 -5
View File
@@ -13,11 +13,7 @@ const Table = ({ children, className, fullWidth, style }) => {
return (
<div
className={classnames(
classes.base,
classes.fullWidth[fullWidth],
className
)}
className={classnames(classes.base, classes.fullWidth[fullWidth], className)}
style={style}
>
{children}
@@ -5,10 +5,7 @@ import classnames from 'classnames';
const TableBody = ({ children, className, style }) => {
return (
<div
className={classnames(
'mt-2 max-h-48 overflow-y-scroll ohif-scrollbar',
className
)}
className={classnames('ohif-scrollbar mt-2 max-h-48 overflow-y-scroll', className)}
style={style}
>
{React.isValidElement(children)
@@ -26,7 +23,7 @@ TableBody.defaultProps = {
};
TableBody.propTypes = {
children: function(props, propName, componentName) {
children: function (props, propName, componentName) {
const elements = React.Children.toArray(props.children);
const isString = elements.some(child => typeof child === 'string');
@@ -36,9 +33,7 @@ TableBody.propTypes = {
);
}
const isInvalidElement = elements.some(
child => !React.isValidElement(child)
);
const isInvalidElement = elements.some(child => !React.isValidElement(child));
if (isInvalidElement) {
return new Error(
@@ -29,7 +29,7 @@ const TableCell = ({
return (
<div
className={classnames(
'px-2 last:border-r-0 break-all',
'break-all px-2 last:border-r-0',
`w-${colSpan}/${cellsNum}`,
classes.align[align],
classes.isTableHead[isTableHead],
Loaded 100 of 656 files, more files were not shown because too many files have changed in this diff. Show more