diff --git a/aleksis/apps/kolego/frontend/components/AbsenceReasons.vue b/aleksis/apps/kolego/frontend/components/AbsenceReasons.vue new file mode 100644 index 0000000000000000000000000000000000000000..2a44295ef1c7d1814a0a67e886e11e4790dc5421 --- /dev/null +++ b/aleksis/apps/kolego/frontend/components/AbsenceReasons.vue @@ -0,0 +1,58 @@ +<script setup> +import InlineCRUDList from "aleksis.core/components/generic/InlineCRUDList.vue"; +</script> + +<template> + <v-container> + <inline-c-r-u-d-list + :headers="headers" + :i18n-key="i18nKey" + create-item-i18n-key="kolego.absence_reason.create" + :gql-query="gqlQuery" + :gql-create-mutation="gqlCreateMutation" + :gql-patch-mutation="gqlPatchMutation" + :gql-delete-mutation="gqlDeleteMutation" + :default-item="defaultItem" + > + </inline-c-r-u-d-list> + </v-container> +</template> + +<script> +import { + gqlAbsenceReasons, + createAbsenceReason, + deleteAbsenceReason, + updateAbsenceReasons, +} from "./absenceReasons.graphql"; + +export default { + name: "AbsenceReasons", + data() { + return { + headers: [ + { + text: this.$t("kolego.absence_reason.short_name"), + value: "shortName", + }, + { + text: this.$t("kolego.absence_reason.name"), + value: "name", + }, + ], + i18nKey: "kolego.absence_reason", + gqlQuery: gqlAbsenceReasons, + gqlCreateMutation: createAbsenceReason, + gqlPatchMutation: updateAbsenceReasons, + gqlDeleteMutation: deleteAbsenceReason, + defaultItem: { + shortName: "", + name: "", + }, + required: [(value) => !!value || this.$t("forms.errors.required")], + }; + }, +}; +</script> + +<style scoped></style> diff --git a/aleksis/apps/kolego/frontend/components/Absences.vue b/aleksis/apps/kolego/frontend/components/Absences.vue new file mode 100644 index 0000000000000000000000000000000000000000..bec3233ac923be84da7b6cacdec0c0e9ef583234 --- /dev/null +++ b/aleksis/apps/kolego/frontend/components/Absences.vue @@ -0,0 +1,153 @@ +<script setup> +import InlineCRUDList from "aleksis.core/components/generic/InlineCRUDList.vue"; +import DateTimeField from "aleksis.core/components/generic/forms/DateTimeField.vue"; +</script> + +<template> + <v-container> + <inline-c-r-u-d-list + :headers="headers" + :i18n-key="i18nKey" + create-item-i18n-key="kolego.absence.create" + :gql-query="gqlQuery" + :gql-create-mutation="gqlCreateMutation" + :gql-patch-mutation="gqlPatchMutation" + :gql-delete-mutation="gqlDeleteMutation" + :default-item="defaultItem" + > + <template #datetimeStart="{ item }"> + {{ $d(new Date(item.datetimeStart), "short") }} + </template> + <!-- eslint-disable-next-line vue/valid-v-slot --> + <template #datetimeStart.field="{ attrs, on, item }"> + <div aria-required="true"> + <date-time-field + v-bind="attrs" + v-on="on" + :rules="required" + :max="item ? item.datetimeEnd : undefined" + required + ></date-time-field> + </div> + </template> + + <template #datetimeEnd="{ item }"> + {{ $d(new Date(item.datetimeEnd), "short") }} + </template> + <!-- eslint-disable-next-line vue/valid-v-slot --> + <template #datetimeEnd.field="{ attrs, on, item }"> + <div aria-required="true"> + <date-time-field + v-bind="attrs" + v-on="on" + required + :rules="required" + :min="item ? item.datetimeStart : undefined" + ></date-time-field> + </div> + </template> + + <template #person="{ item }"> + <v-chip>{{ + item.person.fullName + }}</v-chip + > + </template> + <!-- eslint-disable-next-line vue/valid-v-slot --> + <template #person.field="{ attrs, on }"> + <div aria-required="true"> + <v-autocomplete + :items="persons" + item-text="fullName" + item-value="id" + v-bind="attrs" + v-on="on" + return-object + required + :rules="required" + /> + </div> + </template> + + <template #reason="{ item }"> + <v-chip>{{ + item.shortName + }}</v-chip + > + </template> + <!-- eslint-disable-next-line vue/valid-v-slot --> + <template #reason.field="{ attrs, on }"> + <div aria-required="true"> + <v-autocomplete + :items="absenceReasons" + item-text="shortName" + item-value="id" + v-bind="attrs" + v-on="on" + return-object + /> + </div> + </template> + </inline-c-r-u-d-list> + </v-container> +</template> + +<script> +import { + absences, + createAbsence, + deleteAbsence, + updateAbsences, +} from "./absences.graphql"; +import gqlPersons from "./persons.graphql"; +import gqlAbsenceReasons from "./absenceReasons.graphql"; + +export default { + name: "Absences", + data() { + return { + headers: [ + { + text: this.$t("school_term.date_start"), + value: "datetimeStart", + }, + { + text: this.$t("school_term.date_end"), + value: "datetimeEnd", + }, + { + text: this.$t("person.title"), + value: "person", + }, + { + text: this.$t("kolego.absence.reason"), + value: "reason", + }, + { + text: this.$t("kolego.absence.comment"), + value: "comment", + }, + ], + i18nKey: "kolego.absence", + gqlQuery: absences, + gqlCreateMutation: createAbsence, + gqlPatchMutation: updateAbsences, + gqlDeleteMutation: deleteAbsence, + defaultItem: { + datetimeStart: new Date().toISOString(), + datetimeEnd: new Date().toISOString(), + person: "", + reason: "", + comment: "", + }, + required: [(value) => !!value || this.$t("forms.errors.required")], + }; + }, + apollo: { + persons: gqlPersons, + absenceReasons: gqlAbsenceReasons, + }, +}; +</script> + +<style scoped></style> diff --git a/aleksis/apps/kolego/frontend/components/absenceReasons.graphql b/aleksis/apps/kolego/frontend/components/absenceReasons.graphql new file mode 100644 index 0000000000000000000000000000000000000000..996e514cdb4511ace135b73a354f39a79c793199 --- /dev/null +++ b/aleksis/apps/kolego/frontend/components/absenceReasons.graphql @@ -0,0 +1,39 @@ +query gqlAbsenceReasons($orderBy: [String], $filters: JSONString) { + items: absenceReasons(orderBy: $orderBy, filters: $filters) { + id + shortName + name + canEdit + canDelete + } +} + +mutation createAbsenceReason($input: CreateAbsenceReasonInput!) { + createAbsenceReason(input: $input) { + absenceReason { + id + shortName + name + canEdit + canDelete + } + } +} + +mutation deleteAbsenceReason($id: ID!) { + deleteAbsenceReason(id: $id) { + ok + } +} + +mutation updateAbsenceReasons($input: [BatchPatchAbsenceReasonInput]!) { + batchMutation: updateAbsenceReasons(input: $input) { + items: absenceReasons { + id + shortName + name + canEdit + canDelete + } + } +} diff --git a/aleksis/apps/kolego/frontend/components/absences.graphql b/aleksis/apps/kolego/frontend/components/absences.graphql new file mode 100644 index 0000000000000000000000000000000000000000..e3b07d18a178e2237f44267095ccccd2539bb129 --- /dev/null +++ b/aleksis/apps/kolego/frontend/components/absences.graphql @@ -0,0 +1,63 @@ +query absences($orderBy: [String], $filters: JSONString) { + items: absences(orderBy: $orderBy, filters: $filters) { + id + person { + fullName + } + reason { + shortName + name + } + comment + dateStart + dateEnd + canEdit + canDelete + } +} + +mutation createAbsence($input: CreateAbsenceInput!) { + createAbsence(input: $input) { + absence { + id + person { + fullName + } + reason { + shortName + name + } + comment + dateStart + dateEnd + canEdit + canDelete + } + } +} + +mutation deleteAbsence($id: ID!) { + deleteAbsence(id: $id) { + ok + } +} + +mutation updateAbsences($input: [BatchPatchAbsenceInput]!) { + batchMutation: updateAbsences(input: $input) { + items: absences { + id + person { + fullName + } + reason { + shortName + name + } + comment + dateStart + dateEnd + canEdit + canDelete + } + } +} diff --git a/aleksis/apps/kolego/frontend/components/persons.graphql b/aleksis/apps/kolego/frontend/components/persons.graphql new file mode 100644 index 0000000000000000000000000000000000000000..42405e59570d8f0816ede5432cf295ebc4309ed8 --- /dev/null +++ b/aleksis/apps/kolego/frontend/components/persons.graphql @@ -0,0 +1,6 @@ +query gqlPersons { + persons { + id + fullName + } +} diff --git a/aleksis/apps/kolego/frontend/index.js b/aleksis/apps/kolego/frontend/index.js index d40caced26f62c10e22abb358d9d9e1c24620e50..9110cd797e9b012b5dbfbf681eb9c3cfbd3f2292 100644 --- a/aleksis/apps/kolego/frontend/index.js +++ b/aleksis/apps/kolego/frontend/index.js @@ -11,12 +11,23 @@ export default { }, children: [ { - path: "empty", - component: () => import("./components/Empty.vue"), - name: "kolego.empty", + path: "absences", + component: () => import("./components/Absences.vue"), + name: "kolego.absences", meta: { inMenu: true, - titleKey: "kolego.menu_title", + titleKey: "kolego.absence.menu_title", + icon: "", + permission: "", + }, + }, + { + path: "absence_reasons", + component: () => import("./components/AbsenceReasons.vue"), + name: "kolego.absence_reasons", + meta: { + inMenu: true, + titleKey: "kolego.absence_reason.menu_title", icon: "", permission: "", }, diff --git a/aleksis/apps/kolego/frontend/messages/de.json b/aleksis/apps/kolego/frontend/messages/de.json new file mode 100644 index 0000000000000000000000000000000000000000..098717b13c50bd5dd5bedc78b2782b5e04db3c11 --- /dev/null +++ b/aleksis/apps/kolego/frontend/messages/de.json @@ -0,0 +1,19 @@ +{ + "kolego": { + "menu_title": "Kolego", + "absence": { + "menu_title": "Abwesenheiten", + "title_plural": "Abwesenheiten", + "create": "Abwesenheit anlegen", + "reason": "Grund", + "comment": "Kommentar" + }, + "absence_reason": { + "menu_title": "Abwesenheitsgründe", + "title_plural": "Abwesenheitsgründe", + "create": "Abwesenheitsgrund erstellen", + "short_name": "Kurzname", + "name": "Name" + } + } +} diff --git a/aleksis/apps/kolego/frontend/messages/en.json b/aleksis/apps/kolego/frontend/messages/en.json index accecb357e3a24610f049b6c23fac544610e4728..bae3de6b87a70bd75454b186a22c9ef9fca54458 100644 --- a/aleksis/apps/kolego/frontend/messages/en.json +++ b/aleksis/apps/kolego/frontend/messages/en.json @@ -1,5 +1,19 @@ { "kolego": { - "menu_title": "Kolego" + "menu_title": "Kolego", + "absence": { + "menu_title": "Absences", + "title_plural": "Absences", + "create": "Create absence", + "reason": "Reason", + "comment": "Comment" + }, + "absence_reason": { + "menu_title": "Absence Reasons", + "title_plural": "Absence Reasons", + "create": "Create absence reason", + "short_name": "Short name", + "name": "Name" + } } }