From 3819b03065c588037ddfb9f207ff7df87187ec77 Mon Sep 17 00:00:00 2001 From: survellow <59056368+survellow@users.noreply.github.com> Date: Mon, 6 Nov 2023 16:16:05 +0100 Subject: [PATCH 01/10] 15 demo of global dialog with reactive state --- frontend/src/App.vue | 2 + frontend/src/components/AdditionalModules.vue | 1 + frontend/src/components/CalendarPreview.vue | 86 +++++++++++++++++++ frontend/src/components/ModuleSelection.vue | 14 +-- .../src/components/ModuleTemplateDialog.vue | 6 +- frontend/src/components/RenameModules.vue | 10 +-- .../components/editCalendar/EditModules.vue | 10 +-- frontend/src/main.ts | 2 + frontend/src/model/module.ts | 2 +- frontend/src/store/moduleStore.ts | 21 ++++- frontend/src/style.css | 7 ++ 11 files changed, 130 insertions(+), 31 deletions(-) create mode 100644 frontend/src/components/CalendarPreview.vue diff --git a/frontend/src/App.vue b/frontend/src/App.vue index 1b80337..7a564bb 100644 --- a/frontend/src/App.vue +++ b/frontend/src/App.vue @@ -1,10 +1,12 @@ diff --git a/frontend/src/components/AdditionalModules.vue b/frontend/src/components/AdditionalModules.vue index 868fdf4..3f2e786 100644 --- a/frontend/src/components/AdditionalModules.vue +++ b/frontend/src/components/AdditionalModules.vue @@ -111,6 +111,7 @@ function selectChange() { rounded outlined aria-label="Information" + class="small-button" @click.stop="showInfo(slotProps.option)" > diff --git a/frontend/src/components/CalendarPreview.vue b/frontend/src/components/CalendarPreview.vue new file mode 100644 index 0000000..b940042 --- /dev/null +++ b/frontend/src/components/CalendarPreview.vue @@ -0,0 +1,86 @@ + + + + + + diff --git a/frontend/src/components/ModuleSelection.vue b/frontend/src/components/ModuleSelection.vue index b7981b5..7ddb751 100644 --- a/frontend/src/components/ModuleSelection.vue +++ b/frontend/src/components/ModuleSelection.vue @@ -4,6 +4,7 @@ import { Module } from "../model/module.ts"; import moduleStore from "../store/moduleStore"; import router from "../router"; +const store = moduleStore(); const props = defineProps({ modules: { type: Array as PropType, @@ -18,9 +19,7 @@ const modulesWithSelection: Ref = ref( props.modules.map((propModule) => { return { module: propModule, - selected: moduleStore().modules.some((module: Module) => - module.isEqual ? module.isEqual(propModule) : false, - ), + selected: store.hasModule(propModule) }; }), ); @@ -48,11 +47,12 @@ watch(currentModules, (newValue: Module[]) => { }); }); -function nextStep() { - selectedModules.value.forEach((module: Module) => { - moduleStore().addModule(module); - }); +// TODO: Refactor and directly use store hashmap +watch(selectedModules, (newValue: Module[]) => { + store.overwriteModules(newValue); +}); +function nextStep() { router.push("/additional-modules"); } diff --git a/frontend/src/components/ModuleTemplateDialog.vue b/frontend/src/components/ModuleTemplateDialog.vue index e583492..9769c2d 100644 --- a/frontend/src/components/ModuleTemplateDialog.vue +++ b/frontend/src/components/ModuleTemplateDialog.vue @@ -47,9 +47,5 @@ const placeholders = ref([ diff --git a/frontend/src/components/RenameModules.vue b/frontend/src/components/RenameModules.vue index 3350100..34d3ec7 100644 --- a/frontend/src/components/RenameModules.vue +++ b/frontend/src/components/RenameModules.vue @@ -6,8 +6,9 @@ import tokenStore from "../store/tokenStore.ts"; import { ref } from "vue"; import ModuleTemplateDialog from "./ModuleTemplateDialog.vue"; +const store = moduleStore(); const tableData = ref( - moduleStore().modules.map((module) => { + store.getAllModules().map((module) => { return { Course: module.course, Module: module, @@ -22,7 +23,7 @@ const columns = ref([ ]); async function finalStep() { - const token: string = await createIndividualFeed(moduleStore().modules); + const token: string = await createIndividualFeed(store.getAllModules()); tokenStore().setToken(token); await router.push("/calendar-link"); } @@ -122,9 +123,4 @@ async function finalStep() { diff --git a/frontend/src/components/editCalendar/EditModules.vue b/frontend/src/components/editCalendar/EditModules.vue index a767e51..c079cce 100644 --- a/frontend/src/components/editCalendar/EditModules.vue +++ b/frontend/src/components/editCalendar/EditModules.vue @@ -8,8 +8,9 @@ import tokenStore from "../../store/tokenStore"; import router from "../../router"; import ModuleTemplateDialog from "../ModuleTemplateDialog.vue"; +const store = moduleStore(); const tableData = computed(() => - moduleStore().modules.map((module: Module) => { + store.getAllModules().map((module: Module) => { return { Course: module.course, Module: module, @@ -42,7 +43,7 @@ fetchedModules().then( ); async function finalStep() { - await saveIndividualFeed(tokenStore().token, moduleStore().modules); + await saveIndividualFeed(tokenStore().token, store.getAllModules()); await router.push("/calendar-link"); } @@ -150,9 +151,4 @@ async function finalStep() { diff --git a/frontend/src/main.ts b/frontend/src/main.ts index ead29f3..3c2c61f 100644 --- a/frontend/src/main.ts +++ b/frontend/src/main.ts @@ -15,6 +15,7 @@ import "primevue/resources/themes/viva-dark/theme.css"; import "primeicons/primeicons.css"; import "primeflex/primeflex.css"; import router from "./router"; +import SpeedDial from "primevue/speeddial"; import TabView from "primevue/tabview"; import TabPanel from "primevue/tabpanel"; import Tag from "primevue/tag"; @@ -47,6 +48,7 @@ app.component("InputSwitch", InputSwitch); app.component("Card", Card); app.component("DataView", DataView); app.component("ToggleButton", ToggleButton); +app.component("SpeedDial", SpeedDial); app.component("TabView", TabView); app.component("TabPanel", TabPanel); app.component("MultiSelect", MultiSelect); diff --git a/frontend/src/model/module.ts b/frontend/src/model/module.ts index 01f277d..e08c18b 100644 --- a/frontend/src/model/module.ts +++ b/frontend/src/model/module.ts @@ -12,7 +12,7 @@ export class Module { public events: Event[] = [], ) {} - isEqual(module: Module): Boolean { + isEqual(module: Module): boolean { return this.name === module.name && this.course === module.course; } } diff --git a/frontend/src/store/moduleStore.ts b/frontend/src/store/moduleStore.ts index 27f6a2b..0324000 100644 --- a/frontend/src/store/moduleStore.ts +++ b/frontend/src/store/moduleStore.ts @@ -3,17 +3,30 @@ import { defineStore } from "pinia"; const moduleStore = defineStore("moduleStore", { state: () => ({ - modules: [] as Module[], + modules: new Map(), }), actions: { addModule(module: Module) { - this.modules.push(module); + this.modules.set(module.uuid, module); }, removeModule(module: Module) { - this.modules.splice(this.modules.indexOf(module), 1); + this.modules.delete(module.uuid); + }, + hasModule(module: Module): boolean { + return this.modules.has(module.uuid) && + (this.modules.get(module.uuid)?.isEqual(module) ?? false); }, removeAllModules() { - this.modules = []; + this.modules.clear(); + }, + overwriteModules(modules: Module[]) { + this.modules.clear(); + modules.forEach((module) => { + this.modules.set(module.uuid, module); + }); + }, + getAllModules(): Module[] { + return Array.from(this.modules.values()); }, }, }); diff --git a/frontend/src/style.css b/frontend/src/style.css index 4d2c94a..99b676e 100644 --- a/frontend/src/style.css +++ b/frontend/src/style.css @@ -1,3 +1,10 @@ body { font-family: var(--font-family); } + +.small-button.p-button.p-button-icon-only, +.small-button.p-button.p-button-icon-only.p-button-rounded { + width: 2rem; + height: 2rem; + padding: 0; +} From bcd1dd714d31e027f07e2a026f7b358390f3458c Mon Sep 17 00:00:00 2001 From: survellow <59056368+survellow@users.noreply.github.com> Date: Mon, 20 Nov 2023 02:24:22 +0100 Subject: [PATCH 02/10] 15 refactor additional modules to table --- backend/Dockerfile | 2 +- backend/go.mod | 2 +- frontend/src/components/AdditionalModules.vue | 158 ++++++++++++++++-- frontend/src/store/moduleStore.ts | 3 + 4 files changed, 151 insertions(+), 14 deletions(-) diff --git a/backend/Dockerfile b/backend/Dockerfile index 67a9d42..655af93 100644 --- a/backend/Dockerfile +++ b/backend/Dockerfile @@ -1,4 +1,4 @@ -FROM golang:1.21.3-alpine +FROM golang:1.21-alpine # Set the Current Working Directory inside the container WORKDIR /app diff --git a/backend/go.mod b/backend/go.mod index 660cc3d..3a2ca8b 100644 --- a/backend/go.mod +++ b/backend/go.mod @@ -1,6 +1,6 @@ module htwkalender -go 1.21.3 +go 1.21 require ( github.com/google/uuid v1.3.1 diff --git a/frontend/src/components/AdditionalModules.vue b/frontend/src/components/AdditionalModules.vue index 3f2e786..bf08122 100644 --- a/frontend/src/components/AdditionalModules.vue +++ b/frontend/src/components/AdditionalModules.vue @@ -3,7 +3,7 @@ import { defineAsyncComponent, ref, Ref } from "vue"; import { Module } from "../model/module.ts"; import { fetchAllModules } from "../api/fetchCourse.ts"; import moduleStore from "../store/moduleStore.ts"; -import { MultiSelectAllChangeEvent } from "primevue/multiselect"; +import { FilterMatchMode } from "primevue/api"; import { useDialog } from "primevue/usedialog"; const dialog = useDialog(); @@ -15,9 +15,25 @@ const fetchedModules = async () => { return await fetchAllModules(); }; +const store = moduleStore(); const modules: Ref = ref([]); +const filters = ref({ + course: { + value: null, + matchMode: FilterMatchMode.CONTAINS, + }, + name: { + value: null, + matchMode: FilterMatchMode.CONTAINS, + }, + prof: { + value: null, + matchMode: FilterMatchMode.CONTAINS, + } +}); -const selectedModules: Ref = ref([] as Module[]); +//const selectedModules: Ref = ref([] as Module[]); +//const additionalModules: Ref> = ref(new Map()); fetchedModules().then( (data) => @@ -27,9 +43,9 @@ fetchedModules().then( ); async function nextStep() { - selectedModules.value.forEach((module: Module) => { - moduleStore().addModule(module); - }); + //selectedModules.value.forEach((module: Module) => { + // moduleStore().addModule(module); + //}); await router.push("/rename-modules"); } @@ -59,20 +75,42 @@ async function showInfo(module: Module) { }); } +/* const display = (module: Module) => module.name + " (" + module.course + ")"; const selectAll = ref(false); const onSelectAllChange = (event: MultiSelectAllChangeEvent) => { - selectedModules.value = event.checked - ? modules.value.map((module: Module) => module) - : []; + if (event.checked) { + additionalModules.value = new Map( + modules.value + .filter((module: Module) => !store.hasModule(module)) + .map((module: Module) => [module.uuid, module]), + ); + store.overwriteModules(modules.value); + } else { + store.overwriteModules( + store.getAllModules().filter( + (module: Module) => !additionalModules.value.has(module.uuid) + ) + ); + additionalModules.value.clear(); + } + selectAll.value = event.checked; }; -function selectChange() { - selectAll.value = selectedModules.value.length === modules.value.length; +function selectChange(event : MultiSelectChangeEvent) { + let wasSelected: boolean = additionalModules.value.has(event.value.uuid); + + if (event.originalEvent.target.) { + additionalModules.value.set(event.value.uuid, event.value); + } else { + additionalModules.value.delete(event.value.uuid); + } + selectAll.value = store.countModules() === modules.value.length; } +*/