feat: improve disableEditing flag (#3875)

Co-authored-by: Igor Octaviano <igoroctaviano@gmail.com>
This commit is contained in:
Pedro H. Köhler 2024-01-08 15:45:24 -03:00 committed by GitHub
parent 7d5607073d
commit 2049c0936c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 82 additions and 44 deletions

View File

@ -1,6 +1,7 @@
import * as ContextMenuItemsBuilder from './ContextMenuItemsBuilder'; import * as ContextMenuItemsBuilder from './ContextMenuItemsBuilder';
import ContextMenu from '../../../../platform/ui/src/components/ContextMenu/ContextMenu'; import ContextMenu from '../../../../platform/ui/src/components/ContextMenu/ContextMenu';
import { CommandsManager, ServicesManager, Types } from '@ohif/core'; import { CommandsManager, ServicesManager, Types } from '@ohif/core';
import { annotation as CsAnnotation } from '@cornerstonejs/tools';
import { Menu, MenuItem, Point, ContextMenuProps } from './types'; import { Menu, MenuItem, Point, ContextMenuProps } from './types';
/** /**
@ -47,6 +48,18 @@ export default class ContextMenuController {
const { event, subMenu, menuId, menus, selectorProps } = contextMenuProps; const { event, subMenu, menuId, menus, selectorProps } = contextMenuProps;
const annotationManager = CsAnnotation.state.getAnnotationManager();
const { locking } = CsAnnotation;
const targetAnnotationId = selectorProps?.nearbyToolData?.annotationUID as string;
const isLocked = locking.isAnnotationLocked(
annotationManager.getAnnotation(targetAnnotationId)
);
if (isLocked) {
console.warn('Annotation is locked.');
return;
}
console.log('Getting items from', menus); console.log('Getting items from', menus);
const items = ContextMenuItemsBuilder.getMenuItems( const items = ContextMenuItemsBuilder.getMenuItems(
selectorProps || contextMenuProps, selectorProps || contextMenuProps,

View File

@ -1,13 +1,13 @@
import { hydrateStructuredReport as baseHydrateStructuredReport } from '@ohif/extension-cornerstone-dicom-sr'; import { hydrateStructuredReport as baseHydrateStructuredReport } from '@ohif/extension-cornerstone-dicom-sr';
function hydrateStructuredReport({ servicesManager, extensionManager }, ctx, evt) { function hydrateStructuredReport({ servicesManager, extensionManager, appConfig }, ctx, evt) {
const { displaySetService } = servicesManager.services; const { displaySetService } = servicesManager.services;
const { viewportId, displaySetInstanceUID } = evt; const { viewportId, displaySetInstanceUID } = evt;
const srDisplaySet = displaySetService.getDisplaySetByUID(displaySetInstanceUID); const srDisplaySet = displaySetService.getDisplaySetByUID(displaySetInstanceUID);
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
const hydrationResult = baseHydrateStructuredReport( const hydrationResult = baseHydrateStructuredReport(
{ servicesManager, extensionManager }, { servicesManager, extensionManager, appConfig },
displaySetInstanceUID displaySetInstanceUID
); );

View File

@ -10,6 +10,7 @@ import {
} from '@ohif/ui'; } from '@ohif/ui';
import { DicomMetadataStore, utils } from '@ohif/core'; import { DicomMetadataStore, utils } from '@ohif/core';
import { useDebounce } from '@hooks'; import { useDebounce } from '@hooks';
import { useAppConfig } from '@state';
import ActionButtons from './ActionButtons'; import ActionButtons from './ActionButtons';
import { useTrackedMeasurements } from '../../getContextModule'; import { useTrackedMeasurements } from '../../getContextModule';
import debounce from 'lodash.debounce'; import debounce from 'lodash.debounce';
@ -36,6 +37,7 @@ function PanelMeasurementTableTracking({ servicesManager, extensionManager }) {
); );
const [displayMeasurements, setDisplayMeasurements] = useState([]); const [displayMeasurements, setDisplayMeasurements] = useState([]);
const measurementsPanelRef = useRef(null); const measurementsPanelRef = useRef(null);
const [appConfig] = useAppConfig();
useEffect(() => { useEffect(() => {
const measurements = measurementService.getMeasurements(); const measurements = measurementService.getMeasurements();
@ -244,20 +246,22 @@ function PanelMeasurementTableTracking({ servicesManager, extensionManager }) {
/> />
)} )}
</div> </div>
<div className="flex justify-center p-4"> {!appConfig?.disableEditing && (
<ActionButtons <div className="flex justify-center p-4">
onExportClick={exportReport} <ActionButtons
onCreateReportClick={() => { onExportClick={exportReport}
sendTrackedMeasurementsEvent('SAVE_REPORT', { onCreateReportClick={() => {
viewportId: viewportGrid.activeViewportId, sendTrackedMeasurementsEvent('SAVE_REPORT', {
isBackupSave: true, viewportId: viewportGrid.activeViewportId,
}); isBackupSave: true,
}} });
disabled={ }}
additionalFindings.length === 0 && displayMeasurementsWithoutFindings.length === 0 disabled={
} additionalFindings.length === 0 && displayMeasurementsWithoutFindings.length === 0
/> }
</div> />
</div>
)}
</> </>
); );
} }

View File

@ -4,7 +4,17 @@ import classnames from 'classnames';
import Icon from '../Icon'; import Icon from '../Icon';
const MeasurementItem = ({ uid, index, label, displayText, isActive, onClick, onEdit, item }) => { const MeasurementItem = ({
uid,
index,
label,
displayText,
isActive,
isLocked,
onClick,
onEdit,
item,
}) => {
const [isHovering, setIsHovering] = useState(false); const [isHovering, setIsHovering] = useState(false);
const onEditHandler = event => { const onEditHandler = event => {
@ -49,20 +59,22 @@ const MeasurementItem = ({ uid, index, label, displayText, isActive, onClick, on
dangerouslySetInnerHTML={{ __html: line }} dangerouslySetInnerHTML={{ __html: line }}
></span> ></span>
))} ))}
<Icon {!isLocked && (
className={classnames( <Icon
'absolute w-4 cursor-pointer text-white transition duration-300', className={classnames(
{ 'invisible mr-2 opacity-0': !isActive && !isHovering }, 'absolute w-4 cursor-pointer text-white transition duration-300',
{ 'opacity-1 visible': !isActive && isHovering } { 'invisible mr-2 opacity-0': !isActive && !isHovering },
)} { 'opacity-1 visible': !isActive && isHovering }
name="pencil" )}
style={{ name="pencil"
top: 4, style={{
right: 4, top: 4,
transform: isActive || isHovering ? '' : 'translateX(100%)', right: 4,
}} transform: isActive || isHovering ? '' : 'translateX(100%)',
onClick={onEditHandler} }}
/> onClick={onEditHandler}
/>
)}
</div> </div>
</div> </div>
); );

View File

@ -2,6 +2,7 @@ import React from 'react';
import { ServicesManager } from '@ohif/core'; import { ServicesManager } from '@ohif/core';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
import { annotation as CsAnnotation } from '@cornerstonejs/tools';
import MeasurementItem from './MeasurementItem'; import MeasurementItem from './MeasurementItem';
@ -16,6 +17,8 @@ const MeasurementTable = ({ data, title, onClick, onEdit, servicesManager }) =>
contentProps: {}, contentProps: {},
}); });
const CustomMeasurementItem = itemCustomization.content; const CustomMeasurementItem = itemCustomization.content;
const annotationManager = CsAnnotation.state.getAnnotationManager();
const { locking } = CsAnnotation;
return ( return (
<div> <div>
@ -25,19 +28,25 @@ const MeasurementTable = ({ data, title, onClick, onEdit, servicesManager }) =>
</div> </div>
<div className="ohif-scrollbar max-h-112 overflow-hidden"> <div className="ohif-scrollbar max-h-112 overflow-hidden">
{data.length !== 0 && {data.length !== 0 &&
data.map((measurementItem, index) => ( data.map((measurementItem, index) => {
<CustomMeasurementItem const isLocked = locking.isAnnotationLocked(
key={measurementItem.uid} annotationManager.getAnnotation(measurementItem.uid)
uid={measurementItem.uid} );
index={index + 1} return (
label={measurementItem.label} <CustomMeasurementItem
isActive={measurementItem.isActive} key={measurementItem.uid}
displayText={measurementItem.displayText} uid={measurementItem.uid}
item={measurementItem} index={index + 1}
onClick={onClick} label={measurementItem.label}
onEdit={onEdit} isActive={measurementItem.isActive}
/> isLocked={isLocked}
))} displayText={measurementItem.displayText}
item={measurementItem}
onClick={onClick}
onEdit={onEdit}
/>
);
})}
{data.length === 0 && ( {data.length === 0 && (
<div className="group flex cursor-default border border-transparent bg-black transition duration-300"> <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="bg-primary-dark text-primary-light group-hover:bg-secondary-main w-6 py-1 text-center text-base transition duration-300"></div>