<template> <div> <!-- compact --> <div class="d-flex flex-column flex-md-row align-stretch align-md-center gap justify-start fill-height" v-if="compact" > <v-text-field :class="{ 'flex-grow-1 min-width': true, 'full-width': $vuetify.breakpoint.mobile }" hide-details outlined :label="$t('alsijil.coursebook.summary.topic')" :value="documentation.topic" @input="topic = $event" @focusout="save" @keydown.enter="saveAndBlur" :loading="loading" :readonly="!documentation.canEdit" /> <div :class="{ 'flex-grow-1 max-width': true, 'full-width': $vuetify.breakpoint.mobile }"> <v-card v-bind="dialogActivator.attrs" v-on="dialogActivator.on" outlined @click="$emit('open')" class="max-width grid-layout pa-1" dense rounded="lg" > <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 class="float-right">{{ homeworkIcon }}</v-icon> <span class="max-width text-truncate">{{ documentation.groupNote ? $t("alsijil.coursebook.summary.group_note.value", documentation) : $t("alsijil.coursebook.summary.group_note.empty") }}</span> <v-icon right class="float-right">{{ groupNoteIcon }}</v-icon> </v-card> </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" :readonly="!documentation.canEdit" /> <v-textarea filled auto-grow rows="3" clearable v-if="!compact" :label="$t('alsijil.coursebook.summary.homework.label')" :value="documentation.homework" @input="homework = $event" :readonly="!documentation.canEdit" /> <v-textarea filled auto-grow rows="3" clearable v-if="!compact" :label="$t('alsijil.coursebook.summary.group_note.label')" :value="documentation.groupNote" @input="groupNote = $event" :readonly="!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: null, homework: null, groupNote: null, }; }, methods: { handleUpdateAfterCreateOrPatch(itemId, wasCreate) { return (cached, incoming) => { 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 !== null || this.homework !== null || this.groupNote !== null) { const topic = this.topic !== null ? { topic: this.topic } : {}; const homework = this.homework !== null ? { homework: this.homework } : {}; const groupNote = this.groupNote !== null ? { groupNote: this.groupNote } : {}; this.createOrPatch([ { id: this.documentation.id, ...topic, ...homework, ...groupNote, }, ]); this.topic = null; this.homework = null; this.groupNote = null; } }, 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; } .grid-layout { display: grid; grid-template-columns: auto min-content; } </style>