| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189 |
- <template>
- <RightDrawer
- :show="stateStore.showingModuleSearch"
- @close="close"
- >
- <h3 class="text-lg font-medium leading-6 text-gray-900 dark:text-white">
- <span class="font-bold text-3xl mr-5 block">Modulsuche</span>
- </h3>
- <div class="mt-5 mb-7">
- <ClassFilter
- v-model="degreeFilter"
- class="mb-2"
- :show-type="false"
- :show-add-remove="false"
- />
- <ClassFilter
- v-model="moduleNameFilter"
- :show-type="false"
- :show-add-remove="false"
- />
- </div>
- <div v-if="matchingModules.length > 0">
- <ul>
- <li
- v-for="mod in paginatedModules"
- :key="mod.short"
- class="module-entry"
- @click="showModuleInfo(mod)"
- >
- <div class="w-5/6">
- <span class="font-bold block">{{ mod.short }}</span>
- <span class="text-sm block truncate w-full">{{
- mod.name.length > 0 ? mod.name : "-"
- }}</span>
- </div>
- <span>
- <font-awesome-icon icon="fa-solid fa-arrow-right" />
- </span>
- </li>
- </ul>
- <NumberedPagination
- v-model="currentPageIdx"
- :page-size="pageSize"
- :result-count="matchingModules.length"
- class="scale-90 sm:scale-75"
- />
- </div>
- <div
- v-else
- class="w-full text-center text-gray-500"
- >
- <span>Leider keine Module gefunden!</span>
- </div>
- </RightDrawer>
- </template>
- <script lang="ts">
- import { useStateStore } from "../../stores/state";
- import { useModulesStore } from "../../stores/modules";
- import RightDrawer from "./RightDrawer.vue";
- import { ClassSelectorColumn, FilterRule, Module } from "../../types";
- import NumberedPagination from "../general/NumberedPagination.vue";
- import { useClassesStore } from "../../stores/classes";
- import { watch } from "vue";
- import ClassFilter from "../general/ClassFilter.vue";
- export default {
- name: "ModuleSearchModal",
- components: {
- RightDrawer,
- NumberedPagination,
- ClassFilter,
- },
- setup() {
- const stateStore = useStateStore();
- const modulesStore = useModulesStore();
- const classesStore = useClassesStore();
- return {
- stateStore,
- modulesStore,
- classesStore,
- pageSize: 10,
- };
- },
- data() {
- return {
- currentPageIdx: 0,
- degreeFilter: {
- column: ClassSelectorColumn.Degree,
- filterData: { degree: "" },
- pk: 0,
- enabled: true,
- } as FilterRule,
- moduleNameFilter: {
- column: ClassSelectorColumn.Module,
- filterData: { term: "" },
- pk: 1,
- enabled: true,
- } as FilterRule,
- };
- },
- computed: {
- matchingModules(): Module[] {
- return this.modulesStore.getModulesMatching(
- this.moduleNameFilter.filterData.term,
- this.degreeFilter.filterData.degree,
- );
- },
- paginatedModules() {
- const idx = this.currentPageIdx;
- return this.matchingModules.slice(
- idx * this.pageSize,
- (idx + 1) * this.pageSize,
- );
- },
- currentSearchAndDegreeTerm(): [string, string] {
- let filterString = "";
- let filterDegree = "";
- this.classesStore.filterRules.filter((f) => {
- if (
- f.column == ClassSelectorColumn.Module &&
- filterString.length == 0 &&
- !!f.filterData?.term
- )
- filterString = f.filterData?.term;
- if (
- f.column == ClassSelectorColumn.Degree &&
- filterString.length == 0 &&
- !!f.filterData?.degree
- )
- filterDegree = f.filterData?.degree;
- });
- return [filterString, filterDegree];
- },
- },
- mounted() {
- watch(
- () => this.stateStore.showingModuleSearch,
- () => {
- const sd = this.currentSearchAndDegreeTerm;
- this.moduleNameFilter.filterData.term = sd[0];
- this.degreeFilter.filterData.degree = sd[1];
- },
- );
- watch(
- () => this.moduleNameFilter.filterData.term,
- () => (this.currentPageIdx = 0),
- );
- watch(
- () => this.degreeFilter.filterData.degree,
- () => (this.currentPageIdx = 0),
- );
- },
- methods: {
- close() {
- this.stateStore.showingModuleSearch = false;
- },
- showModuleInfo(mod: Module) {
- this.stateStore.inspectingModule = mod;
- },
- },
- };
- </script>
- <style scoped>
- .module-entry {
- @apply flex
- items-center
- justify-between
- bg-gray-200
- hover:bg-gray-300
- active:bg-gray-400
- dark:bg-gray-600
- dark:hover:bg-gray-700
- dark:active:bg-gray-900
- my-2
- py-1
- px-5
- rounded
- cursor-pointer
- transition-all
- duration-200;
- }
- </style>
|