diff --git a/aleksis/apps/alsijil/assets/components/coursebook/CourseBook.graphql b/aleksis/apps/alsijil/assets/components/coursebook/CourseBook.graphql deleted file mode 100644 index 9af1bf9dd9ffb33e16f12ebdd969393f40cab7f1..0000000000000000000000000000000000000000 --- a/aleksis/apps/alsijil/assets/components/coursebook/CourseBook.graphql +++ /dev/null @@ -1,80 +0,0 @@ -query CourseBook($lessonId: ID!) { - excuseTypes { - id - name - shortName - } - lesson: lessonById(id: $lessonId) { - groups { - name - shortName - members { - id - fullName - } - } - subject { - name - } - plannedLessonperiodsDatetimes { - year - week - datetimeStart - lessonPeriod{ - id - period{ - period - } - } - } - } - lessonDocumentations: lessonDocumentationsByLessonId(id: $lessonId) { - id - topic - homework - groupNote - year - week - lessonPeriod { - id - period { - id - period - } - } - event { - id - } - extraLesson { - id - } - period - date - personalNotes { - id - person { - id - fullName - } - tardiness - absent - excused - excuseType { - id - name - shortName - } - remarks - extraMarks { - id - name - shortName - } - } - } - extraMarks { - id - name - shortName - } -} diff --git a/aleksis/apps/alsijil/assets/components/coursebook/CourseBook.vue b/aleksis/apps/alsijil/assets/components/coursebook/CourseBook.vue deleted file mode 100644 index 6c29cc64e5635cf89b825a0e2809c9bf018eb047..0000000000000000000000000000000000000000 --- a/aleksis/apps/alsijil/assets/components/coursebook/CourseBook.vue +++ /dev/null @@ -1,85 +0,0 @@ -<template> - <ApolloQuery - :query="require('./CourseBook.graphql')" - :variables="{ lessonId: $route.params.lessonId }" - > - <template v-slot="{ result: { loading, error, data } }"> - <!-- Error --> - <message-box v-if="error" type="error">{{ $t("alsijil.error_occurred") }}</message-box> - - <!-- Result --> - <div v-else-if="data" class="result apollo"> - <div class="d-flex justify-space-between"> - <v-btn text color="primary" :href="$root.urls.select_coursebook()"> - <v-icon left>mdi-chevron-left</v-icon> - {{ $t("alsijil.back") }} - </v-btn> - <update-indicator @manual-update="updateManually()" ref="indicator" :status="status"></update-indicator> - </div> - <v-row> - <v-col cols="12"> - <lesson-documentations - :lesson-documentations="data.lessonDocumentations" - :planned-lesson-periods-date-times="data.lesson.plannedLessonperiodsDatetimes" - :groups="data.lesson.groups" - :excuse-types="data.excuseTypes" - :extra-marks="data.extraMarks" - :save-lesson-documentations-per-week="saveLessonDocumentationsPerWeek" - /> - </v-col> - </v-row> - </div> - <!-- No result or Loading --> - <div v-else class="text-center"> - <v-progress-circular - indeterminate - color="primary" - class="ma-auto" - ></v-progress-circular> - </div> - </template> - </ApolloQuery> -</template> - -<script> -import {CHANGES, SAVED, UPDATING} from "../../UpdateStatuses.js"; -import UpdateIndicator from "./UpdateIndicator.vue"; -import LessonDocumentations from "./LessonDocumentations.vue"; - -export default { - components: { - UpdateIndicator, - LessonDocumentations, - }, - props: [ "saveLessonDocumentationsPerWeek" ], - methods: { - processDataChange(event) { - this.status = CHANGES; - // alert("Probably save the data"); - console.log(event); - setTimeout(() => { - this.status = UPDATING; - }, 500) - - setTimeout(() => { - this.status = SAVED; - }, 1000) - - }, - updateManually(event) { - alert("Data sync triggered manually"); - this.status = UPDATING; - setTimeout(() => { - this.status = SAVED; - }, 500) - }, - }, - name: "course-book", - data: () => { - return { - ping: "ping", - status: SAVED, - } - } -} -</script> diff --git a/aleksis/apps/alsijil/assets/index.js b/aleksis/apps/alsijil/assets/index.js deleted file mode 100644 index 77d41966e5d3688accb0916b457b6be9ea390c73..0000000000000000000000000000000000000000 --- a/aleksis/apps/alsijil/assets/index.js +++ /dev/null @@ -1,3 +0,0 @@ -export default [ - { path: "/coursebook/:lessonId", component: () => import("./components/coursebook/CourseBook.vue"), props: true }, -]; diff --git a/aleksis/apps/alsijil/assets/messages/de.json b/aleksis/apps/alsijil/assets/messages/de.json deleted file mode 100644 index db9d51e142764360a680f4b53e4e913f1d239595..0000000000000000000000000000000000000000 --- a/aleksis/apps/alsijil/assets/messages/de.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "coursebook": { - "title": "Kursbuch" - } -} diff --git a/aleksis/apps/alsijil/assets/UpdateStatuses.js b/aleksis/apps/alsijil/frontend/UpdateStatuses.js similarity index 100% rename from aleksis/apps/alsijil/assets/UpdateStatuses.js rename to aleksis/apps/alsijil/frontend/UpdateStatuses.js diff --git a/aleksis/apps/alsijil/frontend/components/coursebook/CourseBook.vue b/aleksis/apps/alsijil/frontend/components/coursebook/CourseBook.vue new file mode 100644 index 0000000000000000000000000000000000000000..3994664e5c80781297d2a054de9c70f0781a53e8 --- /dev/null +++ b/aleksis/apps/alsijil/frontend/components/coursebook/CourseBook.vue @@ -0,0 +1,118 @@ +<template> + <div> + <div class="text-h2"> + {{ title(courseBookLesson) }} + </div> + <div v-if="courseBookLesson && alsijilSitePreferences"> + <div class="d-flex justify-space-between"> + <v-btn text color="primary" :to="{ name: 'alsijil.courseBookList' }"> + <v-icon left>mdi-chevron-left</v-icon> + {{ $t("alsijil.back") }} + </v-btn> + <update-indicator @manual-update="updateManually()" ref="indicator" :status="status"></update-indicator> + </div> + <v-row> + <v-col cols="12"> + <lesson-documentations + :lesson-documentations="courseBookLessonDocumentations" + :planned-lesson-periods-date-times="courseBookLesson.plannedLessonperiodsDatetimes" + :groups="courseBookLesson.groups" + :excuse-types="excuseTypes" + :extra-marks="extraMarks" + :save-lesson-documentations-per-week="alsijilSitePreferences.saveLessonDocumentationsByWeek" + /> + </v-col> + </v-row> + </div> + </div> +</template> + +<script> +import {CHANGES, SAVED, UPDATING} from "../../UpdateStatuses.js"; +import UpdateIndicator from "./UpdateIndicator.vue"; +import LessonDocumentations from "./LessonDocumentations.vue"; + +import gqlCourseBookLesson from "./courseBookLesson.graphql"; +import gqlCourseBookLessonDocumentations from "./courseBookLesson.graphql"; +import gqlExcuseTypes from "./excuseTypes.graphql"; +import gqlExtraMarks from "./extraMarks.graphql"; +import gqlAlsijilSitePreferences from "./alsijilSitePreferences.graphql"; + +export default { + components: { + UpdateIndicator, + LessonDocumentations, + }, + props: { + lessonId: String, + }, + apollo: { + courseBookLesson: { + query: gqlCourseBookLesson, + variables() { + return { + lessonId: this.lessonId, + }; + }, + update: (data) => data.lesson, + }, + courseBookLessonDocumentations: { + query: gqlCourseBookLessonDocumentations, + variables() { + return { + lessonId: this.lessonId, + }; + }, + update: (data) => data.lessonDocumentationsByLessonId, + }, + excuseTypes: gqlExcuseTypes, + extraMarks: gqlExtraMarks, + alsijilSitePreferences: gqlAlsijilSitePreferences, + }, + methods: { + processDataChange(event) { + this.status = CHANGES; + // alert("Probably save the data"); + console.log(event); + setTimeout(() => { + this.status = UPDATING; + }, 500) + + setTimeout(() => { + this.status = SAVED; + }, 1000) + + }, + updateManually(event) { + alert("Data sync triggered manually"); + this.status = UPDATING; + setTimeout(() => { + this.status = SAVED; + }, 500) + }, + title(lesson) { + return this.$t('alsijil.coursebook.menu_title') + (lesson && lesson.groups && lesson.subject ? (" " + lesson.groups.map(g => g.shortName).join() + " · " + lesson.subject.name) : ""); + }, + }, + watch: { + courseBookLesson: { + handler(newLesson) { + this.$root.$setPageTitle(this.title(newLesson)); + }, + deep: true, + } + }, + name: "course-book", + data: () => { + return{ + ping: "ping", + status: SAVED, + alsijilSitePreferences: null, + courseBookLesson: null, + courseBookLessonDocumentations: null, + excuseTypes: null, + extraMarks: null, + } + } +} +</script> diff --git a/aleksis/apps/alsijil/frontend/components/coursebook/CourseBookList.vue b/aleksis/apps/alsijil/frontend/components/coursebook/CourseBookList.vue new file mode 100644 index 0000000000000000000000000000000000000000..1cca0dd2aa28bd1a6b7e80a7dc2c3a4c38991e24 --- /dev/null +++ b/aleksis/apps/alsijil/frontend/components/coursebook/CourseBookList.vue @@ -0,0 +1,84 @@ +<template> + <v-row> + <v-col cols="12" xl="12" class="d-flex"> + <div class="text-h2"> + {{ $t("alsijil.coursebook.title") }} + </div> + </v-col> + <v-col + v-if="$apollo.queries.coursebookLessons.loading" + cols="12" + xs="12" + sm="6" + md="6" + lg="4" + xl="3" + class="d-flex" + > + <v-card + class="flex-grow-1" + v-for="idx in 4" + :key="idx" + > + <v-skeleton-loader + type="heading, text@2, actions" + ></v-skeleton-loader> + </v-card> + </v-col> + <v-col v-else-if="coursebookLessons" v-for="lesson in coursebookLessons" xs="12" sm="6" md="6" lg="4" xl="3" class="d-flex"> + <v-card class="flex-grow-1"> + <v-card-title> + {{ lesson.groups.map(g => g.shortName).join() + " · " + lesson.subject.name }} + </v-card-title> + <v-card-subtitle> + {{ lesson.validity.dateStart + " - " + lesson.validity.dateEnd }} + </v-card-subtitle> + <v-card-text> + {{ lesson.teachers.map(t => t.fullName).join() }} + </v-card-text> + <v-card-actions> + <v-btn :to="{ name: 'alsijil.courseBookByID', params: { lessonId: lesson.id } }" text color="secondary"> + <v-icon left>mdi-book-search-outline</v-icon> + {{ $t("alsijil.coursebook.open_coursebook") }} + </v-btn> + </v-card-actions> + </v-card> + </v-col> + <v-container + class="text-center fill-height" + style="height: calc(100vh - 58px);" + v-else-if="!coursebookLessons" + > + <v-row align="center"> + <v-col> + <h1 class="text-h3 primary--text"> + <v-icon color="error" x-large>mdi-book-off-outline</v-icon> + {{ $t("alsijil.coursebook.no_coursebook") }} + </h1> + + <p> {{ $t("alsijil.coursebook.no_courses_as_teacher") }} </p> + </v-col> + </v-row> + </v-container> + </v-row> +</template> + +<script> +import gqlCourseBookLessons from "./courseBookLessons.graphql"; + +export default { + name: "CourseBookList", + data() { + return { + coursebookLessons: null, + } + }, + apollo: { + coursebookLessons: gqlCourseBookLessons, + }, +} +</script> + +<style scoped> + +</style> \ No newline at end of file diff --git a/aleksis/apps/alsijil/assets/components/coursebook/LessonDocumentation.vue b/aleksis/apps/alsijil/frontend/components/coursebook/LessonDocumentation.vue similarity index 98% rename from aleksis/apps/alsijil/assets/components/coursebook/LessonDocumentation.vue rename to aleksis/apps/alsijil/frontend/components/coursebook/LessonDocumentation.vue index e2679b4ade3b67b44b24ef60f96f2d024d29aeab..244938ff45d31a595a65f9f9f4b8fb4f3d165bc6 100644 --- a/aleksis/apps/alsijil/assets/components/coursebook/LessonDocumentation.vue +++ b/aleksis/apps/alsijil/frontend/components/coursebook/LessonDocumentation.vue @@ -1,6 +1,6 @@ <template> <ApolloMutation - :mutation="require('./LessonDocumentation.graphql')" + :mutation="require('./lessonDocumentation.graphql')" :variables=lessonDocumentationEdit @done="onDone" > diff --git a/aleksis/apps/alsijil/assets/components/coursebook/LessonDocumentations.vue b/aleksis/apps/alsijil/frontend/components/coursebook/LessonDocumentations.vue similarity index 100% rename from aleksis/apps/alsijil/assets/components/coursebook/LessonDocumentations.vue rename to aleksis/apps/alsijil/frontend/components/coursebook/LessonDocumentations.vue diff --git a/aleksis/apps/alsijil/assets/components/coursebook/PersonalNotes.vue b/aleksis/apps/alsijil/frontend/components/coursebook/PersonalNotes.vue similarity index 100% rename from aleksis/apps/alsijil/assets/components/coursebook/PersonalNotes.vue rename to aleksis/apps/alsijil/frontend/components/coursebook/PersonalNotes.vue diff --git a/aleksis/apps/alsijil/assets/components/coursebook/UpdateIndicator.vue b/aleksis/apps/alsijil/frontend/components/coursebook/UpdateIndicator.vue similarity index 100% rename from aleksis/apps/alsijil/assets/components/coursebook/UpdateIndicator.vue rename to aleksis/apps/alsijil/frontend/components/coursebook/UpdateIndicator.vue diff --git a/aleksis/apps/alsijil/frontend/components/coursebook/alsijilSitePreferences.graphql b/aleksis/apps/alsijil/frontend/components/coursebook/alsijilSitePreferences.graphql new file mode 100644 index 0000000000000000000000000000000000000000..527fb25a62ac80afb4589234178cf63fbcb53023 --- /dev/null +++ b/aleksis/apps/alsijil/frontend/components/coursebook/alsijilSitePreferences.graphql @@ -0,0 +1,5 @@ +{ + alsijilSitePreferences { + saveLessonDocumentationsByWeek + } +} \ No newline at end of file diff --git a/aleksis/apps/alsijil/frontend/components/coursebook/courseBookLesson.graphql b/aleksis/apps/alsijil/frontend/components/coursebook/courseBookLesson.graphql new file mode 100644 index 0000000000000000000000000000000000000000..cca66a4b6874f5b1b4b1ce283bdbc366e0d037e1 --- /dev/null +++ b/aleksis/apps/alsijil/frontend/components/coursebook/courseBookLesson.graphql @@ -0,0 +1,26 @@ +query courseBookLesson($lessonId: ID!) { + lesson: lessonById(id: $lessonId) { + groups { + name + shortName + members { + id + fullName + } + } + subject { + name + } + plannedLessonperiodsDatetimes { + year + week + datetimeStart + lessonPeriod{ + id + period{ + period + } + } + } + } +} \ No newline at end of file diff --git a/aleksis/apps/alsijil/frontend/components/coursebook/courseBookLessonDocumentations.graphql b/aleksis/apps/alsijil/frontend/components/coursebook/courseBookLessonDocumentations.graphql new file mode 100644 index 0000000000000000000000000000000000000000..1ba37ce5d4a3c1b9a5d3a0264eac0452178321b0 --- /dev/null +++ b/aleksis/apps/alsijil/frontend/components/coursebook/courseBookLessonDocumentations.graphql @@ -0,0 +1,47 @@ +query courseBookLessonDocumentations ($lessonId: ID!) { + lessonDocumentationsByLessonId(id: $lessonId) { + id + topic + homework + groupNote + year + week + lessonPeriod { + id + period { + id + period + } + } + event { + id + } + extraLesson { + id + } + period + date + personalNotes { + id + person { + id + fullName + } + tardiness + absent + excused + excuseType { + id + name + shortName + } + remarks + extraMarks { + id + name + shortName + } + } + } + } +} \ No newline at end of file diff --git a/aleksis/apps/alsijil/frontend/components/coursebook/courseBookLessons.graphql b/aleksis/apps/alsijil/frontend/components/coursebook/courseBookLessons.graphql new file mode 100644 index 0000000000000000000000000000000000000000..6531a76c2a4f5790e027c7f151d21e3540f3c581 --- /dev/null +++ b/aleksis/apps/alsijil/frontend/components/coursebook/courseBookLessons.graphql @@ -0,0 +1,18 @@ +{ + coursebookLessons { + groups { + shortName + } + subject { + name + } + validity { + dateStart + dateEnd + } + teachers { + fullName + } + id + } +} diff --git a/aleksis/apps/alsijil/frontend/components/coursebook/excuseTypes.graphql b/aleksis/apps/alsijil/frontend/components/coursebook/excuseTypes.graphql new file mode 100644 index 0000000000000000000000000000000000000000..6eb0650dcd18e80839ad6e9e8168b0997f6b2707 --- /dev/null +++ b/aleksis/apps/alsijil/frontend/components/coursebook/excuseTypes.graphql @@ -0,0 +1,7 @@ +{ + excuseTypes { + id + name + shortName + } +} \ No newline at end of file diff --git a/aleksis/apps/alsijil/frontend/components/coursebook/extraMarks.graphql b/aleksis/apps/alsijil/frontend/components/coursebook/extraMarks.graphql new file mode 100644 index 0000000000000000000000000000000000000000..ffbb48f2020c7c7fe646f91a8ca612850d6fa204 --- /dev/null +++ b/aleksis/apps/alsijil/frontend/components/coursebook/extraMarks.graphql @@ -0,0 +1,7 @@ +{ + extraMarks { + id + name + shortName + } +} \ No newline at end of file diff --git a/aleksis/apps/alsijil/assets/components/coursebook/LessonDocumentation.graphql b/aleksis/apps/alsijil/frontend/components/coursebook/lessonDocumentation.graphql similarity index 100% rename from aleksis/apps/alsijil/assets/components/coursebook/LessonDocumentation.graphql rename to aleksis/apps/alsijil/frontend/components/coursebook/lessonDocumentation.graphql diff --git a/aleksis/apps/alsijil/frontend/index.js b/aleksis/apps/alsijil/frontend/index.js new file mode 100644 index 0000000000000000000000000000000000000000..1ac48feef5e5ed3a86bf8d448a3bb70e3ec10a81 --- /dev/null +++ b/aleksis/apps/alsijil/frontend/index.js @@ -0,0 +1,288 @@ +export default + { + meta: { + inMenu: true, + titleKey: "alsijil.menu_title", + icon: "mdi-account-group-outline", + }, + children: [ + { + path: "coursebook/:lessonId(\\d+)/", + component: () => import("./components/coursebook/CourseBook.vue"), + props: true, + name: "alsijil.courseBookByID", + }, + { + path: "coursebook/", + component: () => import("./components/coursebook/CourseBookList.vue"), + name: "alsijil.courseBookList", + meta: { + inMenu: true, + titleKey: "alsijil.coursebook.menu_title", + icon: "mdi-book-education-outline", + permission: "alsijil.view_coursebook_rule", + }, + }, + { + path: "lesson", + component: () => import("aleksis.core/components/LegacyBaseTemplate.vue"), + name: "alsijil.lessonPeriod", + meta: { + inMenu: true, + titleKey: "alsijil.lesson.menu_title", + icon: "mdi-alarm", + permission: "alsijil.view_lesson_menu_rule", + }, + }, + { + path: "lesson/:year(\\d+)/:week(\\d+)/:id_(\\d+)", + component: () => import("aleksis.core/components/LegacyBaseTemplate.vue"), + name: "alsijil.lessonPeriodByCWAndID", + }, + { + path: "extra_lesson/:id_(\\d+)/", + component: () => import("aleksis.core/components/LegacyBaseTemplate.vue"), + name: "alsijil.extraLessonByID", + }, + { + path: "event/:id_(\\d+)/", + component: () => import("aleksis.core/components/LegacyBaseTemplate.vue"), + name: "alsijil.eventByID", + }, + { + path: "week/", + component: () => import("aleksis.core/components/LegacyBaseTemplate.vue"), + name: "alsijil.weekView", + meta: { + inMenu: true, + titleKey: "alsijil.week.menu_title", + icon: "mdi-view-week-outline", + permission: "alsijil.view_week_menu_rule", + }, + }, + { + path: "week/:year(\\d+)/:week(\\d+)/", + component: () => import("aleksis.core/components/LegacyBaseTemplate.vue"), + name: "alsijil.weekViewByWeek", + }, + { + path: "week/year/cw/", + component: () => import("aleksis.core/components/LegacyBaseTemplate.vue"), + name: "alsijil.weekViewPlaceholders", + }, + { + path: "week/:type_/:id_(\\d+)/", + component: () => import("aleksis.core/components/LegacyBaseTemplate.vue"), + name: "alsijil.weekViewByTypeAndID", + }, + { + path: "week/year/cw/:type_/:id_(\\d+)/", + component: () => import("aleksis.core/components/LegacyBaseTemplate.vue"), + name: "alsijil.weekViewPlaceholdersByTypeAndID", + }, + { + path: "week/:year(\\d+)/:week(\\d+)/:type_/:id_(\\d+)/", + component: () => import("aleksis.core/components/LegacyBaseTemplate.vue"), + name: "alsijil.weekViewByWeekTypeAndID", + }, + { + path: "print/group/:id_(\\d+)", + component: () => import("aleksis.core/components/LegacyBaseTemplate.vue"), + name: "alsijil.fullRegisterGroup", + }, + { + path: "groups/", + component: () => import("aleksis.core/components/LegacyBaseTemplate.vue"), + name: "alsijil.myGroups", + meta: { + inMenu: true, + titleKey: "alsijil.groups.menu_title", + icon: "mdi-account-multiple-outline", + permission: "alsijil.view_my_groups_rule", + }, + }, + { + path: "groups/:pk(\\d+)/", + component: () => import("aleksis.core/components/LegacyBaseTemplate.vue"), + name: "alsijil.studentsList", + }, + { + path: "persons/", + component: () => import("aleksis.core/components/LegacyBaseTemplate.vue"), + name: "alsijil.myStudents", + meta: { + inMenu: true, + titleKey: "alsijil.persons.menu_title", + icon: "mdi-account-school-outline", + permission: "alsijil.view_my_students_rule", + }, + }, + { + path: "persons/:id_(\\d+)/", + component: () => import("aleksis.core/components/LegacyBaseTemplate.vue"), + name: "alsijil.overviewPerson", + }, + { + path: "me/", + component: () => import("aleksis.core/components/LegacyBaseTemplate.vue"), + name: "alsijil.overviewMe", + meta: { + inMenu: true, + titleKey: "alsijil.my_overview.menu_title", + icon: "mdi-chart-box-outline", + permission: "alsijil.view_person_overview_menu_rule", + }, + }, + { + path: "notes/:pk(\\d+)/delete/", + component: () => import("aleksis.core/components/LegacyBaseTemplate.vue"), + name: "alsijil.deletePersonalNote", + }, + { + path: "absence/new/:id_(\\d+)/", + component: () => import("aleksis.core/components/LegacyBaseTemplate.vue"), + name: "alsijil.registerAbsenceWithID", + }, + { + path: "absence/new/", + component: () => import("aleksis.core/components/LegacyBaseTemplate.vue"), + name: "alsijil.registerAbsence", + meta: { + inMenu: true, + titleKey: "alsijil.absence.menu_title", + icon: "mdi-message-draw", + permission: "alsijil.view_register_absence_rule", + }, + }, + { + path: "extra_marks/", + component: () => import("aleksis.core/components/LegacyBaseTemplate.vue"), + name: "alsijil.extraMarks", + meta: { + inMenu: true, + titleKey: "alsijil.extra_marks.menu_title", + icon: "mdi-label-variant-outline", + permission: "alsijil.view_extramarks_rule", + }, + }, + { + path: "extra_marks/create/", + component: () => import("aleksis.core/components/LegacyBaseTemplate.vue"), + name: "alsijil.createExtraMark", + }, + { + path: "extra_marks/:pk(\\d+)/edit/", + component: () => import("aleksis.core/components/LegacyBaseTemplate.vue"), + name: "alsijil.editExtraMark", + }, + { + path: "extra_marks/:pk(\\d+)/delete/", + component: () => import("aleksis.core/components/LegacyBaseTemplate.vue"), + name: "alsijil.deleteExtraMark", + }, + { + path: "excuse_types/", + component: () => import("aleksis.core/components/LegacyBaseTemplate.vue"), + name: "alsijil.excuseTypes", + meta: { + inMenu: true, + titleKey: "alsijil.excuse_types.menu_title", + icon: "mdi-label-outline", + permission: "alsijil.view_excusetypes_rule", + }, + }, + { + path: "excuse_types/create/", + component: () => import("aleksis.core/components/LegacyBaseTemplate.vue"), + name: "alsijil.createExcuseType", + }, + { + path: "excuse_types/:pk(\\d+)/edit/", + component: () => import("aleksis.core/components/LegacyBaseTemplate.vue"), + name: "alsijil.editExcuseType", + }, + { + path: "excuse_types/:pk(\\d+)/delete/", + component: () => import("aleksis.core/components/LegacyBaseTemplate.vue"), + name: "alsijil.deleteExcuseType", + }, + { + path: "group_roles/", + component: () => import("aleksis.core/components/LegacyBaseTemplate.vue"), + name: "alsijil.groupRoles", + meta: { + inMenu: true, + titleKey: "alsijil.group_roles.menu_title_manage", + icon: "mdi-clipboard-plus-outline", + permission: "alsijil.view_grouproles_rule", + }, + }, + { + path: "group_roles/create/", + component: () => import("aleksis.core/components/LegacyBaseTemplate.vue"), + name: "alsijil.createGroupRole", + }, + { + path: "group_roles/:pk(\\d+)/edit/", + component: () => import("aleksis.core/components/LegacyBaseTemplate.vue"), + name: "alsijil.editGroupRole", + }, + { + path: "group_roles/:pk(\\d+)/delete/", + component: () => import("aleksis.core/components/LegacyBaseTemplate.vue"), + name: "alsijil.deleteGroupRole", + }, + { + path: "groups/:pk(\\d+)/group_roles/", + component: () => import("aleksis.core/components/LegacyBaseTemplate.vue"), + name: "alsijil.assignedGroupRoles", + }, + { + path: "groups/:pk(\\d+)/group_roles/assign/", + component: () => import("aleksis.core/components/LegacyBaseTemplate.vue"), + name: "alsijil.assignGroupRole", + }, + { + path: "groups/:pk(\\d+)/group_roles/:role_pk(\\d+)/assign/", + component: () => import("aleksis.core/components/LegacyBaseTemplate.vue"), + name: "alsijil.assignGroupRoleByRolePK", + }, + { + path: "group_roles/assignments/:pk(\\d+)/edit/", + component: () => import("aleksis.core/components/LegacyBaseTemplate.vue"), + name: "alsijil.editGroupRoleAssignment", + }, + { + path: "group_roles/assignments/:pk(\\d+)/stop/", + component: () => import("aleksis.core/components/LegacyBaseTemplate.vue"), + name: "alsijil.stopGroupRoleAssignment", + }, + { + path: "group_roles/assignments/:pk(\\d+)/delete/", + component: () => import("aleksis.core/components/LegacyBaseTemplate.vue"), + name: "alsijil.deleteGroupRoleAssignment", + }, + { + path: "group_roles/assignments/assign/", + component: () => import("aleksis.core/components/LegacyBaseTemplate.vue"), + name: "alsijil.assignGroupRoleMultiple", + meta: { + inMenu: true, + titleKey: "alsijil.group_roles.menu_title_assign", + icon: "mdi-clipboard-account-outline", + permission: "alsijil.assign_grouprole_for_multiple_rule", + }, + }, + { + path: "all/", + component: () => import("aleksis.core/components/LegacyBaseTemplate.vue"), + name: "alsijil.allRegisterObjects", + meta: { + inMenu: true, + titleKey: "alsijil.all_lessons.menu_title", + icon: "mdi-format-list-text", + permission: "alsijil.view_register_objects_list_rule", + }, + }, + ], + }; diff --git a/aleksis/apps/alsijil/frontend/messages/de.json b/aleksis/apps/alsijil/frontend/messages/de.json new file mode 100644 index 0000000000000000000000000000000000000000..ea3e2c3287309d22a4919fea006ae95da040a73c --- /dev/null +++ b/aleksis/apps/alsijil/frontend/messages/de.json @@ -0,0 +1,9 @@ +{ + "alsijil": { + "coursebook": { + "menu_title": "Kursbuch", + "title": "Kursbücher" + }, + "menu_title": "Klassenbuch" + } +} diff --git a/aleksis/apps/alsijil/assets/messages/en.json b/aleksis/apps/alsijil/frontend/messages/en.json similarity index 57% rename from aleksis/apps/alsijil/assets/messages/en.json rename to aleksis/apps/alsijil/frontend/messages/en.json index 8982646859803afd3ec7cfafa7e335767f8d9b5e..0466559b9fb01a99276b4135da1b790253f422e8 100644 --- a/aleksis/apps/alsijil/assets/messages/en.json +++ b/aleksis/apps/alsijil/frontend/messages/en.json @@ -1,7 +1,8 @@ { "alsijil": { "coursebook": { - "title": "Coursebook", + "menu_title": "Coursebook", + "title": "Coursebooks", "create_documentation": "Create documentation", "choose_week": "Choose week", "choose_lesson_date": "Choose lesson date", @@ -10,7 +11,41 @@ "updating": "Changes are being synced.", "changes": "You have unsaved changes. Click to save them immediately.", "error": "There has been an error while saving the latest changes." - } + }, + "no_coursebook": "No coursebook", + "no_courses_as_teacher": "There are no courses where you are a teacher.", + "open_coursebook": "Open in coursebook" + }, + "lesson": { + "menu_title": "Current lesson" + }, + "week": { + "menu_title": "Current week" + }, + "groups": { + "menu_title": "My groups" + }, + "persons": { + "menu_title": "My students" + }, + "absence": { + "menu_title": "Register absence" + }, + "my_overview": { + "menu_title": "My overview" + }, + "extra_marks": { + "menu_title": "Extra marks" + }, + "excuse_types": { + "menu_title": "Excuse types" + }, + "group_roles": { + "menu_title_manage": "Manage group roles", + "menu_title_assign": "Assign group roles" + }, + "all_lessons": { + "menu_title": "All lessons" }, "period": "Period", "period_number": "{number}. period", @@ -41,6 +76,7 @@ "error_updating": "Error updating data", "cancel": "Cancel", "save": "Save", - "back": "Back" + "back": "Back", + "menu_title": "Class register" } } diff --git a/aleksis/apps/alsijil/schema.py b/aleksis/apps/alsijil/schema.py index d7f746170a13985dd7f5b012f71017dfb50c303e..0c30a501897bcf563b5251db85c395eb9cd2c139 100644 --- a/aleksis/apps/alsijil/schema.py +++ b/aleksis/apps/alsijil/schema.py @@ -1,11 +1,16 @@ from datetime import datetime +from django.db.models import Q + import graphene +from calendarweek import CalendarWeek from graphene_django import DjangoObjectType from aleksis.apps.chronos.models import Lesson +from aleksis.apps.chronos.schema import LessonType +from aleksis.apps.chronos.util.date import get_current_year from aleksis.core.models import Group, Person -from aleksis.core.util.core_helpers import get_site_preferences +from aleksis.core.util.core_helpers import get_site_preferences, has_person from .models import ( Event, @@ -59,6 +64,13 @@ class ExtraMarkType(DjangoObjectType): model = ExtraMark +class AlsijilSitePreferencesType(graphene.ObjectType): + save_lesson_documentations_by_week = graphene.Boolean() + + def resolve_save_lesson_documentations_by_week(root, info, **kwargs): + return root["alsijil__save_lesson_documentations_by_week"] + + class LessonDocumentationMutation(graphene.Mutation): class Arguments: year = graphene.Int(required=True) @@ -78,18 +90,18 @@ class LessonDocumentationMutation(graphene.Mutation): @classmethod def mutate( - cls, - root, - info, - year, - week, - lesson_period_id=None, - event_id=None, - extra_lesson_id=None, - lesson_documentation_id=None, - topic=None, - homework=None, - group_note=None, + cls, + root, + info, + year, + week, + lesson_period_id=None, + event_id=None, + extra_lesson_id=None, + lesson_documentation_id=None, + topic=None, + homework=None, + group_note=None, ): lesson_period = LessonPeriod.objects.filter(pk=lesson_period_id).first() @@ -114,13 +126,13 @@ class LessonDocumentationMutation(graphene.Mutation): lesson_documentation.save() if ( - get_site_preferences()["alsijil__save_lesson_documentations_by_week"] - and ( + get_site_preferences()["alsijil__save_lesson_documentations_by_week"] + and ( lesson_documentation.topic or lesson_documentation.homework or lesson_documentation.group_note - ) - and lesson_documentation.lesson_period + ) + and lesson_documentation.lesson_period ): lesson_documentation.carry_over_data( LessonPeriod.objects.filter(lesson=lesson_documentation.lesson_period.lesson), True @@ -147,18 +159,18 @@ class PersonalNoteMutation(graphene.Mutation): @classmethod def mutate( - cls, - root, - info, - person_id, - lesson_documentation, - personal_note_id=None, - late=None, - absent=None, - excused=None, - excuse_type=None, - remarks=None, - extra_marks=None, + cls, + root, + info, + person_id, + lesson_documentation, + personal_note_id=None, + late=None, + absent=None, + excused=None, + excuse_type=None, + remarks=None, + extra_marks=None, ): person = Person.objects.get(pk=person_id) lesson_documentation = LessonDocumentation.objects.get(pk=lesson_documentation) @@ -205,8 +217,10 @@ class Query(graphene.ObjectType): lesson_documentations = graphene.List(LessonDocumentationType) lesson_documentation_by_id = graphene.Field(LessonDocumentationType, id=graphene.ID()) lesson_documentations_by_lesson_id = graphene.List(LessonDocumentationType, id=graphene.ID()) + coursebook_lessons = graphene.List(LessonType) personal_notes = graphene.List(PersonalNoteType) extra_marks = graphene.List(ExtraMarkType) + alsijil_site_preferences = graphene.Field(AlsijilSitePreferencesType) def resolve_excuse_types(root, info, **kwargs): # FIXME do permission stuff @@ -241,9 +255,40 @@ class Query(graphene.ObjectType): "-year", "-week", "-lesson_period__period__weekday", "-lesson_period__period__period" ) - def resolve_personal_notes(root, info, **kwargs): - # FIXME do permission stuff - return PersonalNote.objects.all() + def resolve_coursebook_lessons(root, info, **kwargs): # noqa + current_week = CalendarWeek.current_week() + current_year = get_current_year() + # Show all future and the ones of last week + + last_week, last_week_year = ( + (current_week - 1, current_year) + if current_week >= 2 + else (CalendarWeek.get_last_week_of_year(current_year - 1).week, current_year - 1) + ) + + last_week_query = Q( + lesson_periods__substitutions__week=last_week, + lesson_periods__substitutions__year=last_week_year, + ) + this_week_query = Q( + lesson_periods__substitutions__week__gte=current_week, + lesson_periods__substitutions__year=current_year, + ) + next_years_query = Q(lesson_periods__substitutions__year__gt=current_year) + return Lesson.objects.filter( + Q(teachers=info.context.user.person) | (Q(lesson_periods__substitutions__teachers=info.context.user.person) + & (last_week_query | this_week_query | next_years_query) + ) + ).for_current_or_all().distinct() if has_person(info.context.user) else None + + def resolve_alsijil_site_preferences(root, info, **kwargs): + return info.context.site.preferences + + +def resolve_personal_notes(root, info, **kwargs): + # FIXME do permission stuff + return PersonalNote.objects.all() + - def resolve_extra_marks(root, info, **kwargs): - return ExtraMark.objects.all() +def resolve_extra_marks(root, info, **kwargs): + return ExtraMark.objects.all() diff --git a/aleksis/apps/alsijil/templates/alsijil/class_register/coursebook.html b/aleksis/apps/alsijil/templates/alsijil/class_register/coursebook.html deleted file mode 100644 index 80378c66a06cbac1951cbf38f1d6d49bea896b49..0000000000000000000000000000000000000000 --- a/aleksis/apps/alsijil/templates/alsijil/class_register/coursebook.html +++ /dev/null @@ -1,16 +0,0 @@ -{% extends "core/vue_base.html" %} -{% load static i18n %} -{% load render_bundle from webpack_loader %} - -{% block page_title %} - {% trans "Coursebook" %} -{% endblock %} -{% block browser_title %}{% trans "Coursebook" %} {{ lesson }}{% endblock %} -{% block content %} -<div class="text-h5">{{ lesson }}</div> -<router-view save-lesson-documentations-per-week={{ SITE_PREFERENCES.alsijil__save_lesson_documentations_by_week }} /> -{% endblock %} - -{% block extra_body %} - {% render_bundle "aleksis.apps.alsijil" %} -{% endblock %} diff --git a/aleksis/apps/alsijil/templates/alsijil/class_register/select_coursebook.html b/aleksis/apps/alsijil/templates/alsijil/class_register/select_coursebook.html deleted file mode 100644 index 57114df23ebd2e1631f56596fd89c220740fdad8..0000000000000000000000000000000000000000 --- a/aleksis/apps/alsijil/templates/alsijil/class_register/select_coursebook.html +++ /dev/null @@ -1,53 +0,0 @@ -{% extends "core/vue_base.html" %} -{% load static i18n %} -{% load render_bundle from webpack_loader %} - -{% block page_title %}{% trans "Select Coursebook" %}{% endblock %} -{% block browser_title %}{% trans "Select Coursebook" %}{% endblock %} -{% block content %} - <v-row> - {% for lesson in lessons %} - <v-col xs="12" sm="6" md="6" lg="4" xl="3" class="d-flex"> - <v-card class="flex-grow-1"> - <v-card-title> - {% for group in lesson.groups.all %}{{ group.short_name }}{% if not forloop.last %},{% endif %}{% endfor %} - · {{ lesson.subject.name }} - </v-card-title> - <v-card-subtitle> - {{ lesson.validity.date_start }}-{{ lesson.validity.date_end }} - </v-card-subtitle> - <v-card-text> - {{ lesson.teachers.all|join:"," }} - </v-card-text> -{# <v-spacer></v-spacer>#} - <v-card-actions> - <v-btn :href="urls.coursebook({{ lesson.pk }})" text color="secondary"> - <v-icon left>mdi-book-search-outline</v-icon> - {% trans "Open in coursebook" %} - </v-btn> - </v-card-actions> - </v-card> - </v-col> - {% empty %} - <v-container - class="text-center fill-height" - style="height: calc(100vh - 58px);" - > - <v-row align="center"> - <v-col> - <h1 class="text-h3 primary--text"> - <v-icon color="error" x-large>mdi-book-off-outline</v-icon> - {% trans "No Coursebook" %} - </h1> - - <p>{% trans "There are no courses where you are a teacher." %} </p> - </v-col> - </v-row> - </v-container> - {% endfor %} - </v-row> -{% endblock %} - -{% block extra_body %} - {% render_bundle "aleksis.apps.alsijil" %} -{% endblock %} diff --git a/aleksis/apps/alsijil/urls.py b/aleksis/apps/alsijil/urls.py index 2cbc63fbbbe9932e3f7fb6e312980971a1fc20dc..b06aebd352774727bb6bddca9dec8a0e28846a69 100644 --- a/aleksis/apps/alsijil/urls.py +++ b/aleksis/apps/alsijil/urls.py @@ -3,8 +3,6 @@ from django.urls import path from . import views urlpatterns = [ - path("coursebook/", views.SelectCoursebookView.as_view(), name="select_coursebook"), - path("coursebook/<int:pk>/", views.CoursebookView.as_view(), name="coursebook"), path("lesson", views.register_object, {"model": "lesson"}, name="lesson_period"), path( "lesson/<int:year>/<int:week>/<int:id_>", diff --git a/aleksis/apps/alsijil/views.py b/aleksis/apps/alsijil/views.py index 55fc21792f9500fc7d9de0c92dc0d38244a4337f..095bc80d221d31dbc81d2b5af081e430f20432d1 100644 --- a/aleksis/apps/alsijil/views.py +++ b/aleksis/apps/alsijil/views.py @@ -1362,16 +1362,6 @@ class AllRegisterObjectsView(PermissionRequiredMixin, View): return render(request, "alsijil/class_register/all_objects.html", context) -class CoursebookView(PermissionRequiredMixin, DetailView): - model = Lesson - template_name = "alsijil/class_register/coursebook.html" - permission_required = "alsijil.view_coursebook_rule" - - def get_context_data(self, **kwargs): - context = super().get_context_data(**kwargs) - return context - - class SelectCoursebookView(PermissionRequiredMixin, TemplateView): template_name = "alsijil/class_register/select_coursebook.html" permission_required = "alsijil.view_coursebook_rule" # FIXME