(),
{
courses: () => [],
showPast: false,
+ cols: 4,
},
);
@@ -25,15 +28,18 @@ const { projects, getProjectsByCourse } = useProject();
/* State */
// The merged projects from all courses
-const allProjects = computed(() => props.courses.flatMap((course) => course.projects));
+const allProjects = computed(() => props.courses?.flatMap((course) => course.projects) ?? null);
/**
* Sorts the projects by deadline
*/
const sortedProjects = computed(() => {
- const projects = allProjects.value.filter((project) =>
- !props.showPast ? moment(project.deadline).isAfter() : true,
- );
+ const projects =
+ allProjects.value?.filter((project) => (!props.showPast ? moment(project.deadline).isAfter() : true)) ?? null;
+
+ if (projects === null) {
+ return projects;
+ }
return [...projects].sort((a, b) => new Date(a.deadline).getTime() - new Date(b.deadline).getTime());
});
@@ -41,18 +47,20 @@ const sortedProjects = computed(() => {
/* Watchers */
watch(
() => props.courses,
- async (courses: Course[]) => {
- for (const course of courses) {
- // Fetch the projects for the course
- await getProjectsByCourse(course.id);
+ async (courses: Course[] | null) => {
+ if (courses !== null) {
+ for (const course of courses) {
+ // Fetch the projects for the course
+ await getProjectsByCourse(course.id);
- // Assign the course to the projects
- projects.value?.forEach((project) => {
- project.course = course;
- });
+ // Assign the course to the projects
+ projects.value?.forEach((project) => {
+ project.course = course;
+ });
- // Assign the projects to the course
- course.projects = projects.value ?? [];
+ // Assign the projects to the course
+ course.projects = projects.value ?? [];
+ }
}
},
{
@@ -62,18 +70,35 @@ watch(
-
-
-
-
+
+
+
+
+
+
+
+
{{ t('views.dashboard.no_projects') }}
+
+
+
+
+
+
-
-
-
-
-
{{ t('views.dashboard.no_projects') }}
-
-
+
+
diff --git a/frontend/src/composables/glob.ts b/frontend/src/composables/glob.ts
new file mode 100644
index 00000000..1f87e971
--- /dev/null
+++ b/frontend/src/composables/glob.ts
@@ -0,0 +1,42 @@
+export interface GlobModule {
+ default: any;
+}
+
+export interface GlobState {
+ getRandomImport: () => any;
+ getImport: (key: string) => any;
+}
+
+export function useGlob(glob: Record
): GlobState {
+ /**
+ * Get a random import from the glob.
+ *
+ * @returns A random import from the glob.
+ */
+ function getRandomImport(): any {
+ const keys = Object.keys(glob);
+ const randomKey = keys[Math.floor(Math.random() * keys.length)];
+ return glob[randomKey].default;
+ }
+
+ /**
+ * Get an import from the glob.
+ *
+ * @param key
+ */
+ function getImport(key: string): any {
+ if (key in glob) {
+ return glob[key].default;
+ }
+
+ return Object.values(glob).find((module) => {
+ const parts = module.default.split('/');
+ return parts[parts.length - 1] === key;
+ })?.default;
+ }
+
+ return {
+ getRandomImport,
+ getImport,
+ };
+}
diff --git a/frontend/src/views/dashboard/roles/StudentDashboardView.vue b/frontend/src/views/dashboard/roles/StudentDashboardView.vue
index fe7d3fcf..5032df43 100644
--- a/frontend/src/views/dashboard/roles/StudentDashboardView.vue
+++ b/frontend/src/views/dashboard/roles/StudentDashboardView.vue
@@ -24,7 +24,7 @@ const selectedYear = ref(User.getAcademicYear());
const showPast = ref(false);
const filteredCourses = computed(
- () => courses.value?.filter((course) => course.academic_startyear === selectedYear.value) ?? [],
+ () => courses.value?.filter((course) => course.academic_startyear === selectedYear.value) ?? null,
);
/* Watchers */