import React, { useState, useRef, useEffect } from 'react';
import PropTypes from 'prop-types';
import classnames from 'classnames';
import { Icon, ButtonGroup, Button, Tooltip, CinePlayer } from '../';
import useOnClickOutside from '../../utils/useOnClickOutside';
const classes = {
infoHeader: 'text-base text-primary-light',
infoText: 'text-base text-white max-w-24 truncate',
firstRow: 'flex flex-col',
row: 'flex flex-col ml-4',
};
const ViewportActionBar = ({
studyData,
showNavArrows,
showCine,
cineProps,
showPatientInfo: patientInfoVisibility,
onSeriesChange,
onDoubleClick,
}) => {
const [showPatientInfo, setShowPatientInfo] = useState(patientInfoVisibility);
// TODO -> Remake this component with a bunch of generic slots that can be filled,
// Its not generic at all, isTracked etc shouldn't be parts of this component.
// It shouldn't care that a tracking mode or SR exists.
// Things like the right/left buttons should be made into smaller
// Components you can compose.
// OHIF-200 ticket.
const {
label,
isTracked,
isLocked,
modality,
studyDate,
currentSeries,
seriesDescription,
patientInformation,
} = studyData;
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
);
useEffect(() => {
if (showPatientInfo) {
clickOutsideListener.add();
} else {
clickOutsideListener.remove();
}
return () => clickOutsideListener.remove();
}, [clickOutsideListener, showPatientInfo]);
const renderIconStatus = () => {
if (modality === 'SR') {
const TooltipMessage = isLocked
? () => (
This SR is locked.
Measurements cannot be duplicated.
)
: () => This SR is unlocked.
;
return (
<>
} position="bottom-left">
SR
{isLocked && (
)}
>
);
}
const trackedIcon = isTracked ? 'tracked' : 'dotted-circle';
return (
{isTracked ? (
<>
Series is
tracked and
can be viewed in the measurement panel
>
) : (
<>
Measurements for
untracked
series will not be shown in the measurements
panel
>
)}
}
>
);
};
return (
{renderIconStatus()}
{label}
{studyDate}
S: {currentSeries}
{/* TODO:
This is tricky. Our "no-wrap" in truncate means this has a hard
length. The overflow forces ellipse. If we don't set max width
appropriately, this causes the ActionBar to overflow.
Can clean up by setting percentage widths + calc on parent
containers
*/}
{seriesDescription}
{showNavArrows && !showCine && (
onSeriesChange('left')}
>
onSeriesChange('right')}
>
)}
{showCine && !showNavArrows && (
)}
);
};
ViewportActionBar.propTypes = {
onSeriesChange: PropTypes.func.isRequired,
showNavArrows: PropTypes.bool,
showCine: PropTypes.bool,
cineProps: PropTypes.object,
showPatientInfo: PropTypes.bool,
studyData: PropTypes.shape({
label: PropTypes.string.isRequired,
isTracked: PropTypes.bool.isRequired,
isLocked: PropTypes.bool.isRequired,
studyDate: PropTypes.string.isRequired,
currentSeries: PropTypes.number.isRequired,
seriesDescription: PropTypes.string.isRequired,
modality: PropTypes.string.isRequired,
patientInformation: PropTypes.shape({
patientName: PropTypes.string.isRequired,
patientSex: PropTypes.string.isRequired,
patientAge: PropTypes.string.isRequired,
MRN: PropTypes.string.isRequired,
thickness: PropTypes.string.isRequired,
spacing: PropTypes.string.isRequired,
scanner: PropTypes.string.isRequired,
}),
}).isRequired,
};
ViewportActionBar.defaultProps = {
cineProps: {},
showCine: false,
showNavArrows: true,
showPatientInfo: false,
};
function PatientInfo({
patientName,
patientSex,
patientAge,
MRN,
thickness,
spacing,
scanner,
isOpen,
showPatientInfoRef,
}) {
while (patientAge.charAt(0) === '0') {
patientAge = patientAge.substr(1);
}
return (
{patientName}
Sex
{patientSex}
Age
{patientAge}
MRN
{MRN}
Thickness
{thickness}
Spacing
{spacing}
Scanner
{scanner}
)
}
>
);
}
export default ViewportActionBar;