svelte-migrate: updated files

This commit is contained in:
nemunaire 2022-12-12 10:24:30 +01:00
parent 4d6149760d
commit ff5a2eef65
36 changed files with 1286 additions and 1418 deletions

View File

@ -10,7 +10,7 @@ import (
"net/http"
)
//go:embed ui/build/* ui/build/css/* ui/build/surveys/* ui/build/_app/* ui/build/_app/immutable/* ui/build/_app/immutable/pages/* ui/build/_app/immutable/pages/surveys/* ui/build/_app/immutable/pages/surveys/_sid_/* ui/build/_app/immutable/pages/surveys/_sid_/responses/* ui/build/_app/immutable/pages/grades/* ui/build/_app/immutable/pages/works/* ui/build/_app/immutable/pages/works/_wid_/* ui/build/_app/immutable/pages/users/* ui/build/_app/immutable/pages/users/_uid_/* ui/build/_app/immutable/pages/users/_uid_/surveys/* ui/build/_app/immutable/chunks/* ui/build/_app/immutable/assets/* ui/build/img/* ui/build/works/*
//go:embed all:ui/build
var _assets embed.FS
var Assets http.FileSystem

View File

@ -48,7 +48,6 @@ func serveOrReverse(forced_url string) func(c *gin.Context) {
}
func declareStaticRoutes(router *gin.Engine) {
router.GET("/@fs/*_", serveOrReverse(""))
router.GET("/", serveOrReverse(""))
router.GET("/_app/*_", serveOrReverse(""))
router.GET("/auth/", serveOrReverse("/"))
@ -74,7 +73,7 @@ func declareStaticRoutes(router *gin.Engine) {
router.GET("/.svelte-kit/*_", serveOrReverse(""))
router.GET("/node_modules/*_", serveOrReverse(""))
router.GET("/@vite/*_", serveOrReverse(""))
router.GET("/__vite_ping", serveOrReverse(""))
router.GET("/@fs/*_", serveOrReverse(""))
router.GET("/src/*_", serveOrReverse(""))
}
}

View File

@ -1,6 +0,0 @@
export async function handle({ event, resolve }) {
const response = await resolve(event, {
ssr: false,
});
return response;
}

View File

@ -8,14 +8,10 @@ function createUserStore() {
set: (auth) => {
update((m) => auth);
},
update: (res_auth, cb=null) => {
update: (res_auth) => {
if (res_auth.status === 200) {
res_auth.json().then((auth) => {
update((m) => (Object.assign(m?m:{}, auth)));
if (cb) {
cb(my);
}
});
} else if (res_auth.status >= 400 && res_auth.status < 500) {
update((m) => (null));
@ -24,4 +20,14 @@ function createUserStore() {
};
}
export async function refresh_auth() {
const res = await fetch('api/auth', {headers: {'Accept': 'application/json'}})
if (res.status == 200) {
const auth = await res.json();
user.set(auth);
} else {
user.set(null);
}
}
export const user = createUserStore();

16
ui/src/routes/+layout.js Normal file
View File

@ -0,0 +1,16 @@
import { refresh_auth, user } from '$lib/stores/user';
export const ssr = false;
let refresh_interval_auth = null;
export async function load({ url }) {
refresh_interval_auth = setInterval(refresh_auth, Math.floor(Math.random() * 200000) + 200000);
refresh_auth();
const rroutes = url.pathname.split('/');
return {
rroute: rroutes.length>1?rroutes[1]:'',
};
}

View File

@ -1,51 +1,9 @@
<script context="module">
import { user } from '$lib/stores/user';
let stop_refresh = false;
let refresh_interval_auth = null;
async function refresh_auth(cb=null, interval=null) {
if (refresh_interval_auth)
clearInterval(refresh_interval_auth);
if (interval === null) {
interval = Math.floor(Math.random() * 200000) + 200000;
}
if (stop_refresh) {
return;
}
refresh_interval_auth = setInterval(refresh_auth, interval);
const res = await fetch('api/auth', {headers: {'Accept': 'application/json'}})
if (res.status == 200) {
const auth = await res.json();
user.set(auth);
} else {
user.set(null);
}
}
export async function load({ props, stuff, url }) {
refresh_auth();
const rroutes = url.pathname.split('/');
return {
props: {
...props,
rroute: rroutes.length>1?rroutes[1]:'',
},
stuff: {
...stuff,
refresh_auth,
}
};
}
</script>
<script>
import AuthButton from '$lib/components/AuthButton.svelte';
import Toaster from '$lib/components/Toaster.svelte';
import { refresh_auth, user } from '$lib/stores/user';
export let rroute = '';
export let data;
function switchAdminMode() {
var tmp = $user.is_admin;
@ -94,17 +52,17 @@
</li>
{/if}
<li class="nav-item">
<a class="nav-link" class:active={rroute === 'surveys'} href="surveys">
<a class="nav-link" class:active={data.rroute === 'surveys'} href="surveys">
Questionnaires
</a>
</li>
<li class="nav-item">
<a class="nav-link" class:active={rroute === 'works'} href="works">
<a class="nav-link" class:active={data.rroute === 'works'} href="works">
Travaux
</a>
</li>
{#if $user && $user.is_admin}
<li class="nav-item"><a class="nav-link" class:active={rroute === 'users'} href="users">Étudiants</a></li>
<li class="nav-item"><a class="nav-link" class:active={data.rroute === 'users'} href="users">Étudiants</a></li>
{/if}
<li class="nav-item"><a class="nav-link" href="virli" target="_self">VIRLI</a></li>
</ul>
@ -129,9 +87,9 @@
<img class="rounded-circle" src="//photos.cri.epita.fr/square/{$user.login}" alt="Menu" style="margin: -0.75em 0; max-height: 2.5em; border: 2px solid white;">
</a>
<ul class="dropdown-menu dropdown-menu-end">
<li><a class="dropdown-item" class:active={rroute === 'keys'} href="keys">Clef PGP</a></li>
<li><a class="dropdown-item" class:active={rroute === 'help'} href="help">Besoin d'aide&nbsp;?</a></li>
<li><a class="dropdown-item" class:active={rroute === 'bug-bounty'} href="bug-bounty">Bug Bounty</a></li>
<li><a class="dropdown-item" class:active={data.rroute === 'keys'} href="keys">Clef PGP</a></li>
<li><a class="dropdown-item" class:active={data.rroute === 'help'} href="help">Besoin d'aide&nbsp;?</a></li>
<li><a class="dropdown-item" class:active={data.rroute === 'bug-bounty'} href="bug-bounty">Bug Bounty</a></li>
<li><hr class="dropdown-divider"></li>
<li>
<button class="dropdown-item" on:click={disconnectCurrentUser}>

View File

@ -0,0 +1,5 @@
export async function load({ params }) {
return {
cid: params.cid,
};
}

View File

@ -1,15 +1,3 @@
<script context="module">
import { getWork } from '$lib/works';
export async function load({ params }) {
return {
props: {
cid: params.cid,
},
};
}
</script>
<script>
import { goto } from '$app/navigation';
@ -17,12 +5,10 @@
import CategoryAdmin from '$lib/components/CategoryAdmin.svelte';
import { Category, getCategory } from '$lib/categories';
export let cid;
export let data;
let categoryP = null;
$: {
categoryP = getCategory(cid);
}
$: categoryP = getCategory(data.cid);
</script>
{#await categoryP then category}

View File

@ -0,0 +1,5 @@
export async function load({ params }) {
return {
promo: params.promo,
};
}

View File

@ -1,17 +1,7 @@
<script context="module">
export async function load({ params }) {
return {
props: {
promo: params.promo,
}
};
}
</script>
<script>
import StudentGrades from '$lib/components/StudentGrades.svelte';
export let promo;
export let data;
</script>
<StudentGrades {promo} />
<StudentGrades promo={data.promo} />

View File

@ -0,0 +1,7 @@
export async function load({ url }) {
return {
secret: url.searchParams.get("secret"),
idsurvey: url.searchParams.get("survey"),
exportview_list: url.searchParams.get("graph_list")?false:true,
};
}

View File

@ -1,26 +1,13 @@
<script context="module">
export async function load({ url }) {
return {
props: {
secret: url.searchParams.get("secret"),
idsurvey: url.searchParams.get("survey"),
exportview_list: url.searchParams.get("graph_list")?false:true,
}
};
}
</script>
<script>
import { getSharedQuestions } from '$lib/questions';
import { getSharedSurvey } from '$lib/surveys';
import CorrectionPieChart from '$lib/components/CorrectionPieChart.svelte';
import SurveyBadge from '$lib/components/SurveyBadge.svelte';
export let secret;
export let idsurvey;
export let data;
let surveyP = getSharedSurvey(idsurvey, secret);
export let exportview_list = true;
let surveyP = null;
$: surveyP = getSharedSurvey(data.idsurvey, data.secret);
</script>
{#await surveyP then survey}
@ -32,7 +19,7 @@
<SurveyBadge class="ms-2" {survey} />
</div>
{#await getSharedQuestions(survey.id, secret)}
{#await getSharedQuestions(survey.id, data.secret)}
<div class="text-center">
<div class="spinner-border text-primary mx-3" role="status"></div>
<span>Chargement des questions &hellip;</span>
@ -40,8 +27,8 @@
{:then questions}
{#each questions as question (question.id)}
<h3>{question.title}</h3>
{#if question.kind == "text" || (exportview_list && question.kind.indexOf("list") == 0)}
{#await question.getResponses(secret) then responses}
{#if question.kind == "text" || (data.exportview_list && question.kind.indexOf("list") == 0)}
{#await question.getResponses(data.secret) then responses}
{#each responses as response (response.id)}
<div class="card mb-2">
<div class="card-body">
@ -53,7 +40,7 @@
{/each}
{/await}
{:else}
<CorrectionPieChart {question} {secret} />
<CorrectionPieChart {question} secret={data.secret} />
{/if}
<hr class="mb-3">
{/each}

View File

@ -0,0 +1,9 @@
import { getSurvey } from '$lib/surveys';
export async function load({ params }) {
const survey = getSurvey(params.sid);
return {
survey,
};
}

View File

@ -1,27 +1,8 @@
<script context="module">
import { getSurvey } from '$lib/surveys';
export async function load({ params, stuff }) {
const survey = getSurvey(params.sid);
return {
props: {
survey,
},
stuff: {
...stuff,
survey,
}
};
}
</script>
<script lang="ts">
export let survey;
export let data;
</script>
{#await survey}
{#await data.survey}
<div class="text-center">
<div class="spinner-border text-primary mx-3" role="status"></div>
<span>Chargement du questionnaire &hellip;</span>

View File

@ -0,0 +1,5 @@
export async function load({ parent }) {
const stuff = await parent();
return stuff;
}

View File

@ -1,15 +1,3 @@
<script context="module">
import { getSurvey } from '$lib/surveys';
export async function load({ params, stuff }) {
return {
props: {
surveyP: stuff.survey,
},
};
}
</script>
<script lang="ts">
import { goto } from '$app/navigation';
@ -19,49 +7,46 @@
import SurveyQuestions from '$lib/components/SurveyQuestions.svelte';
import { getQuestions } from '$lib/questions';
export let surveyP;
export let data;
let survey = null;
$: {
if (surveyP) {
surveyP.then((survey) => {
survey = data.survey;
if (survey.direct && !$user.is_admin) {
goto(`surveys/${survey.id}/live`);
}
})
}
}
let edit = false;
</script>
{#await surveyP then survey}
{#if $user && $user.is_admin}
{#if $user && $user.is_admin}
<button class="btn btn-primary ms-1 float-end" on:click={() => { edit = !edit; } } title="Éditer"><i class="bi bi-pencil"></i></button>
<a href="surveys/{survey.id}/responses" class="btn btn-success ms-1 float-end" title="Voir les réponses"><i class="bi bi-files"></i></a>
{#if survey.direct}
<a href="surveys/{survey.id}/live" class="btn btn-danger ms-1 float-end" title="Aller au direct"><i class="bi bi-film"></i></a>
{/if}
{/if}
<div class="d-flex align-items-center">
{/if}
<div class="d-flex align-items-center">
<h2>
<a href="surveys/" class="text-muted" style="text-decoration: none">&lt;</a>
{survey.title}
</h2>
<SurveyBadge class="ms-2" {survey} />
</div>
</div>
{#if $user && $user.is_admin && edit}
{#if $user && $user.is_admin && edit}
<SurveyAdmin {survey} on:saved={() => edit = false} />
{/if}
{/if}
{#await getQuestions(survey.id)}
{#await getQuestions(survey.id)}
<div class="text-center">
<div class="spinner-border text-primary mx-3" role="status"></div>
<span>Chargement des questions &hellip;</span>
</div>
{:then questions}
{:then questions}
<SurveyQuestions {survey} {questions} />
{:catch error}
{:catch error}
<div class="row mt-5">
<div class="d-none d-sm-block col-sm">
<hr>
@ -76,5 +61,4 @@
<strong><a href="surveys/{survey.id}/live">Cliquez ici pour accéder au direct</a>.</strong> Il s'agit d'un questionnaire en direct, le questionnaire n'est pas accessible sur cette page.
</div>
{/if}
{/await}
{/await}

View File

@ -0,0 +1,8 @@
export async function load({ parent, params }) {
const stuff = await parent();
return {
survey: stuff.survey,
sid: params.sid,
};
}

View File

@ -1,14 +1,3 @@
<script context="module">
export async function load({ params, stuff }) {
return {
props: {
surveyP: stuff.survey,
sid: params.sid,
},
};
}
</script>
<script>
import { user } from '$lib/stores/user';
import CorrectionPieChart from '$lib/components/CorrectionPieChart.svelte';
@ -21,28 +10,24 @@
import { getQuestion, getQuestions, Question } from '$lib/questions';
import { getUsers } from '$lib/users';
export let surveyP;
export let sid;
export let data;
let survey;
let req_questions;
surveyP.then((s) => {
survey = s;
$: {
survey = data.survey;
updateQuestions();
if (survey.direct !== null) {
wsconnect();
}
});
}
function updateSurvey() {
surveyP = getSurvey(survey.id);
surveyP.then((s) => {
survey = s;
async function updateSurvey() {
survey = await getSurvey(survey.id);
updateQuestions();
if (survey.direct !== null) {
wsconnect();
}
});
}
function updateQuestions() {
@ -162,7 +147,7 @@
function wsconnect() {
if (ws !== null) return;
ws = new WebSocket((window.location.protocol == 'https:'?'wss://':'ws://') + window.location.host + `/api/surveys/${sid}/ws-admin`);
ws = new WebSocket((window.location.protocol == 'https:'?'wss://':'ws://') + window.location.host + `/api/surveys/${data.sid}/ws-admin`);
ws.addEventListener("open", () => {
ws_up = true;
@ -233,8 +218,7 @@
}
</script>
{#await surveyP then survey}
{#if $user && $user.is_admin}
{#if $user && $user.is_admin}
<StartStopLiveSurvey
{survey}
class="ms-1 float-end"
@ -242,8 +226,8 @@
on:end={() => { if (confirm("Sûr ?")) ws.send('{"action":"end"}') }}
/>
<a href="surveys/{survey.id}/responses" class="btn btn-success ms-1 float-end" title="Voir les réponses"><i class="bi bi-files"></i></a>
{/if}
<div class="d-flex align-items-center">
{/if}
<div class="d-flex align-items-center">
<h2>
<a href="surveys/" class="text-muted" style="text-decoration: none">&lt;</a>
{survey.title}
@ -251,7 +235,7 @@
Administration
</small>
{#if asks.length}
<a href="surveys/{sid}/admin#questions_part">
<a href="surveys/{data.sid}/admin#questions_part">
<i class="bi bi-patch-question-fill text-danger"></i>
</a>
{/if}
@ -270,14 +254,14 @@
{survey}
/>
{/if}
</div>
</div>
{#if survey.direct === null}
{#if survey.direct === null}
<SurveyAdmin
{survey}
on:saved={updateSurvey}
/>
{:else}
{:else}
{#await req_questions}
<div class="text-center">
<div class="spinner-border text-primary mx-3" role="status"></div>
@ -368,7 +352,7 @@
<tr>
<td>
{#if responses[question.id]}
<a href="surveys/{sid}/admin#q{question.id}_res">
<a href="surveys/{data.sid}/admin#q{question.id}_res">
{question.title}
</a>
{:else}
@ -699,6 +683,4 @@
{/each}
</div>
{/if}
{/if}
{/await}
{/if}

View File

@ -0,0 +1,8 @@
export async function load({ params, parent }) {
const stuff = await parent();
return {
survey: stuff.survey,
sid: params.sid,
};
}

View File

@ -1,14 +1,3 @@
<script context="module">
export async function load({ params, stuff }) {
return {
props: {
surveyP: stuff.survey,
sid: params.sid,
},
};
}
</script>
<script>
import { onDestroy } from 'svelte';
@ -18,11 +7,9 @@
import QuestionForm from '$lib/components/QuestionForm.svelte';
import { getQuestion } from '$lib/questions';
export let surveyP;
export let sid;
export let data;
let survey;
surveyP.then((s) => survey = s);
$: survey = data.survey;
let ws_up = false;
let show_question = null;
@ -75,7 +62,7 @@
}
});
function wsconnect() {
ws = new WebSocket((window.location.protocol == 'https:'?'wss://':'ws://') + window.location.host + `/api/surveys/${sid}/ws`);
ws = new WebSocket((window.location.protocol == 'https:'?'wss://':'ws://') + window.location.host + `/api/surveys/${data.sid}/ws`);
ws.addEventListener("open", () => {
ws_up = true;
@ -183,23 +170,22 @@
let corrections = null;
</script>
{#await surveyP then unused}
<div
<div
style={"transition: opacity 150ms ease-out; opacity: " + (displaySendInProgress?1:0)}
class="ms-2 float-end"
>
>
<div style="position: relative; left: 25%; top: 4px">
<div style="position: absolute">
<i class="bi bi-save"></i>
</div>
</div>
<div class="spinner-border text-primary" role="status"></div>
</div>
{#if $user && $user.is_admin}
</div>
{#if $user && $user.is_admin}
<a href="surveys/{survey.id}/admin" class="btn btn-primary ms-1 float-end" title="Aller à l'interface d'administration"><i class="bi bi-pencil"></i></a>
<a href="surveys/{survey.id}/responses" class="btn btn-success ms-1 float-end" title="Voir les réponses"><i class="bi bi-files"></i></a>
{/if}
<div class="d-flex align-items-center mb-3 mb-md-4 mb-lg-5">
{/if}
<div class="d-flex align-items-center mb-3 mb-md-4 mb-lg-5">
<h2>
<a href="surveys/" class="text-muted" style="text-decoration: none">&lt;</a>
{survey.title}
@ -211,9 +197,9 @@
>
{#if ws_up}Connecté{:else}Déconnecté{/if}
</div>
</div>
</div>
<form on:submit|preventDefault={sendValue}>
<form on:submit|preventDefault={sendValue}>
{#if show_question}
{#await req_question}
<div class="text-center">
@ -298,5 +284,4 @@
La session est terminée. <small class="text-muted">On se retrouve une prochaine fois&hellip;</small>
</h2>
{/if}
</form>
{/await}
</form>

View File

@ -0,0 +1,7 @@
export async function load({ parent }) {
const stuff = await parent();
return {
survey: stuff.survey,
};
}

View File

@ -1,32 +1,20 @@
<script context="module">
import CorrectionPieChart from '$lib/components/CorrectionPieChart.svelte';
import { getSurvey } from '$lib/surveys';
import { getUsers } from '$lib/users';
export async function load({ params, stuff }) {
return {
props: {
surveyP: stuff.survey,
},
};
}
</script>
<script lang="ts">
import { goto } from '$app/navigation';
import { user } from '$lib/stores/user';
import CorrectionPieChart from '$lib/components/CorrectionPieChart.svelte';
import StartStopLiveSurvey from '$lib/components/StartStopLiveSurvey.svelte';
import SurveyAdmin from '$lib/components/SurveyAdmin.svelte';
import SurveyBadge from '$lib/components/SurveyBadge.svelte';
import SurveyQuestions from '$lib/components/SurveyQuestions.svelte';
import { getQuestions } from '$lib/questions';
import { getUsers } from '$lib/users';
export let surveyP;
let usersP = null;
surveyP.then((s) => {
usersP = getUsers(s.promo, s.group);
})
export let data;
let survey;
let usersP;
$: survey = data.survey;
$: usersP = getUsers(data.survey.promo, data.survey.group);
let edit = false;
let exportview = false;
let exportview_list = false;
@ -41,8 +29,7 @@
}
</script>
{#await surveyP then survey}
{#if $user && $user.is_admin}
{#if $user && $user.is_admin}
<button class="btn btn-primary ms-1 float-end" on:click={() => { edit = !edit; } } title="Éditer"><i class="bi bi-pencil"></i></button>
<StartStopLiveSurvey
{survey}
@ -70,26 +57,26 @@
on:click={() => { exportview_list = !exportview_list; } }
><i class="bi bi-view-list"></i></button>
{/if}
{/if}
<div class="d-flex align-items-center">
{/if}
<div class="d-flex align-items-center">
<h2>
<a href="surveys/{survey.id}" class="text-muted" style="text-decoration: none">&lt;</a>
{survey.title}
<small class="text-muted">{#if exportview}Réponses{:else}Corrections{/if}</small>
</h2>
<SurveyBadge class="ms-2" {survey} />
</div>
</div>
{#if $user && $user.is_admin && edit}
{#if $user && $user.is_admin && edit}
<SurveyAdmin {survey} on:saved={() => edit = false} />
{/if}
{/if}
{#await getQuestions(survey.id)}
{#await getQuestions(survey.id)}
<div class="text-center">
<div class="spinner-border text-primary mx-3" role="status"></div>
<span>Chargement des questions &hellip;</span>
</div>
{:then questions}
{:then questions}
{#if !exportview}
<div class="card mt-3 mb-5">
<table class="table table-hover table-striped mb-0">
@ -156,7 +143,6 @@
<hr class="mb-3">
{/each}
{/if}
{/await}
{/await}
<div class="modal fade" tabindex="-1" id="shareModal">

View File

@ -0,0 +1,8 @@
export async function load({ params, parent }) {
const stuff = await parent();
return {
survey: stuff.survey,
rid: params.rid,
};
}

View File

@ -1,16 +1,3 @@
<script context="module">
import { getSurvey } from '$lib/surveys';
export async function load({ params, stuff }) {
return {
props: {
surveyP: stuff.survey,
rid: params.rid,
},
};
}
</script>
<script lang="ts">
import Correction from '$lib/components/Correction.svelte';
import CorrectionPieChart from '$lib/components/CorrectionPieChart.svelte';
@ -20,8 +7,7 @@
import { getCorrectionTemplates } from '$lib/correctionTemplates';
import { getQuestion } from '$lib/questions';
export let surveyP;
export let rid;
export let data;
let showChart = false;
let showResponses = false;
@ -31,10 +17,11 @@
let child;
let waitApply = false;
let ctpls = getCorrectionTemplates(rid);
let filter = "";
let ctpls;
let cts = { };
$: {
ctpls = getCorrectionTemplates(data.rid);
if (ctpls) {
ctpls.then((ctpls) => {
for (const tpl of ctpls) {
cts[tpl.id] = { };
@ -46,27 +33,31 @@
}
})
}
cts = cts;
});
}
}
let filter = "";
let nodescription = false;
let y = 0;
$: nodescription = y > 10;
let survey = null;
$: survey = data.survey;
</script>
<svelte:window bind:scrollY={y} />
{#await surveyP then survey}
{#await getQuestion(rid)}
{#await getQuestion(data.rid)}
<div class="text-center">
<div class="spinner-border text-primary mx-3" role="status"></div>
<span>Chargement de la question&hellip;</span>
</div>
{:then question}
{:then question}
{#await ctpls}
<div class="text-center">
<div class="spinner-border text-primary mx-3" role="status"></div>
<span>Chargement de la question&hellip;</span>
<span>Chargement des templates&hellip;</span>
</div>
{:then correctionTemplates}
<div class="float-end">
@ -177,7 +168,6 @@
on:nb_responses={(v) => { nb_responses = v.detail; } }
/>
{/await}
{/await}
{/await}
<div class="mb-5" style="min-height: 60vh"></div>

View File

@ -0,0 +1,5 @@
export async function load({ params }) {
return {
uid: params.uid,
};
}

View File

@ -1,13 +1,3 @@
<script context="module">
export async function load({ params }) {
return {
props: {
uid: params.uid,
}
};
}
</script>
<script lang="ts">
import UserKeys from '$lib/components/UserKeys.svelte';
import UserSurveys from '$lib/components/UserSurveys.svelte';
@ -15,13 +5,13 @@
import { getSurveys } from '$lib/surveys';
import { getUser, getUserGrade, getUserScore } from '$lib/users';
export let uid;
export let data;
let allPromos = false;
let myuser = null;
let userP = null;
$: userP = getUser(uid).then((u) => myuser = u)
$: userP = getUser(data.uid).then((u) => myuser = u)
function impersonate() {
fetch('api/auth/impersonate', {

View File

@ -0,0 +1,5 @@
export async function load({ params }) {
return {
uid: params.uid,
};
}

View File

@ -1,25 +1,15 @@
<script context="module">
export async function load({ params }) {
return {
props: {
uid: params.uid,
}
};
}
</script>
<script lang="ts">
import UserSurveys from '$lib/components/UserSurveys.svelte';
import { user } from '$lib/stores/user';
import { getSurveys } from '$lib/surveys';
import { getUser, getUserGrade, getUserScore } from '$lib/users';
export let uid;
export let data;
let allPromos = false;
</script>
{#await getUser(uid)}
{#await getUser(data.uid)}
<h2>
Étudiant
</h2>

View File

@ -0,0 +1,6 @@
export async function load({ params }) {
return {
sid: params.sid,
uid: params.uid,
};
}

View File

@ -1,14 +1,3 @@
<script context="module">
export async function load({ params }) {
return {
props: {
sid: params.sid,
uid: params.uid,
}
};
}
</script>
<script lang="ts">
import SurveyBadge from '$lib/components/SurveyBadge.svelte';
import SurveyQuestions from '$lib/components/SurveyQuestions.svelte';
@ -16,11 +5,10 @@
import { getQuestions } from '$lib/questions';
import { getUser } from '$lib/users';
export let sid;
export let uid;
export let data;
</script>
{#await getUser(uid)}
{#await getUser(data.uid)}
<h2>
Étudiant
</h2>
@ -30,7 +18,7 @@
Chargement des d&eacute;tails&hellip;
</div>
{:then student}
{#await getSurvey(sid)}
{#await getSurvey(data.sid)}
<div class="text-center">
<div class="spinner-border text-primary mx-3" role="status"></div>
<span>Chargement du questionnaire &hellip;</span>
@ -50,7 +38,7 @@
<span>Chargement des questions &hellip;</span>
</div>
{:then questions}
<SurveyQuestions {survey} {questions} id_user={uid} />
<SurveyQuestions {survey} {questions} id_user={data.uid} />
{/await}
{:catch error}
<div class="text-center">

View File

@ -0,0 +1,9 @@
import { getWork } from '$lib/works';
export async function load({ params }) {
const work = getWork(params.wid);
return {
work,
};
}

View File

@ -1,27 +1,8 @@
<script context="module">
import { getWork } from '$lib/works';
export async function load({ params, stuff }) {
const work = getWork(params.wid);
return {
props: {
work,
},
stuff: {
...stuff,
work,
}
};
}
</script>
<script lang="ts">
export let work;
export let data;
</script>
{#await work}
{#await data.work}
<div class="text-center">
<div class="spinner-border text-primary mx-3" role="status"></div>
<span>Chargement du rendu &hellip;</span>

View File

@ -0,0 +1,7 @@
export async function load({ parent }) {
const stuff = await parent();
return {
work: stuff.work,
};
}

View File

@ -1,15 +1,3 @@
<script context="module">
import { getWork } from '$lib/works';
export async function load({ params, stuff }) {
return {
props: {
work: stuff.work,
},
};
}
</script>
<script lang="ts">
import { goto } from '$app/navigation';
@ -21,34 +9,33 @@
import WorkRepository from '$lib/components/WorkRepository.svelte';
import { getScore } from '$lib/users';
export let work = null;
export let data;
let edit = false;
let my_submission = null;
let warn_already_used = false;
let w = null;
work.then((w) => {
refresh_submission(w);
})
$: w = data.work;
$: refresh_submission(data.work);
function refresh_submission(w) {
my_submission = w.getSubmission();
}
</script>
{#await work then w}
{#if $user && $user.is_admin}
{#if $user && $user.is_admin}
<button class="btn btn-primary ms-1 float-end" on:click={() => { edit = !edit; } } title="Éditer"><i class="bi bi-pencil"></i></button>
<a class="btn btn-success ms-1 float-end" href="works/{w.id}/rendus" title="Voir les rendus"><i class="bi bi-files"></i></a>
{/if}
<div class="d-flex align-items-center">
{/if}
<div class="d-flex align-items-center">
<h2>
<a href="works/" class="text-muted" style="text-decoration: none">&lt;</a>
{w.title}
</h2>
<SurveyBadge class="ms-2" survey={w} />
</div>
</div>
{#if $user && $user.is_admin && edit}
{#if $user && $user.is_admin && edit}
<WorkAdmin work={w} on:saved={() => edit = false} />
{#if w.description}
@ -95,12 +82,12 @@
</table>
{/await}
</div>
{:else if (!$user || !$user.is_admin) && new Date(w.start_availability) > new Date()}
{:else if (!$user || !$user.is_admin) && new Date(w.start_availability) > new Date()}
<div class="alert alert-warning">
<i class="bi bi-stopwatch-fill"></i>
<strong>Ce travail n'est pas encore ouvert.</strong> Revenez plus tard&nbsp;!
</div>
{:else}
{:else}
<dl style="columns: 3">
<dt>Date de début</dt>
<dd><DateFormat date={new Date(w.start_availability)} dateStyle="medium" timeStyle="medium" /></dd>
@ -226,7 +213,7 @@
42sh$ git checkout renduY
-- ou --
42sh$ git checkout master
</pre>
</pre>
</div>
{/if}
<div class="alert alert-warning">
@ -237,6 +224,5 @@
Ce travail n'a pas de modalité de rendu.
</div>
{/if}
{/if}
{/await}
{/if}
<div class="mb-5"></div>

View File

@ -0,0 +1,7 @@
export async function load({ parent }) {
const stuff = await parent();
return {
work: stuff.work,
};
}

View File

@ -1,15 +1,3 @@
<script context="module">
import { getWork } from '$lib/works';
export async function load({ params, stuff }) {
return {
props: {
work: stuff.work,
},
};
}
</script>
<script lang="ts">
import { goto } from '$app/navigation';
@ -23,11 +11,13 @@
import { ToastsStore } from '$lib/stores/toasts';
import { getUsers } from '$lib/users';
export let work = null;
export let data;
let usersP = null;
let show_dl_btn = { };
let repositoriesP = { };
work.then((w) => {
let w = null;
$: {
w = data.work;
usersP = getUsers(w.promo, w.group);
usersP.then((users) => {
nb_users = users.length;
@ -36,7 +26,7 @@
updateRepoUser(w.id, user.id);
}
});
});
}
function updateRepoUser(wid, userid) {
repositoriesP[userid] = getRepositories(wid, userid);
@ -50,17 +40,16 @@
let search_repo_for = {repo: null, user: null};
</script>
{#await work then w}
<div class="d-flex align-items-center">
<div class="d-flex align-items-center">
<h2>
<a href="works/{w.id}" class="text-muted" style="text-decoration: none">&lt;</a>
{w.title}
<small class="text-muted">Rendus {Math.trunc(nb_rendus/nb_users*100)}&nbsp;% ({nb_rendus}/{nb_users})</small>
</h2>
<SurveyBadge class="ms-2" survey={w} />
</div>
</div>
{#await usersP then users}
{#await usersP then users}
<table class="w-100 mb-5">
<thead>
<tr>
@ -143,9 +132,9 @@
{/each}
</tbody>
</table>
{/await}
{/await}
<div class="modal fade" tabindex="-1" id="pullModal">
<div class="modal fade" tabindex="-1" id="pullModal">
<div class="modal-dialog">
<form class="modal-content" on:submit|preventDefault={() => {run_pull_for.modal.hide(); try { run_pull_for.repo.retrieveWork(run_pull_for.struct); updateRepoUser(w.id, run_pull_for.user.id); } catch(err) { ToastsStore.addToast({color: "danger", title: "Connexion impossible", msg: err}) };}}>
<div class="modal-header">
@ -171,9 +160,9 @@
</div>
</form>
</div>
</div>
</div>
<div class="modal fade" tabindex="-1" id="repoModal">
<div class="modal fade" tabindex="-1" id="repoModal">
<div class="modal-dialog">
<form class="modal-content" on:submit|preventDefault={() => {search_repo_for.modal.hide(); try { search_repo_for.repo.retrieveWork(run_pull_for.struct); updateRepoUser(w.id, run_pull_for.user.id); } catch(err) { ToastsStore.addToast({color: "danger", title: "Connexion impossible", msg: err}) }; search_repo_for.user = null; }}>
<div class="modal-header">
@ -187,8 +176,7 @@
</div>
</form>
</div>
</div>
{/await}
</div>
<div class="modal fade" tabindex="-1" id="logsModal">
<div class="modal-dialog modal-xl">