mirror of
https://github.com/IT4Change/Ocelot-Social.git
synced 2025-12-13 07:45:56 +00:00
Merge pull request #1169 from Human-Connection/964-filter-posts-by-followers
Move filter by followers functionality to filter dropdown
This commit is contained in:
commit
3261237b48
@ -13,57 +13,39 @@ describe('FilterMenu.vue', () => {
|
||||
let mocks
|
||||
let propsData
|
||||
|
||||
const createWrapper = mountMethod => {
|
||||
return mountMethod(FilterMenu, {
|
||||
propsData,
|
||||
mocks,
|
||||
localVue,
|
||||
})
|
||||
}
|
||||
|
||||
beforeEach(() => {
|
||||
mocks = { $t: () => {} }
|
||||
propsData = {}
|
||||
})
|
||||
|
||||
describe('given a user', () => {
|
||||
beforeEach(() => {
|
||||
propsData = {
|
||||
user: {
|
||||
id: '4711',
|
||||
},
|
||||
hashtag: {},
|
||||
}
|
||||
})
|
||||
|
||||
describe('mount', () => {
|
||||
const Wrapper = () => {
|
||||
return mount(FilterMenu, { mocks, localVue, propsData })
|
||||
}
|
||||
beforeEach(() => {
|
||||
wrapper = createWrapper(mount)
|
||||
wrapper = Wrapper()
|
||||
})
|
||||
|
||||
it('renders a card', () => {
|
||||
it('does not render a card if there are no hashtags', () => {
|
||||
expect(wrapper.is('.ds-card')).toBe(true)
|
||||
})
|
||||
|
||||
describe('click "filter-by-followed-authors-only" button', () => {
|
||||
it('emits filterBubble object', () => {
|
||||
wrapper.find({ name: 'filter-by-followed-authors-only' }).trigger('click')
|
||||
expect(wrapper.emitted('changeFilterBubble')).toBeTruthy()
|
||||
})
|
||||
it('renders a card if there are hashtags', () => {
|
||||
propsData.hashtag = { hashtag: 'Frieden' }
|
||||
wrapper = Wrapper()
|
||||
expect(wrapper.is('.ds-card')).toBe(true)
|
||||
})
|
||||
|
||||
it('toggles filterBubble.author property', () => {
|
||||
wrapper.find({ name: 'filter-by-followed-authors-only' }).trigger('click')
|
||||
expect(wrapper.emitted('changeFilterBubble')[0]).toEqual([
|
||||
{ author: { followedBy_some: { id: '4711' } } },
|
||||
])
|
||||
wrapper.find({ name: 'filter-by-followed-authors-only' }).trigger('click')
|
||||
expect(wrapper.emitted('changeFilterBubble')[1]).toEqual([{}])
|
||||
})
|
||||
|
||||
it('makes button primary', () => {
|
||||
wrapper.find({ name: 'filter-by-followed-authors-only' }).trigger('click')
|
||||
expect(
|
||||
wrapper.find({ name: 'filter-by-followed-authors-only' }).classes('ds-button-primary'),
|
||||
).toBe(true)
|
||||
describe('click "clear-search-button" button', () => {
|
||||
it('emits clearSearch', () => {
|
||||
wrapper.find({ name: 'clear-search-button' }).trigger('click')
|
||||
expect(wrapper.emitted().clearSearch).toHaveLength(1)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
@ -1,26 +1,6 @@
|
||||
<template>
|
||||
<ds-card class="filter-menu-card">
|
||||
<ds-flex>
|
||||
<ds-flex-item class="filter-menu-title">
|
||||
<ds-heading size="h3">{{ $t('filter-menu.title') }}</ds-heading>
|
||||
</ds-flex-item>
|
||||
<ds-flex-item>
|
||||
<div class="filter-menu-buttons">
|
||||
<ds-button
|
||||
v-tooltip="{
|
||||
content: this.$t('contribution.filterFollow'),
|
||||
placement: 'left',
|
||||
delay: { show: 500 },
|
||||
}"
|
||||
name="filter-by-followed-authors-only"
|
||||
icon="user-plus"
|
||||
:primary="!!filterAuthorIsFollowedById"
|
||||
@click="toggleOnlyFollowed"
|
||||
/>
|
||||
</div>
|
||||
</ds-flex-item>
|
||||
</ds-flex>
|
||||
<div v-if="hashtag">
|
||||
<ds-card v-show="hashtag" class="filter-menu-card">
|
||||
<div>
|
||||
<ds-space margin-bottom="x-small" />
|
||||
<ds-flex>
|
||||
<ds-flex-item>
|
||||
@ -34,7 +14,7 @@
|
||||
placement: 'left',
|
||||
delay: { show: 500 },
|
||||
}"
|
||||
name="filter-by-followed-authors-only"
|
||||
name="clear-search-button"
|
||||
icon="close"
|
||||
@click="clearSearch"
|
||||
/>
|
||||
@ -48,31 +28,9 @@
|
||||
<script>
|
||||
export default {
|
||||
props: {
|
||||
user: { type: Object, required: true },
|
||||
hashtag: { type: Object, default: null },
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
filter: {},
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
filterAuthorIsFollowedById() {
|
||||
const { author = {} } = this.filter
|
||||
/* eslint-disable camelcase */
|
||||
const { followedBy_some = {} } = author
|
||||
const { id } = followedBy_some
|
||||
/* eslint-enable */
|
||||
return id
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
toggleOnlyFollowed() {
|
||||
this.filter = this.filterAuthorIsFollowedById
|
||||
? {}
|
||||
: { author: { followedBy_some: { id: this.user.id } } }
|
||||
this.$emit('changeFilterBubble', this.filter)
|
||||
},
|
||||
clearSearch() {
|
||||
this.$emit('clearSearch')
|
||||
},
|
||||
|
||||
@ -4,8 +4,7 @@ import Styleguide from '@human-connection/styleguide'
|
||||
import Vuex from 'vuex'
|
||||
import FilterPosts from './FilterPosts.vue'
|
||||
import FilterPostsMenuItem from './FilterPostsMenuItems.vue'
|
||||
import { mutations } from '~/store/posts'
|
||||
|
||||
import { mutations, getters } from '~/store/posts'
|
||||
const localVue = createLocalVue()
|
||||
|
||||
localVue.use(Styleguide)
|
||||
@ -53,6 +52,21 @@ describe('FilterPosts.vue', () => {
|
||||
const store = new Vuex.Store({
|
||||
mutations: {
|
||||
'posts/SET_POSTS': mutations.SET_POSTS,
|
||||
'posts/SET_FILTERED_BY_CATEGORIES': mutations.SET_FILTERED_BY_CATEGORIES,
|
||||
'posts/SET_FILTERED_BY_FOLLOWERS': mutations.SET_FILTERED_BY_FOLLOWERS,
|
||||
'posts/SET_USERS_FOLLOWED_FILTER': mutations.SET_USERS_FOLLOWED_FILTER,
|
||||
'posts/SET_CATEGORIES_FILTER': mutations.SET_CATEGORIES_FILTER,
|
||||
'posts/SET_SELECTED_CATEGORY_IDS': mutations.SET_SELECTED_CATEGORY_IDS,
|
||||
},
|
||||
getters: {
|
||||
'auth/user': () => {
|
||||
return { id: 'u34' }
|
||||
},
|
||||
'posts/filteredByCategories': getters.filteredByCategories,
|
||||
'posts/filteredByUsersFollowed': getters.filteredByUsersFollowed,
|
||||
'posts/usersFollowedFilter': getters.usersFollowedFilter,
|
||||
'posts/categoriesFilter': getters.categoriesFilter,
|
||||
'posts/selectedCategoryIds': getters.selectedCategoryIds,
|
||||
},
|
||||
})
|
||||
const Wrapper = () => {
|
||||
@ -60,6 +74,13 @@ describe('FilterPosts.vue', () => {
|
||||
}
|
||||
|
||||
beforeEach(() => {
|
||||
store.replaceState({
|
||||
filteredByCategories: false,
|
||||
filteredByUsersFollowed: false,
|
||||
usersFollowedFilter: {},
|
||||
categoriesFilter: {},
|
||||
selectedCategoryIds: [],
|
||||
})
|
||||
wrapper = Wrapper()
|
||||
menuToggle = wrapper.findAll('a').at(0)
|
||||
menuToggle.trigger('click')
|
||||
@ -130,5 +151,42 @@ describe('FilterPosts.vue', () => {
|
||||
const filterPostsMenuItem = wrapper.find(FilterPostsMenuItem)
|
||||
expect(filterPostsMenuItem.vm.selectedCategoryIds).toEqual([])
|
||||
})
|
||||
|
||||
describe('click "filter-by-followed-authors-only" button', () => {
|
||||
beforeEach(() => {
|
||||
wrapper.find({ name: 'filter-by-followed-authors-only' }).trigger('click')
|
||||
})
|
||||
|
||||
it('calls the filterPost query', () => {
|
||||
expect(mocks.$apollo.query).toHaveBeenCalledWith(
|
||||
expect.objectContaining({
|
||||
variables: {
|
||||
filter: { author: { followedBy_some: { id: 'u34' } } },
|
||||
first: expect.any(Number),
|
||||
offset: expect.any(Number),
|
||||
},
|
||||
}),
|
||||
)
|
||||
})
|
||||
|
||||
it('toggles filterBubble.author property', () => {
|
||||
wrapper.find({ name: 'filter-by-followed-authors-only' }).trigger('click')
|
||||
expect(mocks.$apollo.query).toHaveBeenCalledWith(
|
||||
expect.objectContaining({
|
||||
variables: {
|
||||
filter: {},
|
||||
first: expect.any(Number),
|
||||
offset: expect.any(Number),
|
||||
},
|
||||
}),
|
||||
)
|
||||
})
|
||||
|
||||
it("sets the button's class to primary when clicked", async () => {
|
||||
expect(
|
||||
wrapper.find({ name: 'filter-by-followed-authors-only' }).classes('ds-button-primary'),
|
||||
).toBe(true)
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
@ -5,7 +5,7 @@
|
||||
<ds-icon style="margin: 7px 0px 0px 2px" size="xx-small" name="angle-down" />
|
||||
</a>
|
||||
<template slot="popover">
|
||||
<filter-posts-menu-items :chunk="chunk" @filterPosts="filterPosts" />
|
||||
<filter-posts-menu-items :chunk="chunk" @filterPosts="filterPosts" :user="currentUser" />
|
||||
</template>
|
||||
</dropdown>
|
||||
</template>
|
||||
@ -13,7 +13,7 @@
|
||||
import _ from 'lodash'
|
||||
import Dropdown from '~/components/Dropdown'
|
||||
import { filterPosts } from '~/graphql/PostQuery.js'
|
||||
import { mapMutations } from 'vuex'
|
||||
import { mapGetters, mapMutations } from 'vuex'
|
||||
import FilterPostsMenuItems from '~/components/FilterPosts/FilterPostsMenuItems'
|
||||
|
||||
export default {
|
||||
@ -32,6 +32,9 @@ export default {
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
...mapGetters({
|
||||
currentUser: 'auth/user',
|
||||
}),
|
||||
chunk() {
|
||||
return _.chunk(this.categories, 2)
|
||||
},
|
||||
@ -40,13 +43,12 @@ export default {
|
||||
...mapMutations({
|
||||
setPosts: 'posts/SET_POSTS',
|
||||
}),
|
||||
filterPosts(categoryIds) {
|
||||
const filter = categoryIds.length ? { categories_some: { id_in: categoryIds } } : {}
|
||||
filterPosts(filter) {
|
||||
this.$apollo
|
||||
.query({
|
||||
query: filterPosts(this.$i18n),
|
||||
variables: {
|
||||
filter: filter,
|
||||
filter,
|
||||
first: this.pageSize,
|
||||
offset: 0,
|
||||
},
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
<ds-container>
|
||||
<ds-space />
|
||||
<ds-flex id="filter-posts-header">
|
||||
<ds-heading tag="h4">{{ $t('filter-posts.header') }}</ds-heading>
|
||||
<ds-heading tag="h4">{{ $t('filter-posts.categories.header') }}</ds-heading>
|
||||
<ds-space margin-bottom="large" />
|
||||
</ds-flex>
|
||||
<ds-flex>
|
||||
@ -16,10 +16,10 @@
|
||||
<ds-button
|
||||
icon="check"
|
||||
@click.stop.prevent="toggleCategory()"
|
||||
:primary="allCategories"
|
||||
:primary="!filteredByCategories"
|
||||
/>
|
||||
<ds-flex-item>
|
||||
<label class="category-labels">{{ $t('filter-posts.all') }}</label>
|
||||
<label class="category-labels">{{ $t('filter-posts.categories.all') }}</label>
|
||||
</ds-flex-item>
|
||||
<ds-space />
|
||||
</ds-flex-item>
|
||||
@ -55,41 +55,107 @@
|
||||
</ds-flex>
|
||||
</ds-flex-item>
|
||||
</ds-flex>
|
||||
<ds-space />
|
||||
<ds-flex id="filter-posts-by-followers-header">
|
||||
<ds-heading tag="h4">{{ $t('filter-posts.general.header') }}</ds-heading>
|
||||
<ds-space margin-bottom="large" />
|
||||
</ds-flex>
|
||||
<ds-flex>
|
||||
<ds-flex-item
|
||||
:width="{ base: '100%', sm: '100%', md: '100%', lg: '10%' }"
|
||||
class="categories-menu-item"
|
||||
>
|
||||
<ds-flex>
|
||||
<ds-flex-item width="10%" />
|
||||
<ds-flex-item width="100%">
|
||||
<div class="follow-button">
|
||||
<ds-button
|
||||
v-tooltip="{
|
||||
content: this.$t('contribution.filterFollow'),
|
||||
placement: 'left',
|
||||
delay: { show: 500 },
|
||||
}"
|
||||
name="filter-by-followed-authors-only"
|
||||
icon="user-plus"
|
||||
:primary="filteredByUsersFollowed"
|
||||
@click="toggleOnlyFollowed"
|
||||
/>
|
||||
<ds-flex-item>
|
||||
<label class="follow-label">{{ $t('filter-posts.followers.label') }}</label>
|
||||
</ds-flex-item>
|
||||
<ds-space />
|
||||
</div>
|
||||
</ds-flex-item>
|
||||
</ds-flex>
|
||||
</ds-flex-item>
|
||||
<ds-space margin-bottom="large" />
|
||||
</ds-flex>
|
||||
</ds-container>
|
||||
</template>
|
||||
<script>
|
||||
import { mapGetters, mapMutations } from 'vuex'
|
||||
|
||||
export default {
|
||||
props: {
|
||||
user: { type: Object, required: true },
|
||||
chunk: { type: Array, default: () => [] },
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
selectedCategoryIds: [],
|
||||
allCategories: true,
|
||||
filter: {},
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
...mapGetters({
|
||||
filteredByUsersFollowed: 'posts/filteredByUsersFollowed',
|
||||
filteredByCategories: 'posts/filteredByCategories',
|
||||
usersFollowedFilter: 'posts/usersFollowedFilter',
|
||||
categoriesFilter: 'posts/categoriesFilter',
|
||||
selectedCategoryIds: 'posts/selectedCategoryIds',
|
||||
}),
|
||||
},
|
||||
methods: {
|
||||
...mapMutations({
|
||||
setFilteredByFollowers: 'posts/SET_FILTERED_BY_FOLLOWERS',
|
||||
setFilteredByCategories: 'posts/SET_FILTERED_BY_CATEGORIES',
|
||||
setUsersFollowedFilter: 'posts/SET_USERS_FOLLOWED_FILTER',
|
||||
setCategoriesFilter: 'posts/SET_CATEGORIES_FILTER',
|
||||
setSelectedCategoryIds: 'posts/SET_SELECTED_CATEGORY_IDS',
|
||||
}),
|
||||
isActive(id) {
|
||||
const index = this.selectedCategoryIds.indexOf(id)
|
||||
if (index > -1) {
|
||||
if (index > -1 && this.setFilteredByCategories) {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
},
|
||||
toggleCategory(id) {
|
||||
if (!id) {
|
||||
this.selectedCategoryIds = []
|
||||
this.allCategories = true
|
||||
toggleCategory(categoryId) {
|
||||
if (!categoryId) {
|
||||
this.setSelectedCategoryIds()
|
||||
} else {
|
||||
const index = this.selectedCategoryIds.indexOf(id)
|
||||
if (index > -1) {
|
||||
this.selectedCategoryIds.splice(index, 1)
|
||||
} else {
|
||||
this.selectedCategoryIds.push(id)
|
||||
}
|
||||
this.allCategories = false
|
||||
this.setSelectedCategoryIds(categoryId)
|
||||
}
|
||||
this.$emit('filterPosts', this.selectedCategoryIds)
|
||||
this.setFilteredByCategories(!!this.selectedCategoryIds.length)
|
||||
this.setCategoriesFilter(
|
||||
this.selectedCategoryIds.length
|
||||
? { categories_some: { id_in: this.selectedCategoryIds } }
|
||||
: {},
|
||||
)
|
||||
this.toggleFilter()
|
||||
},
|
||||
toggleOnlyFollowed() {
|
||||
this.setFilteredByFollowers(!this.filteredByUsersFollowed)
|
||||
this.setUsersFollowedFilter(
|
||||
this.filteredByUsersFollowed ? { author: { followedBy_some: { id: this.user.id } } } : {},
|
||||
)
|
||||
this.toggleFilter()
|
||||
},
|
||||
toggleFilter() {
|
||||
this.filter = {
|
||||
...this.usersFollowedFilter,
|
||||
...this.categoriesFilter,
|
||||
}
|
||||
this.$emit('filterPosts', this.filter)
|
||||
},
|
||||
},
|
||||
}
|
||||
@ -99,6 +165,10 @@ export default {
|
||||
display: block;
|
||||
}
|
||||
|
||||
#filter-posts-by-followers-header {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.categories-menu-item {
|
||||
text-align: center;
|
||||
}
|
||||
@ -107,7 +177,8 @@ export default {
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.category-labels {
|
||||
.category-labels,
|
||||
.follow-label {
|
||||
font-size: $font-size-small;
|
||||
}
|
||||
|
||||
@ -122,5 +193,8 @@ export default {
|
||||
#filter-posts-header {
|
||||
text-align: center;
|
||||
}
|
||||
.follow-button {
|
||||
float: left;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@ -38,7 +38,12 @@
|
||||
:class="{ 'hide-mobile-menu': !toggleMobileMenu }"
|
||||
>
|
||||
<no-ssr>
|
||||
<filter-posts placement="top-start" offset="8" :categories="categories" />
|
||||
<filter-posts
|
||||
v-show="showFilterPostsDropdown"
|
||||
placement="top-start"
|
||||
offset="8"
|
||||
:categories="categories"
|
||||
/>
|
||||
</no-ssr>
|
||||
</ds-flex-item>
|
||||
<ds-flex-item :width="{ base: '100%', sm: '100%', md: '10%', lg: '2%' }" />
|
||||
@ -142,7 +147,7 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { mapGetters, mapActions } from 'vuex'
|
||||
import { mapGetters, mapActions, mapMutations } from 'vuex'
|
||||
import LocaleSwitch from '~/components/LocaleSwitch/LocaleSwitch'
|
||||
import SearchInput from '~/components/SearchInput.vue'
|
||||
import Modal from '~/components/Modal'
|
||||
@ -178,6 +183,9 @@ export default {
|
||||
isAdmin: 'auth/isAdmin',
|
||||
quickSearchResults: 'search/quickResults',
|
||||
quickSearchPending: 'search/quickPending',
|
||||
showFilterPostsDropdown: 'default/showFilterPostsDropdown',
|
||||
usersFollowedFilter: 'posts/usersFollowedFilter',
|
||||
categoriesFilter: 'posts/categoriesFilter',
|
||||
}),
|
||||
userName() {
|
||||
const { name } = this.user || {}
|
||||
@ -227,6 +235,9 @@ export default {
|
||||
quickSearch: 'search/quickSearch',
|
||||
fetchPosts: 'posts/fetchPosts',
|
||||
}),
|
||||
...mapMutations({
|
||||
setFilteredByFollowers: 'posts/SET_FILTERED_BY_FOLLOWERS',
|
||||
}),
|
||||
goToPost(item) {
|
||||
this.$nextTick(() => {
|
||||
this.$router.push({
|
||||
@ -247,7 +258,14 @@ export default {
|
||||
},
|
||||
redirectToRoot() {
|
||||
this.$router.replace('/')
|
||||
this.fetchPosts({ i18n: this.$i18n, filter: {} })
|
||||
this.fetchPosts({
|
||||
i18n: this.$i18n,
|
||||
filter: {
|
||||
...this.usersFollowedFilter,
|
||||
...this.categoriesFilter,
|
||||
...this.filter,
|
||||
},
|
||||
})
|
||||
},
|
||||
},
|
||||
apollo: {
|
||||
|
||||
@ -5,8 +5,16 @@
|
||||
"clearSearch": "Suche löschen"
|
||||
},
|
||||
"filter-posts": {
|
||||
"header": "Themenkategorien",
|
||||
"all": "Alle"
|
||||
"categories": {
|
||||
"header": "Themenkategorien",
|
||||
"all": "Alle"
|
||||
},
|
||||
"general": {
|
||||
"header": "Filtern nach..."
|
||||
},
|
||||
"followers": {
|
||||
"label": "Benutzern, denen ich folge"
|
||||
}
|
||||
},
|
||||
"site": {
|
||||
"made": "Mit ❤ gemacht",
|
||||
|
||||
@ -5,8 +5,16 @@
|
||||
"clearSearch": "Clear search"
|
||||
},
|
||||
"filter-posts": {
|
||||
"header": "Categories of Content",
|
||||
"all": "All"
|
||||
"categories": {
|
||||
"header": "Categories of Content",
|
||||
"all": "All"
|
||||
},
|
||||
"general": {
|
||||
"header": "Filter by..."
|
||||
},
|
||||
"followers": {
|
||||
"label": "Users I follow"
|
||||
}
|
||||
},
|
||||
"site": {
|
||||
"made": "Made with ❤",
|
||||
|
||||
@ -5,6 +5,7 @@ import Styleguide from '@human-connection/styleguide'
|
||||
import Filters from '~/plugins/vue-filters'
|
||||
import VTooltip from 'v-tooltip'
|
||||
import FilterMenu from '~/components/FilterMenu/FilterMenu'
|
||||
import { mutations } from '~/store/default'
|
||||
|
||||
const localVue = createLocalVue()
|
||||
|
||||
@ -40,6 +41,11 @@ describe('PostIndex', () => {
|
||||
'auth/user': () => {
|
||||
return { id: 'u23' }
|
||||
},
|
||||
'posts/usersFollowedFilter': () => {},
|
||||
'posts/categoriesFilter': () => {},
|
||||
},
|
||||
mutations: {
|
||||
'default/SET_SHOW_FILTER_POSTS_DROPDOWN': mutations.SET_SHOW_FILTER_POSTS_DROPDOWN,
|
||||
},
|
||||
})
|
||||
mocks = {
|
||||
@ -95,11 +101,6 @@ describe('PostIndex', () => {
|
||||
wrapper = Wrapper()
|
||||
})
|
||||
|
||||
it('refetches Posts when changeFilterBubble is emitted', () => {
|
||||
wrapper.find(FilterMenu).vm.$emit('changeFilterBubble')
|
||||
expect(mocks.$apollo.queries.Post.refetch).toHaveBeenCalledTimes(1)
|
||||
})
|
||||
|
||||
it('clears the search when the filter menu emits clearSearch', () => {
|
||||
wrapper.find(FilterMenu).vm.$emit('clearSearch')
|
||||
expect(wrapper.vm.hashtag).toBeNull()
|
||||
|
||||
@ -2,12 +2,7 @@
|
||||
<div>
|
||||
<ds-flex :width="{ base: '100%' }" gutter="base">
|
||||
<ds-flex-item>
|
||||
<filter-menu
|
||||
:user="currentUser"
|
||||
@changeFilterBubble="changeFilterBubble"
|
||||
:hashtag="hashtag"
|
||||
@clearSearch="clearSearch"
|
||||
/>
|
||||
<filter-menu :hashtag="hashtag" @clearSearch="clearSearch" />
|
||||
</ds-flex-item>
|
||||
<ds-flex-item>
|
||||
<div class="sorting-dropdown">
|
||||
@ -97,10 +92,14 @@ export default {
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.toggleShowFilterPostsDropdown(true)
|
||||
if (this.hashtag) {
|
||||
this.changeFilterBubble({ tags_some: { name: this.hashtag } })
|
||||
}
|
||||
},
|
||||
beforeDestroy() {
|
||||
this.toggleShowFilterPostsDropdown(false)
|
||||
},
|
||||
watch: {
|
||||
Post(post) {
|
||||
this.setPosts(this.Post)
|
||||
@ -110,6 +109,8 @@ export default {
|
||||
...mapGetters({
|
||||
currentUser: 'auth/user',
|
||||
posts: 'posts/posts',
|
||||
usersFollowedFilter: 'posts/usersFollowedFilter',
|
||||
categoriesFilter: 'posts/categoriesFilter',
|
||||
}),
|
||||
tags() {
|
||||
return this.posts ? this.posts.tags.map(tag => tag.name) : '-'
|
||||
@ -121,6 +122,7 @@ export default {
|
||||
methods: {
|
||||
...mapMutations({
|
||||
setPosts: 'posts/SET_POSTS',
|
||||
toggleShowFilterPostsDropdown: 'default/SET_SHOW_FILTER_POSTS_DROPDOWN',
|
||||
}),
|
||||
changeFilterBubble(filter) {
|
||||
if (this.hashtag) {
|
||||
@ -133,6 +135,11 @@ export default {
|
||||
this.$apollo.queries.Post.refetch()
|
||||
},
|
||||
toggleOnlySorting(x) {
|
||||
this.filter = {
|
||||
...this.usersFollowedFilter,
|
||||
...this.categoriesFilter,
|
||||
}
|
||||
|
||||
this.sortingIcon = x.icons
|
||||
this.sorting = x.order
|
||||
this.$apollo.queries.Post.refetch()
|
||||
@ -187,7 +194,11 @@ export default {
|
||||
},
|
||||
variables() {
|
||||
return {
|
||||
filter: this.filter,
|
||||
filter: {
|
||||
...this.usersFollowedFilter,
|
||||
...this.categoriesFilter,
|
||||
...this.filter,
|
||||
},
|
||||
first: this.pageSize,
|
||||
offset: 0,
|
||||
orderBy: this.sorting,
|
||||
|
||||
17
webapp/store/default.js
Normal file
17
webapp/store/default.js
Normal file
@ -0,0 +1,17 @@
|
||||
export const state = () => {
|
||||
return {
|
||||
showFilterPostsDropdown: false,
|
||||
}
|
||||
}
|
||||
|
||||
export const getters = {
|
||||
showFilterPostsDropdown(state) {
|
||||
return state.showFilterPostsDropdown || false
|
||||
},
|
||||
}
|
||||
|
||||
export const mutations = {
|
||||
SET_SHOW_FILTER_POSTS_DROPDOWN(state, boolean) {
|
||||
state.showFilterPostsDropdown = boolean || null
|
||||
},
|
||||
}
|
||||
@ -3,6 +3,11 @@ import gql from 'graphql-tag'
|
||||
export const state = () => {
|
||||
return {
|
||||
posts: [],
|
||||
filteredByUsersFollowed: false,
|
||||
filteredByCategories: false,
|
||||
usersFollowedFilter: {},
|
||||
categoriesFilter: {},
|
||||
selectedCategoryIds: [],
|
||||
}
|
||||
}
|
||||
|
||||
@ -10,12 +15,51 @@ export const mutations = {
|
||||
SET_POSTS(state, posts) {
|
||||
state.posts = posts || null
|
||||
},
|
||||
SET_FILTERED_BY_FOLLOWERS(state, boolean) {
|
||||
state.filteredByUsersFollowed = boolean || null
|
||||
},
|
||||
SET_FILTERED_BY_CATEGORIES(state, boolean) {
|
||||
state.filteredByCategories = boolean || null
|
||||
},
|
||||
SET_USERS_FOLLOWED_FILTER(state, filter) {
|
||||
state.usersFollowedFilter = filter || null
|
||||
},
|
||||
SET_CATEGORIES_FILTER(state, filter) {
|
||||
state.categoriesFilter = filter || null
|
||||
},
|
||||
SET_SELECTED_CATEGORY_IDS(state, categoryId) {
|
||||
if (!categoryId) {
|
||||
state.selectedCategoryIds = []
|
||||
} else {
|
||||
const index = state.selectedCategoryIds.indexOf(categoryId)
|
||||
if (index > -1) {
|
||||
state.selectedCategoryIds.splice(index, 1)
|
||||
} else {
|
||||
state.selectedCategoryIds.push(categoryId)
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
export const getters = {
|
||||
posts(state) {
|
||||
return state.posts || []
|
||||
},
|
||||
filteredByUsersFollowed(state) {
|
||||
return state.filteredByUsersFollowed || false
|
||||
},
|
||||
filteredByCategories(state) {
|
||||
return state.filteredByCategories || false
|
||||
},
|
||||
usersFollowedFilter(state) {
|
||||
return state.usersFollowedFilter || {}
|
||||
},
|
||||
categoriesFilter(state) {
|
||||
return state.categoriesFilter || {}
|
||||
},
|
||||
selectedCategoryIds(state) {
|
||||
return state.selectedCategoryIds || []
|
||||
},
|
||||
}
|
||||
|
||||
export const actions = {
|
||||
@ -24,7 +68,7 @@ export const actions = {
|
||||
const {
|
||||
data: { Post },
|
||||
} = await client.query({
|
||||
query: gql(`
|
||||
query: gql`
|
||||
query Post($filter: _PostFilter, $first: Int, $offset: Int) {
|
||||
Post(filter: $filter, first: $first, offset: $offset) {
|
||||
id
|
||||
@ -63,7 +107,7 @@ export const actions = {
|
||||
}
|
||||
shoutedCount
|
||||
}
|
||||
}`),
|
||||
}`,
|
||||
variables: {
|
||||
filter,
|
||||
first: 12,
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user