From 197c23736df1ce48f8a417d33ee15670f2110e0a Mon Sep 17 00:00:00 2001 From: Pierre-Olivier Mercier Date: Fri, 8 Jul 2022 11:53:50 +0200 Subject: [PATCH] ui: Working on works --- assets.go | 2 +- static.go | 2 + ui/src/components/SurveyList.svelte | 24 +++- ui/src/components/WorkAdmin.svelte | 135 ++++++++++++++++++++++ ui/src/lib/surveys.js | 17 ++- ui/src/lib/works.js | 108 +++++++++++++++++ ui/src/routes/__layout.svelte | 1 + ui/src/routes/index.svelte | 2 +- ui/src/routes/works/[wid]/__layout.svelte | 39 +++++++ ui/src/routes/works/[wid]/index.svelte | 34 ++++++ ui/src/routes/works/index.svelte | 99 ++++++++++++++++ ui/src/routes/works/new.svelte | 22 ++++ 12 files changed, 475 insertions(+), 10 deletions(-) create mode 100644 ui/src/components/WorkAdmin.svelte create mode 100644 ui/src/lib/works.js create mode 100644 ui/src/routes/works/[wid]/__layout.svelte create mode 100644 ui/src/routes/works/[wid]/index.svelte create mode 100644 ui/src/routes/works/index.svelte create mode 100644 ui/src/routes/works/new.svelte diff --git a/assets.go b/assets.go index 16d8de7..137a155 100644 --- a/assets.go +++ b/assets.go @@ -10,7 +10,7 @@ import ( "net/http" ) -//go:embed ui/build/* ui/build/_app/* ui/build/_app/assets/pages/* ui/build/_app/pages/* ui/build/_app/pages/grades/* ui/build/_app/pages/surveys/* ui/build/_app/pages/surveys/_sid_/* ui/build/_app/pages/surveys/_sid_/responses/* ui/build/_app/pages/users/* ui/build/_app/pages/users/_uid_/* ui/build/_app/pages/users/_uid_/surveys/* +//go:embed ui/build/* ui/build/_app/* ui/build/_app/assets/pages/* ui/build/_app/pages/* ui/build/_app/pages/grades/* ui/build/_app/pages/surveys/* ui/build/_app/pages/surveys/_sid_/* ui/build/_app/pages/surveys/_sid_/responses/* ui/build/_app/pages/users/* ui/build/_app/pages/users/_uid_/* ui/build/_app/pages/users/_uid_/surveys/* ui/build/_app/pages/works/_wid_/* ui/build/_app/pages/works/* var _assets embed.FS var Assets http.FileSystem diff --git a/static.go b/static.go index 59b7788..2bae2d2 100644 --- a/static.go +++ b/static.go @@ -59,6 +59,8 @@ func init() { Router().GET("/surveys/*_", serveOrReverse("/")) Router().GET("/users", serveOrReverse("/")) Router().GET("/users/*_", serveOrReverse("/")) + Router().GET("/works", serveOrReverse("/")) + Router().GET("/works/*_", serveOrReverse("/")) Router().GET("/css/*_", serveOrReverse("")) Router().GET("/fonts/*_", serveOrReverse("")) Router().GET("/img/*_", serveOrReverse("")) diff --git a/ui/src/components/SurveyList.svelte b/ui/src/components/SurveyList.svelte index 2dae7ab..2e72224 100644 --- a/ui/src/components/SurveyList.svelte +++ b/ui/src/components/SurveyList.svelte @@ -7,7 +7,9 @@ import { getSurveys } from '../lib/surveys'; import { getScore } from '../lib/users'; - let req_surveys = getSurveys(); + export let allworks = false; + + let req_surveys = getSurveys(allworks); export let direct = null; req_surveys.then((surveys) => { @@ -17,6 +19,18 @@ } } }); + + function gotoSurvey(survey) { + if (survey.kind === "w") { + goto(`works/${survey.id}`); + } else if (survey.direct != null) { + goto(`surveys/${survey.id}/live`); + } else if ($user.is_admin) { + goto(`surveys/${survey.id}/responses`); + } else { + goto(`surveys/${survey.id}`); + } + } @@ -38,7 +52,7 @@ {:then surveys} - {#each surveys as survey, sid (survey.id)} + {#each surveys as survey, sid (survey.kind + survey.id)} {#if (survey.shown || survey.direct != null || ($user && $user.is_admin)) && (!$user || (!$user.was_admin || $user.promo == survey.promo) || $user.is_admin)} {#if $user && $user.is_admin && (sid == 0 || surveys[sid-1].promo != survey.promo)} @@ -47,7 +61,7 @@ {/if} - goto(survey.direct != null ?`surveys/${survey.id}/live`:$user.is_admin?`surveys/${survey.id}/responses`:`surveys/${survey.id}`)}> + gotoSurvey(survey)}> {#if survey.startAvailability() > Date.now()} - {:else} - diff --git a/ui/src/components/WorkAdmin.svelte b/ui/src/components/WorkAdmin.svelte new file mode 100644 index 0000000..85fe95b --- /dev/null +++ b/ui/src/components/WorkAdmin.svelte @@ -0,0 +1,135 @@ + + + + + {#if work.id} +
+
+ +
+
+ +
+
+ {/if} + +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ + +
+ +
+ + +
+
+ +
+
+ + {#if work.id} + + + {/if} +
+
+ + diff --git a/ui/src/lib/surveys.js b/ui/src/lib/surveys.js index 27b5edd..b3904d3 100644 --- a/ui/src/lib/surveys.js +++ b/ui/src/lib/surveys.js @@ -1,8 +1,10 @@ import { getQuestions } from './questions'; import { Response } from './response'; +import { Work } from './works'; export class Survey { constructor(res) { + this.kind = "s"; if (res) { this.update(res); } @@ -126,10 +128,19 @@ export class Survey { } } -export async function getSurveys() { - const res = await fetch(`api/surveys`, {headers: {'Accept': 'application/json'}}) +export async function getSurveys(allworks) { + const res = await fetch(allworks?`api/all_works`:`api/surveys`, {headers: {'Accept': 'application/json'}}) if (res.status == 200) { - return (await res.json()).map((s) => new Survey(s)); + if (allworks) { + return (await res.json()).map((s) => { + if (s.kind == "survey") + return new Survey(s); + else + return new Work(s); + }); + } else { + return (await res.json()).map((s) => new Survey(s)); + } } else { throw new Error((await res.json()).errmsg); } diff --git a/ui/src/lib/works.js b/ui/src/lib/works.js new file mode 100644 index 0000000..57fd02e --- /dev/null +++ b/ui/src/lib/works.js @@ -0,0 +1,108 @@ +export class Work { + constructor(res) { + this.kind = "w"; + if (res) { + this.update(res); + } + } + + update({ id, title, promo, group, shown, submission_url, corrected, start_availability, end_availability }) { + this.id = id; + this.title = title; + this.promo = promo; + this.group = group; + this.shown = shown; + this.submission_url = submission_url; + this.corrected = corrected; + if (this.start_availability != start_availability) { + this.start_availability = start_availability; + delete this.__start_availability; + } + if (this.end_availability != end_availability) { + this.end_availability = end_availability; + delete this.__end_availability; + } + } + + startAvailability() { + if (!this.__start_availability) { + this.__start_availability = new Date(this.start_availability) + } + return this.__start_availability + } + + endAvailability() { + if (!this.__end_availability) { + this.__end_availability = new Date(this.end_availability) + } + return this.__end_availability + } + + isFinished() { + return this.endAvailability() < new Date(); + } + + async save() { + const res = await fetch(this.id?`api/works/${this.id}`:'api/works', { + method: this.id?'PUT':'POST', + headers: {'Accept': 'application/json'}, + body: JSON.stringify(this), + }); + if (res.status == 200) { + const data = await res.json() + this.update(data); + return data; + } else { + throw new Error((await res.json()).errmsg); + } + } + + async duplicate() { + if (this.id) { + const oldSurveyId = this.id; + delete this.id; + const res = await fetch(`api/works`, { + method: 'POST', + headers: {'Accept': 'application/json'}, + body: JSON.stringify(this), + }); + if (res.status == 200) { + return await res.json(); + } else { + throw new Error((await res.json()).errmsg); + } + } + } + + async delete() { + if (this.id) { + const res = await fetch(`api/works/${this.id}`, { + method: 'DELETE', + headers: {'Accept': 'application/json'}, + }); + if (res.status == 200) { + return true; + } else { + throw new Error((await res.json()).errmsg); + } + } + } +} + +export async function getWorks() { + const res = await fetch(`api/works`, {headers: {'Accept': 'application/json'}}) + if (res.status == 200) { + return (await res.json()).map((s) => new Work(s)); + } else { + throw new Error((await res.json()).errmsg); + } +} + +export async function getWork(wid) { + const res = await fetch(`api/works/${wid}`, {headers: {'Accept': 'application/json'}}) + if (res.status == 200) { + return new Work(await res.json()); + } else { + throw new Error((await res.json()).errmsg); + } +} diff --git a/ui/src/routes/__layout.svelte b/ui/src/routes/__layout.svelte index a99d9f2..6fd5f94 100644 --- a/ui/src/routes/__layout.svelte +++ b/ui/src/routes/__layout.svelte @@ -89,6 +89,7 @@ {#if $user && $user.is_admin} + {/if} diff --git a/ui/src/routes/index.svelte b/ui/src/routes/index.svelte index 852e3f7..96ba01f 100644 --- a/ui/src/routes/index.svelte +++ b/ui/src/routes/index.svelte @@ -67,7 +67,7 @@ Vous devez vous identifier pour accéder au contenu.

{/if} - + diff --git a/ui/src/routes/works/[wid]/__layout.svelte b/ui/src/routes/works/[wid]/__layout.svelte new file mode 100644 index 0000000..6c5b2dc --- /dev/null +++ b/ui/src/routes/works/[wid]/__layout.svelte @@ -0,0 +1,39 @@ + + + + +{#await work} +
+
+ Chargement du rendu … +
+{:then} + +{:catch error} +
+

+ < + Travail introuvable +

+ {error} +
+{/await} diff --git a/ui/src/routes/works/[wid]/index.svelte b/ui/src/routes/works/[wid]/index.svelte new file mode 100644 index 0000000..b640946 --- /dev/null +++ b/ui/src/routes/works/[wid]/index.svelte @@ -0,0 +1,34 @@ + + + + +{#await work then w} +
+

+ < + {w.title} +

+
+ + {#if $user && $user.is_admin} + edit = false} /> + {/if} +{/await} diff --git a/ui/src/routes/works/index.svelte b/ui/src/routes/works/index.svelte new file mode 100644 index 0000000..fa4b01d --- /dev/null +++ b/ui/src/routes/works/index.svelte @@ -0,0 +1,99 @@ + + +{#if $user && $user.is_admin} + + + + {#await getPromos() then promos} +
+ +
+ {/await} +{/if} +

+ Travaux +

+ +{#await getWorks()} +
+
+ Chargement des travaux … +
+{:then works} +
{#if !survey.shown}{/if} {survey.title} @@ -55,12 +69,12 @@ + +
+ + + + + {#if $user} + + {/if} + + + + {#each works as work, wid (work.id)} + {#if (work.shown || ($user && $user.is_admin)) && (!$user || (!$user.was_admin || $user.promo == work.promo) || $user.is_admin)} + {#if $user && $user.is_admin && (wid == 0 || works[wid-1].promo != work.promo)} + + + + {/if} + goto(`works/${work.id}`)}> + + {#if work.startAvailability() > Date.now()} + + {:else} + + {/if} + {#if $user} + {#if !work.corrected} + + {:else} + + {/if} + {/if} + + {/if} + {/each} + +
IntituléDateScore
+ {work.promo} +
+ {#if !work.shown}{/if} + {work.title} + {#if work.group}{work.group}{/if} + + + + + + + + N/A + {#await getScore(work)} +
+ {:then score} + {score.score} + {/await} +
+{:catch error} +
+ {error.message} +
+{/await} diff --git a/ui/src/routes/works/new.svelte b/ui/src/routes/works/new.svelte new file mode 100644 index 0000000..efbcfd0 --- /dev/null +++ b/ui/src/routes/works/new.svelte @@ -0,0 +1,22 @@ + + +
+

+ < + Nouveau travail +

+ +
+ +{#if $user && $user.is_admin} + { goto(`works/${e.detail.id}`)}} /> +{/if}