Skip to content
Snippets Groups Projects
Commit 05b31c69 authored by Remco Tukker's avatar Remco Tukker
Browse files

improved the survey management frontend to deal with failures and longer...

improved the survey management frontend to deal with failures and longer running api calls such as publish
parent f63aec60
Branches
Tags
1 merge request!77Feature/comp 276 publisher v2
This commit is part of merge request !77. Comments created here will be created in the context of that merge request.
Source diff could not be displayed: it is too large. Options to address this: view the blob.
This diff is collapsed.
This diff is collapsed.
import React, { useState, useEffect } from "react";
import React, { useState, useEffect, useRef } from "react";
import Accordion from 'react-bootstrap/Accordion';
import Button from 'react-bootstrap/Button';
import Table from 'react-bootstrap/Table';
import toast, { Toaster } from "react-hot-toast";
import { useNavigate } from 'react-router-dom';
import { ResponseStatus, SurveyStatus } from "./Schema";
import { SurveyStatus } from "./Schema";
import { fetchSurveys } from "./api/survey";
import { Survey } from "./api/types";
import { Spinner } from "react-bootstrap";
function ApiCallButton({ text, helpText, onClick, enabled }) {
const [buttonLoading, setButtonLoading] = useState(false);
const handleClick = async () => {
if (buttonLoading) {
return;
}
setButtonLoading(true);
try {
await onClick();
} finally {
setButtonLoading(false);
}
};
return (
<Button onClick={handleClick} disabled={!enabled} style={{ pointerEvents: 'auto', marginLeft: '.5rem' }} title={helpText}>
{buttonLoading && <Spinner as="span" animation="border" size="sm" role="status" aria-hidden="true"/>}
{text}
</Button>
);
}
function SurveyManagementComponent() {
const [surveys, setSurveys] = useState<Survey[]>([]);
const surveyStatusUpdating = useRef(false);
useEffect(() => {
fetchSurveys().then((surveyList) => {
......@@ -16,25 +44,47 @@ function SurveyManagementComponent() {
});
}, []);
async function apiCall(url, failureToast, successToast) {
try {
const response = await fetch(url, { method: 'POST' });
const json = await response.json();
if (!response.ok) {
toast(failureToast + json['message']);
} else {
toast(successToast);
fetchSurveys().then((surveyList) => {
setSurveys(surveyList);
});
}
} catch(e) {
toast(failureToast + (e as Error).message);
}
}
async function newSurvey() {
await fetch('/api/survey/new', { method: 'POST' });
fetchSurveys().then((surveyList) => {
setSurveys(surveyList);
});
await apiCall('/api/survey/new', "Failed creating new survey: ", "Created new survey");
}
async function postSurveyStatus(year, status) {
await fetch('/api/survey/' + status + '/' + year, { method: 'POST' });
fetchSurveys().then((surveyList) => {
setSurveys(surveyList);
});
if (surveyStatusUpdating.current) {
toast("Wait for status update to be finished...");
return;
}
surveyStatusUpdating.current = true;
await apiCall(
'/api/survey/' + status + '/' + year,
"Error while updating " + year + " survey status to " + status + ": ",
year + " survey status updated to " + status
);
surveyStatusUpdating.current = false;
}
async function removeLock(year, nrenName) {
await fetch('/api/response/unlock/' + year + '/' + nrenName, { method: 'POST' });
fetchSurveys().then((surveyList) => {
setSurveys(surveyList);
});
await apiCall(
'/api/response/unlock/' + year + '/' + nrenName,
"Error while unlocking " + nrenName + " " + year + " survey response: ",
nrenName + " " + year + " survey response unlocked"
);
}
const newSurveyAllowed = surveys.length > 0 && surveys.every(s => s.status == SurveyStatus.published);
......@@ -45,6 +95,7 @@ function SurveyManagementComponent() {
return (
<div>
<Toaster />
<Button onClick={newSurvey} disabled={!newSurveyAllowed} style={{ pointerEvents: 'auto' }}
title="Create a new survey for the next year. Only possible if all current surveys are published.">
start new survey
......@@ -63,23 +114,26 @@ function SurveyManagementComponent() {
title="Open the survey exactly as the nrens will see it, but without any nren data.">
Try Survey
</Button>
{survey.status !== SurveyStatus.published &&
<Button onClick={() => postSurveyStatus(survey.year, 'open')} disabled={survey.status != SurveyStatus.closed} style={{ pointerEvents: 'auto', marginLeft: '.5rem' }}
title="Allow the NRENs to respond to this survey. Only 1 survey may be open at a time, and published surveys cannot be opened anymore.">
Mark as Open
</Button>}
<Button onClick={() => postSurveyStatus(survey.year, 'close')} disabled={survey.status != SurveyStatus.open} style={{ pointerEvents: 'auto', marginLeft: '.5rem' }}
title="Do not allow the NRENs to respond to this survey anymore. Only surveys with status open can be closed.">
Mark as closed
</Button>
<Button onClick={() => postSurveyStatus(survey.year, 'preview')} disabled={survey.status != SurveyStatus.closed && survey.status != SurveyStatus.preview} style={{ pointerEvents: 'auto', marginLeft: '.5rem' }}
title="Publish all completed survey responses to the compendium website for preview. This is only possible if the survey is closed or previewed already.">
Preview results
</Button>
<Button onClick={() => postSurveyStatus(survey.year, 'publish')} disabled={survey.status != SurveyStatus.preview && survey.status != SurveyStatus.published} style={{ pointerEvents: 'auto', marginLeft: '.5rem' }}
title="Publish or re-publish all completed survey responses to the compendium website. This is only possible if the survey is in preview or published already.">
Publish results
</Button>
<ApiCallButton text="Mark as open"
helpText="Allow the NRENs to respond to this survey. Only 1 survey may be open at a time, and (pre)-published surveys cannot be opened anymore."
enabled={survey.status == SurveyStatus.closed}
onClick={() => postSurveyStatus(survey.year, 'open')}
/>
<ApiCallButton text="Mark as closed"
helpText="Do not allow the NRENs to respond to this survey anymore. Only surveys with status open can be closed."
enabled={survey.status == SurveyStatus.open}
onClick={() => postSurveyStatus(survey.year, 'close')}
/>
<ApiCallButton text="Preview results"
helpText="Publish all completed survey responses to the compendium website for preview by admins. This is only possible if the survey is closed or previewed already."
enabled={survey.status == SurveyStatus.closed || survey.status == SurveyStatus.preview}
onClick={() => postSurveyStatus(survey.year, 'preview')}
/>
<ApiCallButton text="Publish results"
helpText="Publish or re-publish all completed survey responses to the compendium website. This is only possible if the survey is in preview or published already."
enabled={survey.status == SurveyStatus.preview || survey.status == SurveyStatus.published}
onClick={() => postSurveyStatus(survey.year, 'publish')}
/>
{survey.status == SurveyStatus.preview && <span>&nbsp; Preview link: <a href={previewLink}>{previewLink}</a></span>}
</div>
<Table>
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment