Merge pull request #1351 from Human-Connection/1333-fix_checks_for_deleted_and_disabled

Fix database import, pagination and counters on user profile page
This commit is contained in:
mattwr18 2019-08-30 13:51:41 +02:00 committed by GitHub
commit f275799856
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 39 additions and 68 deletions

View File

@ -61,7 +61,6 @@ export default function Resolver(type, options = {}) {
const id = parent[idAttribute]
const statement = `
MATCH(u:${type} {${idAttribute}: {id}})${connection}
WHERE NOT related.deleted = true AND NOT related.disabled = true
RETURN COUNT(DISTINCT(related)) as count
`
const result = await instance.cypher(statement, { id })

View File

@ -147,12 +147,15 @@ export default {
'MATCH (this)<-[:BLOCKED]-(u:User {id: $cypherParams.currentUserId}) RETURN COUNT(u) >= 1',
},
count: {
contributionsCount: '-[:WROTE]->(related:Post)',
contributionsCount:
'-[:WROTE]->(related:Post) WHERE NOT related.disabled = true AND NOT related.deleted = true',
friendsCount: '<-[:FRIENDS]->(related:User)',
followingCount: '-[:FOLLOWS]->(related:User)',
followedByCount: '<-[:FOLLOWS]-(related:User)',
commentedCount: '-[:WROTE]->(:Comment)-[:COMMENTS]->(related:Post)',
shoutedCount: '-[:SHOUTED]->(related:Post)',
commentedCount:
'-[:WROTE]->(c:Comment)-[:COMMENTS]->(related:Post) WHERE NOT related.disabled = true AND NOT related.deleted = true',
shoutedCount:
'-[:SHOUTED]->(related:Post) WHERE NOT related.disabled = true AND NOT related.deleted = true',
badgesCount: '<-[:REWARDED]-(related:Badge)',
},
hasOne: {

View File

@ -64,7 +64,7 @@ type User {
)
comments: [Comment]! @relation(name: "WROTE", direction: "OUT")
commentedCount: Int! @cypher(statement: "MATCH (this)-[:WROTE]->(r:Comment)-[:COMMENTS]->(p:Post) WHERE NOT r.deleted = true AND NOT r.disabled = true AND NOT p.deleted = true AND NOT p.disabled = true RETURN COUNT(DISTINCT(p))")
commentedCount: Int! @cypher(statement: "MATCH (this)-[:WROTE]->(:Comment)-[:COMMENTS]->(p:Post) WHERE NOT p.deleted = true AND NOT p.disabled = true RETURN COUNT(DISTINCT(p))")
shouted: [Post]! @relation(name: "SHOUTED", direction: "OUT")
shoutedCount: Int! @cypher(statement: "MATCH (this)-[:SHOUTED]->(r:Post) WHERE NOT r.deleted = true AND NOT r.disabled = true RETURN COUNT(DISTINCT r)")

View File

@ -137,8 +137,8 @@ p.contentExcerpt = post.contentExcerpt,
p.visibility = toLower(post.visibility),
p.createdAt = post.createdAt.`$date`,
p.updatedAt = post.updatedAt.`$date`,
p.deleted = COALESCE(post.deleted,false),
p.disabled = NOT post.isEnabled
p.deleted = COALESCE(post.deleted, false),
p.disabled = COALESCE(NOT post.isEnabled, false)
WITH p, post
MATCH (u:User {id: post.userId})
MERGE (u)-[:WROTE]->(p)

View File

@ -185,9 +185,6 @@ export default {
return result
},
update({ Post }) {
// TODO: find out why `update` gets called twice initially.
// We have to filter for uniq posts only because we get the same
// result set twice.
this.hasMore = Post.length >= this.pageSize
const posts = uniqBy([...this.posts, ...Post], 'id')
this.posts = posts

View File

@ -104,9 +104,7 @@ describe('ProfileSlug', () => {
describe('currently no posts available (e.g. after tab switching)', () => {
beforeEach(() => {
wrapper.setData({
Post: null,
})
wrapper.setData({ posts: [], hasMore: false })
})
it('displays no "load more" button', () => {
@ -137,9 +135,7 @@ describe('ProfileSlug', () => {
}
})
wrapper.setData({
Post: posts,
})
wrapper.setData({ posts, hasMore: true })
})
it('displays a "load more" button', () => {
@ -170,9 +166,7 @@ describe('ProfileSlug', () => {
}
})
wrapper.setData({
Post: posts,
})
wrapper.setData({ posts, hasMore: false })
})
it('displays no "load more" button', () => {

View File

@ -219,8 +219,8 @@
</ds-space>
</ds-grid-item>
<template v-if="activePosts.length">
<masonry-grid-item v-for="(post, index) in activePosts" :key="post.id">
<template v-if="posts.length">
<masonry-grid-item v-for="(post, index) in posts" :key="post.id">
<hc-post-card
:post="post"
:width="{ base: '100%', md: '100%', xl: '50%' }"
@ -229,10 +229,10 @@
</masonry-grid-item>
</template>
<template v-else-if="$apollo.loading">
<ds-grid-item>
<ds-section centered>
<ds-grid-item column-span="fullWidth">
<ds-space centered>
<ds-spinner size="base"></ds-spinner>
</ds-section>
</ds-space>
</ds-grid-item>
</template>
<template v-else>
@ -306,33 +306,21 @@ export default {
const filter = tabToFilterMapping({ tab: 'post', id: this.$route.params.id })
return {
User: [],
Post: [],
activePosts: [],
voted: false,
page: 1,
posts: [],
hasMore: false,
offset: 0,
pageSize: 6,
tabActive: 'post',
filter,
}
},
computed: {
hasMore() {
const total = {
post: this.user.contributionsCount,
shout: this.user.shoutedCount,
comment: this.user.commentedCount,
}[this.tabActive]
return this.Post && this.Post.length < total
},
myProfile() {
return this.$route.params.id === this.$store.getters['auth/user'].id
},
user() {
return this.User ? this.User[0] : {}
},
offset() {
return (this.page - 1) * this.pageSize
},
socialMediaLinks() {
const { socialMedia = [] } = this.user
return socialMedia.map(socialMedia => {
@ -355,19 +343,15 @@ export default {
throw new Error('User not found!')
}
},
Post(val) {
this.activePosts = this.setActivePosts()
},
},
methods: {
removePostFromList(index) {
this.activePosts.splice(index, 1)
this.$apollo.queries.User.refetch()
this.posts.splice(index, 1)
},
handleTab(tab) {
this.tabActive = tab
this.Post = null
this.filter = tabToFilterMapping({ tab, id: this.$route.params.id })
this.resetPostList()
},
uniq(items, field = 'id') {
return uniqBy(items, field)
@ -377,38 +361,23 @@ export default {
this.$apollo.queries.User.refetch()
},
showMoreContributions() {
// this.page++
// Fetch more data and transform the original result
this.page++
this.$apollo.queries.Post.fetchMore({
variables: {
filter: this.filter,
first: this.pageSize,
offset: this.offset,
},
// Transform the previous result with new data
updateQuery: (previousResult, { fetchMoreResult }) => {
let output = { Post: this.Post }
output.Post = [...previousResult.Post, ...fetchMoreResult.Post]
return output
},
fetchPolicy: 'cache-and-network',
})
this.offset += this.pageSize
},
setActivePosts() {
if (!this.Post) {
return []
}
return this.uniq(this.Post.filter(post => !post.deleted))
resetPostList() {
this.offset = 0
this.posts = []
this.hasMore = false
},
async block(user) {
await this.$apollo.mutate({ mutation: Block(), variables: { id: user.id } })
this.$apollo.queries.User.refetch()
this.resetPostList()
this.$apollo.queries.Post.refetch()
},
async unblock(user) {
await this.$apollo.mutate({ mutation: Unblock(), variables: { id: user.id } })
this.$apollo.queries.User.refetch()
this.resetPostList()
this.$apollo.queries.Post.refetch()
},
},
@ -421,10 +390,19 @@ export default {
return {
filter: this.filter,
first: this.pageSize,
offset: 0,
offset: this.offset,
orderBy: 'createdAt_desc',
}
},
fetchPolicy: 'cache-and-network',
update({ Post }) {
if (!Post) return
// TODO: find out why `update` gets called twice initially.
// We have to filter for uniq posts only because we get the same
// result set twice.
this.hasMore = Post.length >= this.pageSize
this.posts = this.uniq([...this.posts, ...Post])
},
},
User: {
query() {