in frontend/src/components/taskSelection/actionSidebars.js [264:383]
export function CompletionTabForValidation({
project,
tasksIds,
taskInstructions,
disabled,
contributors,
validationStatus,
setValidationStatus,
validationComments,
setValidationComments,
}: Object) {
const token = useSelector((state) => state.auth.get('token'));
const [showMapChangesModal, setShowMapChangesModal] = useState(false);
const fetchLockedTasks = useFetchLockedTasks();
const clearLockedTasks = useClearLockedTasks();
const updateStatus = (id, newStatus) =>
setValidationStatus({ ...validationStatus, [id]: newStatus });
const updateComment = (id, newComment) =>
setValidationComments({ ...validationComments, [id]: newComment });
const copyCommentToTasks = (id, statusFilter) => {
const comment = validationComments[id];
let tasks = tasksIds.filter((task) => task !== id);
if (statusFilter) {
tasks = tasks.filter((task) => validationStatus[task] === statusFilter);
}
let payload = {};
tasks.forEach((task) => (payload[task] = comment));
setValidationComments({ ...validationComments, ...payload });
};
const areAllTasksVerified = Object.keys(validationStatus).length === tasksIds.length;
const stopValidation = () => {
if (!disabled) {
return pushToLocalJSONAPI(
`projects/${project.projectId}/tasks/actions/stop-validation/`,
JSON.stringify({
resetTasks: tasksIds.map((taskId) => ({
taskId: taskId,
comment: validationComments[taskId],
})),
}),
token,
).then((r) => {
clearLockedTasks();
navigate(`../tasks/`);
});
} else {
return new Promise((resolve, reject) => {
setShowMapChangesModal('unlock');
resolve();
});
}
};
const stopValidationAsync = useAsync(stopValidation);
const submitTask = () => {
if (!disabled && areAllTasksVerified) {
const url = `projects/${project.projectId}/tasks/actions/unlock-after-validation/`;
let payload = {
validatedTasks: tasksIds.map((taskId) => ({
taskId: taskId,
comment: validationComments[taskId],
status: validationStatus[taskId],
})),
};
return pushToLocalJSONAPI(url, JSON.stringify(payload), token).then((r) => {
fetchLockedTasks();
navigate(`../tasks/?filter=readyToValidate`);
});
}
};
const submitTaskAsync = useAsync(submitTask);
return (
<div>
{disabled && showMapChangesModal && (
<Popup
modal
open
closeOnEscape={true}
closeOnDocumentClick={true}
onClose={() => setShowMapChangesModal(null)}
>
{(close) => <UnsavedMapChangesModalContent close={close} action={showMapChangesModal} />}
</Popup>
)}
<div className="cf">
{taskInstructions && (
<TaskSpecificInstructions instructions={taskInstructions} open={false} />
)}
<h4 className="ttu blue-grey f5">
<FormattedMessage {...messages.editStatus} />
</h4>
<p className="b mb2">
<FormattedMessage {...messages.validatedQuestion} values={{ number: tasksIds.length }} />
</p>
{tasksIds.map((id) => (
<TaskValidationSelector
key={id}
id={id}
projectId={project.projectId}
contributors={contributors}
currentStatus={validationStatus[id]}
updateStatus={updateStatus}
comment={validationComments[id]}
updateComment={updateComment}
copyCommentToTasks={copyCommentToTasks}
isValidatingMultipleTasks={tasksIds.length > 1}
/>
))}
</div>
<div className="cf mv3">
<Button
className="bg-primary white w-100 fl"
onClick={() => submitTaskAsync.execute()}
disabled={disabled || !areAllTasksVerified || stopValidationAsync.status === 'pending'}
loading={submitTaskAsync.status === 'pending'}
>
<FormattedMessage {...messages[tasksIds.length > 1 ? 'submitTasks' : 'submitTask']} />