Refactor current instrument filter query, add styling for active state

This commit is contained in:
Ramon Wenger 2021-11-01 11:57:07 +01:00
parent bfe31ee146
commit 3e82389299
9 changed files with 191 additions and 33 deletions

View File

@ -3,13 +3,17 @@
:class="typeClass"
class="filter-entry">
<span class="filter-entry__text">{{ text }}</span>
<chevron-right class="filter-entry__icon"/>
<span class="filter-entry__icon-wrapper">
<chevron-right class="filter-entry__icon"/>
</span>
</a>
</template>
<script>
import ChevronRight from '@/components/icons/ChevronRight';
import {INTERDISCIPLINARY, LANGUAGE_COMMUNICATION, SOCIETY} from '@/consts/instrument.consts';
import INSTRUMENT_FILTER_QUERY from 'gql/local/instrumentFiler.gql';
export default {
props: {
@ -21,18 +25,51 @@
type: String,
default: '',
},
isCategory: {
type: Boolean,
default: false,
},
category: {
type: String,
default: '',
},
},
components: {
ChevronRight,
},
apollo: {
instrumentFilter: {
query: INSTRUMENT_FILTER_QUERY
}
},
data() {
return {
instrumentFilter: {
currentFilter: '',
},
};
},
computed: {
isActive() {
console.log(this.instrumentFilter.currentFilter);
if (!this.instrumentFilter.currentFilter) {
return this.type === '';
}
const [_, identifier] = this.instrumentFilter.currentFilter.split(':');
console.log(identifier, this.type);
return this.type === identifier;
},
typeClass() {
return {
'filter-entry--language-communication': this.type === LANGUAGE_COMMUNICATION,
'filter-entry--society': this.type === SOCIETY,
'filter-entry--interdisciplinary': this.type === INTERDISCIPLINARY,
'filter-entry--language-communication': this.category === LANGUAGE_COMMUNICATION,
'filter-entry--society': this.category === SOCIETY,
'filter-entry--interdisciplinary': this.category === INTERDISCIPLINARY,
'filter-entry--active': this.isActive,
'filter-entry--category': this.isCategory,
};
},
},
@ -46,6 +83,7 @@
display: flex;
justify-content: space-between;
align-items: center;
cursor: pointer;
&__text {
@include sub-heading;
@ -53,21 +91,62 @@
color: inherit;
}
&__icon-wrapper {
display: flex;
align-items: center;
justify-content: center;
height: 20px;
width: 20px;
border-radius: 10px;
}
&__icon {
width: 10px;
height: 10px;
}
$root: &;
@mixin filter-block($color) {
&#{$root}--category {
color: $color;
}
&#{$root}--active {
#{$root}__icon-wrapper {
background-color: $color;
}
}
#{$root}__icon {
fill: $color;
}
}
&--language-communication {
color: $color-accent-2-dark;
@include filter-block($color-accent-2-dark);
}
&--society {
color: $color-accent-1-dark;
@include filter-block($color-accent-1-dark);
}
&--interdisciplinary {
color: $color-accent-4-dark;
@include filter-block($color-accent-4-dark);
}
&--active {
#{$root}__text {
font-weight: 600;
}
#{$root}__icon-wrapper {
background-color: black;
}
#{$root}__icon {
fill: white;
}
}
}
</style>

View File

@ -3,16 +3,20 @@
<filter-entry
:text="title"
v-bind="$attrs"
:type="type"
@click.native="$emit('click')"/>
:type="category"
:category="category"
:is-category="true"
@click.native="setCategoryFilter(category)"/>
<div class="filter-group__children">
<filter-entry
:key="type.id"
:data-cy="`filter-${type.type}`"
:category="type.category"
:text="type.name"
:type="type.type"
v-for="type in types"
@click.native="$emit('filter', i=>i.type.type===type.type)" />
@click.native="setFilter(`type:${type.type}`)"
/>
</div>
</div>
</template>
@ -21,6 +25,9 @@
import ChevronRight from '@/components/icons/ChevronRight';
import FilterEntry from '@/components/instruments/FilterEntry';
import SET_FILTER_MUTATION from 'gql/local/mutations/setInstrumentFilter.gql';
import INSTRUMENT_FILTER_QUERY from 'gql/local/instrumentFiler.gql';
export default {
props: {
title: {
@ -31,13 +38,48 @@
type: Array,
default: () => [],
},
type: {
category: {
type: String,
default: ''
default: '',
},
},
components: {
FilterEntry,
ChevronRight,
},
apollo: {
instrumentFilter: {
query: INSTRUMENT_FILTER_QUERY
}
},
components: {FilterEntry, ChevronRight},
data() {
return {
instrumentFilter: {
currentFilter: ''
}
};
},
inheritAttrs: false,
methods: {
setCategoryFilter(category) {
if (category) {
this.setFilter(`category:${category}`);
} else {
this.setFilter(``);
}
},
setFilter(filter) {
this.$apollo.mutate({
mutation: SET_FILTER_MUTATION,
variables: {
filter
}
});
}
},
};
</script>
@ -46,6 +88,7 @@
.filter-group {
border-bottom: 1px solid $color-silver;
padding: $medium-spacing 0;
display: flex;
flex-direction: column;

View File

@ -3,33 +3,28 @@
<filter-group
title="Alle Instrumente"
data-cy="filter-all-instruments"
@click="setFilter(i=>i)"/>
/>
<filter-group
:types="languageCommunicationTypes"
:type="LANGUAGE_COMMUNICATION"
:category="LANGUAGE_COMMUNICATION"
title="Sprache und Kommunikation"
data-cy="filter-language-communication"
class="instrument-filter__group--language"
@filter="setFilter($event)"
@click="setFilter(i=>i.type.category===LANGUAGE_COMMUNICATION)"
/>
<filter-group
:types="societyTypes"
:type="SOCIETY"
:category="SOCIETY"
title="Gesellschaft"
data-cy="filter-society"
@filter="setFilter($event)"
@click="setFilter(i=>i.type.category===SOCIETY)"/>
/>
<filter-group
:types="interdisciplinaryTypes"
:type="INTERDISCIPLINARY"
:category="INTERDISCIPLINARY"
title="Überfachliche Instrumente"
data-cy="filter-interdisciplinary"
@filter="setFilter($event)"
@click="setFilter(i=>i.type.category===INTERDISCIPLINARY)"/>
/>
</div>
</template>

View File

@ -24,6 +24,10 @@ const writeLocalCache = cache => {
__typename: 'HelloEmail',
email: '',
},
instrumentFilter: {
__typename: 'InstrumentFilter',
currentFilter: 'abc'
}
},
});
};

View File

@ -0,0 +1,5 @@
query InstrumentFilter {
instrumentFilter @client {
currentFilter
}
}

View File

@ -0,0 +1,3 @@
mutation($filter: String!) {
setInstrumentFilter(filter: $filter) @client
}

View File

@ -1,6 +1,7 @@
import SCROLL_POSITION from '@/graphql/gql/local/scrollPosition.gql';
import HELLO_EMAIL from '@/graphql/gql/local/helloEmail.gql';
import SIDEBAR from '@/graphql/gql/local/sidebar.gql';
import INSTRUMENT_FILTER from '@/graphql/gql/local/instrumentFiler.gql';
export const resolvers = {
Mutation: {
@ -16,6 +17,12 @@ export const resolvers = {
cache.writeQuery({query: HELLO_EMAIL, data});
return data.helloEmail;
},
setInstrumentFilter: (_, {filter}, {cache}) => {
const data = cache.readQuery({query: INSTRUMENT_FILTER});
data.instrumentFilter.currentFilter = filter;
cache.writeQuery({query: INSTRUMENT_FILTER, data});
return data.instrumentFilter;
},
toggleSidebar: (_, {sidebar: {profile, navigation}}, {cache}) => {
const data = cache.readQuery({query: SIDEBAR});
if (typeof profile !== 'undefined') {
@ -26,6 +33,6 @@ export const resolvers = {
}
cache.writeQuery({query: SIDEBAR, data});
return data.sidebar;
}
}
},
},
};

View File

@ -19,6 +19,10 @@ export const typeDefs = gql`
profile: Boolean
}
type InstrumentFilter {
currentFilter: String!
}
type Mutation {
scrollTo(scrollTo: String!): ScrollPosition
helloEmail(email: String!): HelloEmail

View File

@ -21,10 +21,12 @@
import InstrumentEntry from '@/components/instruments/InstrumentEntry';
import INSTRUMENTS_QUERY from '@/graphql/gql/queries/instrumentsQuery.gql';
import INSTRUMENT_FILTER_QUERY from 'gql/local/instrumentFiler.gql';
export default {
components: {
InstrumentFilter,
InstrumentEntry
InstrumentEntry,
},
apollo: {
@ -32,27 +34,43 @@
query: INSTRUMENTS_QUERY,
update(data) {
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(':');
this.filter = i => i.type[filterType] === identifier;
} else {
this.filter = i => i; // identity
}
return instrumentFilter;
},
},
},
data() {
return {
instruments: [],
filter: i => i
filter: i => i, // identity
instrumentFilter: {
currentFilter: '',
},
};
},
computed: {
filteredInstruments() {
return this.instruments.filter(i => this.filter(i));
}
},
},
methods: {
updateFilter(filter) {
this.filter = filter;
}
},
},
};
</script>