<template> <div> <!-- compact --> <div class="d-flex flex-column flex-md-row align-stretch align-md-center gap justify-start" v-if="compact" > <v-text-field class="flex-grow-1 min-width" dense hide-details filled :label="$t('alsijil.coursebook.summary.topic')" :value="documentation.topic" @input="topic = $event" @focusout="save" @keydown.enter="saveAndBlur" :loading="loading" :disabled="!documentation.canEdit" /> <div class="d-flex flex-column align-start flex-grow-1"> <v-chip v-bind="dialogActivator.attrs" v-on="dialogActivator.on" :outlined="!documentation.homework" @click="$emit('open')" class="mb-2 max-width" dense > <span class="max-width text-truncate">{{ documentation.homework ? $t("alsijil.coursebook.summary.homework.value", documentation) : $t("alsijil.coursebook.summary.homework.empty") }}</span> <v-icon right>{{ homeworkIcon }}</v-icon> </v-chip> <v-chip v-bind="dialogActivator.attrs" v-on="dialogActivator.on" :outlined="!documentation.groupNote" @click="$emit('open')" class="max-width" dense > <span class="max-width text-truncate">{{ documentation.groupNote ? $t("alsijil.coursebook.summary.group_note.value", { groupNote: truncate(documentation.groupNote), }) : $t("alsijil.coursebook.summary.group_note.empty") }}</span> <v-icon right>{{ groupNoteIcon }}</v-icon> </v-chip> </div> </div> <!-- not compact --> <!-- Are focusout & enter enough trigger? --> <v-text-field filled v-if="!compact" :label="$t('alsijil.coursebook.summary.topic')" :value="documentation.topic" @input="topic = $event" :disabled="!documentation.canEdit" /> <v-textarea filled auto-grow v-if="!compact" :label="$t('alsijil.coursebook.summary.homework.label')" :value="documentation.homework" @input="homework = $event" :disabled="!documentation.canEdit" /> <v-textarea filled auto-grow v-if="!compact" :label="$t('alsijil.coursebook.summary.group_note.label')" :value="documentation.groupNote" @input="groupNote = $event" :disabled="!documentation.canEdit" /> </div> </template> <script> import createOrPatchMixin from "aleksis.core/mixins/createOrPatchMixin.js"; import documentationPartMixin from "./documentationPartMixin"; export default { name: "LessonSummary", mixins: [createOrPatchMixin, documentationPartMixin], emits: ["open"], data() { return { topic: "", homework: "", groupNote: "", loading: false, }; }, methods: { truncate(str) { return str ? (str.length > 25 ? str.slice(0, 24) + " …" : str) : ""; }, handleUpdateAfterCreateOrPatch(itemId, wasCreate) { return (cached, incoming) => { this.loading = false; for (const object of incoming) { console.log("summary: handleUpdateAfterCreateOrPatch", object); // Replace the current documentation const index = cached.findIndex( (o) => o[itemId] === this.documentation.id, ); // merged with the incoming partial documentation cached[index] = { ...this.documentation, ...object }; } return cached; }; }, save() { if (this.topic || this.homework || this.groupNote) { const topic = this.topic ? { topic: this.topic } : {}; const homework = this.homework ? { homework: this.homework } : {}; const groupNote = this.groupNote ? { groupNote: this.groupNote } : {}; this.loading = true; this.createOrPatch([ { id: this.documentation.id, ...topic, ...homework, ...groupNote, }, ]); this.topic = ""; this.homework = ""; this.groupNote = ""; } }, saveAndBlur(event) { this.save(); event.target.blur(); }, }, computed: { homeworkIcon() { if (this.documentation.homework) { return this.documentation.canEdit ? "mdi-book-edit-outline" : "mdi-book-alert-outline"; } return this.documentation.canEdit ? "mdi-book-plus-outline" : "mdi-book-off-outline"; }, groupNoteIcon() { if (this.documentation.groupNote) { return this.documentation.canEdit ? "mdi-note-edit-outline" : "mdi-note-alert-outline"; } return this.documentation.canEdit ? "mdi-note-plus-outline" : "mdi-note-off-outline"; }, minWidth() { return Math.min(this.documentation?.topic?.length || 15, 15) + "ch"; }, maxWidth() { return this.$vuetify.breakpoint.mobile ? "100%" : "20ch"; } }, }; </script> <style scoped> .min-width { min-width: v-bind(minWidth); } .max-width { max-width: v-bind(maxWidth) } .gap { gap: 1em; } </style>