diff --git a/platform/viewer/src/App.js b/platform/viewer/src/App.js index d3941a513..9f01c3e29 100644 --- a/platform/viewer/src/App.js +++ b/platform/viewer/src/App.js @@ -9,7 +9,7 @@ import { hot } from 'react-hot-loader/root'; import OHIFCornerstoneExtension from '@ohif/extension-cornerstone'; import ToolContextMenu from './connectedComponents/ToolContextMenu'; -import LabellingManager from './components/Labelling/LabellingManager'; +import LabellingFlow from './components/Labelling/LabellingFlow'; import { SnackbarProvider, @@ -183,7 +183,7 @@ class App extends Component { > { + const [fadeOutTimer, setFadeOutTimer] = useState(); + const [showComponent, setShowComponent] = useState(true); + const descriptionInput = useRef(); + const [state, setState] = useState({ + measurementData, + editLocation, + editDescription, + skipAddLabelButton, + }); + + useEffect(() => { + const newMeasurementData = cloneDeep(measurementData); + + if (editDescription) { + newMeasurementData.description = undefined; + } + + if (editLocation) { + newMeasurementData.location = undefined; + } + + let newEditLocation = editLocation; + if (!editDescription && !editLocation) { + newEditLocation = true; + } + + setState(state => ({ + ...state, + editLocation: newEditLocation, + measurementData: newMeasurementData, + })); + }, [editDescription, editLocation, measurementData]); + + useEffect(() => { + if (descriptionInput.current) { + descriptionInput.current.focus(); + } + }, [state]); + + const relabel = event => + setState(state => ({ ...state, editLocation: true })); + + const setDescriptionUpdateMode = () => { + descriptionInput.current.focus(); + setState(state => ({ ...state, editDescription: true })); }; - constructor(props) { - super(props); + const descriptionCancel = () => { + const { description = '' } = cloneDeep(state); + descriptionInput.current.value = description; + setState(state => ({ ...state, editDescription: false })); + }; - const { location, locationLabel, description } = props.measurementData; - - this.state = { - location, - locationLabel, - description, - skipAddLabelButton: props.skipAddLabelButton, - editDescription: props.editDescription, - editLocation: props.editLocation, - confirmationState: false, - displayComponent: true, - }; - - this.mainElement = React.createRef(); - this.descriptionInput = React.createRef(); - this.initialItems = OHIFLabellingData; - this.currentItems = cloneDeep(this.initialItems); - } - - componentDidUpdate = () => { - if (this.state.editDescription) { - this.descriptionInput.current.focus(); + const handleKeyPress = event => { + if (event.key === 'Enter') { + descriptionSave(); } }; - render() { - let mainElementClassName = 'labellingComponent'; - if (this.state.editDescription) { - mainElementClassName += ' editDescription'; - } + const descriptionSave = () => { + const description = descriptionInput.current.value; + updateLabelling({ description }); - return ( - - <> -
- {this.labellingStateFragment()} -
- -
- ); - } - - labellingStateFragment = () => { - const { - skipAddLabelButton, - editLocation, + setState(state => ({ + ...state, description, - locationLabel, - } = this.state; + editDescription: false, + })); + }; + + const selectTreeSelectCallback = (event, itemSelected) => { + const location = itemSelected.value; + const locationLabel = itemSelected.label; + updateLabelling({ location }); + + setState(state => ({ + ...state, + editLocation: false, + measurementData: { + ...state.measurementData, + location, + locationLabel, + }, + })); + }; + + const showLabelling = () => { + setState(state => ({ + ...state, + skipAddLabelButton: true, + editLocation: false, + })); + }; + + /* + * Waits for 1 sec to dismiss the labelling component. + * + */ + const fadeOutAndLeave = () => + setFadeOutTimer(setTimeout(fadeOutAndLeaveFast, 1000)); + + const fadeOutAndLeaveFast = () => setShowComponent(false); + + const clearFadeOutTimer = () => { + if (fadeOutTimer) { + clearTimeout(fadeOutTimer); + setFadeOutTimer(null); + } + }; + + const descriptionDialogUpdate = description => { + updateLabelling({ description }); + labellingDoneCallback(); + }; + + const labellingStateFragment = () => { + const { skipAddLabelButton, editLocation, measurementData } = state; + const { description, locationLabel, location } = measurementData; if (!skipAddLabelButton) { return ( - <> - - + ); } else { if (editLocation) { return ( ); } else { return ( <> -
+
@@ -114,10 +167,10 @@ export default class LabellingFlow extends Component {
@@ -125,14 +178,14 @@ export default class LabellingFlow extends Component { @@ -160,77 +213,51 @@ export default class LabellingFlow extends Component { } }; - relabel = event => this.setState({ editLocation: true }); - - setDescriptionUpdateMode = () => { - this.descriptionInput.current.focus(); - this.setState({ editDescription: true }); - }; - - descriptionCancel = () => { - const { description = '' } = cloneDeep(this.state); - this.descriptionInput.current.value = description; - this.setState({ editDescription: false }); - }; - - handleKeyPress = e => { - if (e.key === 'Enter') { - this.descriptionSave(); - } - }; - - descriptionSave = () => { - const description = this.descriptionInput.current.value; - this.props.updateLabelling({ description }); - - this.setState({ - description, - editDescription: false, - }); - }; - - selectTreeSelectCallback = (event, itemSelected) => { - const location = itemSelected.value; - this.props.updateLabelling({ location }); - - this.setState({ - editLocation: false, - confirmationState: true, - location: itemSelected.value, - locationLabel: itemSelected.label, - }); - - if (this.isTouchScreen) { - this.setTimeout = setTimeout(() => { - this.setState({ - displayComponent: false, - }); - }, 2000); - } - }; - - showLabelling = () => { - this.setState({ - skipAddLabelButton: true, - editLocation: false, - }); - }; - - fadeOutAndLeave = () => { - // Wait for 1 sec to dismiss the labelling component - this.fadeOutTimer = setTimeout( - () => this.setState({ displayComponent: false }), - 1000 + if (editDescriptionOnDialog) { + return ( + ); - }; + } - fadeOutAndLeaveFast = () => this.setState({ displayComponent: false }); + return ( + + <> +
+ {labellingStateFragment()} +
+ +
+ ); +}; - clearFadeOutTimer = () => { - if (!this.fadeOutTimer) { - return; - } +LabellingFlow.propTypes = { + measurementData: PropTypes.object.isRequired, + labellingDoneCallback: PropTypes.func.isRequired, + updateLabelling: PropTypes.func.isRequired, + initialTopDistance: PropTypes.number, + skipAddLabelButton: PropTypes.bool, + editLocation: PropTypes.bool, + editDescription: PropTypes.bool, + editDescriptionOnDialog: PropTypes.bool, +}; - clearTimeout(this.fadeOutTimer); - }; -} +LabellingFlow.defaultProps = { + skipAddLabelButton: false, + editLocation: false, + editDescription: false, + editDescriptionOnDialog: false, +}; + +export default LabellingFlow; diff --git a/platform/viewer/src/components/Labelling/LabellingManager.js b/platform/viewer/src/components/Labelling/LabellingManager.js deleted file mode 100644 index 8b0148886..000000000 --- a/platform/viewer/src/components/Labelling/LabellingManager.js +++ /dev/null @@ -1,103 +0,0 @@ -import React, { Component } from 'react'; -import PropTypes from 'prop-types'; -import cloneDeep from 'lodash.clonedeep'; - -import EditDescriptionDialog from './../EditDescriptionDialog/EditDescriptionDialog.js'; -import LabellingFlow from './LabellingFlow.js'; -import './LabellingManager.css'; - -export default class LabellingManager extends Component { - static propTypes = { - measurementData: PropTypes.object.isRequired, - labellingDoneCallback: PropTypes.func.isRequired, - updateLabelling: PropTypes.func.isRequired, - skipAddLabelButton: PropTypes.bool, - editLocation: PropTypes.bool, - editDescription: PropTypes.bool, - editDescriptionOnDialog: PropTypes.bool, - }; - - static defaultProps = { - skipAddLabelButton: false, - editLocation: false, - editDescription: false, - editDescriptionOnDialog: false, - }; - - constructor(props) { - super(props); - - const measurementData = cloneDeep(props.measurementData); - this.treatMeasurementData(measurementData); - - let editLocation = props.editLocation; - if (!props.editDescription && !props.editLocation) { - editLocation = true; - } - - this.state = { - skipAddLabelButton: props.skipAddLabelButton, - editLocation: editLocation, - editDescription: props.editDescription, - editDescriptionOnDialog: props.editDescriptionOnDialog, - measurementData: measurementData, - }; - } - - componentDidMount = () => { - document.addEventListener('touchstart', this.onTouchStart); - }; - - componentWillUnmount = () => { - document.removeEventListener('touchstart', this.onTouchStart); - }; - - render() { - return this.getRenderComponent(); - } - - getRenderComponent = () => { - const { - editLocation, - editDescription, - editDescriptionOnDialog, - measurementData, - } = this.state; - - if (editDescriptionOnDialog) { - return ( - - ); - } - - if (editLocation || editDescription) { - return ; - } - }; - - treatMeasurementData = measurementData => { - const { editDescription, editLocation } = this.props; - - if (editDescription) { - measurementData.description = undefined; - } - - if (editLocation) { - measurementData.location = undefined; - } - }; - - responseDialogUpdate = response => { - this.props.updateLabelling({ response }); - this.props.labellingDoneCallback(); - }; - - descriptionDialogUpdate = description => { - this.props.updateLabelling({ description }); - this.props.labellingDoneCallback(); - }; -}