Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 5 additions & 4 deletions src/clincoded/static/components/experimental_curation.js
Original file line number Diff line number Diff line change
Expand Up @@ -2551,15 +2551,16 @@ const ExperimentalViewer = createReactClass({
userScoreObj: {}, // Logged-in user's score object
submitBusy: false, // True while form is submitting
experimentalEvidenceType: null,
formError: false
scoreError: false,
scoreErrorMsg: ''
};
},

// Called by child function props to update user score obj
handleUserScoreObj: function(newUserScoreObj) {
this.setState({userScoreObj: newUserScoreObj}, () => {
if (!newUserScoreObj.hasOwnProperty('score') || (newUserScoreObj.hasOwnProperty('score') && newUserScoreObj.score !== false && newUserScoreObj.scoreExplanation)) {
this.setState({formError: false});
this.setState({scoreError: false, scoreErrorMsg: ''});
}
});
},
Expand All @@ -2582,7 +2583,7 @@ const ExperimentalViewer = createReactClass({

if (Object.keys(newUserScoreObj).length) {
if(newUserScoreObj.hasOwnProperty('score') && newUserScoreObj.score !== false && !newUserScoreObj.scoreExplanation) {
this.setState({formError: true});
this.setState({scoreError: true, scoreErrorMsg: 'A reason is required for the changed score.'});
return false;
}
this.setState({submitBusy: true});
Expand Down Expand Up @@ -3268,7 +3269,7 @@ const ExperimentalViewer = createReactClass({
{isEvidenceScored || (!isEvidenceScored && affiliation && affiliatedExperimental) || (!isEvidenceScored && !affiliation && userExperimental) ?
<ScoreExperimental evidence={experimental} experimentalType={experimental.evidenceType} experimentalEvidenceType={experimentalEvidenceType}
evidenceType="Experimental" session={this.props.session} handleUserScoreObj={this.handleUserScoreObj} scoreSubmit={this.scoreSubmit}
formError={this.state.formError} affiliation={affiliation} />
scoreError={this.state.scoreError} scoreErrorMsg={this.state.scoreErrorMsg} affiliation={affiliation} />
: null}
{!isEvidenceScored && ((affiliation && !affiliatedExperimental) || (!affiliation && !userExperimental)) ?
<div className="row">
Expand Down
30 changes: 27 additions & 3 deletions src/clincoded/static/components/score/case_control_score.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ var ScoreCaseControl = module.exports.ScoreCaseControl = createReactClass({
handleUserScoreObj: PropTypes.func, // Function to call create/update score object
scoreSubmit: PropTypes.func, // Function to call when Save button is clicked; This prop's existence makes the Save button exist
submitBusy: PropTypes.bool, // TRUE while the form submit is running
scoreError: PropTypes.bool, // TRUE if score selection is not changed
scoreErrorMsg: PropTypes.string, // Text string in response to the type of score error
affiliation: PropTypes.object, // Affiliation object passed from parent
isDisabled: PropTypes.bool // Boolean for the state (disabled or not) of the input field
},
Expand All @@ -28,6 +30,9 @@ var ScoreCaseControl = module.exports.ScoreCaseControl = createReactClass({
modifiedScore: null, // Score that is selected by curator
userScoreUuid: null, // Pre-existing logged-in user's score uuuid
submitBusy: false, // TRUE while form is submitting
userOrigScore: null, // User originally selected score
scoreError: this.props.scoreError, // TRUE if score selection is not changed
scoreErrorMsg: this.props.scoreErrorMsg, // Text string in response to the type of score error
scoreAffiliation: null // Affiliation associated with the score
};
},
Expand All @@ -43,6 +48,7 @@ var ScoreCaseControl = module.exports.ScoreCaseControl = createReactClass({
this.updateUserScoreObj();
});
}
this.setState({scoreError: nextProps.scoreError, scoreErrorMsg: nextProps.scoreErrorMsg});
},

loadData() {
Expand All @@ -69,6 +75,8 @@ var ScoreCaseControl = module.exports.ScoreCaseControl = createReactClass({
this.refs.scoreRange.setValue(modifiedScore ? modifiedScore : 'none');
this.updateUserScoreObj();
});
// Save original score for checking if change has been made
this.setState({userOrigScore: !isNaN(parseFloat(modifiedScore)) ? modifiedScore : null});
}
}
});
Expand Down Expand Up @@ -165,9 +173,20 @@ var ScoreCaseControl = module.exports.ScoreCaseControl = createReactClass({
return affiliatedScore;
},

// Check if score has been changed before saving the score object
saveScore(e) {
if (this.state.modifiedScore === this.state.userOrigScore ||
this.state.modifiedScore === 'none' && this.state.userOrigScore === null) {
this.setState({scoreError: true, scoreErrorMsg: 'Cannot save because score is not changed. Please select a new score then save.'});
}
else {
this.props.scoreSubmit(e);
}
},

render() {
let modifiedScore = this.state.modifiedScore ? this.state.modifiedScore : 'none';

let scoreError = this.state.scoreError;
return (
<div>
<div className="row">
Expand All @@ -190,6 +209,11 @@ var ScoreCaseControl = module.exports.ScoreCaseControl = createReactClass({
<option value="5.5">5.5</option>
<option value="6">6</option>
</Input>
{scoreError ?
<div className="col-sm-7 col-sm-offset-5 score-alert-message">
<p className="alert alert-warning"><i className="icon icon-exclamation-triangle"></i> {this.state.scoreErrorMsg}</p>
</div>
: null}
{this.props.isDisabled ?
<div className="col-sm-7 col-sm-offset-5 score-alert-message">
<p className="alert alert-warning"><i className="icon icon-info-circle"></i> A Study type must be selected
Expand All @@ -199,8 +223,8 @@ var ScoreCaseControl = module.exports.ScoreCaseControl = createReactClass({
</div>
{this.props.scoreSubmit ?
<div className="curation-submit clearfix">
<Input type="button" inputClassName="btn-primary pull-right" clickHandler={this.props.scoreSubmit}
title="Save" submitBusy={this.props.submitBusy} />
<Input type="button" inputClassName="btn-primary pull-right" clickHandler={this.saveScore}
title="Save" submitBusy={this.props.submitBusy} inputDisabled={this.props.isDisabled} />
</div>
: null}
</div>
Expand Down
62 changes: 45 additions & 17 deletions src/clincoded/static/components/score/experimental_score.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,8 @@ var ScoreExperimental = module.exports.ScoreExperimental = createReactClass({
handleUserScoreObj: PropTypes.func, // Function to call create/update score object
scoreSubmit: PropTypes.func, // Function to call when Save button is clicked; This prop's existence makes the Save button exist
submitBusy: PropTypes.bool, // TRUE while the form submit is running
formError: PropTypes.bool, // TRUE if no explanation is given for a different score
scoreError: PropTypes.bool, // TRUE if no explanation is given for a different score or no change is made
scoreErrorMsg: PropTypes.string, // Text string in response to the type of score error
scoreDisabled: PropTypes.bool, // FALSE if the matched checkbox is selected
affiliation: PropTypes.object // Affiliation object passed from parent
},
Expand All @@ -45,8 +46,12 @@ var ScoreExperimental = module.exports.ScoreExperimental = createReactClass({
submitBusy: false, // TRUE while form is submitting
disableScoreStatus: this.props.scoreDisabled, // FALSE if the matched checkbox is selected
willNotCountScore: false, // TRUE if 'Review' is selected when Mode of Inheritance is not AD, AR, or X-Linked
formError: false, // TRUE if no explanation is given for a different score
scoreAffiliation: null // Affiliation associated with the score
scoreAffiliation: null, // Affiliation associated with the score
scoreError: this.props.scoreError, // TRUE if no explanation is given for a different score or no change is made
scoreErrorMsg: this.props.scoreErrorMsg, // Text string in response to the type of score error
origStatus: null, // User originally selected status
origScore: null, // User originally selected score
origScoreExplanation: null // User originally entered explanation for selected score
};
},

Expand All @@ -65,9 +70,7 @@ var ScoreExperimental = module.exports.ScoreExperimental = createReactClass({
this.refs.scoreStatus.resetValue();
});
}
if (nextProps.formError && nextProps.formError !== this.props.formError) {
this.setState({formError: true});
}
this.setState({scoreError: nextProps.scoreError, scoreErrorMsg: nextProps.scoreErrorMsg});
this.setState({disableScoreStatus: nextProps.scoreDisabled}, () => {
if (this.state.disableScoreStatus) {
this.setState({showScoreInput: false}, () => {
Expand Down Expand Up @@ -102,6 +105,14 @@ var ScoreExperimental = module.exports.ScoreExperimental = createReactClass({
modifiedScore = matchedScore.hasOwnProperty('score') ? matchedScore.score.toString() : null,
scoreExplanation = matchedScore.scoreExplanation,
calcScoreRange = this.getScoreRange(experimentalEvidenceType, parseFloat(defaultScore));

// Save original data for checking if changes has been made
this.setState({
origStatus: scoreStatus,
origScore: modifiedScore,
origScoreExplanation: scoreExplanation === undefined ? null : scoreExplanation
});

/**************************************************************************************/
/* Curators are allowed to access the score form fields when the 'Score' is selected, */
/* or when 'Review' is selected given the matched Mode of Inheritance types */
Expand Down Expand Up @@ -160,7 +171,8 @@ var ScoreExperimental = module.exports.ScoreExperimental = createReactClass({
modifiedScore: null,
scoreExplanation: null,
requiredScoreExplanation: false,
formError: false,
scoreError: false,
scoreErrorMsg: '',
updateDefaultScore: true
}, () => {
let calcScoreRange = this.getScoreRange(experimentalEvidenceType, calcDefaultScore);
Expand All @@ -183,7 +195,8 @@ var ScoreExperimental = module.exports.ScoreExperimental = createReactClass({
scoreRange: [],
scoreExplanation: null,
requiredScoreExplanation: false,
formError: false
scoreError: false,
scoreErrorMsg: ''
}, () => {
if (this.refs.scoreExplanation && this.refs.scoreExplanation.getValue()) {
this.refs.scoreExplanation.resetValue();
Expand All @@ -209,7 +222,7 @@ var ScoreExperimental = module.exports.ScoreExperimental = createReactClass({
});
} else {
// Reset explanation if default score is kept
this.setState({scoreExplanation: null, requiredScoreExplanation: false, formError: false}, () => {
this.setState({scoreExplanation: null, requiredScoreExplanation: false, scoreError: false, scoreErrorMsg: ''}, () => {
this.refs.scoreExplanation.resetValue();
this.updateUserScoreObj();
});
Expand All @@ -221,12 +234,27 @@ var ScoreExperimental = module.exports.ScoreExperimental = createReactClass({
if (this.refs.scoreExplanation) {
// Parse the score explanation entered by the curator
let scoreExplanation = this.refs.scoreExplanation.getValue();
this.setState({scoreExplanation: scoreExplanation, formError: false}, () => {
this.setState({scoreExplanation: scoreExplanation, scoreError: false, scoreErrorMsg: ''}, () => {
this.updateUserScoreObj();
});
}
},

// Check if changes has been made before saving the score object.
saveScore(e) {
if ((this.state.scoreStatus === this.state.origStatus ||
this.state.scoreStatus === 'none' && this.state.origStatus === null) &&
(this.state.modifiedScore === this.state.origScore ||
this.state.modifiedScore === 'none' && this.state.origScore === null) &&
(this.state.scoreExplanation === this.state.origScoreExplanation ||
this.state.scoreExplanation === '' && this.state.origScoreExplanation === null)) {
this.setState({scoreError: true, scoreErrorMsg: 'Cannot save because score/explanation has not been modified. Please make your changes then save.'});
}
else {
this.props.scoreSubmit(e);
}
},

// Put together the score object based on the form values for
// the currently logged-in user
updateUserScoreObj() {
Expand Down Expand Up @@ -413,7 +441,7 @@ var ScoreExperimental = module.exports.ScoreExperimental = createReactClass({
let requiredScoreExplanation = this.state.requiredScoreExplanation;
let disableScoreStatus = this.state.disableScoreStatus;
let willNotCountScore = this.state.willNotCountScore;
let formError = this.state.formError;
let scoreError = this.state.scoreError;

return (
<div>
Expand Down Expand Up @@ -457,17 +485,17 @@ var ScoreExperimental = module.exports.ScoreExperimental = createReactClass({
value={scoreExplanation} handleChange={this.handleScoreExplanation}
placeholder="Note: If you selected a score different from the default score, you must provide a reason for the change here."
rows="3" labelClassName="col-sm-5 control-label" wrapperClassName="col-sm-7" groupClassName="form-group" />
{formError ?
<div className="col-sm-7 col-sm-offset-5 score-alert-message">
<p className="alert alert-warning"><i className="icon icon-exclamation-triangle"></i> A reason is required for the changed score.</p>
</div>
: null}
</div>
: null}
{scoreError ?
<div className="col-sm-7 col-sm-offset-5 score-alert-message">
<p className="alert alert-warning"><i className="icon icon-exclamation-triangle"></i> {this.state.scoreErrorMsg}</p>
</div>
: null}
</div>
{this.props.scoreSubmit ?
<div className="curation-submit clearfix">
<Input type="button" inputClassName="btn-primary pull-right" clickHandler={this.props.scoreSubmit}
<Input type="button" inputClassName="btn-primary pull-right" clickHandler={this.saveScore}
title="Save" submitBusy={this.props.submitBusy} />
</div>
: null}
Expand Down
Loading