mirror of
https://github.com/IT4Change/Ocelot-Social.git
synced 2025-12-13 07:45:56 +00:00
Start setting up frontend pinning/unpinning
- Add pin/unpin post to content menu - Update apollo cache to reactively unpin - Update apollo cache in root path to re-order Posts - Order with pinned post first - Start setting up filters, so that the pinned post is always the first post visible
This commit is contained in:
parent
36f6be9e36
commit
f871df02ae
@ -55,24 +55,46 @@ export default {
|
|||||||
routes() {
|
routes() {
|
||||||
let routes = []
|
let routes = []
|
||||||
|
|
||||||
if (this.isOwner && this.resourceType === 'contribution') {
|
if (this.resourceType === 'contribution') {
|
||||||
routes.push({
|
if (this.isOwner) {
|
||||||
name: this.$t(`post.menu.edit`),
|
routes.push({
|
||||||
path: this.$router.resolve({
|
name: this.$t(`post.menu.edit`),
|
||||||
name: 'post-edit-id',
|
path: this.$router.resolve({
|
||||||
params: {
|
name: 'post-edit-id',
|
||||||
id: this.resource.id,
|
params: {
|
||||||
|
id: this.resource.id,
|
||||||
|
},
|
||||||
|
}).href,
|
||||||
|
icon: 'edit',
|
||||||
|
})
|
||||||
|
routes.push({
|
||||||
|
name: this.$t(`post.menu.delete`),
|
||||||
|
callback: () => {
|
||||||
|
this.openModal('delete')
|
||||||
},
|
},
|
||||||
}).href,
|
icon: 'trash',
|
||||||
icon: 'edit',
|
})
|
||||||
})
|
}
|
||||||
routes.push({
|
|
||||||
name: this.$t(`post.menu.delete`),
|
if (this.isAdmin) {
|
||||||
callback: () => {
|
if (!this.resource.pinnedBy) {
|
||||||
this.openModal('delete')
|
routes.push({
|
||||||
},
|
name: this.$t(`post.menu.pin`),
|
||||||
icon: 'trash',
|
callback: () => {
|
||||||
})
|
this.$emit('pinPost', this.resource)
|
||||||
|
},
|
||||||
|
icon: 'link',
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
routes.push({
|
||||||
|
name: this.$t(`post.menu.unpin`),
|
||||||
|
callback: () => {
|
||||||
|
this.$emit('unpinPost', this.resource)
|
||||||
|
},
|
||||||
|
icon: 'unlink',
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.isOwner && this.resourceType === 'comment') {
|
if (this.isOwner && this.resourceType === 'comment') {
|
||||||
@ -155,6 +177,9 @@ export default {
|
|||||||
isModerator() {
|
isModerator() {
|
||||||
return this.$store.getters['auth/isModerator']
|
return this.$store.getters['auth/isModerator']
|
||||||
},
|
},
|
||||||
|
isAdmin() {
|
||||||
|
return this.$store.getters['auth/isAdmin']
|
||||||
|
},
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
openItem(route, toggleMenu) {
|
openItem(route, toggleMenu) {
|
||||||
@ -175,6 +200,7 @@ export default {
|
|||||||
},
|
},
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
pinPost() {},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@ -61,6 +61,8 @@
|
|||||||
:resource="post"
|
:resource="post"
|
||||||
:modalsData="menuModalsData"
|
:modalsData="menuModalsData"
|
||||||
:is-owner="isAuthor"
|
:is-owner="isAuthor"
|
||||||
|
@pinPost="pinPost"
|
||||||
|
@unpinPost="unpinPost"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</client-only>
|
</client-only>
|
||||||
@ -127,6 +129,12 @@ export default {
|
|||||||
this.$toast.error(err.message)
|
this.$toast.error(err.message)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
pinPost(post) {
|
||||||
|
this.$emit('pinPost', post)
|
||||||
|
},
|
||||||
|
unpinPost(post) {
|
||||||
|
this.$emit('unpinPost', post)
|
||||||
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@ -57,6 +57,12 @@ export const postFragment = lang => gql`
|
|||||||
name
|
name
|
||||||
icon
|
icon
|
||||||
}
|
}
|
||||||
|
pinnedBy {
|
||||||
|
id
|
||||||
|
name
|
||||||
|
role
|
||||||
|
}
|
||||||
|
pinnedAt
|
||||||
}
|
}
|
||||||
`
|
`
|
||||||
export const commentFragment = lang => gql`
|
export const commentFragment = lang => gql`
|
||||||
|
|||||||
@ -34,6 +34,8 @@ export default () => {
|
|||||||
$imageUpload: Upload
|
$imageUpload: Upload
|
||||||
$categoryIds: [ID]
|
$categoryIds: [ID]
|
||||||
$image: String
|
$image: String
|
||||||
|
$pinned: Boolean
|
||||||
|
$unpinned: Boolean
|
||||||
) {
|
) {
|
||||||
UpdatePost(
|
UpdatePost(
|
||||||
id: $id
|
id: $id
|
||||||
@ -43,6 +45,8 @@ export default () => {
|
|||||||
imageUpload: $imageUpload
|
imageUpload: $imageUpload
|
||||||
categoryIds: $categoryIds
|
categoryIds: $categoryIds
|
||||||
image: $image
|
image: $image
|
||||||
|
pinned: $pinned
|
||||||
|
unpinned: $unpinned
|
||||||
) {
|
) {
|
||||||
id
|
id
|
||||||
title
|
title
|
||||||
@ -50,6 +54,11 @@ export default () => {
|
|||||||
content
|
content
|
||||||
contentExcerpt
|
contentExcerpt
|
||||||
language
|
language
|
||||||
|
pinnedBy {
|
||||||
|
id
|
||||||
|
name
|
||||||
|
role
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
`,
|
`,
|
||||||
|
|||||||
@ -368,7 +368,11 @@
|
|||||||
},
|
},
|
||||||
"menu": {
|
"menu": {
|
||||||
"edit": "Edit Post",
|
"edit": "Edit Post",
|
||||||
"delete": "Delete Post"
|
"delete": "Delete Post",
|
||||||
|
"pin": "Pin post",
|
||||||
|
"pinnedSuccessfully": "Post pinned successfully!",
|
||||||
|
"unpin": "Unpin post",
|
||||||
|
"unpinnedSuccessfully": "Post unpinned successfully!"
|
||||||
},
|
},
|
||||||
"comment": {
|
"comment": {
|
||||||
"submit": "Comment",
|
"submit": "Comment",
|
||||||
|
|||||||
@ -21,6 +21,8 @@
|
|||||||
:post="post"
|
:post="post"
|
||||||
:width="{ base: '100%', xs: '100%', md: '50%', xl: '33%' }"
|
:width="{ base: '100%', xs: '100%', md: '50%', xl: '33%' }"
|
||||||
@removePostFromList="deletePost"
|
@removePostFromList="deletePost"
|
||||||
|
@pinPost="pinPost"
|
||||||
|
@unpinPost="unpinPost"
|
||||||
/>
|
/>
|
||||||
</masonry-grid-item>
|
</masonry-grid-item>
|
||||||
</template>
|
</template>
|
||||||
@ -64,6 +66,7 @@ import MasonryGrid from '~/components/MasonryGrid/MasonryGrid.vue'
|
|||||||
import MasonryGridItem from '~/components/MasonryGrid/MasonryGridItem.vue'
|
import MasonryGridItem from '~/components/MasonryGrid/MasonryGridItem.vue'
|
||||||
import { mapGetters } from 'vuex'
|
import { mapGetters } from 'vuex'
|
||||||
import { filterPosts } from '~/graphql/PostQuery.js'
|
import { filterPosts } from '~/graphql/PostQuery.js'
|
||||||
|
import PostMutations from '~/graphql/PostMutations'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
components: {
|
components: {
|
||||||
@ -166,6 +169,37 @@ export default {
|
|||||||
return post.id !== deletedPost.id
|
return post.id !== deletedPost.id
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
resetPostList() {
|
||||||
|
this.offset = 0
|
||||||
|
this.posts = []
|
||||||
|
this.hasMore = true
|
||||||
|
},
|
||||||
|
pinPost(post) {
|
||||||
|
this.$apollo
|
||||||
|
.mutate({
|
||||||
|
mutation: PostMutations().UpdatePost,
|
||||||
|
variables: { id: post.id, title: post.title, content: post.content, pinned: true },
|
||||||
|
})
|
||||||
|
.then(() => {
|
||||||
|
this.$toast.success(this.$t('post.menu.pinnedSuccessfully'))
|
||||||
|
this.resetPostList()
|
||||||
|
this.$apollo.queries.Post.refetch()
|
||||||
|
})
|
||||||
|
.catch(error => this.$toast.error(error.message))
|
||||||
|
},
|
||||||
|
unpinPost(post) {
|
||||||
|
this.$apollo
|
||||||
|
.mutate({
|
||||||
|
mutation: PostMutations().UpdatePost,
|
||||||
|
variables: { id: post.id, title: post.title, content: post.content, unpinned: true },
|
||||||
|
})
|
||||||
|
.then(() => {
|
||||||
|
this.$toast.success(this.$t('post.menu.unpinnedSuccessfully'))
|
||||||
|
this.resetPostList()
|
||||||
|
this.$apollo.queries.Post.refetch()
|
||||||
|
})
|
||||||
|
.catch(error => this.$toast.error(error.message))
|
||||||
|
},
|
||||||
},
|
},
|
||||||
apollo: {
|
apollo: {
|
||||||
Post: {
|
Post: {
|
||||||
@ -176,7 +210,7 @@ export default {
|
|||||||
return {
|
return {
|
||||||
filter: this.finalFilters,
|
filter: this.finalFilters,
|
||||||
first: this.pageSize,
|
first: this.pageSize,
|
||||||
orderBy: this.sorting,
|
orderBy: ['pinnedAt_asc', this.sorting],
|
||||||
offset: 0,
|
offset: 0,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|||||||
@ -18,6 +18,8 @@
|
|||||||
:resource="post"
|
:resource="post"
|
||||||
:modalsData="menuModalsData"
|
:modalsData="menuModalsData"
|
||||||
:is-owner="isAuthor(post.author ? post.author.id : null)"
|
:is-owner="isAuthor(post.author ? post.author.id : null)"
|
||||||
|
@pinPost="pinPost"
|
||||||
|
@unpinPost="unpinPost"
|
||||||
/>
|
/>
|
||||||
</client-only>
|
</client-only>
|
||||||
<ds-space margin-bottom="small" />
|
<ds-space margin-bottom="small" />
|
||||||
@ -77,6 +79,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
import { mapMutations } from 'vuex'
|
||||||
import ContentViewer from '~/components/Editor/ContentViewer'
|
import ContentViewer from '~/components/Editor/ContentViewer'
|
||||||
import HcCategory from '~/components/Category'
|
import HcCategory from '~/components/Category'
|
||||||
import HcHashtag from '~/components/Hashtag/Hashtag'
|
import HcHashtag from '~/components/Hashtag/Hashtag'
|
||||||
@ -88,6 +91,7 @@ import HcCommentList from '~/components/CommentList/CommentList'
|
|||||||
import { postMenuModalsData, deletePostMutation } from '~/components/utils/PostHelpers'
|
import { postMenuModalsData, deletePostMutation } from '~/components/utils/PostHelpers'
|
||||||
import PostQuery from '~/graphql/PostQuery'
|
import PostQuery from '~/graphql/PostQuery'
|
||||||
import HcEmotions from '~/components/Emotions/Emotions'
|
import HcEmotions from '~/components/Emotions/Emotions'
|
||||||
|
import PostMutations from '~/graphql/PostMutations'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'PostSlug',
|
name: 'PostSlug',
|
||||||
@ -141,6 +145,9 @@ export default {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
...mapMutations({
|
||||||
|
setCurrentUser: 'auth/SET_USER',
|
||||||
|
}),
|
||||||
isAuthor(id) {
|
isAuthor(id) {
|
||||||
return this.$store.getters['auth/user'].id === id
|
return this.$store.getters['auth/user'].id === id
|
||||||
},
|
},
|
||||||
@ -156,6 +163,33 @@ export default {
|
|||||||
async createComment(comment) {
|
async createComment(comment) {
|
||||||
this.post.comments.push(comment)
|
this.post.comments.push(comment)
|
||||||
},
|
},
|
||||||
|
resetPostList() {
|
||||||
|
this.offset = 0
|
||||||
|
this.posts = []
|
||||||
|
this.hasMore = true
|
||||||
|
},
|
||||||
|
pinPost(post) {
|
||||||
|
this.$apollo
|
||||||
|
.mutate({
|
||||||
|
mutation: PostMutations().UpdatePost,
|
||||||
|
variables: { id: post.id, title: post.title, content: post.content, pinned: true },
|
||||||
|
})
|
||||||
|
.then(() => {
|
||||||
|
this.$toast.success(this.$t('post.menu.pinnedSuccessfully'))
|
||||||
|
})
|
||||||
|
.catch(error => this.$toast.error(error.message))
|
||||||
|
},
|
||||||
|
unpinPost(post) {
|
||||||
|
this.$apollo
|
||||||
|
.mutate({
|
||||||
|
mutation: PostMutations().UpdatePost,
|
||||||
|
variables: { id: post.id, title: post.title, content: post.content, unpinned: true },
|
||||||
|
})
|
||||||
|
.then(() => {
|
||||||
|
this.$toast.success(this.$t('post.menu.unpinnedSuccessfully'))
|
||||||
|
})
|
||||||
|
.catch(error => this.$toast.error(error.message))
|
||||||
|
},
|
||||||
},
|
},
|
||||||
apollo: {
|
apollo: {
|
||||||
Post: {
|
Post: {
|
||||||
|
|||||||
@ -444,7 +444,7 @@ export default {
|
|||||||
filter: this.filter,
|
filter: this.filter,
|
||||||
first: this.pageSize,
|
first: this.pageSize,
|
||||||
offset: 0,
|
offset: 0,
|
||||||
orderBy: 'createdAt_desc',
|
orderBy: ['pinnedAt_asc', 'createdAt_desc'],
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
update({ Post }) {
|
update({ Post }) {
|
||||||
|
|||||||
@ -10,23 +10,31 @@ const defaultFilter = {}
|
|||||||
export const state = () => {
|
export const state = () => {
|
||||||
return {
|
return {
|
||||||
filter: {
|
filter: {
|
||||||
...defaultFilter,
|
OR: [{ pinnedBy_in: { role_in: ['admin'] } }, {}],
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export const mutations = {
|
export const mutations = {
|
||||||
TOGGLE_FILTER_BY_FOLLOWED(state, currentUserId) {
|
TOGGLE_FILTER_BY_FOLLOWED(state, currentUserId) {
|
||||||
const filter = clone(state.filter)
|
let filter = clone(state.filter)
|
||||||
const id = get(filter, 'author.followedBy_some.id')
|
const id = filter.OR.find(object => object.author)
|
||||||
if (id) {
|
if (id) {
|
||||||
delete filter.author
|
filter.OR.forEach(object => delete object.author)
|
||||||
state.filter = filter
|
state.filter = filter
|
||||||
} else {
|
} else {
|
||||||
state.filter = {
|
if (isEmpty(filter.OR[-1])) filter.OR.pop()
|
||||||
...filter,
|
filter.OR.map(object => {
|
||||||
|
for (let key in object) {
|
||||||
|
if (object.hasOwnProperty(key)) {
|
||||||
|
object = { key: object[key] }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
filter.OR.unshift({
|
||||||
author: { followedBy_some: { id: currentUserId } },
|
author: { followedBy_some: { id: currentUserId } },
|
||||||
}
|
})
|
||||||
|
state.filter = filter
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
RESET_CATEGORIES(state) {
|
RESET_CATEGORIES(state) {
|
||||||
@ -35,9 +43,20 @@ export const mutations = {
|
|||||||
state.filter = filter
|
state.filter = filter
|
||||||
},
|
},
|
||||||
TOGGLE_CATEGORY(state, categoryId) {
|
TOGGLE_CATEGORY(state, categoryId) {
|
||||||
const filter = clone(state.filter)
|
let filter = clone(state.filter)
|
||||||
update(filter, 'categories_some.id_in', categoryIds => xor(categoryIds, [categoryId]))
|
if (isEmpty(filter.OR[-1])) filter.OR.pop()
|
||||||
if (isEmpty(get(filter, 'categories_some.id_in'))) delete filter.categories_some
|
filter.OR.map(object => {
|
||||||
|
for (let key in object) {
|
||||||
|
if (object.hasOwnProperty(key)) {
|
||||||
|
object = { key: object[key] }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
filter.OR.unshift({
|
||||||
|
categories_some: { id_in: [categoryId] },
|
||||||
|
})
|
||||||
|
// update(filter, 'categories_some.id_in', categoryIds => xor(categoryIds, [categoryId]))
|
||||||
|
// if (isEmpty(get(filter.OR[0], 'categories_some.id_in'))) delete filter.OR[0].categories_some
|
||||||
state.filter = filter
|
state.filter = filter
|
||||||
},
|
},
|
||||||
TOGGLE_EMOTION(state, emotion) {
|
TOGGLE_EMOTION(state, emotion) {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user