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

export default {
  name: "Timetable",
  components: { NoTimetableCard },
  apollo: {
    availableTimetables: {
      query: gqlAvailableTimetables,
      result(data) {
        console.log(
          data.data.availableTimetables.map((a) => {
            return a.id + a.name;
          })
        );
      },
    },
  },
  data() {
    return {
      availableTimetables: [],
      selected: null,
      selectedFull: null,
      search: "",
      selectedTypes: ["GROUP", "TEACHER", "ROOM"],
      types: {
        GROUP: {
          name: "Groups",
          id: "GROUP",
          icon: "mdi-account-group-outline",
        },
        TEACHER: {
          name: "Teachers",
          id: "TEACHER",
          icon: "mdi-account-outline",
        },
        ROOM: { name: "Rooms", id: "ROOM", icon: "mdi-door" },
      },
    };
  },
  watch: {
    selected(selected) {
      if (selected == null) {
        this.selectedFull = null;
      }
    },
    selectedFull(selectedFull) {
      // Align navigation with currently selected timetable
      if (!selectedFull) {
        this.$router.push({ name: "chronos.timetable" });
      } else if (
        selectedFull.objId !== this.$route.params.id ||
        selectedFull.type !== this.$route.params.type
      ) {
        this.$router.push({
          name: "chronos.timetableWithId",
          params: {
            type: selectedFull.type.toLowerCase(),
            id: selectedFull.objId,
          },
        });
      }
    },
  },
  methods: {
    findNextTimetable(offset = 1) {
      const currentIndex = this.availableTimetablesIds.indexOf(
        this.selectedFull.id
      );
      const newIndex = currentIndex + offset;
      if (newIndex < 0 || newIndex >= this.availableTimetablesIds.length) {
        return null;
      }
      return this.availableTimetables[newIndex];
    },
    selectTimetable(timetable) {
      this.selected = timetable.id;
      this.selectedFull = 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-col cols="3">
        <v-card>
          <v-card-text class="mb-0">
            <!-- Search field for timetables -->
            <v-text-field
              search
              filled
              rounded
              clearable
              autofocus
              v-model="search"
              :placeholder="$t('chronos.timetable.search')"
              prepend-inner-icon="mdi-magnify"
              hide-details="auto"
              class="mb-2"
            />

            <!-- Filter by timetable types -->
            <v-btn-toggle
              v-model="selectedTypes"
              dense
              block
              multiple
              class="d-flex"
            >
              <v-btn
                v-for="type in types"
                :key="type.id"
                class="flex-grow-1"
                :value="type.id"
              >
                {{ type.name }}
              </v-btn>
            </v-btn-toggle>
          </v-card-text>

          <!-- Select of available timetables -->
          <v-data-iterator
            :items="availableTimetablesFiltered"
            item-key="id"
            :search="search"
            single-expand
          >
            <template #default="{ items, isExpanded, expand }">
              <v-list>
                <v-list-item-group v-model="selected">
                  <v-list-item
                    v-for="item in items"
                    @click="selectedFull = item"
                    :value="item.id"
                    :key="item.id"
                  >
                    <v-list-item-icon color="primary">
                      <v-icon v-if="item.type in types" color="secondary">
                        {{ types[item.type].icon }}
                      </v-icon>
                      <v-icon v-else color="secondary">mdi-grid</v-icon>
                    </v-list-item-icon>
                    <v-list-item-content>
                      <v-list-item-title>{{ item.name }}</v-list-item-title>
                    </v-list-item-content>
                    <v-list-item-action>
                      <v-icon>mdi-chevron-right</v-icon>
                    </v-list-item-action>
                  </v-list-item>
                </v-list-item-group>
              </v-list>
            </template>
          </v-data-iterator>
        </v-card>
      </v-col>
      <v-col cols="9" class="full-height">
        <!-- No timetable card-->
        <no-timetable-card v-if="selectedFull == null" />

        <!-- Calendar card-->
        <v-card v-else>
          <div class="d-flex">
            <v-card-title>
              {{ selectedFull.name }}
            </v-card-title>
            <v-spacer />
            <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">{{
                selectedFull.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>
        </v-card>
      </v-col>
    </v-row>
  </div>
</template>