feat: nieuwe lijstview voor assignment
This commit is contained in:
parent
c03669eda7
commit
7e4e179121
1 changed files with 178 additions and 156 deletions
|
@ -2,55 +2,44 @@
|
||||||
import { ref, computed, onMounted, watch } from "vue";
|
import { ref, computed, onMounted, watch } from "vue";
|
||||||
import { useI18n } from "vue-i18n";
|
import { useI18n } from "vue-i18n";
|
||||||
import { useRouter } from "vue-router";
|
import { useRouter } from "vue-router";
|
||||||
|
import authState from "@/services/auth/auth-service.ts";
|
||||||
import auth from "@/services/auth/auth-service.ts";
|
import auth from "@/services/auth/auth-service.ts";
|
||||||
import { useTeacherClassesQuery } from "@/queries/teachers.ts";
|
import { useTeacherAssignmentsQuery, useTeacherClassesQuery } from "@/queries/teachers.ts";
|
||||||
import { useStudentClassesQuery } from "@/queries/students.ts";
|
import { useStudentAssignmentsQuery, useStudentClassesQuery } from "@/queries/students.ts";
|
||||||
import { ClassController } from "@/controllers/classes.ts";
|
import { ClassController } from "@/controllers/classes.ts";
|
||||||
import type { ClassDTO } from "@dwengo-1/common/interfaces/class";
|
import type { ClassDTO } from "@dwengo-1/common/interfaces/class";
|
||||||
import { asyncComputed } from "@vueuse/core";
|
import { asyncComputed } from "@vueuse/core";
|
||||||
import { useDeleteAssignmentMutation } from "@/queries/assignments.ts";
|
import { useDeleteAssignmentMutation } from "@/queries/assignments.ts";
|
||||||
|
import type { AssignmentsResponse } from "@/controllers/assignments";
|
||||||
|
import type { AssignmentDTO } from "@dwengo-1/common/interfaces/assignment";
|
||||||
|
import UsingQueryResult from "@/components/UsingQueryResult.vue";
|
||||||
|
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
|
|
||||||
const role = ref(auth.authState.activeRole);
|
const role = ref(auth.authState.activeRole);
|
||||||
const username = ref<string>("");
|
const username = ref<string | undefined>(undefined);
|
||||||
|
const isLoading = ref(false);
|
||||||
|
const isError = ref(false);
|
||||||
|
const errorMessage = ref<string>("");
|
||||||
|
|
||||||
|
// Load current user before rendering the page
|
||||||
|
onMounted(async () => {
|
||||||
|
isLoading.value = true;
|
||||||
|
try {
|
||||||
|
const userObject = await authState.loadUser();
|
||||||
|
username.value = userObject!.profile.preferred_username;
|
||||||
|
} catch (error) {
|
||||||
|
isError.value = true;
|
||||||
|
errorMessage.value = error instanceof Error ? error.message : String(error);
|
||||||
|
} finally {
|
||||||
|
isLoading.value = false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
const isTeacher = computed(() => role.value === "teacher");
|
const isTeacher = computed(() => role.value === "teacher");
|
||||||
|
|
||||||
// Fetch and store all the teacher's classes
|
const assignmentsQuery = isTeacher ? useTeacherAssignmentsQuery(username, true) : useStudentAssignmentsQuery(username, true);
|
||||||
let classesQueryResults = undefined;
|
|
||||||
|
|
||||||
if (isTeacher.value) {
|
|
||||||
classesQueryResults = useTeacherClassesQuery(username, true);
|
|
||||||
} else {
|
|
||||||
classesQueryResults = useStudentClassesQuery(username, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
//TODO: remove later
|
|
||||||
const classController = new ClassController();
|
|
||||||
|
|
||||||
//TODO: replace by query that fetches all user's assignment
|
|
||||||
const assignments = asyncComputed(async () => {
|
|
||||||
const classes = classesQueryResults?.data?.value?.classes;
|
|
||||||
if (!classes) return [];
|
|
||||||
const result = await Promise.all(
|
|
||||||
(classes as ClassDTO[]).map(async (cls) => {
|
|
||||||
const { assignments } = await classController.getAssignments(cls.id);
|
|
||||||
return assignments.map((a) => ({
|
|
||||||
id: a.id,
|
|
||||||
class: cls,
|
|
||||||
title: a.title,
|
|
||||||
description: a.description,
|
|
||||||
learningPath: a.learningPath,
|
|
||||||
language: a.language,
|
|
||||||
groups: a.groups,
|
|
||||||
}));
|
|
||||||
}),
|
|
||||||
);
|
|
||||||
|
|
||||||
return result.flat();
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
async function goToCreateAssignment(): Promise<void> {
|
async function goToCreateAssignment(): Promise<void> {
|
||||||
await router.push("/assignment/create");
|
await router.push("/assignment/create");
|
||||||
|
@ -79,32 +68,69 @@
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div class="assignments-container">
|
<main>
|
||||||
<h1>{{ t("assignments") }}</h1>
|
<h1>{{ t("assignments") }}</h1>
|
||||||
|
<div class="loading-div" v-if="isLoading">
|
||||||
<v-btn
|
<v-progress-circular indeterminate></v-progress-circular>
|
||||||
v-if="isTeacher"
|
</div>
|
||||||
color="primary"
|
<div v-if="isError">
|
||||||
class="mb-4 center-btn"
|
<v-empty-state icon="mdi-alert-circle-outline" :text="errorMessage"
|
||||||
@click="goToCreateAssignment"
|
:title="t('error_title')"></v-empty-state>
|
||||||
>
|
</div>
|
||||||
|
<div v-else>
|
||||||
|
<using-query-result :query-result="assignmentsQuery"
|
||||||
|
v-slot="assignmentsResponse: { data: AssignmentsResponse }">
|
||||||
|
<v-btn v-if="isTeacher" color="primary" class="mb-4 center-btn" @click="goToCreateAssignment">
|
||||||
{{ t("new-assignment") }}
|
{{ t("new-assignment") }}
|
||||||
</v-btn>
|
</v-btn>
|
||||||
|
<v-container>
|
||||||
|
<v-table class="table">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th class="header">{{ t("assignments") }}</th>
|
||||||
|
<th class="header">
|
||||||
|
{{ t("class") }}
|
||||||
|
</th>
|
||||||
|
<th class="header">{{ t("groups") }}</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<tr v-for="a in assignmentsResponse.data.assignments as AssignmentDTO[]"
|
||||||
|
:key="a.id + a.within">
|
||||||
|
<td>
|
||||||
|
<v-btn :to="`/class/${a.within}`" variant="text">
|
||||||
|
{{ a.title }}
|
||||||
|
<v-icon end> mdi-menu-right </v-icon>
|
||||||
|
</v-btn>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<span>{{ a.within }}</span>
|
||||||
|
<!-- <span v-if="!isMdAndDown">{{ c.id }}</span>
|
||||||
|
<span v-else style="cursor: pointer" @click="openCodeDialog(c.id)"><v-icon
|
||||||
|
icon="mdi-eye"></v-icon></span> -->
|
||||||
|
</td>
|
||||||
|
|
||||||
|
<td>{{ a.groups.length }}</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</v-table>
|
||||||
|
</v-container>
|
||||||
|
</using-query-result>
|
||||||
|
</div>
|
||||||
|
<div class="assignments-container">
|
||||||
|
<using-query-result :query-result="assignmentsQuery"
|
||||||
|
v-slot="assignmentsResponse: { data: AssignmentsResponse }">
|
||||||
<v-container>
|
<v-container>
|
||||||
<v-row>
|
<v-row>
|
||||||
<v-col
|
<v-col v-for="assignment in assignmentsResponse.data.assignments as AssignmentDTO[]"
|
||||||
v-for="assignment in assignments"
|
:key="assignment.id + assignment.within" cols="12">
|
||||||
:key="assignment.id"
|
|
||||||
cols="12"
|
|
||||||
>
|
|
||||||
<v-card class="assignment-card">
|
<v-card class="assignment-card">
|
||||||
<div class="top-content">
|
<div class="top-content">
|
||||||
<div class="assignment-title">{{ assignment.title }}</div>
|
<div class="assignment-title">{{ assignment.title }}</div>
|
||||||
<div class="assignment-class">
|
<div class="assignment-class">
|
||||||
{{ t("class") }}:
|
{{ t("class") }}:
|
||||||
<span class="class-name">
|
<span class="class-name">
|
||||||
{{ assignment.class.displayName }}
|
{{ assignment.within }}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -112,19 +138,12 @@
|
||||||
<div class="spacer"></div>
|
<div class="spacer"></div>
|
||||||
|
|
||||||
<div class="button-row">
|
<div class="button-row">
|
||||||
<v-btn
|
<v-btn color="primary" variant="text"
|
||||||
color="primary"
|
@click="goToAssignmentDetails(assignment.id, assignment.within)">
|
||||||
variant="text"
|
|
||||||
@click="goToAssignmentDetails(assignment.id, assignment.class.id)"
|
|
||||||
>
|
|
||||||
{{ t("view-assignment") }}
|
{{ t("view-assignment") }}
|
||||||
</v-btn>
|
</v-btn>
|
||||||
<v-btn
|
<v-btn v-if="isTeacher" color="red" variant="text"
|
||||||
v-if="isTeacher"
|
@click="goToDeleteAssignment(assignment.id, assignment.within)">
|
||||||
color="red"
|
|
||||||
variant="text"
|
|
||||||
@click="goToDeleteAssignment(assignment.id, assignment.class.id)"
|
|
||||||
>
|
|
||||||
{{ t("delete") }}
|
{{ t("delete") }}
|
||||||
</v-btn>
|
</v-btn>
|
||||||
</div>
|
</div>
|
||||||
|
@ -132,7 +151,10 @@
|
||||||
</v-col>
|
</v-col>
|
||||||
</v-row>
|
</v-row>
|
||||||
</v-container>
|
</v-container>
|
||||||
|
</using-query-result>
|
||||||
</div>
|
</div>
|
||||||
|
</main>
|
||||||
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue