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="typeClass"
class="filter-entry"> class="filter-entry">
<span class="filter-entry__text">{{ text }}</span> <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> </a>
</template> </template>
<script> <script>
import ChevronRight from '@/components/icons/ChevronRight'; import ChevronRight from '@/components/icons/ChevronRight';
import {INTERDISCIPLINARY, LANGUAGE_COMMUNICATION, SOCIETY} from '@/consts/instrument.consts'; import {INTERDISCIPLINARY, LANGUAGE_COMMUNICATION, SOCIETY} from '@/consts/instrument.consts';
import INSTRUMENT_FILTER_QUERY from 'gql/local/instrumentFiler.gql';
export default { export default {
props: { props: {
@ -21,18 +25,51 @@
type: String, type: String,
default: '', default: '',
}, },
isCategory: {
type: Boolean,
default: false,
},
category: {
type: String,
default: '',
},
}, },
components: { components: {
ChevronRight, ChevronRight,
}, },
apollo: {
instrumentFilter: {
query: INSTRUMENT_FILTER_QUERY
}
},
data() {
return {
instrumentFilter: {
currentFilter: '',
},
};
},
computed: { 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() { typeClass() {
return { return {
'filter-entry--language-communication': this.type === LANGUAGE_COMMUNICATION, 'filter-entry--language-communication': this.category === LANGUAGE_COMMUNICATION,
'filter-entry--society': this.type === SOCIETY, 'filter-entry--society': this.category === SOCIETY,
'filter-entry--interdisciplinary': this.type === INTERDISCIPLINARY, 'filter-entry--interdisciplinary': this.category === INTERDISCIPLINARY,
'filter-entry--active': this.isActive,
'filter-entry--category': this.isCategory,
}; };
}, },
}, },
@ -46,6 +83,7 @@
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;
align-items: center; align-items: center;
cursor: pointer;
&__text { &__text {
@include sub-heading; @include sub-heading;
@ -53,21 +91,62 @@
color: inherit; color: inherit;
} }
&__icon-wrapper {
display: flex;
align-items: center;
justify-content: center;
height: 20px;
width: 20px;
border-radius: 10px;
}
&__icon { &__icon {
width: 10px; width: 10px;
height: 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 { &--language-communication {
color: $color-accent-2-dark; @include filter-block($color-accent-2-dark);
} }
&--society { &--society {
color: $color-accent-1-dark; @include filter-block($color-accent-1-dark);
} }
&--interdisciplinary { &--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> </style>

View File

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

View File

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

View File

@ -24,6 +24,10 @@ const writeLocalCache = cache => {
__typename: 'HelloEmail', __typename: 'HelloEmail',
email: '', 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 SCROLL_POSITION from '@/graphql/gql/local/scrollPosition.gql';
import HELLO_EMAIL from '@/graphql/gql/local/helloEmail.gql'; import HELLO_EMAIL from '@/graphql/gql/local/helloEmail.gql';
import SIDEBAR from '@/graphql/gql/local/sidebar.gql'; import SIDEBAR from '@/graphql/gql/local/sidebar.gql';
import INSTRUMENT_FILTER from '@/graphql/gql/local/instrumentFiler.gql';
export const resolvers = { export const resolvers = {
Mutation: { Mutation: {
@ -16,6 +17,12 @@ export const resolvers = {
cache.writeQuery({query: HELLO_EMAIL, data}); cache.writeQuery({query: HELLO_EMAIL, data});
return data.helloEmail; 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}) => { toggleSidebar: (_, {sidebar: {profile, navigation}}, {cache}) => {
const data = cache.readQuery({query: SIDEBAR}); const data = cache.readQuery({query: SIDEBAR});
if (typeof profile !== 'undefined') { if (typeof profile !== 'undefined') {
@ -26,6 +33,6 @@ export const resolvers = {
} }
cache.writeQuery({query: SIDEBAR, data}); cache.writeQuery({query: SIDEBAR, data});
return data.sidebar; return data.sidebar;
} },
} },
}; };

View File

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

View File

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