Skip to content

Commit

Permalink
updated conflict resolver fix function
Browse files Browse the repository at this point in the history
  • Loading branch information
HenriRabalais committed Jul 23, 2020
1 parent 06acba0 commit 50d6687
Show file tree
Hide file tree
Showing 12 changed files with 136 additions and 128 deletions.
Binary file not shown.
98 changes: 49 additions & 49 deletions modules/conflict_resolver/jsx/fix_conflict_form.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import PropTypes from 'prop-types';
* dropdown is removed to prevent the user from sending a POST request with an empty
* value.
*
* Knowned issue: When sorting the datatable, previouly fixed conflicts are
* Known issue: When sorting the datatable, previouly fixed conflicts are
* considered unresolved; there is no green checkmark beside the dropdown anymore.
*/
class FixConflictForm extends Component {
Expand All @@ -28,7 +28,26 @@ class FixConflictForm extends Component {
constructor(props) {
super(props);

this.fix = this.fix.bind(this);
this.state = {
success: false,
error: false,
emptyOption: true,
};

this.resolveConflict = this.resolveConflict.bind(this);
}

componentDidUpdate(prevProps, prevState) {
if (this.state.error) {
setTimeout(() => {
this.setState({error: false});
}, 3000);
}
if (this.state.success) {
setTimeout(() => {
this.setState({success: false});
}, 3000);
}
}

/**
Expand All @@ -41,81 +60,62 @@ class FixConflictForm extends Component {
* beside the dropdown. On error, a red cross will be displayed as well as a
* sweetalert (swal) with the error message.
*
* @param {Event} e - The onChange event.
* @param {string} name
* @param {string} value
*/
fix(e) {
const conflictid = e.target.name;
const correctanswer = e.target.value;

const feedbackicon = e.target.parentElement.getElementsByTagName('span')[0];
resolveConflict(name, value) {
// Hide any previously displayed icon.
feedbackicon.style.display = 'none';

try {
// Remove the empty option from the options to prevent sending an empty value.
e.target.querySelector('option[name="0"]').remove();
} catch (error) {
// TypeError when already removed. Do nothing.
}
this.setState({success: false, error: false, emptyOption: false});

fetch(loris.BaseURL.concat('/conflict_resolver/unresolved'), {
method: 'POST',
credentials: 'same-origin',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({conflictid: conflictid, correctanswer: correctanswer}),
body: JSON.stringify({conflictid: name, correctanswer: value}),
})
.then((resp) => {
return resp.ok ? {} : resp.json();
})
.then((json) => {
if (json.error) {
throw json.error;
}
// Set feedback icon to green checkmark
setTimeout(() => {
feedbackicon.className = 'glyphicon glyphicon-ok-circle';
feedbackicon.style.color = 'green';
feedbackicon.style.display = 'inline';
}, 200);
if (json.error) {
throw json.error;
}
this.setState({success: true});
})
.catch((error) => {
swal('Error!', error, 'error');
// Set feedback icon to red cross
setTimeout(() => {
feedbackicon.className = 'glyphicon glyphicon-remove-sign';
feedbackicon.style.color = 'red';
feedbackicon.style.display = 'inline';
}, 200);
this.setState({error: true});
});
}
}

render() {
const options = [
<option key='option0' name='0'></option>,
<option key='option1' name='1'>{this.props.values[0].value}</option>,
<option key='option2' name='2'>{this.props.values[1].value}</option>,
];
const {success, error, emptyOption} = this.state;
const iconStyle = {
opacity: success || error ? 1 : 0,
color: success ? 'green' : (error ? 'red' : 'white'),
transition: 'opacity 2s, color 2s',
};
const iconClass = 'glyphicon glyphicon-' + (success ? 'ok' : 'remove')
+ '-circle';
return (
<td>
<form>
<span />
<select style={{width: '85%', marginLeft: '10px'}} name={this.props.conflictid} onChange={this.fix}>
{options}
</select>
</form>
<span className={iconClass} style={iconStyle}/>
<SelectElement
name={this.props.conflictId}
onUserInput={this.resolveConflict}
options={this.props.options}
emptyOption={emptyOption}
/>
</td>
);
}
}

FixConflictForm.propTypes = {
conflictid: PropTypes.string.isRequired,
values: PropTypes.arrayOf(PropTypes.shape({
name: PropTypes.string.isRequired,
value: PropTypes.string.isRequired,
})).isRequired,
conflictId: PropTypes.string.isRequired,
options: PropTypes.object.isRequired,
};

export default FixConflictForm;
16 changes: 10 additions & 6 deletions modules/conflict_resolver/jsx/unresolved_filterabledatatable.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,12 +34,15 @@ class UnresolvedFilterableDataTable extends Component {
formatColumn(column, cell, rowData, rowHeaders) {
switch (column) {
case 'Correct Answer':
const values = [
{name: '1', value: rowData['Value 1']},
{name: '2', value: rowData['Value 2']},
];
const options = {
1: rowData['Value 1'],
2: rowData['Value 2'],
};
return (
<FixConflictForm conflictid={rowData['Conflict ID']} values={values} />
<FixConflictForm
conflictId={rowData['Conflict ID']}
options={options}
/>
);
}
return (
Expand All @@ -52,7 +55,8 @@ class UnresolvedFilterableDataTable extends Component {
* @return {object}
*/
fetchData() {
return fetch(loris.BaseURL.concat('/conflict_resolver/unresolved'), {credentials: 'same-origin'})
const url = loris.BaseURL.concat('/conflict_resolver/unresolved');
return fetch(url, {credentials: 'same-origin'})
.then((resp) => resp.json())
.then((json) => {
if (json.error) {
Expand Down
6 changes: 3 additions & 3 deletions modules/conflict_resolver/php/conflict_resolver.class.inc
Original file line number Diff line number Diff line change
Expand Up @@ -53,9 +53,9 @@ class Conflict_Resolver extends \NDB_Page
$deps = parent::getJSDependencies();
return array_merge(
$deps,
array(
$baseURL . '/conflict_resolver/js/conflict_resolver.js',
)
[
$baseURL . '/conflict_resolver/js/conflict_resolver.js',
]
);
}
}
10 changes: 5 additions & 5 deletions modules/conflict_resolver/php/endpoints/resolved.class.inc
Original file line number Diff line number Diff line change
Expand Up @@ -85,12 +85,12 @@ class Resolved extends Endpoint implements ETagCalculator
$visitlabels = array_values(\Utility::getVisitList());
$projects = array_values(\Utility::getProjectList());

return array(
return [
'site' => array_combine($sites, $sites),
'instrument' => \Utility::getAllInstruments(),
'visitLabel' => array_combine($visitlabels, $visitlabels),
'project' => array_combine($projects, $projects),
);
];
}

/**
Expand Down Expand Up @@ -133,7 +133,7 @@ class Resolved extends Endpoint implements ETagCalculator
$provisioner = (new ResolvedProvisioner())
->filter(
new HasAnyPermissionOrUserSiteMatch(
array('access_all_profiles')
['access_all_profiles']
)
)
->filter(new UserProjectMatch());
Expand All @@ -143,10 +143,10 @@ class Resolved extends Endpoint implements ETagCalculator
->withDataFrom($provisioner)
->toArray($user);

$body = array(
$body = [
'data' => $conflicts,
'fieldOptions' => $this->_getFieldOptions(),
);
];

$this->_cache = new \LORIS\Http\Response\JsonResponse($body);

Expand Down
27 changes: 14 additions & 13 deletions modules/conflict_resolver/php/endpoints/unresolved.class.inc
Original file line number Diff line number Diff line change
Expand Up @@ -77,10 +77,10 @@ class Unresolved extends Endpoint implements ETagCalculator
*/
protected function allowedMethods() : array
{
return array(
return [
'GET',
'POST',
);
];
}

/**
Expand All @@ -94,12 +94,12 @@ class Unresolved extends Endpoint implements ETagCalculator
$visitlabels = array_values(\Utility::getVisitList());
$projects = array_values(\Utility::getProjectList());

return array(
return [
'site' => array_combine($sites, $sites),
'instrument' => \Utility::getAllInstruments(),
'visitLabel' => array_combine($visitlabels, $visitlabels),
'project' => array_combine($projects, $projects),
);
];
}

/**
Expand Down Expand Up @@ -145,7 +145,7 @@ class Unresolved extends Endpoint implements ETagCalculator
$provisioner = (new UnresolvedProvisioner())
->filter(
new HasAnyPermissionOrUserSiteMatch(
array('access_all_profiles')
['access_all_profiles']
)
)
->filter(new UserProjectMatch());
Expand All @@ -155,10 +155,10 @@ class Unresolved extends Endpoint implements ETagCalculator
->withDataFrom($provisioner)
->toArray($user);

$body = array(
$body = [
'data' => $conflicts,
'fieldOptions' => $this->_getFieldOptions(),
);
];

$this->_cache = new \LORIS\Http\Response\JsonResponse($body);

Expand Down Expand Up @@ -219,10 +219,10 @@ class Unresolved extends Endpoint implements ETagCalculator
WHERE
ConflictID = :v_conflictid
',
array(
[
'v_conflictid' => $conflictid,
'v_value' => $correctanswer,
)
]
);

if (empty($conflict)) {
Expand All @@ -239,8 +239,9 @@ class Unresolved extends Endpoint implements ETagCalculator
false
);

$instrument->_saveValues(array($conflict['FieldName'] => $correctanswer));
$instrument->_saveValues([$conflict['FieldName'] => $correctanswer]);

// TODO: UNCOMMENT THE FOLLOWING LINES BEFORE SUBMITTING PR.
// Using an output buffer because the score function prints to STDOUT
ob_start();
$instrument->score();
Expand Down Expand Up @@ -313,19 +314,19 @@ class Unresolved extends Endpoint implements ETagCalculator
);

$success = $stmt->execute(
array(
[
'v_username' => $user->getUsername(),
'v_newvalue' => $correctanswer,
'v_conflictid' => $conflictid,
)
]
);

if (!$success) {
return new \LORIS\Http\Response\JSON\InternalServerError();
}

// Delete from conflicts_unresolved
$db->delete('conflicts_unresolved', array('ConflictID' => $conflictid));
$db->delete('conflicts_unresolved', ['ConflictID' => $conflictid]);

return new \LORIS\Http\Response();
}
Expand Down
30 changes: 15 additions & 15 deletions modules/conflict_resolver/php/models/resolveddto.class.inc
Original file line number Diff line number Diff line change
Expand Up @@ -36,21 +36,21 @@ class ResolvedDTO implements \LORIS\Data\DataInstance
public function jsonSerialize(): array
{
return [
'ResolvedID' => $this->resolvedid,
'Project' => $this->project,
'Site' => $this->site,
'CandID' => $this->candid,
'PSCID' => $this->pscid,
'Visit Label' => $this->visitlabel,
'Instrument' => $this->instrument,
'Question' => $this->question,
'Value 1' => $this->value1,
'Value 2' => $this->value2,
'Correct Answer' => $this->correctanswer,
'User 1' => $this->user1,
'User 2' => $this->user2,
'Resolver' => $this->resolver,
'ResolutionTimestamp' => $this->resolutiontimestamp,
'ResolvedID' => $this->resolvedid,
'Project' => $this->project,
'Site' => $this->site,
'CandID' => $this->candid,
'PSCID' => $this->pscid,
'Visit Label' => $this->visitlabel,
'Instrument' => $this->instrument,
'Question' => $this->question,
'Value 1' => $this->value1,
'Value 2' => $this->value2,
'Correct Answer' => $this->correctanswer,
'User 1' => $this->user1,
'User 2' => $this->user2,
'Resolver' => $this->resolver,
'ResolutionTimestamp' => $this->resolutiontimestamp,
];
}

Expand Down
Loading

0 comments on commit 50d6687

Please sign in to comment.