import React, { useEffect, useState } from 'react'; import PropTypes from 'prop-types'; import { StudySummary, MeasurementTable } from '@ohif/ui'; import { DicomMetadataStore, DICOMSR } from '@ohif/core'; import { useDebounce } from '@hooks'; import ActionButtons from './ActionButtons'; import { useTrackedMeasurements } from '../../getContextModule'; const DISPLAY_STUDY_SUMMARY_INITIAL_VALUE = { key: undefined, // date: undefined, // '07-Sep-2010', modality: undefined, // 'CT', description: undefined, // 'CHEST/ABD/PELVIS W CONTRAST', }; function PanelMeasurementTableTracking({ servicesManager, extensionManager }) { const [measurementChangeTimestamp, setMeasurementsUpdated] = useState( Date.now().toString() ); const debouncedMeasurementChangeTimestamp = useDebounce( measurementChangeTimestamp, 200 ); const { MeasurementService, UINotificationService, UIDialogService, DisplaySetService } = servicesManager.services; const [ trackedMeasurements, sendTrackedMeasurementsEvent, ] = useTrackedMeasurements(); const { trackedStudy, trackedSeries } = trackedMeasurements.context; const [displayStudySummary, setDisplayStudySummary] = useState( DISPLAY_STUDY_SUMMARY_INITIAL_VALUE ); const [displayMeasurements, setDisplayMeasurements] = useState([]); // TODO: measurements subscribtion // Initial? useEffect(() => { const measurements = MeasurementService.getMeasurements(); const filteredMeasurements = measurements.filter( m => trackedStudy === m.referenceStudyUID && trackedSeries.includes(m.referenceSeriesUID) ); const mappedMeasurements = filteredMeasurements.map((m, index) => _mapMeasurementToDisplay(m, index, MeasurementService.VALUE_TYPES) ); setDisplayMeasurements(mappedMeasurements); // eslint-ignore-next-line }, [ MeasurementService, trackedStudy, trackedSeries, debouncedMeasurementChangeTimestamp, ]); // ~~ DisplayStudySummary useEffect(() => { if (trackedMeasurements.matches('tracking')) { const StudyInstanceUID = trackedStudy; const studyMeta = DicomMetadataStore.getStudy(StudyInstanceUID); const instanceMeta = studyMeta.series[0].instances[0]; const { Modality, StudyDate, StudyDescription } = instanceMeta; if (displayStudySummary.key !== StudyInstanceUID) { setDisplayStudySummary({ key: StudyInstanceUID, date: StudyDate, // TODO: Format: '07-Sep-2010' modality: Modality, description: StudyDescription, }); } } else if (trackedStudy === '' || trackedStudy === undefined) { setDisplayStudySummary(DISPLAY_STUDY_SUMMARY_INITIAL_VALUE); } }, [displayStudySummary.key, trackedMeasurements, trackedStudy]); // TODO: Better way to consolidated, debounce, check on change? // Are we exposing the right API for measurementService? // This watches for ALL MeasurementService changes. It updates a timestamp, // which is debounced. After a brief period of inactivity, this triggers // a re-render where we grab up-to-date measurements. useEffect(() => { const added = MeasurementService.EVENTS.MEASUREMENT_ADDED; const updated = MeasurementService.EVENTS.MEASUREMENT_UPDATED; const removed = MeasurementService.EVENTS.MEASUREMENT_REMOVED; const subscriptions = []; [added, updated, removed].forEach(evt => { subscriptions.push( MeasurementService.subscribe(evt, () => { setMeasurementsUpdated(Date.now().toString()); }).unsubscribe ); }); return () => { subscriptions.forEach(unsub => { unsub(); }); }; }, [MeasurementService, sendTrackedMeasurementsEvent]); const activeMeasurementItem = 0; const exportReport = () => { const measurements = MeasurementService.getMeasurements(); const trackedMeasurements = measurements.filter( m => trackedStudy === m.referenceStudyUID && trackedSeries.includes(m.referenceSeriesUID) ); // TODO -> local download. DICOMSR.downloadReport(trackedMeasurements, dataSource); }; const createReport = async () => { const loadingDialogId = UIDialogService.create({ showOverlay: true, isDraggable: false, centralize: true, // TODO: Create a loading indicator component + zeplin design? content: () =>