Skip to content
Snippets Groups Projects
Timetable.vue 5.83 KiB
<script>
import { gqlAvailableTimetables } from "./timetables.graphql";
import NoTimetableCard from "./NoTimetableCard.vue";
import SelectTimetable from "./SelectTimetable.vue";
import timetableTypes from "./timetableTypes";

export default {
  name: "Timetable",
  components: { NoTimetableCard, SelectTimetable },
  apollo: {
    availableTimetables: {
      query: gqlAvailableTimetables,
      result() {
        if (
          !this.selected &&
          this.$route.params.id &&
          this.$route.params.type
        ) {
          this.selectTimetable(
            this.availableTimetables.find(
              (t) =>
                t.objId === this.$route.params.id &&
                t.type.toLowerCase() === this.$route.params.type
            )
          );
        }
      },
    },
  },
  data() {
    return {
      availableTimetables: [],
      selected: null,
      search: "",
      selectedTypes: ["GROUP", "TEACHER", "ROOM"],
      types: timetableTypes,
      selectDialog: false,
    };
  },
  watch: {
    selected(selected) {
      // Align navigation with currently selected timetable
      if (!selected) {
        this.$router.push({ name: "chronos.timetable" });
      } else if (
        selected.objId !== this.$route.params.id ||
        selected.type.toLowerCase() !== this.$route.params.type
      ) {
        this.$router.push({
          name: "chronos.timetableWithId",
          params: {
            type: selected.type.toLowerCase(),
            id: selected.objId,
          },
        });
      }
    },
  },
  methods: {
    findNextTimetable(offset = 1) {
      const currentIndex = this.availableTimetablesIds.indexOf(
        this.selected.id
      );
      const newIndex = currentIndex + offset;
      if (newIndex < 0 || newIndex >= this.availableTimetablesIds.length) {
        return null;
      }
      return this.availableTimetables[newIndex];
    },
    selectTimetable(timetable) {
      this.selected = timetable;
    },
  },
  computed: {
    selectedTypesFull() {
      return this.selectedTypes.map((type) => {
        return this.types[type];
      });
    },
    availableTimetablesFiltered() {
      // Filter timetables by selected types
      return this.availableTimetables.filter((timetable) => {
        return this.selectedTypes.indexOf(timetable.type) !== -1;
      });
    },
    availableTimetablesIds() {
      return this.availableTimetables.map((timetable) => timetable.id);
    },
    prevTimetable() {
      return this.findNextTimetable(-1);
    },
    nextTimetable() {
      return this.findNextTimetable(1);
    },
  },
};
</script>

<template>
  <div>
    <v-row>
      <v-dialog
        v-model="selectDialog"
        fullscreen
        hide-overlay
        transition="dialog-bottom-transition"
      >
        <v-card>
          <v-toolbar dark color="primary">
            <v-toolbar-title>{{
              $t("chronos.timetable.select")
            }}</v-toolbar-title>
            <v-spacer></v-spacer>
          </v-toolbar>
          <select-timetable
            v-model="selected"
            @input="selectDialog = false"
            :available-timetables="availableTimetables"
          />
        </v-card>
      </v-dialog>

      <v-col md="3" lg="3" xl="3" v-if="$vuetify.breakpoint.lgAndUp">
        <v-card>
          <select-timetable
            v-model="selected"
            :available-timetables="availableTimetables"
          />
        </v-card>
      </v-col>
      <v-col sm="12" md="12" lg="9" xl="9" class="full-height">
        <!-- No timetable card-->
        <no-timetable-card
          v-if="selected == null"
          @selectTimetable="selectDialog = true"
        />

        <!-- Calendar card-->
        <v-card v-else>
          <div class="d-flex flex-column" v-if="$vuetify.breakpoint.smAndDown">
            <v-card-title class="pt-2">
              <v-btn
                icon
                :disabled="!prevTimetable"
                @click="selectTimetable(prevTimetable)"
                :title="$t('chronos.timetable.prev')"
                class="mr-1"
              >
                <v-icon>mdi-chevron-left</v-icon>
              </v-btn>
              <v-spacer />
              <v-chip outlined color="secondary" @click="selectDialog = true">
                {{ selected.name }}
                <v-icon right>mdi-chevron-down</v-icon>
              </v-chip>
              <v-spacer />
              <v-btn
                icon
                :disabled="!nextTimetable"
                @click="selectTimetable(nextTimetable)"
                :title="$t('chronos.timetable.next')"
                class="ml-1 float-right"
              >
                <v-icon>mdi-chevron-right</v-icon>
              </v-btn>
            </v-card-title>
          </div>

          <div class="d-flex flex-wrap justify-space-between mb-2" v-else>
            <v-card-title>
              {{ selected.name }}
            </v-card-title>
            <div class="pa-2 mt-1">
              <v-btn
                icon
                :disabled="!prevTimetable"
                @click="selectTimetable(prevTimetable)"
                :title="$t('chronos.timetable.prev')"
              >
                <v-icon>mdi-chevron-left</v-icon>
              </v-btn>
              <v-chip label color="secondary" outlined class="mx-1">{{
                selected.shortName
              }}</v-chip>
              <v-btn
                icon
                :disabled="!nextTimetable"
                @click="selectTimetable(nextTimetable)"
                :title="$t('chronos.timetable.next')"
              >
                <v-icon>mdi-chevron-right</v-icon>
              </v-btn>
            </div>
          </div>
          <calendar-with-controls
            :calendar-feeds="[{ name: 'lesson' }]"
            :params="{ type: selected.type, id: selected.objId }"
          />
        </v-card>
      </v-col>
    </v-row>
  </div>
</template>