Merge remote-tracking branch 'origin/fix-category-filter-buttons' into merge-all-events

This commit is contained in:
ogerly 2023-04-26 09:00:47 +02:00
commit e0b93ae796
9 changed files with 160 additions and 7 deletions

View File

@ -0,0 +1,5 @@
<!-- Generated by IcoMoon.io -->
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32">
<title>book</title>
<path d="M10 5c2.92 0 5.482 0.981 6 1.188 0.518-0.206 3.080-1.188 6-1.188 3.227 0 6.375 1.313 6.375 1.313l0.625 0.281v20.406h-11.281c-0.346 0.597-0.979 1-1.719 1s-1.373-0.403-1.719-1h-11.281v-20.406l0.625-0.281s3.148-1.313 6.375-1.313zM10 7c-2.199 0-4.232 0.69-5 0.969v16.125c1.188-0.392 2.897-0.875 5-0.875 2.057 0 3.888 0.506 5 0.875v-16.125c-1-0.343-3.067-0.969-5-0.969zM22 7c-1.933 0-4 0.626-5 0.969v16.125c1.112-0.369 2.943-0.875 5-0.875 2.103 0 3.813 0.483 5 0.875v-16.125c-0.768-0.279-2.801-0.969-5-0.969z"></path>
</svg>

After

Width:  |  Height:  |  Size: 680 B

View File

@ -0,0 +1,5 @@
<!-- Generated by IcoMoon.io -->
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32">
<title>calendar</title>
<path d="M9 4h2v1h10v-1h2v1h4v22h-22v-22h4v-1zM7 7v2h18v-2h-2v1h-2v-1h-10v1h-2v-1h-2zM7 11v14h18v-14h-18zM13 13h2v2h-2v-2zM17 13h2v2h-2v-2zM21 13h2v2h-2v-2zM9 17h2v2h-2v-2zM13 17h2v2h-2v-2zM17 17h2v2h-2v-2zM21 17h2v2h-2v-2zM9 21h2v2h-2v-2zM13 21h2v2h-2v-2zM17 21h2v2h-2v-2z"></path>
</svg>

After

Width:  |  Height:  |  Size: 445 B

View File

@ -17,18 +17,22 @@
</template>
<template #filter-list>
<li v-for="category in categories" :key="category.id" class="item item-category">
<labeled-button
:icon="category.icon"
:filled="filteredCategoryIds.includes(category.id)"
:label="$t(`contribution.category.name.${category.slug}`)"
<div class="category-filter-list">
<base-button
v-for="category in categories"
:key="category.id"
@click="toggleCategory(category.id)"
:filled="filteredCategoryIds.includes(category.id)"
:icon="category.icon"
size="small"
v-tooltip="{
content: $t(`contribution.category.description.${category.slug}`),
placement: 'bottom-start',
}"
/>
</li>
>
{{ $t(`contribution.category.name.${category.slug}`) }}
</base-button>
</div>
</template>
</filter-menu-section>
</template>
@ -95,3 +99,13 @@ export default {
},
}
</script>
<style lang="scss">
.category-filter-list {
margin-left: $space-xx-large;
> .base-button {
margin-right: $space-xx-small;
margin-bottom: $space-xx-small;
}
}
</style>

View File

@ -3,6 +3,7 @@
<div class="filter-menu-options">
<h2 class="title">{{ $t('filter-menu.filter-by') }}</h2>
<following-filter />
<post-type-filter />
<categories-filter v-if="categoriesActive" @showFilterMenu="$emit('showFilterMenu')" />
</div>
<div class="filter-menu-options">
@ -13,6 +14,7 @@
</template>
<script>
import PostTypeFilter from './PostTypeFilter'
import FollowingFilter from './FollowingFilter'
import OrderByFilter from './OrderByFilter'
import CategoriesFilter from './CategoriesFilter'
@ -22,6 +24,7 @@ export default {
FollowingFilter,
OrderByFilter,
CategoriesFilter,
PostTypeFilter,
},
data() {
return {

View File

@ -0,0 +1,59 @@
<template>
<filter-menu-section
:title="$t('filter-menu.post-type')"
:divider="false"
class="following-filter"
>
<template #filter-follower>
<li class="item article-item">
<labeled-button
icon="book"
:label="$t('filter-menu.article')"
:filled="articleSet"
:title="$t('filter-menu.article')"
@click="toggleFilterPostType('Article')"
/>
</li>
<li class="item event-item">
<labeled-button
icon="calendar"
:label="$t('filter-menu.events')"
:filled="eventSet"
:title="$t('filter-menu.events')"
@click="toggleFilterPostType('Event')"
/>
</li>
</template>
</filter-menu-section>
</template>
<script>
import { mapGetters, mapMutations } from 'vuex'
import FilterMenuSection from '~/components/FilterMenu/FilterMenuSection'
import LabeledButton from '~/components/_new/generic/LabeledButton/LabeledButton'
export default {
name: 'PostTypeFilter',
components: {
FilterMenuSection,
LabeledButton,
},
computed: {
...mapGetters({
filteredPostTypes: 'posts/filteredPostTypes',
currentUser: 'auth/user',
}),
articleSet() {
return this.filteredPostTypes.includes('Article')
},
eventSet() {
return this.filteredPostTypes.includes('Event')
},
},
methods: {
...mapMutations({
toggleFilterPostType: 'posts/TOGGLE_POST_TYPE',
}),
},
}
</script>

View File

@ -378,9 +378,11 @@
},
"filter-menu": {
"all": "Alle",
"article": "Artikel",
"categories": "Themen",
"deleteFilter": "Filter löschen",
"emotions": "Emotionen",
"events": "Veranstaltungen",
"filter-by": "Filtern nach ...",
"following": "Nutzer denen ich folge",
"languages": "Sprachen",
@ -396,6 +398,7 @@
}
},
"order-by": "Sortieren nach ...",
"post-type": "Beitrags-Typ",
"save": {
"error": "Themen konnten nicht gespeichert werden!",
"success": "Themen gespeichert!"

View File

@ -378,9 +378,11 @@
},
"filter-menu": {
"all": "All",
"article": "Article",
"categories": "Topics",
"deleteFilter": "Delete filter",
"emotions": "Emotions",
"events": "Events",
"filter-by": "Filter by ...",
"following": "Users I follow",
"languages": "Languages",
@ -396,6 +398,7 @@
}
},
"order-by": "Order by ...",
"post-type": "Post type",
"save": {
"error": "Failed saving topic settings!",
"success": "Topics saved!"

View File

@ -63,6 +63,12 @@ export const mutations = {
if (isEmpty(get(filter, 'categories_some.id_in'))) delete filter.categories_some
state.filter = filter
},
TOGGLE_POST_TYPE(state, postType) {
const filter = clone(state.filter)
update(filter, 'postType_in', (postTypes) => xor(postTypes, [postType]))
if (isEmpty(get(filter, 'postType_in'))) delete filter.postType_in
state.filter = filter
},
TOGGLE_LANGUAGE(state, languageCode) {
const filter = clone(state.filter)
update(filter, 'language_in', (languageCodes) => xor(languageCodes, [languageCode]))
@ -90,6 +96,9 @@ export const getters = {
filteredCategoryIds(state) {
return get(state.filter, 'categories_some.id_in') || []
},
filteredPostTypes(state) {
return get(state.filter, 'postType_in') || []
},
filteredLanguageCodes(state) {
return get(state.filter, 'language_in') || []
},

View File

@ -25,6 +25,18 @@ describe('getters', () => {
})
})
describe('filteredPostTypes', () => {
it('returns post types if filter is set', () => {
state = { filter: { postType_in: ['Article', 'Event'] } }
expect(getters.filteredPostTypes(state)).toEqual(['Article', 'Event'])
})
it('returns empty array if post type filter is not set', () => {
state = { filter: { author: { followedBy_some: { id: 7 } } } }
expect(getters.filteredPostTypes(state)).toEqual([])
})
})
describe('filteredLanguageCodes', () => {
it('returns category ids if filter is set', () => {
state = { filter: { language_in: ['en', 'de', 'pt'] } }
@ -213,6 +225,46 @@ describe('mutations', () => {
})
})
describe('TOGGLE_POST_TYPE', () => {
beforeEach(() => {
testMutation = (postType) => {
mutations.TOGGLE_POST_TYPE(state, postType)
return getters.filter(state)
}
})
it('creates post type filter if empty', () => {
state = { filter: {} }
expect(testMutation('Event')).toEqual({ postType_in: ['Event'] })
})
it('adds post type not present', () => {
state = { filter: { postType_in: ['Event'] } }
expect(testMutation('Article')).toEqual({ postType_in: ['Event', 'Article'] })
})
it('removes category id if present', () => {
state = { filter: { postType_in: ['Event', 'Article'] } }
const result = testMutation('Event')
expect(result).toEqual({ postType_in: ['Article'] })
})
it('removes category filter if empty', () => {
state = { filter: { postType_in: ['Event'] } }
expect(testMutation('Event')).toEqual({})
})
it('does not get in the way of other filters', () => {
state = {
filter: {
author: { followedBy_some: { id: 7 } },
postType_in: ['Event'],
},
}
expect(testMutation('Event')).toEqual({ author: { followedBy_some: { id: 7 } } })
})
})
describe('TOGGLE_FILTER_BY_FOLLOWED', () => {
beforeEach(() => {
testMutation = (userId) => {