LessonSummary.vue 4.90 KiB
<template>
<v-card-text>
<!-- 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">
<v-chip
:outlined="!documentation.homework"
@click="$emit('open')"
class="mb-2 chip-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
:outlined="!documentation.groupNote"
@click="$emit('open')"
class="chip-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"
/>
</v-card-text>
</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";
},
},
};
</script>
<style scoped>
.min-width {
min-width: 25ch;
}
.max-width {
max-width: min(100%, 40ch);
}
.chip-width {
max-width: 40ch;
}
.gap {
gap: 1em;
}
</style>