From b647a8f4d7eadad32e47e22f1c3defe6b0e85651 Mon Sep 17 00:00:00 2001 From: Bram Kreulen Date: Fri, 15 Nov 2024 00:43:03 +0100 Subject: [PATCH] load animation --- src/lib/assets/burger-icon.svg | 1 - src/lib/components/Layout.svelte | 62 ++++++++++ src/lib/components/ListRow.svelte | 11 +- src/lib/components/Loading.svelte | 100 +++++++++++++++++ src/lib/components/Modal.svelte | 9 +- src/lib/components/SortableList.svelte | 38 ++++--- .../scripts/controllers/CourseController.ts | 10 ++ src/routes/app/+layout.svelte | 55 +-------- .../course/[course]/overview/+page.server.ts | 16 ++- .../app/course/[course]/overview/+page.svelte | 92 +++++++++++++++ .../app/course/[course]/overview/+page.ts | 27 ----- .../course/[course]/overview/+page@.svelte | 52 --------- .../course/[course]/overview/GraphRow.svelte | 4 +- .../app/course/[course]/overview/stores.ts | 19 +--- .../course/[course]/settings/+page.server.ts | 24 ++-- .../app/course/[course]/settings/+page.svelte | 96 ++++++++++++++++ .../app/course/[course]/settings/+page.ts | 26 ----- .../course/[course]/settings/+page@.svelte | 58 ---------- src/routes/app/dashboard/+page.server.ts | 8 +- .../dashboard/{+page@.svelte => +page.svelte} | 104 +++++++++++------ src/routes/app/dashboard/+page.ts | 27 ----- src/routes/app/graph/+page.ts | 6 + src/routes/app/graph/[graph]/+page.ts | 7 ++ .../graph/[graph]/settings/+page.server.ts | 22 ++++ .../app/graph/[graph]/settings/+page.svelte | 106 ++++++++++++++++++ .../graph/[graph]/settings/DomainTab.svelte | 22 ++++ .../graph/[graph]/settings/GeneralCard.svelte | 66 +++++++++++ .../graph/[graph]/settings/LectureTab.svelte | 2 + .../graph/[graph]/settings/SubjectTab.svelte | 2 + .../app/graph/[graph]/settings/stores.ts | 11 ++ .../[program]/settings/+page.server.ts | 19 ++-- .../program/[program]/settings/+page.svelte | 89 +++++++++++++++ .../app/program/[program]/settings/+page.ts | 25 ----- .../program/[program]/settings/+page@.svelte | 55 --------- .../app/program/[program]/settings/stores.ts | 4 +- 35 files changed, 842 insertions(+), 433 deletions(-) delete mode 100644 src/lib/assets/burger-icon.svg create mode 100644 src/lib/components/Layout.svelte create mode 100644 src/lib/components/Loading.svelte create mode 100644 src/routes/app/course/[course]/overview/+page.svelte delete mode 100644 src/routes/app/course/[course]/overview/+page.ts delete mode 100644 src/routes/app/course/[course]/overview/+page@.svelte create mode 100644 src/routes/app/course/[course]/settings/+page.svelte delete mode 100644 src/routes/app/course/[course]/settings/+page.ts delete mode 100644 src/routes/app/course/[course]/settings/+page@.svelte rename src/routes/app/dashboard/{+page@.svelte => +page.svelte} (75%) delete mode 100644 src/routes/app/dashboard/+page.ts create mode 100644 src/routes/app/graph/+page.ts create mode 100644 src/routes/app/graph/[graph]/+page.ts create mode 100644 src/routes/app/graph/[graph]/settings/+page.server.ts create mode 100644 src/routes/app/graph/[graph]/settings/+page.svelte create mode 100644 src/routes/app/graph/[graph]/settings/DomainTab.svelte create mode 100644 src/routes/app/graph/[graph]/settings/GeneralCard.svelte create mode 100644 src/routes/app/graph/[graph]/settings/LectureTab.svelte create mode 100644 src/routes/app/graph/[graph]/settings/SubjectTab.svelte create mode 100644 src/routes/app/graph/[graph]/settings/stores.ts create mode 100644 src/routes/app/program/[program]/settings/+page.svelte delete mode 100644 src/routes/app/program/[program]/settings/+page.ts delete mode 100644 src/routes/app/program/[program]/settings/+page@.svelte diff --git a/src/lib/assets/burger-icon.svg b/src/lib/assets/burger-icon.svg deleted file mode 100644 index 79039c0..0000000 --- a/src/lib/assets/burger-icon.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/components/Layout.svelte b/src/lib/components/Layout.svelte new file mode 100644 index 0000000..06fe99e --- /dev/null +++ b/src/lib/components/Layout.svelte @@ -0,0 +1,62 @@ + +
+
+ +
+ + {#if $$slots.toolbar} +
+ +
+ {/if} + +
+ +
+
+ + + + + + \ No newline at end of file diff --git a/src/lib/components/ListRow.svelte b/src/lib/components/ListRow.svelte index d755ef9..364399d 100644 --- a/src/lib/components/ListRow.svelte +++ b/src/lib/components/ListRow.svelte @@ -1,7 +1,7 @@ -
+ -
+ + + \ No newline at end of file diff --git a/src/lib/components/Modal.svelte b/src/lib/components/Modal.svelte index 99bcaa3..308d3d6 100644 --- a/src/lib/components/Modal.svelte +++ b/src/lib/components/Modal.svelte @@ -38,7 +38,6 @@ - {#if visible}
@@ -79,16 +78,16 @@ background-color: black .modal - display: flex - flex-flow: column nowrap - gap: 1rem - position: fixed translate: -50% -50% z-index: 1000 top: 50% left: 50% + display: flex + flex-flow: column nowrap + gap: 1rem + width: 100% max-width: $small-column padding: $card-thick-padding diff --git a/src/lib/components/SortableList.svelte b/src/lib/components/SortableList.svelte index 06c14a0..b11bb5b 100644 --- a/src/lib/components/SortableList.svelte +++ b/src/lib/components/SortableList.svelte @@ -1,15 +1,13 @@ {#if list?.length} @@ -109,7 +117,7 @@ width: $total-icon-size height: $total-icon-size - cursor: grab + cursor: ns-resize user-select: none \ No newline at end of file diff --git a/src/lib/scripts/controllers/CourseController.ts b/src/lib/scripts/controllers/CourseController.ts index a33ec96..af23f32 100644 --- a/src/lib/scripts/controllers/CourseController.ts +++ b/src/lib/scripts/controllers/CourseController.ts @@ -119,6 +119,16 @@ class CourseController { return result } + // Copy properties + get copy_options(): DropdownOption[] { + const courses = this.cache.all(CourseController) + return courses.map(course => ({ + value: course, + label: course.name, + validation: Validation.success() + })) + } + // Graph properties get graph_ids(): number[] { if (this._graph_ids === undefined) diff --git a/src/routes/app/+layout.svelte b/src/routes/app/+layout.svelte index b67588d..d86e12a 100644 --- a/src/routes/app/+layout.svelte +++ b/src/routes/app/+layout.svelte @@ -2,9 +2,7 @@ + + + + + + await $course.save()} /> + +{#await revive()} + +{:then} + + + + + Course settings + + + Here you can view the graphs and links associated to this course, and edit their properties. + + + + + +{/await} \ No newline at end of file diff --git a/src/routes/app/course/[course]/overview/+page.ts b/src/routes/app/course/[course]/overview/+page.ts deleted file mode 100644 index be580e8..0000000 --- a/src/routes/app/course/[course]/overview/+page.ts +++ /dev/null @@ -1,27 +0,0 @@ - -// External dependencies -import type { PageLoad } from './$types' - -// Internal dependencies -import { course, courses } from './stores' - -import { - ControllerCache, - CourseController, - GraphController, - LinkController -} from '$scripts/controllers' - -// Load -export const load: PageLoad = async ({ data }) => { - const cache = new ControllerCache() - - // Revive controllers into stores - course.set(CourseController.revive(cache, data.course)) - courses.set(data.courses.map(course => CourseController.revive(cache, course))) - - // Revive controllers into cache - data.graphs.forEach(graph => GraphController.revive(cache, graph)) - data.links.forEach(link => LinkController.revive(cache, link)) - data.lectures.forEach(lecture => GraphController.revive(cache, lecture)) -} \ No newline at end of file diff --git a/src/routes/app/course/[course]/overview/+page@.svelte b/src/routes/app/course/[course]/overview/+page@.svelte deleted file mode 100644 index bdb7c6f..0000000 --- a/src/routes/app/course/[course]/overview/+page@.svelte +++ /dev/null @@ -1,52 +0,0 @@ - - - - - - - - - - - - - - Course settings - - - Here you can view the graphs and links associated to this course, and edit their properties. - - - - - \ No newline at end of file diff --git a/src/routes/app/course/[course]/overview/GraphRow.svelte b/src/routes/app/course/[course]/overview/GraphRow.svelte index 3680019..ce5ca45 100644 --- a/src/routes/app/course/[course]/overview/GraphRow.svelte +++ b/src/routes/app/course/[course]/overview/GraphRow.svelte @@ -2,7 +2,7 @@ + + + + + + await $course.save()} /> + +{#await revive()} + +{:then} + + + + Course overview + + + Here you can change your course settings, like its coordinators, graphs, links, etc. + + + + + + + +{/await} diff --git a/src/routes/app/course/[course]/settings/+page.ts b/src/routes/app/course/[course]/settings/+page.ts deleted file mode 100644 index b6a0523..0000000 --- a/src/routes/app/course/[course]/settings/+page.ts +++ /dev/null @@ -1,26 +0,0 @@ - -// External dependencies -import type { PageLoad } from './$types' - -// Internal dependencies -import { course } from './stores' - -import { - ControllerCache, - ProgramController, - CourseController, - UserController -} from '$scripts/controllers' - -// Load -export const load: PageLoad = async ({ data }) => { - const cache = new ControllerCache() - - // Revive controllers into stores - course.set(CourseController.revive(cache, data.course)) - - // Revive controllers into cache - data.programs.forEach(program => ProgramController.revive(cache, program)) - data.users.forEach(user => UserController.revive(cache, user)) - data.courses.forEach(course => CourseController.revive(cache, course)) -} \ No newline at end of file diff --git a/src/routes/app/course/[course]/settings/+page@.svelte b/src/routes/app/course/[course]/settings/+page@.svelte deleted file mode 100644 index ef8b2ee..0000000 --- a/src/routes/app/course/[course]/settings/+page@.svelte +++ /dev/null @@ -1,58 +0,0 @@ - - - - - - - - - - - - - - Course overview - - - Here you can change your course settings, like its coordinators, graphs, links, etc. - - - - - - - diff --git a/src/routes/app/dashboard/+page.server.ts b/src/routes/app/dashboard/+page.server.ts index 504b56e..25d5a05 100644 --- a/src/routes/app/dashboard/+page.server.ts +++ b/src/routes/app/dashboard/+page.server.ts @@ -11,8 +11,12 @@ export const load: PageServerLoad = async () => { // Get data from the database const programs = await ProgramHelper.getAll('courses', 'admins') - const courses = await CourseHelper.getAll() - const admins = await asyncFlatmap(programs, program => ProgramHelper.getAdmins(program.id)) + + // Start data streams + const courses = CourseHelper.getAll() + .catch(error => { throw new Error(error) }) + const admins = asyncFlatmap(programs, program => ProgramHelper.getAdmins(program.id)) + .catch(error => { throw new Error(error) }) return { programs, courses, admins } } diff --git a/src/routes/app/dashboard/+page@.svelte b/src/routes/app/dashboard/+page.svelte similarity index 75% rename from src/routes/app/dashboard/+page@.svelte rename to src/routes/app/dashboard/+page.svelte index 7e62452..d230fd4 100644 --- a/src/routes/app/dashboard/+page@.svelte +++ b/src/routes/app/dashboard/+page.svelte @@ -9,23 +9,29 @@ import * as settings from '$scripts/settings' import { programs, courses } from './stores' - import { ProgramController, CourseController } from '$scripts/controllers' import { Validation, Severity } from '$scripts/validation' import { FormModal } from '$scripts/modals' + import { + ControllerCache, + ProgramController, + CourseController, + UserController + } from '$scripts/controllers' + // Components - import Layout from '$routes/app/+layout.svelte' + import CoursesCard from './CoursesCard.svelte' + import ProgramCard from './ProgramCard.svelte' import Textfield from '$components/Textfield.svelte' - import Feedback from '$components/Feedback.svelte' import Searchbar from '$components/Searchbar.svelte' + import Feedback from '$components/Feedback.svelte' + import Loading from '$components/Loading.svelte' + import Layout from '$components/Layout.svelte' import Navbar from '$components/Navbar.svelte' import Button from '$components/Button.svelte' import Modal from '$components/Modal.svelte' - import CoursesCard from './CoursesCard.svelte' - import ProgramCard from './ProgramCard.svelte' - // Assets import plus_icon from '$assets/plus-icon.svg' @@ -164,9 +170,31 @@ } } - // Exports + // Functions + async function revive() { + + // Await all promises + const [ + awaited_courses, + awaited_programs, + awaited_admins + ] = await Promise.all([ + data.courses, + data.programs, + data.admins + ]) + + // Revive controllers into stores + programs.set(awaited_programs.map(program => ProgramController.revive(cache, program))) + courses.set(awaited_courses.map(course => CourseController.revive(cache, course))) + + // Revive controllers into cache + awaited_admins.forEach(admin => UserController.revive(cache, admin)) + } + + // Initialization export let data: PageData - const cache = data.cache + const cache = new ControllerCache() // Modals let program_modal = new ProgramModal() @@ -222,31 +250,35 @@ - - - - Welcome to your Dashboard! Here you can find all Programs and associated Courses. Click on any of them to edit or view - more information. You can also create a sandbox environment to experiment with the Graph Editor. Can't find a specific - Program or Course? Maybe you don't have access to it. Contact one of its Admins to get access. - - - - - - - -
- - - - - - - {#each $programs as program} - - {/each} - \ No newline at end of file +{#await revive()} + +{:then} + + + + Welcome to your Dashboard! Here you can find all Programs and associated Courses. Click on any of them to edit or view + more information. You can also create a sandbox environment to experiment with the Graph Editor. Can't find a specific + Program or Course? Maybe you don't have access to it. Contact one of its Admins to get access. + + + + + + + +
+ + + + + + + {#each $programs as program} + + {/each} + +{/await} \ No newline at end of file diff --git a/src/routes/app/dashboard/+page.ts b/src/routes/app/dashboard/+page.ts deleted file mode 100644 index 3f66a6b..0000000 --- a/src/routes/app/dashboard/+page.ts +++ /dev/null @@ -1,27 +0,0 @@ - -// External dependencies -import type { PageLoad } from './$types' - -// Internal dependencies -import { programs, courses } from './stores' - -import { - ControllerCache, - ProgramController, - CourseController, - UserController -} from '$scripts/controllers' - -// Load -export const load: PageLoad = async ({ data }) => { - const cache = new ControllerCache() - - // Revive controllers into stores - programs.set(data.programs.map(program => ProgramController.revive(cache, program))) - courses.set(data.courses.map(course => CourseController.revive(cache, course))) - - // Revive controllers into cache - data.admins.forEach(admin => UserController.revive(cache, admin)) - - return { cache } -} \ No newline at end of file diff --git a/src/routes/app/graph/+page.ts b/src/routes/app/graph/+page.ts new file mode 100644 index 0000000..0ab5b53 --- /dev/null +++ b/src/routes/app/graph/+page.ts @@ -0,0 +1,6 @@ + +import { redirect } from '@sveltejs/kit' + +export const load = () => { + redirect(302, `/app/dashboard`) +} diff --git a/src/routes/app/graph/[graph]/+page.ts b/src/routes/app/graph/[graph]/+page.ts new file mode 100644 index 0000000..7491684 --- /dev/null +++ b/src/routes/app/graph/[graph]/+page.ts @@ -0,0 +1,7 @@ + +import { redirect } from '@sveltejs/kit' +import type { PageLoad } from './$types' + +export const load: PageLoad = ({ params }) => { + redirect(302, `/app/graph/${params.graph}/settings`) // TODO Change to /app/graph/${params.graph}/overview +} diff --git a/src/routes/app/graph/[graph]/settings/+page.server.ts b/src/routes/app/graph/[graph]/settings/+page.server.ts new file mode 100644 index 0000000..636cf76 --- /dev/null +++ b/src/routes/app/graph/[graph]/settings/+page.server.ts @@ -0,0 +1,22 @@ + +// External dependencies +import type { PageServerLoad } from './$types' + +import { + GraphHelper +} from '$scripts/helpers' + +// Load +export const load: PageServerLoad = async ({ params }) => { + const graph_id = Number(params.graph) + if (isNaN(graph_id)) + return Promise.reject('Invalid graph ID') + + // Start data streams + const graph = GraphHelper.getById(graph_id, 'course', 'domains') + .catch(error => { throw new Error(error) }) + const course = GraphHelper.getCourse(graph_id) + .catch(error => { throw new Error(error) }) + + return { graph, course } +} diff --git a/src/routes/app/graph/[graph]/settings/+page.svelte b/src/routes/app/graph/[graph]/settings/+page.svelte new file mode 100644 index 0000000..95ceb2f --- /dev/null +++ b/src/routes/app/graph/[graph]/settings/+page.svelte @@ -0,0 +1,106 @@ + + + + + + + + + $graph.save()} /> + +{#await revive()} + +{:then} + + + + + Here you can change your graph settings, like its domains, subjects, and lectures. + + + + + + +{/await} diff --git a/src/routes/app/graph/[graph]/settings/DomainTab.svelte b/src/routes/app/graph/[graph]/settings/DomainTab.svelte new file mode 100644 index 0000000..edd18b8 --- /dev/null +++ b/src/routes/app/graph/[graph]/settings/DomainTab.svelte @@ -0,0 +1,22 @@ + + + + {item.name} + \ No newline at end of file diff --git a/src/routes/app/graph/[graph]/settings/GeneralCard.svelte b/src/routes/app/graph/[graph]/settings/GeneralCard.svelte new file mode 100644 index 0000000..170e8d4 --- /dev/null +++ b/src/routes/app/graph/[graph]/settings/GeneralCard.svelte @@ -0,0 +1,66 @@ + + + + + + + +

Delete Graph

+ Are you certain you want to archive this graph? + When you archive a graph, it, and all associated courses and graphs, will no longer be visible to anyone except super-admins. Only they can restore them. + + + delete_modal.hide()}> Cancel + + +
+ + + +

General

+
+ + + + + + { + if ($graph.validateName().severity !== Severity.error) { + await $graph.save() + } + }} + /> + + + \ No newline at end of file diff --git a/src/routes/app/graph/[graph]/settings/LectureTab.svelte b/src/routes/app/graph/[graph]/settings/LectureTab.svelte new file mode 100644 index 0000000..50d2d01 --- /dev/null +++ b/src/routes/app/graph/[graph]/settings/LectureTab.svelte @@ -0,0 +1,2 @@ + +lectures! \ No newline at end of file diff --git a/src/routes/app/graph/[graph]/settings/SubjectTab.svelte b/src/routes/app/graph/[graph]/settings/SubjectTab.svelte new file mode 100644 index 0000000..878afd5 --- /dev/null +++ b/src/routes/app/graph/[graph]/settings/SubjectTab.svelte @@ -0,0 +1,2 @@ + +subjects! \ No newline at end of file diff --git a/src/routes/app/graph/[graph]/settings/stores.ts b/src/routes/app/graph/[graph]/settings/stores.ts new file mode 100644 index 0000000..d36ad29 --- /dev/null +++ b/src/routes/app/graph/[graph]/settings/stores.ts @@ -0,0 +1,11 @@ + +// External dependencies +import { writable } from 'svelte/store' + +// Internal dependencies +import type { + GraphController +} from '$scripts/controllers' + +// Exports +export const graph = writable() \ No newline at end of file diff --git a/src/routes/app/program/[program]/settings/+page.server.ts b/src/routes/app/program/[program]/settings/+page.server.ts index 3208564..a1d23d3 100644 --- a/src/routes/app/program/[program]/settings/+page.server.ts +++ b/src/routes/app/program/[program]/settings/+page.server.ts @@ -2,10 +2,10 @@ // External dependencies import type { PageServerLoad } from './$types' -import { +import { CourseHelper, - ProgramHelper, - UserHelper + ProgramHelper, + UserHelper } from '$scripts/helpers' // Load @@ -13,11 +13,14 @@ export const load: PageServerLoad = async ({ params }) => { const program_id = Number(params.program) if (isNaN(program_id)) return Promise.reject('Invalid program ID') - - // Get data from the database - const program = await ProgramHelper.getById(program_id, 'courses', 'editors', 'admins') - const courses = await CourseHelper.getAll() // For adding courses - const users = await UserHelper.getAll() // For adding users + + // Start data streams + const program = ProgramHelper.getById(program_id, 'courses', 'editors', 'admins') + .catch(error => { throw new Error(error) }) + const courses = CourseHelper.getAll() + .catch(error => { throw new Error(error) }) + const users = UserHelper.getAll() + .catch(error => { throw new Error(error) }) return { program, courses, users } } diff --git a/src/routes/app/program/[program]/settings/+page.svelte b/src/routes/app/program/[program]/settings/+page.svelte new file mode 100644 index 0000000..576c679 --- /dev/null +++ b/src/routes/app/program/[program]/settings/+page.svelte @@ -0,0 +1,89 @@ + + + + + + + + + await $program.save()} /> + +{#await revive()} + +{:then} + + + + + Here you can change your program settings, like its courses and coordinators. + + + + + + + +{/await} diff --git a/src/routes/app/program/[program]/settings/+page.ts b/src/routes/app/program/[program]/settings/+page.ts deleted file mode 100644 index 64513b6..0000000 --- a/src/routes/app/program/[program]/settings/+page.ts +++ /dev/null @@ -1,25 +0,0 @@ - -// External dependencies -import type { PageLoad } from './$types' - -// Internal dependencies -import { program } from './stores' - -import { - ControllerCache, - ProgramController, - CourseController -} from '$scripts/controllers' -import { UserController } from '$scripts/controllers' - -// Load -export const load: PageLoad = async ({ data }) => { - const cache = new ControllerCache() - - // Revive controllers into stores - program.set(ProgramController.revive(cache, data.program)) - - // Revive controllers into cache - data.courses.forEach(course => CourseController.revive(cache, course)) - data.users.forEach(user => UserController.revive(cache, user)) -} \ No newline at end of file diff --git a/src/routes/app/program/[program]/settings/+page@.svelte b/src/routes/app/program/[program]/settings/+page@.svelte deleted file mode 100644 index c56fadf..0000000 --- a/src/routes/app/program/[program]/settings/+page@.svelte +++ /dev/null @@ -1,55 +0,0 @@ - - - - - - - - - - - - - - - Here you can change your program settings, like its courses and coordinators. - - - - - - - diff --git a/src/routes/app/program/[program]/settings/stores.ts b/src/routes/app/program/[program]/settings/stores.ts index 614c35e..5859983 100644 --- a/src/routes/app/program/[program]/settings/stores.ts +++ b/src/routes/app/program/[program]/settings/stores.ts @@ -3,9 +3,7 @@ import { writable } from 'svelte/store' // Internal dependencies -import type { - ProgramController -} from '$scripts/controllers' +import type { ProgramController } from '$scripts/controllers' // Exports export const program = writable() \ No newline at end of file