Skip to content
Snippets Groups Projects

Resolve "Frontend for Models"

Merged Julian requested to merge 1-frontend-for-models into master
Compare and Show latest version
7 files
+ 430
2
Compare changes
  • Side-by-side
  • Inline
Files
7
<script setup>
import InlineCRUDList from "aleksis.core/components/generic/InlineCRUDList.vue";
import WeekDayField from "aleksis.core/components/generic/forms/WeekDayField.vue";
import TimeGridField from "../validity_range/TimeGridField.vue";
</script>
<template>
<inline-c-r-u-d-list
:headers="headers"
:i18n-key="i18nKey"
:create-item-i18n-key="createItemI18nKey"
:gql-query="gqlQuery"
:gql-create-mutation="gqlCreateMutation"
:gql-patch-mutation="gqlPatchMutation"
:gql-delete-mutation="gqlDeleteMutation"
:gql-delete-multiple-mutation="gqlDeleteMultipleMutation"
:default-item="defaultItem"
:get-create-data="getCreateData"
:get-patch-data="getPatchData"
filter
>
<template #breakSlot="{ item }">
<div class="body-1">{{ formatBreakSlotItem(item.breakSlot) }}</div>
<div class="caption">{{ formatTimeGridItem(item.breakSlot.timeGrid) }}</div>
</template>
<!-- eslint-disable-next-line vue/valid-v-slot -->
<template #breakSlot.field="{ attrs, on }">
<div aria-required="true">
<v-autocomplete
return-object
:items="internalBreakSlots"
:item-text="formatBreakSlotItem"
item-value="id"
:loading="$apollo.queries.internalBreakSlots.loading"
v-bind="attrs"
v-on="on"
>
<template v-slot:item="data">
<v-list-item-content>
<v-list-item-title>{{ formatBreakSlotItem(data.item) }}</v-list-item-title>
<v-list-item-subtitle>{{ formatTimeGridItem(data.item.timeGrid) }}</v-list-item-subtitle>
</v-list-item-content>
</template>
</v-autocomplete>
</div>
</template>
<template #rooms="{ item }">
<v-chip v-for="room in item.rooms" dense class="mx-1">{{ room.shortName }}</v-chip>
</template>
<!-- eslint-disable-next-line vue/valid-v-slot -->
<template #rooms.field="{ attrs, on }">
<div aria-required="true">
<v-autocomplete
multiple
return-object
:items="internalRooms"
item-text="name"
item-value="id"
:loading="$apollo.queries.internalRooms.loading"
v-bind="attrs"
v-on="on"
/>
</div>
</template>
<template #teachers="{ item }">
<v-chip v-for="teacher in item.teachers" dense class="mx-1">{{ teacher.fullName }}</v-chip>
</template>
<!-- eslint-disable-next-line vue/valid-v-slot -->
<template #teachers.field="{ attrs, on }">
<div aria-required="true">
<v-autocomplete
multiple
return-object
:items="persons"
item-text="shortName"
item-value="id"
v-bind="attrs"
v-on="on"
:loading="$apollo.queries.persons.loading"
/>
</div>
</template>
<!--<template #filters="{ attrs, on }">-->
<!-- <time-grid-field-->
<!-- outlined-->
<!-- filled-->
<!-- v-bind="attrs('break_slot__time_grid__exact')"-->
<!-- v-on="on('break_slot__time_grid__exact')"-->
<!-- :label="$t('labels.select_validity_range')"-->
<!-- hide-details-->
<!-- />-->
<!--</template>-->
</inline-c-r-u-d-list>
</template>
<script>
import {
supervisions,
createSupervision,
deleteSupervision,
deleteSupervisions,
updateSupervisions,
} from "./supervision.graphql";
import { gqlTeachers } from "../helper.graphql";
import { rooms } from "aleksis.core/components/room/room.graphql";
import { breakSlots } from "../breaks_and_slots/break.graphql";
import { RRule } from "rrule";
export default {
name: "LesroosterSupervision",
data() {
return {
headers: [
{
text: this.$t("lesrooster.supervision.break_slot"),
value: "breakSlot",
},
{
text: this.$t("lesrooster.supervision.rooms"),
value: "rooms",
},
{
text: this.$t("lesrooster.supervision.teachers"),
value: "teachers",
},
],
i18nKey: "lesrooster.supervision",
createItemI18nKey: "lesrooster.supervision.create_supervision",
gqlQuery: supervisions,
gqlCreateMutation: createSupervision,
gqlPatchMutation: updateSupervisions,
gqlDeleteMutation: deleteSupervision,
gqlDeleteMultipleMutation: deleteSupervisions,
defaultItem: {
breakSlot: null,
teachers: [],
rooms: [],
},
required: [(value) => !!value || this.$t("forms.errors.required")],
};
},
apollo: {
persons: {
query: gqlTeachers,
},
internalRooms: {
query: rooms,
update: (data) => data.items,
},
internalBreakSlots: {
query: breakSlots,
update: (data) => data.items,
},
},
methods: {
formatTimeGridItem(item) {
if (item.group === null) {
return this.$t("lesrooster.validity_range.time_grid.repr.generic", item.validityRange);
}
return this.$t("lesrooster.validity_range.time_grid.repr.default", [item.validityRange.name, item.group.name]);
},
formatBreakSlotItem(item) {
return this.$t("lesrooster.break.repr.weekday_short", { weekday: this.$t("weekdays." + item.weekday), timeStart: item.timeStart, timeEnd: item.timeEnd })
},
getRRule(timeGrid) {
const rule = new RRule({
freq: RRule.WEEKLY, // TODO: Make this configurable
dtstart: new Date(timeGrid.validityRange.dateStart), // FIXME: check if this is correct with timezones etc.
until: new Date(timeGrid.validityRange.dateEnd), // FIXME: check if this is correct with timezones etc.
});
return rule;
},
getCreateData(item) {
return {
breakSlot: item.breakSlot.id,
rooms: item.rooms.map((r) => r.id),
teachers: item.teachers.map((t) => t.id),
recurrence: this.getRRule(item.breakSlot.timeGrid).toString(),
};
},
getPatchData(items) {
return items.map((item) => ({
id: item.id,
breakSlot: item.breakSlot.id,
rooms: item.rooms.map((r) => r.id),
teachers: item.teachers.map((t) => t.id),
recurrence: this.getRRule(item.breakSlot.timeGrid).toString(),
}));
},
},
};
</script>
<style scoped></style>
Loading