skillbox/client/src/pages/instrumentOverview.vue

158 lines
4.1 KiB
Vue

<template>
<div class="instrument-overview">
<instrument-filter
class="instrument-overview__filter"
v-if="$flavor.showInstrumentFilterSidebar"
@filter="updateFilter"
/>
<div
class="instrument-overview__filter"
v-else
/>
<div class="instrument-overview__list">
<filter-bar
:search-query="searchText"
@update:searchQuery="(val) => (searchText = val)"
></filter-bar>
<info-message
class="instrument-overview__no-instruments"
data-cy="info-message-no-entry"
v-if="instruments.length > 1 && filteredInstruments.length === 0 && !loading"
>
Für die ausgewählten Filtereinstellungen sind keine Einträge vorhanden
</info-message>
<div v-if="loading"><instrument-entry-blank v-for="index in 10" :key="index"></instrument-entry-blank></div>
<router-link
:to="{ name: 'instrument', params: { slug: instrument.slug } }"
data-cy="instrument"
v-for="instrument in filteredInstruments"
:key="instrument.id"
>
<instrument-entry :instrument="instrument" />
</router-link>
</div>
</div>
</template>
<script>
import InstrumentFilter from '@/components/instruments/InstrumentFilter.vue';
import InstrumentEntry from '@/components/instruments/InstrumentEntry.vue';
import INSTRUMENTS_QUERY from '@/graphql/gql/queries/instrumentsQuery.gql';
import INSTRUMENT_FILTER_QUERY from 'gql/local/instrumentFilter.gql';
import FilterBar from '@/components/instruments/FilterBar.vue';
import { graphql } from '@/__generated__';
import InfoMessage from '@/components/ui/InfoMessage.vue';
import InstrumentEntryBlank from '@/components/instruments/InstrumentEntryBlank.vue';
export default {
components: {
InstrumentEntryBlank,
InfoMessage,
FilterBar,
InstrumentFilter,
InstrumentEntry,
},
apollo: {
instruments: {
query: INSTRUMENTS_QUERY,
update(data) {
this.loading = false;
return this.$getRidOfEdges(data).instruments;
},
},
instrumentFilter: {
query: INSTRUMENT_FILTER_QUERY,
update({ instrumentFilter }) {
const { currentFilter } = instrumentFilter;
if (currentFilter && currentFilter.indexOf(':') > -1) {
const [filterType, identifier] = currentFilter.split(':');
if (filterType === 'type') {
this.filter = (i) => i.type.id === identifier;
} else {
this.filter = (i) => i.type.category.id === identifier;
}
} else {
this.filter = (i) => i; // identity
}
return instrumentFilter;
},
},
me: {
query: graphql(`
query MeLanguage {
me {
language @client
}
}
`),
},
},
data() {
return {
instruments: [],
filter: (i) => i, // identity
instrumentFilter: {
currentFilter: '',
},
searchText: '',
me: { language: 'de' },
loading: true,
};
},
computed: {
filteredInstruments() {
// Filter by category and category type
let instruments = this.instruments.filter((i) => this.filter(i));
// Filter by language
instruments = instruments.filter((i) => i.language === this.me.language);
// Filter by search text
instruments = instruments.filter((i) => i.title.toLowerCase().includes(this.searchText.toLowerCase()));
return instruments;
},
},
methods: {
updateFilter(filter) {
this.filter = filter;
},
},
};
</script>
<style scoped lang="scss">
@import 'styles/helpers';
.instrument-overview {
display: grid;
@include desktop {
grid-template-columns: 300px auto;
}
grid-column-gap: $small-spacing;
padding: 0 $small-spacing;
box-sizing: border-box;
&__list {
padding: $large-spacing 0;
max-width: min($screen-width, 100vw);
width: 100%;
display: flex;
overflow: hidden;
flex-direction: column;
justify-self: center;
}
&__list-item {
padding: $medium-spacing 0;
@include regular-text;
@include table-row($color-silver);
}
}
</style>