mirror of
https://gitlab.dit.htwk-leipzig.de/htwk-software/htwkalender.git
synced 2025-08-04 02:39:14 +02:00
Merge branch 'main' into 15-calendar-preview
# Conflicts: # frontend/src/view/AdditionalModules.vue # frontend/src/view/EditCalendarView.vue
This commit is contained in:
@@ -1,13 +1,8 @@
|
||||
import { Module } from "../model/module";
|
||||
|
||||
export async function fetchModule(module: Module): Promise<Module> {
|
||||
const request = new Request("/api/module", {
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
body: JSON.stringify(module),
|
||||
});
|
||||
// request to the backend on /api/module with query parameters name as the module name
|
||||
const request = new Request("/api/module?uuid=" + module.uuid);
|
||||
|
||||
return await fetch(request)
|
||||
.then((response) => {
|
||||
|
@@ -6,9 +6,13 @@ export async function getCalender(token: string): Promise<Module[]> {
|
||||
method: "GET",
|
||||
});
|
||||
|
||||
return await fetch(request)
|
||||
.then((response) => {
|
||||
return response.json();
|
||||
})
|
||||
.then((calendarResponse: Calendar) => calendarResponse.modules);
|
||||
return await fetch(request).then((response) => {
|
||||
if (response.ok) {
|
||||
return response
|
||||
.json()
|
||||
.then((calendarResponse: Calendar) => calendarResponse.modules);
|
||||
} else {
|
||||
return [];
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@@ -1,13 +1,16 @@
|
||||
<script lang="ts" setup>
|
||||
import { defineAsyncComponent, ref, Ref } from "vue";
|
||||
import { Module } from "../../model/module";
|
||||
import { fetchAllModules } from "../../api/fetchCourse";
|
||||
import { Module } from "../../model/module.ts";
|
||||
import { fetchAllModules } from "../../api/fetchCourse.ts";
|
||||
import moduleStore from "../../store/moduleStore";
|
||||
import { MultiSelectAllChangeEvent } from "primevue/multiselect";
|
||||
import router from "../../router";
|
||||
import { fetchModule } from "../../api/fetchModule";
|
||||
import { fetchModule } from "../../api/fetchModule.ts";
|
||||
import { useDialog } from "primevue/usedialog";
|
||||
import { useI18n } from "vue-i18n";
|
||||
|
||||
const dialog = useDialog();
|
||||
const { t } = useI18n({ useScope: "global" });
|
||||
|
||||
const fetchedModules = async () => {
|
||||
return await fetchAllModules();
|
||||
@@ -70,14 +73,29 @@ const onSelectAllChange = (event: MultiSelectAllChangeEvent) => {
|
||||
function selectChange() {
|
||||
selectAll.value = selectedModules.value.length === modules.value.length;
|
||||
}
|
||||
|
||||
function itemsLabel(selectedModules: Module[]): string {
|
||||
return (selectedModules ? selectedModules.length : 0) != 1
|
||||
? t("additionalModules.modules")
|
||||
: t("additionalModules.module");
|
||||
}
|
||||
|
||||
function itemsLabelWithNumber(selectedModules: Module[]): string {
|
||||
return (
|
||||
selectedModules.length.toString() +
|
||||
" " +
|
||||
itemsLabel(selectedModules) +
|
||||
" " +
|
||||
t("additionalModules.dropDownFooterSelected")
|
||||
);
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="flex flex-column">
|
||||
<div class="flex align-items-center justify-content-center h-4rem m-2">
|
||||
<h3>
|
||||
Select additional Modules that are not listed in the regular semester
|
||||
for your Course
|
||||
{{ $t("additionalModules.subTitle") }}
|
||||
</h3>
|
||||
</div>
|
||||
<div class="card flex align-items-center justify-content-center m-2">
|
||||
@@ -90,8 +108,10 @@ function selectChange() {
|
||||
:virtual-scroller-options="{ itemSize: 70 }"
|
||||
class="custom-multiselect"
|
||||
filter
|
||||
placeholder="Select additional modules"
|
||||
:placeholder="$t('additionalModules.dropDown')"
|
||||
:auto-filter-focus="true"
|
||||
:show-toggle-all="false"
|
||||
:selected-items-label="itemsLabelWithNumber(selectedModules)"
|
||||
@change="selectChange()"
|
||||
@selectall-change="onSelectAllChange($event)"
|
||||
>
|
||||
@@ -104,6 +124,7 @@ function selectChange() {
|
||||
</div>
|
||||
<div class="flex align-items-center justify-content-center ml-2">
|
||||
<Button
|
||||
class="small-button"
|
||||
icon="pi pi-info"
|
||||
severity="secondary"
|
||||
rounded
|
||||
@@ -127,7 +148,9 @@ function selectChange() {
|
||||
</MultiSelect>
|
||||
</div>
|
||||
<div class="flex align-items-center justify-content-center h-4rem m-2">
|
||||
<Button @click="nextStep()">Next Step</Button>
|
||||
<Button @click="nextStep()">{{
|
||||
$t("additionalModules.nextStep")
|
||||
}}</Button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
@@ -140,4 +163,10 @@ function selectChange() {
|
||||
:deep(.custom-multiselect li) {
|
||||
height: unset;
|
||||
}
|
||||
|
||||
.small-button.p-button {
|
||||
width: 2rem;
|
||||
height: 2rem;
|
||||
padding: 0;
|
||||
}
|
||||
</style>
|
||||
|
@@ -1,13 +1,15 @@
|
||||
<script lang="ts" setup>
|
||||
import { computed, Ref, ref } from "vue";
|
||||
import { Module } from "../../model/module";
|
||||
import { Module } from "../../model/module.ts";
|
||||
import moduleStore from "../../store/moduleStore";
|
||||
import { fetchAllModules } from "../../api/fetchCourse";
|
||||
import { saveIndividualFeed } from "../../api/createFeed";
|
||||
import { fetchAllModules } from "../../api/fetchCourse.ts";
|
||||
import { saveIndividualFeed } from "../../api/createFeed.ts";
|
||||
import tokenStore from "../../store/tokenStore";
|
||||
import router from "../../router";
|
||||
import ModuleTemplateDialog from "../ModuleTemplateDialog.vue";
|
||||
import { onlyWhitespace } from "../../helpers/strings.ts";
|
||||
import { useI18n } from "vue-i18n";
|
||||
const { t } = useI18n({ useScope: "global" });
|
||||
|
||||
const store = moduleStore();
|
||||
const tableData = computed(() =>
|
||||
@@ -20,9 +22,9 @@ const tableData = computed(() =>
|
||||
);
|
||||
|
||||
const columns = ref([
|
||||
{ field: "Course", header: "Course" },
|
||||
{ field: "Module", header: "Module" },
|
||||
{ field: "Reminder", header: "Reminder" },
|
||||
{ field: "Course", header: t("moduleInformation.course") },
|
||||
{ field: "Module", header: t("moduleInformation.module") },
|
||||
{ field: "Reminder", header: t("renameModules.reminder") },
|
||||
]);
|
||||
|
||||
const fetchedModules = async () => {
|
||||
@@ -52,7 +54,7 @@ async function finalStep() {
|
||||
<template>
|
||||
<div class="flex flex-column card-container mx-8 mt-2">
|
||||
<div class="flex align-items-center justify-content-center h-4rem m-2">
|
||||
<h3>Rename your selected Modules to your liking.</h3>
|
||||
<h3>{{ $t("renameModules.subTitle") }}</h3>
|
||||
<ModuleTemplateDialog />
|
||||
</div>
|
||||
<div
|
||||
@@ -66,7 +68,7 @@ async function finalStep() {
|
||||
>
|
||||
<template #header>
|
||||
<div class="flex align-items-center justify-content-end">
|
||||
Enable all notifications:
|
||||
{{ $t("renameModules.enableAllNotifications") }}
|
||||
<InputSwitch
|
||||
class="mx-4"
|
||||
:model-value="
|
||||
@@ -153,7 +155,7 @@ async function finalStep() {
|
||||
<div
|
||||
class="flex align-items-center justify-content-center border-round m-2"
|
||||
>
|
||||
<Button label="Save Calendar" @click="finalStep()" />
|
||||
<Button @click="finalStep()">{{ $t("renameModules.nextStep") }}</Button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
@@ -49,7 +49,8 @@
|
||||
"invalidToken": "Ungültiger Token",
|
||||
"headline": "Bearbeite deinen HTWKalender",
|
||||
"subTitle": "Füge deinen Link oder Token ein um den Kalender zu bearbeiten",
|
||||
"loadCalendar": "Kalender laden"
|
||||
"loadCalendar": "Kalender laden",
|
||||
"noCalendarFound": "Keinen Kalender gefunden"
|
||||
},
|
||||
"additionalModules": {
|
||||
"subTitle": "Füge weitere Module hinzu die nicht in deinem Studiengang enthalten sind.",
|
||||
@@ -63,7 +64,7 @@
|
||||
"reminder": "Erinnerung",
|
||||
"enableAllNotifications": "Alle Benachrichtigungen aktivieren",
|
||||
"subTitle": "Konfigurieren Sie die ausgewählten Module nach Ihren Wünschen.",
|
||||
"nextStep": "Weiter"
|
||||
"nextStep": "Speichern"
|
||||
},
|
||||
"moduleTemplateDialog": {
|
||||
"explanationOne": "Hier können Module nach Wunsch umbenannt werden, welche dann als Anzeigename im Kalender dargestellt werden.",
|
||||
|
@@ -49,7 +49,8 @@
|
||||
"invalidToken": "invalid token",
|
||||
"headline": "edit your HTWKalender",
|
||||
"subTitle": "please enter your link or calendar token",
|
||||
"loadCalendar": "load calendar"
|
||||
"loadCalendar": "load calendar",
|
||||
"noCalendarFound": "no calendar found"
|
||||
},
|
||||
"additionalModules": {
|
||||
"subTitle": "Select additional Modules that are not listed in the regular semester for your Course",
|
||||
@@ -63,7 +64,7 @@
|
||||
"reminder": "reminder",
|
||||
"enableAllNotifications": "enable all notifications",
|
||||
"subTitle": "Configure your selected Modules to your liking.",
|
||||
"nextStep": "next step"
|
||||
"nextStep": "Save"
|
||||
},
|
||||
"moduleTemplateDialog": {
|
||||
"explanationOne": "Here you can rename your modules to your liking. This will be the name of the event in your calendar.",
|
||||
|
@@ -7,8 +7,10 @@ import { FilterMatchMode } from "primevue/api";
|
||||
import { useDialog } from "primevue/usedialog";
|
||||
import router from "../router";
|
||||
import { fetchModule } from "../api/fetchModule.ts";
|
||||
import { useI18n } from "vue-i18n";
|
||||
|
||||
const dialog = useDialog();
|
||||
const { t } = useI18n({ useScope: "global" });
|
||||
|
||||
const fetchedModules = async () => {
|
||||
return await fetchAllModules();
|
||||
@@ -111,11 +113,19 @@ function selectChange(event : MultiSelectChangeEvent) {
|
||||
}
|
||||
|
||||
function itemsLabel(selectedModules: Module[]): string {
|
||||
return (selectedModules ? selectedModules.length : 0) != 1 ? t("additionalModules.modules") : t("additionalModules.module");
|
||||
return (selectedModules ? selectedModules.length : 0) != 1
|
||||
? t("additionalModules.modules")
|
||||
: t("additionalModules.module");
|
||||
}
|
||||
|
||||
function itemsLabelWithNumber(selectedModules: Module[]): string {
|
||||
return selectedModules.length.toString() + " " + itemsLabel(selectedModules) + " " + t("additionalModules.dropDownFooterSelected");
|
||||
return (
|
||||
selectedModules.length.toString() +
|
||||
" " +
|
||||
itemsLabel(selectedModules) +
|
||||
" " +
|
||||
t("additionalModules.dropDownFooterSelected")
|
||||
);
|
||||
}
|
||||
*/
|
||||
</script>
|
||||
@@ -228,11 +238,11 @@ function itemsLabelWithNumber(selectedModules: Module[]): string {
|
||||
:placeholder="$t('additionalModules.dropDown')"
|
||||
:auto-filter-focus="true"
|
||||
:show-toggle-all="false"
|
||||
:selected-items-label="itemsLabelWithNumber(selectedModules)"
|
||||
@change="selectChange()"
|
||||
placeholder="Select additional modules"
|
||||
@change="selectChange($event)"
|
||||
@selectall-change="onSelectAllChange($event)"
|
||||
:selectedItemsLabel="itemsLabelWithNumber(selectedModules)"
|
||||
>
|
||||
<template #option="slotProps">
|
||||
<div class="flex justify-content-between w-full">
|
||||
@@ -243,6 +253,7 @@ function itemsLabelWithNumber(selectedModules: Module[]): string {
|
||||
</div>
|
||||
<div class="flex align-items-center justify-content-center ml-2">
|
||||
<Button
|
||||
class="small-button"
|
||||
icon="pi pi-info"
|
||||
severity="secondary"
|
||||
rounded
|
||||
@@ -258,8 +269,10 @@ function itemsLabelWithNumber(selectedModules: Module[]): string {
|
||||
<template #footer>
|
||||
<div class="py-2 px-3">
|
||||
<b>{{ selectedModules ? selectedModules.length : 0 }}</b>
|
||||
{{ itemsLabel(selectedModules) }}
|
||||
{{ $t("additionalModules.dropDownFooterSelected") }}
|
||||
item{{
|
||||
(selectedModules ? selectedModules.length : 0) > 1 ? "s" : ""
|
||||
}}
|
||||
selected.
|
||||
</div>
|
||||
</template>
|
||||
</MultiSelect>
|
||||
@@ -280,4 +293,10 @@ function itemsLabelWithNumber(selectedModules: Module[]): string {
|
||||
:deep(.custom-multiselect li) {
|
||||
height: unset;
|
||||
}
|
||||
|
||||
.small-button.p-button {
|
||||
width: 2rem;
|
||||
height: 2rem;
|
||||
padding: 0;
|
||||
}
|
||||
</style>
|
||||
|
@@ -46,14 +46,22 @@ function loadCalendar(): void {
|
||||
moduleStore().removeAllModules();
|
||||
tokenStore().setToken(token.value);
|
||||
|
||||
getCalender(token.value).then((data) => {
|
||||
data.forEach((module) => {
|
||||
moduleStore().addModule(module);
|
||||
});
|
||||
modules.value = moduleStore().modules;
|
||||
getCalender(token.value).then((data: Module[]) => {
|
||||
if (data.length > 0) {
|
||||
data.forEach((module) => {
|
||||
moduleStore().addModule(module);
|
||||
});
|
||||
modules.value = moduleStore().modules;
|
||||
router.push("/edit-additional-modules");
|
||||
} else {
|
||||
toast.add({
|
||||
severity: "error",
|
||||
summary: t("editCalendarView.error"),
|
||||
detail: t("editCalendarView.noCalendarFound"),
|
||||
life: 3000,
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
router.push("/edit-additional-modules");
|
||||
}
|
||||
</script>
|
||||
|
||||
|
Reference in New Issue
Block a user