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

added admin edit button

parent 1411f349
No related branches found
No related tags found
1 merge request!52Feature/admin workflow surveys page
......@@ -2,7 +2,7 @@ import json
import logging
from enum import Enum
from pathlib import Path
from typing import Any, Optional
from typing import Any, Optional, TypedDict, List, Dict
from flask import Blueprint, jsonify, request
from sqlalchemy import select
......@@ -125,19 +125,34 @@ def list_surveys() -> Any:
).order_by(Survey.year.desc())
).unique()
entries = [
def response_key(response):
return response.status.value + response.nren.name.lower()
class SurveyDict(TypedDict):
year: int
status: str
responses: List[Dict[str, str]]
entries: List[SurveyDict] = [
{
"year": entry.year,
"status": entry.status.value,
"responses": [{"nren": r.nren.name, "status": r.status.value} for r in entry.responses]
"responses": [
{"nren": r.nren.name, "status": r.status.value}
for r in sorted(entry.responses, key=response_key)
]
}
for entry in surveys
]
# TODO i suppose we should also add response entries for the nrens that didnt start the survey, with
# a not started status? (only when open?)
# TODO fix the ordering of the responses by nren name, i couldnt convince SA yet..
# add in nrens without a response if the survey is open
nren_names = set([name for name in db.session.scalars(select(NREN.name))])
for entry in entries:
if entry["status"] != SurveyStatus.open.value:
continue
nrens_with_responses = set([r["nren"] for r in entry["responses"]])
for nren_name in sorted(nren_names.difference(nrens_with_responses), key=str.lower):
entry["responses"].append({"nren": nren_name, "status": "not started"})
return jsonify(entries)
......@@ -227,15 +242,11 @@ def load_survey(year, nren_name) -> Any:
page = 0
verification_status = {}
# just a hardcoded year for development for now TODO should be removed
year = 1989
last_year = 2022
response = db.session.scalar(
select(SurveyResponse).where(SurveyResponse.survey_year == year).where(SurveyResponse.nren_id == nren.id)
)
previous_response = db.session.scalar(
select(SurveyResponse).where(SurveyResponse.survey_year == last_year).where(SurveyResponse.nren_id == nren.id)
select(SurveyResponse).where(SurveyResponse.survey_year == year-1).where(SurveyResponse.nren_id == nren.id)
)
if response:
......@@ -258,17 +269,17 @@ def load_survey(year, nren_name) -> Any:
@routes.route('/save/<int:year>/<string:nren_name>', methods=['POST'])
@common.require_accepts_json
def save_survey(nren_name) -> Any:
def save_survey(year, nren_name) -> Any:
# TODO validation (if not admin) on year (is survey open?) and nren (logged in user is part of nren?)
nren = db.session.scalar(select(NREN).filter(NREN.name == nren_name))
if nren is None:
return "NREN not found", 404
# just a hardcoded year for development for now
nren = db.session.execute(select(NREN).filter(NREN.name == nren_name)).scalar_one()
year = 1989
survey = db.session.scalar(select(Survey).where(Survey.year == year))
if survey is None:
survey = Survey(year=year, survey={}, status=SurveyStatus.open)
db.session.add(survey)
return "Survey not found", 404
# TODO validation (if not admin) on year (is survey open?) and nren (logged in user is part of nren?)
response = db.session.scalar(
select(SurveyResponse).where(SurveyResponse.survey_year == year).where(SurveyResponse.nren_id == nren.id)
......
......@@ -69,7 +69,7 @@ function SurveyComponent({ loadFrom, saveTo = ''}) {
return;
}
const xhr = new XMLHttpRequest();
xhr.open("POST", saveTo + nren);
xhr.open("POST", saveTo + year + '/' + nren);
xhr.setRequestHeader("Content-Type", "application/json; charset=utf-8");
xhr.onload = xhr.onerror = () => {
if (xhr.status == 200 && success) {
......@@ -87,7 +87,7 @@ function SurveyComponent({ loadFrom, saveTo = ''}) {
}
async function getModel() {
const response = await fetch(loadFrom + (year ?? '') + (nren ?? '')) // one of year and nren is set
const response = await fetch(loadFrom + year + (nren ? '/' + nren : '')) // year is always set, nren stays empty for inspect and try
const json = await response.json();
for (const questionName in json["verification_status"]) {
......@@ -148,9 +148,6 @@ function SurveyComponent({ loadFrom, saveTo = ''}) {
options.showSaveInProgress();
saveSurveyData(sender, () => options.showSaveSuccess(), () => options.showSaveError());
});
survey.onPartialSend.add((sender) => {
saveSurveyData(sender);
});
survey.onAfterRenderQuestion.add(function (survey, options) {
const status = verificationStatus.current.get(options.question.name);
......
......@@ -69,6 +69,8 @@ function SurveyManagementComponent() {
<Button onClick={() => postSurveyStatus(survey.year, 'open')} disabled={openSurveys || survey.status!='closed'}>open</Button>
<Button onClick={() => postSurveyStatus(survey.year, 'close')} disabled={survey.status!='open'}>close</Button>
<Button onClick={() => postSurveyStatus(survey.year, 'publish')} disabled={(survey.status!='closed' && survey.status!='published') || !survey.responses.every(r => r.status == 'checked')}>publish</Button>
{/* maybe something like this: <Button disabled={survey.status!='published'}>Show in compendium</Button>
<Button disabled={survey.status!='published'}>Hide from compendium</Button> */}
</Accordion.Header>
<Accordion.Body>
<Table>
......@@ -79,8 +81,8 @@ function SurveyManagementComponent() {
<td>{response.status}</td>
<td>locked by</td>
<td>
inspect (with the option to mark as checked)
edit (only available when completed)
inspect (with the option to mark as checked? or just use the edit button below?)
<Button onClick={() => navigate(`/survey/respond/${survey.year}/${response.nren}`)}>edit</Button>
remove lock (only available when locked)
</td>
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please to comment