Refactoring labellingflow to function component

This commit is contained in:
Igor 2019-12-10 18:08:51 -03:00
parent d128fd6bf0
commit ef611e4849

View File

@ -1,5 +1,5 @@
import { Icon, SelectTree } from '@ohif/ui'; import { Icon, SelectTree } from '@ohif/ui';
import React, { Component } from 'react'; import React, { useState, useEffect, useRef } from 'react';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import cloneDeep from 'lodash.clonedeep'; import cloneDeep from 'lodash.clonedeep';
@ -8,41 +8,30 @@ import OHIFLabellingData from './OHIFLabellingData.js';
import EditDescriptionDialog from './../EditDescriptionDialog/EditDescriptionDialog.js'; import EditDescriptionDialog from './../EditDescriptionDialog/EditDescriptionDialog.js';
import './LabellingFlow.css'; import './LabellingFlow.css';
class LabellingFlow extends Component { const LabellingFlow = ({
constructor(props) { measurementData,
super(props); editLocation,
editDescription,
skipAddLabelButton,
updateLabelling,
labellingDoneCallback,
editDescriptionOnDialog,
}) => {
const [fadeOutTimer, setFadeOutTimer] = useState();
const [showComponent, setShowComponent] = useState(true);
const descriptionInput = useRef();
const [state, setState] = useState({
measurementData,
editLocation,
editDescription,
skipAddLabelButton,
});
const newMeasurementData = cloneDeep(props.measurementData); const initialItems = OHIFLabellingData;
this.treatMeasurementData(newMeasurementData); const currentItems = cloneDeep(initialItems);
let newEditLocation = props.editLocation;
if (!props.editDescription && !props.editLocation) {
newEditLocation = true;
}
this.state = {
measurementData: newMeasurementData,
skipAddLabelButton: props.skipAddLabelButton,
editDescription: props.editDescription,
editLocation: newEditLocation,
confirmationState: false,
displayComponent: true,
};
this.descriptionInput = React.createRef();
this.initialItems = OHIFLabellingData;
this.currentItems = cloneDeep(this.initialItems);
}
componentDidUpdate = () => {
if (this.state.editDescription) {
this.descriptionInput.current.focus();
}
};
treatMeasurementData = measurementData => {
const { editDescription, editLocation } = this.props;
useEffect(() => {
const treatMeasurementData = measurementData => {
if (editDescription) { if (editDescription) {
measurementData.description = undefined; measurementData.description = undefined;
} }
@ -52,43 +41,107 @@ class LabellingFlow extends Component {
} }
}; };
descriptionDialogUpdate = description => { const newMeasurementData = cloneDeep(measurementData);
this.props.updateLabelling({ description }); treatMeasurementData(newMeasurementData);
this.props.labellingDoneCallback();
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 }));
}; };
render() { const descriptionCancel = () => {
if (this.props.editDescriptionOnDialog) { const { description = '' } = cloneDeep(state);
return ( descriptionInput.current.value = description;
<EditDescriptionDialog setState(state => ({ ...state, editDescription: false }));
onCancel={this.props.labellingDoneCallback} };
onUpdate={this.descriptionDialogUpdate}
measurementData={this.state.measurementData} const handleKeyPress = e => {
/> if (e.key === 'Enter') {
); descriptionSave();
}
};
const descriptionSave = () => {
const description = descriptionInput.current.value;
updateLabelling({ description });
setState(state => ({
...state,
description,
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(() => setShowComponent(false), 1000));
};
const fadeOutAndLeaveFast = () => setShowComponent(false);
const clearFadeOutTimer = () => {
if (!fadeOutTimer) {
return;
} }
return ( clearTimeout(fadeOutTimer);
<LabellingTransition setFadeOutTimer(null);
displayComponent={this.state.displayComponent} };
onTransitionExit={this.props.labellingDoneCallback}
>
<>
<div
className={`labellingComponent ${this.state.editDescription &&
'editDescription'}`}
onMouseLeave={this.fadeOutAndLeave}
onMouseEnter={this.clearFadeOutTimer}
>
{this.labellingStateFragment()}
</div>
</>
</LabellingTransition>
);
}
labellingStateFragment = () => { const descriptionDialogUpdate = description => {
const { skipAddLabelButton, editLocation, measurementData } = this.state; updateLabelling({ description });
labellingDoneCallback();
};
const labellingStateFragment = () => {
const { skipAddLabelButton, editLocation, measurementData } = state;
const { description, locationLabel, location } = measurementData; const { description, locationLabel, location } = measurementData;
if (!skipAddLabelButton) { if (!skipAddLabelButton) {
@ -97,7 +150,7 @@ class LabellingFlow extends Component {
<button <button
type="button" type="button"
className="addLabelButton" className="addLabelButton"
onClick={this.showLabelling} onClick={showLabelling}
> >
{location ? 'Edit' : 'Add'} Label {location ? 'Edit' : 'Add'} Label
</button> </button>
@ -107,19 +160,16 @@ class LabellingFlow extends Component {
if (editLocation) { if (editLocation) {
return ( return (
<SelectTree <SelectTree
items={this.currentItems} items={currentItems}
columns={1} columns={1}
onSelected={this.selectTreeSelectCallback} onSelected={selectTreeSelectCallback}
selectTreeFirstTitle="Assign Label" selectTreeFirstTitle="Assign Label"
/> />
); );
} else { } else {
return ( return (
<> <>
<div <div className="checkIconWrapper" onClick={fadeOutAndLeaveFast}>
className="checkIconWrapper"
onClick={this.fadeOutAndLeaveFast}
>
<Icon name="check" className="checkIcon" /> <Icon name="check" className="checkIcon" />
</div> </div>
<div className="locationDescriptionWrapper"> <div className="locationDescriptionWrapper">
@ -127,10 +177,10 @@ class LabellingFlow extends Component {
<div className="description"> <div className="description">
<input <input
id="descriptionInput" id="descriptionInput"
ref={this.descriptionInput} ref={descriptionInput}
defaultValue={description || ''} defaultValue={description || ''}
autoComplete="off" autoComplete="off"
onKeyPress={this.handleKeyPress} onKeyPress={handleKeyPress}
/> />
</div> </div>
</div> </div>
@ -138,14 +188,14 @@ class LabellingFlow extends Component {
<button <button
type="button" type="button"
className="commonButton left" className="commonButton left"
onClick={this.relabel} onClick={relabel}
> >
Relabel Relabel
</button> </button>
<button <button
type="button" type="button"
className="commonButton right" className="commonButton right"
onClick={this.setDescriptionUpdateMode} onClick={setDescriptionUpdateMode}
> >
{description ? 'Edit ' : 'Add '} {description ? 'Edit ' : 'Add '}
Description Description
@ -155,14 +205,14 @@ class LabellingFlow extends Component {
<button <button
type="button" type="button"
className="commonButton left" className="commonButton left"
onClick={this.descriptionCancel} onClick={descriptionCancel}
> >
Cancel Cancel
</button> </button>
<button <button
type="button" type="button"
className="commonButton right" className="commonButton right"
onClick={this.descriptionSave} onClick={descriptionSave}
> >
Save Save
</button> </button>
@ -173,83 +223,34 @@ class LabellingFlow extends Component {
} }
}; };
relabel = event => this.setState({ editLocation: true }); if (editDescriptionOnDialog) {
return (
setDescriptionUpdateMode = () => { <EditDescriptionDialog
this.descriptionInput.current.focus(); onCancel={labellingDoneCallback}
this.setState({ editDescription: true }); onUpdate={descriptionDialogUpdate}
}; measurementData={state.measurementData}
/>
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;
const locationLabel = itemSelected.label;
this.props.updateLabelling({ location });
this.setState({
editLocation: false,
confirmationState: true,
measurementData: {
...this.state.measurementData,
location,
locationLabel,
},
});
if (this.isTouchScreen) {
this.setTimeout = setTimeout(
() => this.setState({ displayComponent: false }),
2000
); );
} }
};
showLabelling = () => { return (
this.setState({ <LabellingTransition
skipAddLabelButton: true, displayComponent={showComponent}
editLocation: false, onTransitionExit={labellingDoneCallback}
}); >
}; <>
<div
fadeOutAndLeave = () => { className={`labellingComponent ${state.editDescription &&
// Wait for 1 sec to dismiss the labelling component 'editDescription'}`}
this.fadeOutTimer = setTimeout( onMouseLeave={fadeOutAndLeave}
() => this.setState({ displayComponent: false }), onMouseEnter={clearFadeOutTimer}
1000 >
{labellingStateFragment()}
</div>
</>
</LabellingTransition>
); );
}; };
fadeOutAndLeaveFast = () => this.setState({ displayComponent: false });
clearFadeOutTimer = () => {
if (!this.fadeOutTimer) {
return;
}
clearTimeout(this.fadeOutTimer);
};
}
LabellingFlow.propTypes = { LabellingFlow.propTypes = {
measurementData: PropTypes.object.isRequired, measurementData: PropTypes.object.isRequired,