From 18ccbc4d72dde68bc4d77ed37076b7d1037cadc2 Mon Sep 17 00:00:00 2001 From: Julian Leucker <leuckerj@gmail.com> Date: Tue, 15 Aug 2023 18:23:16 +0200 Subject: [PATCH] Create generic TimeGridField.vue (hopefully as a drop-in replacement for the validity-range-field) --- .../validity_range/TimeGridField.vue | 143 ++++++++++++++++++ .../apps/lesrooster/frontend/messages/en.json | 7 +- 2 files changed, 149 insertions(+), 1 deletion(-) create mode 100644 aleksis/apps/lesrooster/frontend/components/validity_range/TimeGridField.vue diff --git a/aleksis/apps/lesrooster/frontend/components/validity_range/TimeGridField.vue b/aleksis/apps/lesrooster/frontend/components/validity_range/TimeGridField.vue new file mode 100644 index 00000000..7b58f9ff --- /dev/null +++ b/aleksis/apps/lesrooster/frontend/components/validity_range/TimeGridField.vue @@ -0,0 +1,143 @@ +<script setup> +import ForeignKeyField from "aleksis.core/components/generic/forms/ForeignKeyField.vue"; +import ValidityRangeField from "./ValidityRangeField.vue"; +</script> + +<script> +import { defineComponent } from 'vue' +import { timeGrids, createTimeGrid } from "./validityRange.graphql"; +import { gqlGroups } from "../helper.graphql"; + +export default defineComponent({ + name: "TimeGridField", + apollo: { + groups: { + query: gqlGroups, + } + }, + data() { + return { + headers: [ + { + text: this.$t("lesrooster.validity_range.time_grid.fields.validity_range"), + value: "validityRange", + cols: 12, + }, + { + text: this.$t("lesrooster.validity_range.time_grid.fields.is_generic"), + value: "isGeneric", + }, + { + text: this.$t("lesrooster.validity_range.time_grid.fields.group"), + value: "group", + }, + ], + i18nKey: "lesrooster.validity_range.time_grid", + gqlQuery: timeGrids, + gqlCreateMutation: createTimeGrid, + defaultItem: { + isGeneric: false, + group: null, + validityRange: null, + }, + required: [(value) => !!value || this.$t("forms.errors.required")], + }; + }, + methods: { + getCreateData(item) { + return { + group: item.group, + validityRange: item.validityRange?.id, + }; + }, + getPatchData(items) {}, + selectableGroups(itemModel) { + if (itemModel.validityRange === null) return []; + + + // Filter all groups, so we only take the ones that are not already used in this validityRange + return this.groups + ?.filter(group => + !this.$refs.field.items + .some(timeGrid => + timeGrid.validityRange.id === itemModel.validityRange.id + && timeGrid.group !== null + && timeGrid.group.id === group.id + ) + ); + }, + genericDisabled(itemModel) { + if (itemModel.validityRange === null) return true; + + // Is there a timeGrid that has the same validityRange as we and no group? + return this.$refs.field.items.some(timeGrid => + timeGrid.validityRange.id === itemModel.validityRange.id && timeGrid.group === null + ); + }, + formatItem(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]); + } + }, +}) +</script> + +<template> +<foreign-key-field + v-bind="$attrs" + v-on="$listeners" + :fields="headers" + create-item-i18n-key="lesrooster.validity_range.time_grid.create_long" + :gql-query="gqlQuery" + :gql-create-mutation="gqlCreateMutation" + :gql-patch-mutation="{}" + :default-item="defaultItem" + :get-create-data="getCreateData" + :get-patch-data="getPatchData" + :item-name="formatItem" + return-object + ref="field" + > + <template #item="{ item }"> + {{ formatItem(item) }} + </template> + + <!-- eslint-disable-next-line vue/valid-v-slot --> + <template #validityRange.field="{ attrs, on }"> + <div aria-required="true"> + <validity-range-field + v-bind="attrs" + v-on="on" + :rules="required" + required + /> + </div> + </template> + + <template #isGeneric.field="{ attrs, on, item }"> + <v-switch + v-bind="attrs" + v-on="on" + :disabled="genericDisabled(item)" + ></v-switch> + </template> + + <template #group.field="{ attrs, on, item }"> + <v-autocomplete + :items="selectableGroups(item)" + item-text="name" + item-value="id" + v-bind="attrs" + v-on="on" + :disabled="item.isGeneric" + :loading="$apollo.queries.groups.loading" + /> + </template> + </foreign-key-field> +</template> + +<style scoped> + +</style> \ No newline at end of file diff --git a/aleksis/apps/lesrooster/frontend/messages/en.json b/aleksis/apps/lesrooster/frontend/messages/en.json index 335732b8..636bb70a 100644 --- a/aleksis/apps/lesrooster/frontend/messages/en.json +++ b/aleksis/apps/lesrooster/frontend/messages/en.json @@ -18,11 +18,16 @@ "multiple_set": "Data connected to this validity range (e.g. slots) can be different for the groups below." }, "create": "Select group", + "create_long": "Create group-specific validity range", "fields": { "is_generic": "Is generic", "group": "Group" }, - "confirm_delete_body": "If you remove this group from the validity range, all connected data, like slots and lessons are deleted." + "confirm_delete_body": "If you remove this group from the validity range, all connected data, like slots and lessons are deleted.", + "repr": { + "default": "{0} ({1})", + "generic": "{name} (generic/catch-all)" + } } }, "slot": { -- GitLab