in frontend/src/components/taskSelection/actionSidebars.js [31:262]
export function CompletionTabForMapping({
project,
tasksIds,
showReadCommentsAlert,
disableBadImagery,
historyTabSwitch,
taskInstructions,
disabled,
contributors,
taskComment,
setTaskComment,
selectedStatus,
setSelectedStatus,
}: Object) {
const token = useSelector((state) => state.auth.get('token'));
const [showHelp, setShowHelp] = useState(false);
const [showMapChangesModal, setShowMapChangesModal] = useState(false);
const [splitTaskError, setSplitTaskError] = useState(false);
const radioInput = 'radio-input input-reset pointer v-mid dib h2 w2 mr2 br-100 ba b--blue-light';
const fetchLockedTasks = useFetchLockedTasks();
const clearLockedTasks = useClearLockedTasks();
const splitTask = () => {
if (!disabled) {
return fetchLocalJSONAPI(
`projects/${project.projectId}/tasks/actions/split/${tasksIds[0]}/`,
token,
'POST',
)
.then((r) => {
clearLockedTasks();
navigate(`../tasks/`);
})
.catch((e) => {
setSplitTaskError(true);
});
} else {
// we need to return a promise in order to be called by useAsync
return new Promise((resolve, reject) => {
setShowMapChangesModal('split');
resolve();
});
}
};
const splitTaskAsync = useAsync(splitTask);
const stopMapping = () => {
if (!disabled) {
return pushToLocalJSONAPI(
`projects/${project.projectId}/tasks/actions/stop-mapping/${tasksIds[0]}/`,
JSON.stringify({ comment: taskComment }),
token,
).then((r) => {
clearLockedTasks();
navigate(`/projects/${project.projectId}/tasks/`);
});
} else {
return new Promise((resolve, reject) => {
setShowMapChangesModal('unlock');
resolve();
});
}
};
const stopMappingAsync = useAsync(stopMapping);
const submitTask = () => {
if (!disabled && selectedStatus) {
let url;
let payload = { comment: taskComment };
if (selectedStatus === 'MAPPED') {
url = `projects/${project.projectId}/tasks/actions/unlock-after-mapping/${tasksIds[0]}/`;
payload.status = 'MAPPED';
}
if (selectedStatus === 'READY') {
url = `projects/${project.projectId}/tasks/actions/stop-mapping/${tasksIds[0]}/`;
}
if (selectedStatus === 'BADIMAGERY') {
url = `projects/${project.projectId}/tasks/actions/unlock-after-mapping/${tasksIds[0]}/`;
payload.status = 'BADIMAGERY';
}
return pushToLocalJSONAPI(url, JSON.stringify(payload), token).then((r) => {
fetchLockedTasks();
navigate(`/projects/${project.projectId}/tasks/`);
});
}
};
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>
)}
{splitTaskError && (
<Popup
modal
open
closeOnEscape={true}
closeOnDocumentClick={true}
onClose={() => setSplitTaskError(false)}
>
{(close) => <TaskSplitErrorModalContent close={close} />}
</Popup>
)}
{showReadCommentsAlert && (
<div
className="tc pa2 mb1 bg-grey-light blue-dark pointer"
onClick={() => historyTabSwitch()}
>
<InfoIcon className="v-mid h1 w1" />
<span className="ml2 fw1 pa1">
<FormattedMessage {...messages.readTaskComments} />
</span>
</div>
)}
<div className="cf">
{taskInstructions && <TaskSpecificInstructions instructions={taskInstructions} />}
<h4 className="ttu blue-grey f5">
<FormattedMessage {...messages.editStatus} />
<QuestionCircleIcon
className="pointer dib v-mid pl2 pb1 blue-light"
height="1.25rem"
onClick={() => setShowHelp(!showHelp)}
/>
</h4>
{showHelp && (
<div className="cf">
<CompletionInstructions setVisibility={setShowHelp} />
</div>
)}
<p className="b">
<FormattedMessage {...messages.mappedQuestion} />
</p>
<p>
<input
id="MAPPED"
type="radio"
value="MAPPED"
className={radioInput}
checked={selectedStatus === 'MAPPED'}
onChange={() => setSelectedStatus('MAPPED')}
/>
<label htmlFor="MAPPED">
<FormattedMessage {...messages.complete} />
</label>
</p>
<p>
<input
id="READY"
type="radio"
value="READY"
className={radioInput}
checked={selectedStatus === 'READY'}
onChange={() => setSelectedStatus('READY')}
/>
<label htmlFor="READY">
<FormattedMessage {...messages.incomplete} />
</label>
</p>
{!disableBadImagery && (
<p>
<input
id="BADIMAGERY"
type="radio"
value="BADIMAGERY"
className={radioInput}
checked={selectedStatus === 'BADIMAGERY'}
onChange={() => setSelectedStatus('BADIMAGERY')}
/>
<label htmlFor="BADIMAGERY">
<FormattedMessage {...messages.badImagery} />
</label>
</p>
)}
</div>
<div className="cf">
<h4 className="ttu blue-grey f5">
<FormattedMessage {...messages.comment} />
</h4>
<p>
<CommentInputField
comment={taskComment}
setComment={setTaskComment}
contributors={contributors}
enableHashtagPaste={true}
/>
</p>
</div>
<div className="cf mv2">
<Button
className="bg-primary white w-100 fl"
onClick={() => submitTaskAsync.execute()}
disabled={
disabled ||
!selectedStatus ||
[stopMappingAsync.status, splitTaskAsync.status].includes('pending')
}
loading={submitTaskAsync.status === 'pending'}
>
<FormattedMessage {...messages.submitTask} />
</Button>
</div>
<div className="cf pb1">
<Button
className="bg-blue-dark white w-50 fl"
onClick={() => splitTaskAsync.execute()}
loading={splitTaskAsync.status === 'pending'}
disabled={[submitTaskAsync.status, stopMappingAsync.status].includes('pending')}
>
<FormattedMessage {...messages.splitTask} />
</Button>
<Button
className="blue-dark bg-white w-50 fl"
onClick={() => stopMappingAsync.execute()}
loading={stopMapping.status === 'pending'}
disabled={[submitTaskAsync.status, splitTaskAsync.status].includes('pending')}
>
<FormattedMessage {...messages.selectAnotherTask} />
</Button>
</div>
<div className="bb b--grey-light w-100 pv2"></div>
</div>
);
}