Skip to content
Snippets Groups Projects
LessonSummary.vue 5.20 KiB
<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>