mirror of
https://github.com/Ocelot-Social-Community/Ocelot-Social.git
synced 2025-12-13 07:46:06 +00:00
Refined list deletion functions and started writing custom mutation for DeleteComment and their tests
This commit is contained in:
parent
b46016203a
commit
5bec0f1d72
@ -16,11 +16,15 @@ const isAdmin = rule()(async (parent, args, { user }, info) => {
|
|||||||
return user && user.role === 'admin'
|
return user && user.role === 'admin'
|
||||||
})
|
})
|
||||||
|
|
||||||
const isMyOwn = rule({ cache: 'no_cache' })(async (parent, args, context, info) => {
|
const isMyOwn = rule({
|
||||||
|
cache: 'no_cache',
|
||||||
|
})(async (parent, args, context, info) => {
|
||||||
return context.user.id === parent.id
|
return context.user.id === parent.id
|
||||||
})
|
})
|
||||||
|
|
||||||
const belongsToMe = rule({ cache: 'no_cache' })(async (_, args, context) => {
|
const belongsToMe = rule({
|
||||||
|
cache: 'no_cache',
|
||||||
|
})(async (_, args, context) => {
|
||||||
const {
|
const {
|
||||||
driver,
|
driver,
|
||||||
user: { id: userId },
|
user: { id: userId },
|
||||||
@ -32,7 +36,10 @@ const belongsToMe = rule({ cache: 'no_cache' })(async (_, args, context) => {
|
|||||||
MATCH (u:User {id: $userId})<-[:NOTIFIED]-(n:Notification {id: $notificationId})
|
MATCH (u:User {id: $userId})<-[:NOTIFIED]-(n:Notification {id: $notificationId})
|
||||||
RETURN n
|
RETURN n
|
||||||
`,
|
`,
|
||||||
{ userId, notificationId },
|
{
|
||||||
|
userId,
|
||||||
|
notificationId,
|
||||||
|
},
|
||||||
)
|
)
|
||||||
const [notification] = result.records.map(record => {
|
const [notification] = result.records.map(record => {
|
||||||
return record.get('n')
|
return record.get('n')
|
||||||
@ -41,12 +48,16 @@ const belongsToMe = rule({ cache: 'no_cache' })(async (_, args, context) => {
|
|||||||
return Boolean(notification)
|
return Boolean(notification)
|
||||||
})
|
})
|
||||||
|
|
||||||
const onlyEnabledContent = rule({ cache: 'strict' })(async (parent, args, ctx, info) => {
|
const onlyEnabledContent = rule({
|
||||||
|
cache: 'strict',
|
||||||
|
})(async (parent, args, ctx, info) => {
|
||||||
const { disabled, deleted } = args
|
const { disabled, deleted } = args
|
||||||
return !(disabled || deleted)
|
return !(disabled || deleted)
|
||||||
})
|
})
|
||||||
|
|
||||||
const isAuthor = rule({ cache: 'no_cache' })(async (parent, args, { user, driver }) => {
|
const isAuthor = rule({
|
||||||
|
cache: 'no_cache',
|
||||||
|
})(async (parent, args, { user, driver }) => {
|
||||||
if (!user) return false
|
if (!user) return false
|
||||||
const session = driver.session()
|
const session = driver.session()
|
||||||
const { id: postId } = args
|
const { id: postId } = args
|
||||||
@ -55,7 +66,9 @@ const isAuthor = rule({ cache: 'no_cache' })(async (parent, args, { user, driver
|
|||||||
MATCH (post:Post {id: $postId})<-[:WROTE]-(author)
|
MATCH (post:Post {id: $postId})<-[:WROTE]-(author)
|
||||||
RETURN author
|
RETURN author
|
||||||
`,
|
`,
|
||||||
{ postId },
|
{
|
||||||
|
postId,
|
||||||
|
},
|
||||||
)
|
)
|
||||||
const [author] = result.records.map(record => {
|
const [author] = result.records.map(record => {
|
||||||
return record.get('author')
|
return record.get('author')
|
||||||
@ -100,6 +113,7 @@ const permissions = shield({
|
|||||||
enable: isModerator,
|
enable: isModerator,
|
||||||
disable: isModerator,
|
disable: isModerator,
|
||||||
CreateComment: isAuthenticated,
|
CreateComment: isAuthenticated,
|
||||||
|
DeleteComment: isAuthenticated,
|
||||||
// CreateUser: allow,
|
// CreateUser: allow,
|
||||||
},
|
},
|
||||||
User: {
|
User: {
|
||||||
|
|||||||
@ -53,6 +53,11 @@ export default {
|
|||||||
)
|
)
|
||||||
session.close()
|
session.close()
|
||||||
|
|
||||||
|
return comment
|
||||||
|
},
|
||||||
|
DeleteComment: async (object, params, context, resolveInfo) => {
|
||||||
|
const socialMedia = await neo4jgraphql(object, params, context, resolveInfo, false)
|
||||||
|
|
||||||
return comment
|
return comment
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|||||||
@ -1,3 +1,4 @@
|
|||||||
|
import gql from 'graphql-tag'
|
||||||
import Factory from '../seed/factories'
|
import Factory from '../seed/factories'
|
||||||
import { GraphQLClient } from 'graphql-request'
|
import { GraphQLClient } from 'graphql-request'
|
||||||
import { host, login } from '../jest/helpers'
|
import { host, login } from '../jest/helpers'
|
||||||
@ -5,6 +6,7 @@ import { host, login } from '../jest/helpers'
|
|||||||
const factory = Factory()
|
const factory = Factory()
|
||||||
let client
|
let client
|
||||||
let createCommentVariables
|
let createCommentVariables
|
||||||
|
let deleteCommentVariables
|
||||||
let createPostVariables
|
let createPostVariables
|
||||||
let createCommentVariablesSansPostId
|
let createCommentVariablesSansPostId
|
||||||
let createCommentVariablesWithNonExistentPost
|
let createCommentVariablesWithNonExistentPost
|
||||||
@ -21,22 +23,22 @@ afterEach(async () => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
describe('CreateComment', () => {
|
describe('CreateComment', () => {
|
||||||
const createCommentMutation = `
|
const createCommentMutation = gql`
|
||||||
mutation($postId: ID, $content: String!) {
|
mutation($postId: ID, $content: String!) {
|
||||||
CreateComment(postId: $postId, content: $content) {
|
CreateComment(postId: $postId, content: $content) {
|
||||||
id
|
id
|
||||||
content
|
content
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
`
|
`
|
||||||
const createPostMutation = `
|
const createPostMutation = gql`
|
||||||
mutation($id: ID!, $title: String!, $content: String!) {
|
mutation($id: ID!, $title: String!, $content: String!) {
|
||||||
CreatePost(id: $id, title: $title, content: $content) {
|
CreatePost(id: $id, title: $title, content: $content) {
|
||||||
id
|
id
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
`
|
`
|
||||||
const commentQueryForPostId = `
|
const commentQueryForPostId = gql`
|
||||||
query($content: String) {
|
query($content: String) {
|
||||||
Comment(content: $content) {
|
Comment(content: $content) {
|
||||||
postId
|
postId
|
||||||
@ -59,8 +61,13 @@ describe('CreateComment', () => {
|
|||||||
describe('authenticated', () => {
|
describe('authenticated', () => {
|
||||||
let headers
|
let headers
|
||||||
beforeEach(async () => {
|
beforeEach(async () => {
|
||||||
headers = await login({ email: 'test@example.org', password: '1234' })
|
headers = await login({
|
||||||
client = new GraphQLClient(host, { headers })
|
email: 'test@example.org',
|
||||||
|
password: '1234',
|
||||||
|
})
|
||||||
|
client = new GraphQLClient(host, {
|
||||||
|
headers,
|
||||||
|
})
|
||||||
createCommentVariables = {
|
createCommentVariables = {
|
||||||
postId: 'p1',
|
postId: 'p1',
|
||||||
content: "I'm authorised to comment",
|
content: "I'm authorised to comment",
|
||||||
@ -96,7 +103,15 @@ describe('CreateComment', () => {
|
|||||||
}
|
}
|
||||||
}`)
|
}`)
|
||||||
|
|
||||||
expect(User).toEqual([{ comments: [{ content: "I'm authorised to comment" }] }])
|
expect(User).toEqual([
|
||||||
|
{
|
||||||
|
comments: [
|
||||||
|
{
|
||||||
|
content: "I'm authorised to comment",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
])
|
||||||
})
|
})
|
||||||
|
|
||||||
it('throw an error if an empty string is sent from the editor as content', async () => {
|
it('throw an error if an empty string is sent from the editor as content', async () => {
|
||||||
@ -186,7 +201,204 @@ describe('CreateComment', () => {
|
|||||||
commentQueryForPostId,
|
commentQueryForPostId,
|
||||||
commentQueryVariablesByContent,
|
commentQueryVariablesByContent,
|
||||||
)
|
)
|
||||||
expect(Comment).toEqual([{ postId: null }])
|
expect(Comment).toEqual([
|
||||||
|
{
|
||||||
|
postId: null,
|
||||||
|
},
|
||||||
|
])
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// describe('DeleteComment', () => {
|
||||||
|
// const createCommentMutation = gql `
|
||||||
|
// mutation($postId: ID, $content: String!) {
|
||||||
|
// CreateComment(postId: $postId, content: $content) {
|
||||||
|
// id
|
||||||
|
// content
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// `
|
||||||
|
// const deleteCommentMutation = gql `
|
||||||
|
// mutation($id: ID!) {
|
||||||
|
// DeleteComment(id: $id) {
|
||||||
|
// id
|
||||||
|
// content
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// `
|
||||||
|
// const createPostMutation = gql `
|
||||||
|
// mutation($id: ID!, $title: String!, $content: String!) {
|
||||||
|
// CreatePost(id: $id, title: $title, content: $content) {
|
||||||
|
// id
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// `
|
||||||
|
// const commentQueryForPostId = gql `
|
||||||
|
// query($content: String) {
|
||||||
|
// Comment(content: $content) {
|
||||||
|
// postId
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// `
|
||||||
|
// describe('unauthenticated', () => {
|
||||||
|
// it('throws authorization error', async () => {
|
||||||
|
// deleteCommentVariables = {
|
||||||
|
// id: 'c1',
|
||||||
|
// }
|
||||||
|
// client = new GraphQLClient(host)
|
||||||
|
// await expect(client.request(deleteCommentMutation, deleteCommentVariables)).rejects.toThrow(
|
||||||
|
// 'Not Authorised',
|
||||||
|
// )
|
||||||
|
// })
|
||||||
|
// })
|
||||||
|
|
||||||
|
// // describe('authenticated', () => {
|
||||||
|
// // let headers
|
||||||
|
// // beforeEach(async () => {
|
||||||
|
// // headers = await login({
|
||||||
|
// // email: 'test@example.org',
|
||||||
|
// // password: '1234'
|
||||||
|
// // })
|
||||||
|
// // client = new GraphQLClient(host, {
|
||||||
|
// // headers
|
||||||
|
// // })
|
||||||
|
// // createCommentVariables = {
|
||||||
|
// // postId: 'p1',
|
||||||
|
// // content: "I'm authorised to comment",
|
||||||
|
// // }
|
||||||
|
// // createPostVariables = {
|
||||||
|
// // id: 'p1',
|
||||||
|
// // title: 'post to comment on',
|
||||||
|
// // content: 'please comment on me',
|
||||||
|
// // }
|
||||||
|
// // await client.request(createPostMutation, createPostVariables)
|
||||||
|
// // })
|
||||||
|
|
||||||
|
// // it('creates a comment', async () => {
|
||||||
|
// // const expected = {
|
||||||
|
// // CreateComment: {
|
||||||
|
// // content: "I'm authorised to comment",
|
||||||
|
// // },
|
||||||
|
// // }
|
||||||
|
|
||||||
|
// // await expect(
|
||||||
|
// // client.request(createCommentMutation, createCommentVariables),
|
||||||
|
// // ).resolves.toMatchObject(expected)
|
||||||
|
// // })
|
||||||
|
|
||||||
|
// // it('assigns the authenticated user as author', async () => {
|
||||||
|
// // await client.request(createCommentMutation, createCommentVariables)
|
||||||
|
|
||||||
|
// // const {
|
||||||
|
// // User
|
||||||
|
// // } = await client.request(`{
|
||||||
|
// // User(email: "test@example.org") {
|
||||||
|
// // comments {
|
||||||
|
// // content
|
||||||
|
// // }
|
||||||
|
// // }
|
||||||
|
// // }`)
|
||||||
|
|
||||||
|
// // expect(User).toEqual([{
|
||||||
|
// // comments: [{
|
||||||
|
// // content: "I'm authorised to comment"
|
||||||
|
// // }]
|
||||||
|
// // }])
|
||||||
|
// // })
|
||||||
|
|
||||||
|
// // it('throw an error if an empty string is sent from the editor as content', async () => {
|
||||||
|
// // createCommentVariables = {
|
||||||
|
// // postId: 'p1',
|
||||||
|
// // content: '<p></p>',
|
||||||
|
// // }
|
||||||
|
|
||||||
|
// // await expect(client.request(createCommentMutation, createCommentVariables)).rejects.toThrow(
|
||||||
|
// // 'Comment must be at least 1 character long!',
|
||||||
|
// // )
|
||||||
|
// // })
|
||||||
|
|
||||||
|
// // it('throws an error if a comment sent from the editor does not contain a single character', async () => {
|
||||||
|
// // createCommentVariables = {
|
||||||
|
// // postId: 'p1',
|
||||||
|
// // content: '<p> </p>',
|
||||||
|
// // }
|
||||||
|
|
||||||
|
// // await expect(client.request(createCommentMutation, createCommentVariables)).rejects.toThrow(
|
||||||
|
// // 'Comment must be at least 1 character long!',
|
||||||
|
// // )
|
||||||
|
// // })
|
||||||
|
|
||||||
|
// // it('throws an error if postId is sent as an empty string', async () => {
|
||||||
|
// // createCommentVariables = {
|
||||||
|
// // postId: 'p1',
|
||||||
|
// // content: '',
|
||||||
|
// // }
|
||||||
|
|
||||||
|
// // await expect(client.request(createCommentMutation, createCommentVariables)).rejects.toThrow(
|
||||||
|
// // 'Comment must be at least 1 character long!',
|
||||||
|
// // )
|
||||||
|
// // })
|
||||||
|
|
||||||
|
// // it('throws an error if content is sent as an string of empty characters', async () => {
|
||||||
|
// // createCommentVariables = {
|
||||||
|
// // postId: 'p1',
|
||||||
|
// // content: ' ',
|
||||||
|
// // }
|
||||||
|
|
||||||
|
// // await expect(client.request(createCommentMutation, createCommentVariables)).rejects.toThrow(
|
||||||
|
// // 'Comment must be at least 1 character long!',
|
||||||
|
// // )
|
||||||
|
// // })
|
||||||
|
|
||||||
|
// // it('throws an error if postId is sent as an empty string', async () => {
|
||||||
|
// // createCommentVariablesSansPostId = {
|
||||||
|
// // postId: '',
|
||||||
|
// // content: 'this comment should not be created',
|
||||||
|
// // }
|
||||||
|
|
||||||
|
// // await expect(
|
||||||
|
// // client.request(createCommentMutation, createCommentVariablesSansPostId),
|
||||||
|
// // ).rejects.toThrow('Comment cannot be created without a post!')
|
||||||
|
// // })
|
||||||
|
|
||||||
|
// // it('throws an error if postId is sent as an string of empty characters', async () => {
|
||||||
|
// // createCommentVariablesSansPostId = {
|
||||||
|
// // postId: ' ',
|
||||||
|
// // content: 'this comment should not be created',
|
||||||
|
// // }
|
||||||
|
|
||||||
|
// // await expect(
|
||||||
|
// // client.request(createCommentMutation, createCommentVariablesSansPostId),
|
||||||
|
// // ).rejects.toThrow('Comment cannot be created without a post!')
|
||||||
|
// // })
|
||||||
|
|
||||||
|
// // it('throws an error if the post does not exist in the database', async () => {
|
||||||
|
// // createCommentVariablesWithNonExistentPost = {
|
||||||
|
// // postId: 'p2',
|
||||||
|
// // content: "comment should not be created cause the post doesn't exist",
|
||||||
|
// // }
|
||||||
|
|
||||||
|
// // await expect(
|
||||||
|
// // client.request(createCommentMutation, createCommentVariablesWithNonExistentPost),
|
||||||
|
// // ).rejects.toThrow('Comment cannot be created without a post!')
|
||||||
|
// // })
|
||||||
|
|
||||||
|
// // it('does not create the comment with the postId as an attribute', async () => {
|
||||||
|
// // const commentQueryVariablesByContent = {
|
||||||
|
// // content: "I'm authorised to comment",
|
||||||
|
// // }
|
||||||
|
|
||||||
|
// // await client.request(createCommentMutation, createCommentVariables)
|
||||||
|
// // const {
|
||||||
|
// // Comment
|
||||||
|
// // } = await client.request(
|
||||||
|
// // commentQueryForPostId,
|
||||||
|
// // commentQueryVariablesByContent,
|
||||||
|
// // )
|
||||||
|
// // expect(Comment).toEqual([{
|
||||||
|
// // postId: null
|
||||||
|
// // }])
|
||||||
|
// // })
|
||||||
|
// // })
|
||||||
|
// })
|
||||||
|
|||||||
@ -1,8 +1,4 @@
|
|||||||
import {
|
import { config, shallowMount, createLocalVue } from '@vue/test-utils'
|
||||||
config,
|
|
||||||
shallowMount,
|
|
||||||
createLocalVue
|
|
||||||
} from '@vue/test-utils'
|
|
||||||
import Comment from './Comment.vue'
|
import Comment from './Comment.vue'
|
||||||
import Vuex from 'vuex'
|
import Vuex from 'vuex'
|
||||||
import Styleguide from '@human-connection/styleguide'
|
import Styleguide from '@human-connection/styleguide'
|
||||||
@ -25,6 +21,13 @@ describe('Comment.vue', () => {
|
|||||||
propsData = {}
|
propsData = {}
|
||||||
mocks = {
|
mocks = {
|
||||||
$t: jest.fn(),
|
$t: jest.fn(),
|
||||||
|
$toast: {
|
||||||
|
success: jest.fn(),
|
||||||
|
error: jest.fn(),
|
||||||
|
},
|
||||||
|
$apollo: {
|
||||||
|
mutate: jest.fn().mockResolvedValue(),
|
||||||
|
},
|
||||||
}
|
}
|
||||||
getters = {
|
getters = {
|
||||||
'auth/user': () => {
|
'auth/user': () => {
|
||||||
@ -76,12 +79,9 @@ describe('Comment.vue', () => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
it('translates a placeholder', () => {
|
it('translates a placeholder', () => {
|
||||||
/* const wrapper = */
|
wrapper = Wrapper()
|
||||||
Wrapper()
|
|
||||||
const calls = mocks.$t.mock.calls
|
const calls = mocks.$t.mock.calls
|
||||||
const expected = [
|
const expected = [['comment.content.unavailable-placeholder']]
|
||||||
['comment.content.unavailable-placeholder']
|
|
||||||
]
|
|
||||||
expect(calls).toEqual(expect.arrayContaining(expected))
|
expect(calls).toEqual(expect.arrayContaining(expected))
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -121,10 +121,6 @@ describe('Comment.vue', () => {
|
|||||||
expect(wrapper.emitted().deleteComment.length).toBe(1)
|
expect(wrapper.emitted().deleteComment.length).toBe(1)
|
||||||
})
|
})
|
||||||
|
|
||||||
// it('does not go to index (main) page', () => {
|
|
||||||
// expect(mocks.$router.history.push).not.toHaveBeenCalled()
|
|
||||||
// })
|
|
||||||
|
|
||||||
it('does call mutation', () => {
|
it('does call mutation', () => {
|
||||||
expect(mocks.$apollo.mutate).toHaveBeenCalledTimes(1)
|
expect(mocks.$apollo.mutate).toHaveBeenCalledTimes(1)
|
||||||
})
|
})
|
||||||
|
|||||||
@ -1,18 +1,32 @@
|
|||||||
<template>
|
<template>
|
||||||
<dropdown class="content-menu"
|
<dropdown
|
||||||
:placement="placement" offset="5">
|
class="content-menu"
|
||||||
<template slot="default"
|
:placement="placement"
|
||||||
slot-scope="{toggleMenu}">
|
offset="5"
|
||||||
<slot name="button"
|
>
|
||||||
:toggleMenu="toggleMenu">
|
<template
|
||||||
<ds-button class="content-menu-trigger"
|
slot="default"
|
||||||
size="small" ghost @click.prevent="toggleMenu">
|
slot-scope="{toggleMenu}"
|
||||||
|
>
|
||||||
|
<slot
|
||||||
|
name="button"
|
||||||
|
:toggleMenu="toggleMenu"
|
||||||
|
>
|
||||||
|
<ds-button
|
||||||
|
class="content-menu-trigger"
|
||||||
|
size="small"
|
||||||
|
ghost
|
||||||
|
@click.prevent="toggleMenu"
|
||||||
|
>
|
||||||
<ds-icon name="ellipsis-v" />
|
<ds-icon name="ellipsis-v" />
|
||||||
</ds-button>
|
</ds-button>
|
||||||
</slot>
|
</slot>
|
||||||
</template>
|
</template>
|
||||||
<div slot="popover"
|
<div
|
||||||
slot-scope="{toggleMenu}" class="content-menu-popover">
|
slot="popover"
|
||||||
|
slot-scope="{toggleMenu}"
|
||||||
|
class="content-menu-popover"
|
||||||
|
>
|
||||||
<ds-menu :routes="routes">
|
<ds-menu :routes="routes">
|
||||||
<ds-menu-item
|
<ds-menu-item
|
||||||
slot="menuitem"
|
slot="menuitem"
|
||||||
|
|||||||
@ -22,7 +22,7 @@
|
|||||||
v-for="(comment, index) in comments"
|
v-for="(comment, index) in comments"
|
||||||
:key="comment.id"
|
:key="comment.id"
|
||||||
:comment="comment"
|
:comment="comment"
|
||||||
@deleteComment="deleteComment(index)"
|
@deleteComment="comments.splice(index, 1)"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<hc-empty
|
<hc-empty
|
||||||
@ -65,9 +65,6 @@ export default {
|
|||||||
this.$apollo.queries.Post.refetch()
|
this.$apollo.queries.Post.refetch()
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
deleteComment(index) {
|
|
||||||
this.comments.splice(index, 1)
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
apollo: {
|
apollo: {
|
||||||
Post: {
|
Post: {
|
||||||
|
|||||||
@ -1,10 +1,7 @@
|
|||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<ds-flex
|
<ds-flex v-if="Post && Post.length"
|
||||||
v-if="Post && Post.length"
|
:width="{ base: '100%' }" gutter="base">
|
||||||
:width="{ base: '100%' }"
|
|
||||||
gutter="base"
|
|
||||||
>
|
|
||||||
<hc-post-card
|
<hc-post-card
|
||||||
v-for="(post, index) in uniq(Post)"
|
v-for="(post, index) in uniq(Post)"
|
||||||
:key="post.id"
|
:key="post.id"
|
||||||
@ -23,11 +20,8 @@
|
|||||||
primary
|
primary
|
||||||
/>
|
/>
|
||||||
</no-ssr>
|
</no-ssr>
|
||||||
<hc-load-more
|
<hc-load-more v-if="true"
|
||||||
v-if="true"
|
:loading="$apollo.loading" @click="showMoreContributions" />
|
||||||
:loading="$apollo.loading"
|
|
||||||
@click="showMoreContributions"
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@ -90,7 +84,8 @@ export default {
|
|||||||
this.Post = this.Post.filter(post => {
|
this.Post = this.Post.filter(post => {
|
||||||
return post.id !== postId
|
return post.id !== postId
|
||||||
})
|
})
|
||||||
// Ideal solution:
|
// Why "uniq(Post)" is used in the array for list creation?
|
||||||
|
// Ideal solution here:
|
||||||
// this.Post.splice(index, 1)
|
// this.Post.splice(index, 1)
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|||||||
@ -1,11 +1,13 @@
|
|||||||
<template>
|
<template>
|
||||||
<ds-card>
|
<ds-card>
|
||||||
<h2 style="margin-bottom: .2em;">
|
<h2 style="margin-bottom: .2em;">
|
||||||
Mehr Informationen
|
Mehr Informationen
|
||||||
</h2>
|
</h2>
|
||||||
<p>Hier findest du weitere infos zum Thema.</p>
|
<p>Hier findest du weitere infos zum Thema.</p>
|
||||||
<ds-space />
|
<ds-space />
|
||||||
<h3><ds-icon name="compass" /> Themenkategorien</h3>
|
<h3>
|
||||||
|
<ds-icon name="compass" />Themenkategorien
|
||||||
|
</h3>
|
||||||
<div class="tags">
|
<div class="tags">
|
||||||
<ds-icon
|
<ds-icon
|
||||||
v-for="category in post.categories"
|
v-for="category in post.categories"
|
||||||
@ -16,39 +18,34 @@
|
|||||||
/>
|
/>
|
||||||
<!--<ds-tag
|
<!--<ds-tag
|
||||||
v-for="category in post.categories"
|
v-for="category in post.categories"
|
||||||
:key="category.id"><ds-icon :name="category.icon" /> {{ category.name }}</ds-tag>-->
|
:key="category.id"><ds-icon :name="category.icon" /> {{ category.name }}</ds-tag>-->
|
||||||
</div>
|
</div>
|
||||||
<template v-if="post.tags && post.tags.length">
|
<template v-if="post.tags && post.tags.length">
|
||||||
<h3><ds-icon name="tags" /> Schlagwörter</h3>
|
<h3>
|
||||||
|
<ds-icon name="tags" />Schlagwörter
|
||||||
|
</h3>
|
||||||
<div class="tags">
|
<div class="tags">
|
||||||
<ds-tag
|
<ds-tag v-for="tag in post.tags"
|
||||||
v-for="tag in post.tags"
|
:key="tag.id">
|
||||||
:key="tag.id"
|
<ds-icon name="tag" />
|
||||||
>
|
{{ tag.name }}
|
||||||
<ds-icon name="tag" /> {{ tag.name }}
|
|
||||||
</ds-tag>
|
</ds-tag>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<h3>Verwandte Beiträge</h3>
|
<h3>Verwandte Beiträge</h3>
|
||||||
<ds-section style="margin: 0 -1.5rem; padding: 1.5rem;">
|
<ds-section style="margin: 0 -1.5rem; padding: 1.5rem;">
|
||||||
<ds-flex
|
<ds-flex v-if="post.relatedContributions && post.relatedContributions.length"
|
||||||
v-if="post.relatedContributions && post.relatedContributions.length"
|
gutter="small">
|
||||||
gutter="small"
|
|
||||||
>
|
|
||||||
<hc-post-card
|
<hc-post-card
|
||||||
v-for="(relatedPost, index) in post.relatedContributions"
|
v-for="(relatedPost, index) in post.relatedContributions"
|
||||||
:key="relatedPost.id"
|
:key="relatedPost.id"
|
||||||
:post="relatedPost"
|
:post="relatedPost"
|
||||||
:width="{ base: '100%', lg: 1 }"
|
:width="{ base: '100%', lg: 1 }"
|
||||||
@deletePost="deletePost(index)"
|
@deletePost="post.relatedContributions.splice(index, 1)"
|
||||||
/>
|
/>
|
||||||
</ds-flex>
|
</ds-flex>
|
||||||
<hc-empty
|
<hc-empty v-else
|
||||||
v-else
|
margin="large" icon="file" message="No related Posts" />
|
||||||
margin="large"
|
|
||||||
icon="file"
|
|
||||||
message="No related Posts"
|
|
||||||
/>
|
|
||||||
</ds-section>
|
</ds-section>
|
||||||
<ds-space margin-bottom="large" />
|
<ds-space margin-bottom="large" />
|
||||||
</ds-card>
|
</ds-card>
|
||||||
@ -73,11 +70,6 @@ export default {
|
|||||||
return this.Post ? this.Post[0] || {} : {}
|
return this.Post ? this.Post[0] || {} : {}
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
methods: {
|
|
||||||
deletePost(index) {
|
|
||||||
this.post.relatedContributions.splice(index, 1)
|
|
||||||
},
|
|
||||||
},
|
|
||||||
apollo: {
|
apollo: {
|
||||||
Post: {
|
Post: {
|
||||||
query() {
|
query() {
|
||||||
|
|||||||
@ -3,27 +3,15 @@
|
|||||||
<ds-card v-if="user && user.image">
|
<ds-card v-if="user && user.image">
|
||||||
<p>PROFILE IMAGE</p>
|
<p>PROFILE IMAGE</p>
|
||||||
</ds-card>
|
</ds-card>
|
||||||
<ds-space />
|
<ds-space/>
|
||||||
<ds-flex
|
<ds-flex v-if="user" :width="{ base: '100%' }" gutter="base">
|
||||||
v-if="user"
|
|
||||||
:width="{ base: '100%' }"
|
|
||||||
gutter="base"
|
|
||||||
>
|
|
||||||
<ds-flex-item :width="{ base: '100%', sm: 2, md: 2, lg: 1 }">
|
<ds-flex-item :width="{ base: '100%', sm: 2, md: 2, lg: 1 }">
|
||||||
<ds-card
|
<ds-card
|
||||||
:class="{'disabled-content': user.disabled}"
|
:class="{'disabled-content': user.disabled}"
|
||||||
style="position: relative; height: auto;"
|
style="position: relative; height: auto;"
|
||||||
>
|
>
|
||||||
<hc-upload
|
<hc-upload v-if="myProfile" :user="user"/>
|
||||||
v-if="myProfile"
|
<hc-avatar v-else :user="user" class="profile-avatar" size="x-large"/>
|
||||||
:user="user"
|
|
||||||
/>
|
|
||||||
<hc-avatar
|
|
||||||
v-else
|
|
||||||
:user="user"
|
|
||||||
class="profile-avatar"
|
|
||||||
size="x-large"
|
|
||||||
/>
|
|
||||||
<no-ssr>
|
<no-ssr>
|
||||||
<content-menu
|
<content-menu
|
||||||
placement="bottom-end"
|
placement="bottom-end"
|
||||||
@ -35,54 +23,32 @@
|
|||||||
/>
|
/>
|
||||||
</no-ssr>
|
</no-ssr>
|
||||||
<ds-space margin="small">
|
<ds-space margin="small">
|
||||||
<ds-heading
|
<ds-heading tag="h3" align="center" no-margin>{{ userName }}</ds-heading>
|
||||||
tag="h3"
|
<ds-text v-if="user.location" align="center" color="soft" size="small">
|
||||||
align="center"
|
<ds-icon name="map-marker"/>
|
||||||
no-margin
|
|
||||||
>
|
|
||||||
{{ userName }}
|
|
||||||
</ds-heading>
|
|
||||||
<ds-text
|
|
||||||
v-if="user.location"
|
|
||||||
align="center"
|
|
||||||
color="soft"
|
|
||||||
size="small"
|
|
||||||
>
|
|
||||||
<ds-icon name="map-marker" />
|
|
||||||
{{ user.location.name }}
|
{{ user.location.name }}
|
||||||
</ds-text>
|
</ds-text>
|
||||||
<ds-text
|
<ds-text
|
||||||
align="center"
|
align="center"
|
||||||
color="soft"
|
color="soft"
|
||||||
size="small"
|
size="small"
|
||||||
>
|
>{{ $t('profile.memberSince') }} {{ user.createdAt | date('MMMM yyyy') }}</ds-text>
|
||||||
{{ $t('profile.memberSince') }} {{ user.createdAt | date('MMMM yyyy') }}
|
|
||||||
</ds-text>
|
|
||||||
</ds-space>
|
</ds-space>
|
||||||
<ds-space
|
<ds-space v-if="user.badges && user.badges.length" margin="x-small">
|
||||||
v-if="user.badges && user.badges.length"
|
<hc-badges :badges="user.badges"/>
|
||||||
margin="x-small"
|
|
||||||
>
|
|
||||||
<hc-badges :badges="user.badges" />
|
|
||||||
</ds-space>
|
</ds-space>
|
||||||
<ds-flex>
|
<ds-flex>
|
||||||
<ds-flex-item>
|
<ds-flex-item>
|
||||||
<no-ssr>
|
<no-ssr>
|
||||||
<ds-number :label="$t('profile.followers')">
|
<ds-number :label="$t('profile.followers')">
|
||||||
<hc-count-to
|
<hc-count-to slot="count" :end-val="followedByCount"/>
|
||||||
slot="count"
|
|
||||||
:end-val="followedByCount"
|
|
||||||
/>
|
|
||||||
</ds-number>
|
</ds-number>
|
||||||
</no-ssr>
|
</no-ssr>
|
||||||
</ds-flex-item>
|
</ds-flex-item>
|
||||||
<ds-flex-item>
|
<ds-flex-item>
|
||||||
<no-ssr>
|
<no-ssr>
|
||||||
<ds-number :label="$t('profile.following')">
|
<ds-number :label="$t('profile.following')">
|
||||||
<hc-count-to
|
<hc-count-to slot="count" :end-val="Number(user.followingCount) || 0"/>
|
||||||
slot="count"
|
|
||||||
:end-val="Number(user.followingCount) || 0"
|
|
||||||
/>
|
|
||||||
</ds-number>
|
</ds-number>
|
||||||
</no-ssr>
|
</no-ssr>
|
||||||
</ds-flex-item>
|
</ds-flex-item>
|
||||||
@ -98,136 +64,69 @@
|
|||||||
</ds-space>
|
</ds-space>
|
||||||
<template v-if="user.about">
|
<template v-if="user.about">
|
||||||
<hr>
|
<hr>
|
||||||
<ds-space
|
<ds-space margin-top="small" margin-bottom="small">
|
||||||
margin-top="small"
|
<ds-text color="soft" size="small">{{ user.about }}</ds-text>
|
||||||
margin-bottom="small"
|
|
||||||
>
|
|
||||||
<ds-text
|
|
||||||
color="soft"
|
|
||||||
size="small"
|
|
||||||
>
|
|
||||||
{{ user.about }}
|
|
||||||
</ds-text>
|
|
||||||
</ds-space>
|
</ds-space>
|
||||||
</template>
|
</template>
|
||||||
</ds-card>
|
</ds-card>
|
||||||
<ds-space />
|
<ds-space/>
|
||||||
<ds-heading
|
<ds-heading tag="h3" soft style="text-align: center; margin-bottom: 10px;">Netzwerk</ds-heading>
|
||||||
tag="h3"
|
|
||||||
soft
|
|
||||||
style="text-align: center; margin-bottom: 10px;"
|
|
||||||
>
|
|
||||||
Netzwerk
|
|
||||||
</ds-heading>
|
|
||||||
<ds-card style="position: relative; height: auto;">
|
<ds-card style="position: relative; height: auto;">
|
||||||
<ds-space
|
<ds-space v-if="user.following && user.following.length" margin="x-small">
|
||||||
v-if="user.following && user.following.length"
|
<ds-text tag="h5" color="soft">Wem folgt {{ userName | truncate(15) }}?</ds-text>
|
||||||
margin="x-small"
|
|
||||||
>
|
|
||||||
<ds-text
|
|
||||||
tag="h5"
|
|
||||||
color="soft"
|
|
||||||
>
|
|
||||||
Wem folgt {{ userName | truncate(15) }}?
|
|
||||||
</ds-text>
|
|
||||||
</ds-space>
|
</ds-space>
|
||||||
<template v-if="user.following && user.following.length">
|
<template v-if="user.following && user.following.length">
|
||||||
<ds-space
|
<ds-space v-for="follow in uniq(user.following)" :key="follow.id" margin="x-small">
|
||||||
v-for="follow in uniq(user.following)"
|
|
||||||
:key="follow.id"
|
|
||||||
margin="x-small"
|
|
||||||
>
|
|
||||||
<!-- TODO: find better solution for rendering errors -->
|
<!-- TODO: find better solution for rendering errors -->
|
||||||
<no-ssr>
|
<no-ssr>
|
||||||
<user
|
<user :user="follow" :trunc="15"/>
|
||||||
:user="follow"
|
|
||||||
:trunc="15"
|
|
||||||
/>
|
|
||||||
</no-ssr>
|
</no-ssr>
|
||||||
</ds-space>
|
</ds-space>
|
||||||
<ds-space
|
<ds-space v-if="user.followingCount - user.following.length" margin="small">
|
||||||
v-if="user.followingCount - user.following.length"
|
|
||||||
margin="small"
|
|
||||||
>
|
|
||||||
<ds-text
|
<ds-text
|
||||||
size="small"
|
size="small"
|
||||||
color="softer"
|
color="softer"
|
||||||
>
|
>und {{ user.followingCount - user.following.length }} weitere</ds-text>
|
||||||
und {{ user.followingCount - user.following.length }} weitere
|
|
||||||
</ds-text>
|
|
||||||
</ds-space>
|
</ds-space>
|
||||||
</template>
|
</template>
|
||||||
<template v-else>
|
<template v-else>
|
||||||
<p style="text-align: center; opacity: .5;">
|
<p style="text-align: center; opacity: .5;">{{ userName }} folgt niemandem</p>
|
||||||
{{ userName }} folgt niemandem
|
|
||||||
</p>
|
|
||||||
</template>
|
</template>
|
||||||
</ds-card>
|
</ds-card>
|
||||||
<ds-space />
|
<ds-space/>
|
||||||
<ds-card style="position: relative; height: auto;">
|
<ds-card style="position: relative; height: auto;">
|
||||||
<ds-space
|
<ds-space v-if="user.followedBy && user.followedBy.length" margin="x-small">
|
||||||
v-if="user.followedBy && user.followedBy.length"
|
<ds-text tag="h5" color="soft">Wer folgt {{ userName | truncate(15) }}?</ds-text>
|
||||||
margin="x-small"
|
|
||||||
>
|
|
||||||
<ds-text
|
|
||||||
tag="h5"
|
|
||||||
color="soft"
|
|
||||||
>
|
|
||||||
Wer folgt {{ userName | truncate(15) }}?
|
|
||||||
</ds-text>
|
|
||||||
</ds-space>
|
</ds-space>
|
||||||
<template v-if="user.followedBy && user.followedBy.length">
|
<template v-if="user.followedBy && user.followedBy.length">
|
||||||
<ds-space
|
<ds-space v-for="follow in uniq(user.followedBy)" :key="follow.id" margin="x-small">
|
||||||
v-for="follow in uniq(user.followedBy)"
|
|
||||||
:key="follow.id"
|
|
||||||
margin="x-small"
|
|
||||||
>
|
|
||||||
<!-- TODO: find better solution for rendering errors -->
|
<!-- TODO: find better solution for rendering errors -->
|
||||||
<no-ssr>
|
<no-ssr>
|
||||||
<user
|
<user :user="follow" :trunc="15"/>
|
||||||
:user="follow"
|
|
||||||
:trunc="15"
|
|
||||||
/>
|
|
||||||
</no-ssr>
|
</no-ssr>
|
||||||
</ds-space>
|
</ds-space>
|
||||||
<ds-space
|
<ds-space v-if="user.followedByCount - user.followedBy.length" margin="small">
|
||||||
v-if="user.followedByCount - user.followedBy.length"
|
|
||||||
margin="small"
|
|
||||||
>
|
|
||||||
<ds-text
|
<ds-text
|
||||||
size="small"
|
size="small"
|
||||||
color="softer"
|
color="softer"
|
||||||
>
|
>und {{ user.followedByCount - user.followedBy.length }} weitere</ds-text>
|
||||||
und {{ user.followedByCount - user.followedBy.length }} weitere
|
|
||||||
</ds-text>
|
|
||||||
</ds-space>
|
</ds-space>
|
||||||
</template>
|
</template>
|
||||||
<template v-else>
|
<template v-else>
|
||||||
<p style="text-align: center; opacity: .5;">
|
<p style="text-align: center; opacity: .5;">niemand folgt {{ userName }}</p>
|
||||||
niemand folgt {{ userName }}
|
|
||||||
</p>
|
|
||||||
</template>
|
</template>
|
||||||
</ds-card>
|
</ds-card>
|
||||||
<ds-space
|
<ds-space v-if="user.socialMedia && user.socialMedia.length" margin="large">
|
||||||
v-if="user.socialMedia && user.socialMedia.length"
|
|
||||||
margin="large"
|
|
||||||
>
|
|
||||||
<ds-card style="position: relative; height: auto;">
|
<ds-card style="position: relative; height: auto;">
|
||||||
<ds-space margin="x-small">
|
<ds-space margin="x-small">
|
||||||
<ds-text
|
<ds-text
|
||||||
tag="h5"
|
tag="h5"
|
||||||
color="soft"
|
color="soft"
|
||||||
>
|
>{{ $t('profile.socialMedia') }} {{ user.name | truncate(15) }}?</ds-text>
|
||||||
{{ $t('profile.socialMedia') }} {{ user.name | truncate(15) }}?
|
|
||||||
</ds-text>
|
|
||||||
<template>
|
<template>
|
||||||
<ds-space
|
<ds-space v-for="link in socialMediaLinks" :key="link.username" margin="x-small">
|
||||||
v-for="link in socialMediaLinks"
|
|
||||||
:key="link.username"
|
|
||||||
margin="x-small"
|
|
||||||
>
|
|
||||||
<a :href="link.url">
|
<a :href="link.url">
|
||||||
<ds-avatar :image="link.favicon" />
|
<ds-avatar :image="link.favicon"/>
|
||||||
{{ 'link.username' }}
|
{{ 'link.username' }}
|
||||||
</a>
|
</a>
|
||||||
</ds-space>
|
</ds-space>
|
||||||
@ -237,10 +136,7 @@
|
|||||||
</ds-space>
|
</ds-space>
|
||||||
</ds-flex-item>
|
</ds-flex-item>
|
||||||
<ds-flex-item :width="{ base: '100%', sm: 3, md: 5, lg: 3 }">
|
<ds-flex-item :width="{ base: '100%', sm: 3, md: 5, lg: 3 }">
|
||||||
<ds-flex
|
<ds-flex :width="{ base: '100%' }" gutter="small">
|
||||||
:width="{ base: '100%' }"
|
|
||||||
gutter="small"
|
|
||||||
>
|
|
||||||
<ds-flex-item class="profile-top-navigation">
|
<ds-flex-item class="profile-top-navigation">
|
||||||
<ds-card class="ds-tab-nav">
|
<ds-card class="ds-tab-nav">
|
||||||
<ds-flex>
|
<ds-flex>
|
||||||
@ -249,10 +145,7 @@
|
|||||||
<!-- TODO: find better solution for rendering errors -->
|
<!-- TODO: find better solution for rendering errors -->
|
||||||
<no-ssr>
|
<no-ssr>
|
||||||
<ds-number :label="$t('common.post', null, user.contributionsCount)">
|
<ds-number :label="$t('common.post', null, user.contributionsCount)">
|
||||||
<hc-count-to
|
<hc-count-to slot="count" :end-val="user.contributionsCount"/>
|
||||||
slot="count"
|
|
||||||
:end-val="user.contributionsCount"
|
|
||||||
/>
|
|
||||||
</ds-number>
|
</ds-number>
|
||||||
</no-ssr>
|
</no-ssr>
|
||||||
</ds-space>
|
</ds-space>
|
||||||
@ -299,23 +192,16 @@
|
|||||||
:key="post.id"
|
:key="post.id"
|
||||||
:post="post"
|
:post="post"
|
||||||
:width="{ base: '100%', md: '100%', xl: '50%' }"
|
:width="{ base: '100%', md: '100%', xl: '50%' }"
|
||||||
@deletePost="deletePost(index)"
|
@deletePost="user.contributions.splice(index, 1)"
|
||||||
/>
|
/>
|
||||||
</template>
|
</template>
|
||||||
<template v-else>
|
<template v-else>
|
||||||
<ds-flex-item :width="{ base: '100%' }">
|
<ds-flex-item :width="{ base: '100%' }">
|
||||||
<hc-empty
|
<hc-empty margin="xx-large" icon="file"/>
|
||||||
margin="xx-large"
|
|
||||||
icon="file"
|
|
||||||
/>
|
|
||||||
</ds-flex-item>
|
</ds-flex-item>
|
||||||
</template>
|
</template>
|
||||||
</ds-flex>
|
</ds-flex>
|
||||||
<hc-load-more
|
<hc-load-more v-if="hasMore" :loading="$apollo.loading" @click="showMoreContributions"/>
|
||||||
v-if="hasMore"
|
|
||||||
:loading="$apollo.loading"
|
|
||||||
@click="showMoreContributions"
|
|
||||||
/>
|
|
||||||
</ds-flex-item>
|
</ds-flex-item>
|
||||||
</ds-flex>
|
</ds-flex>
|
||||||
</div>
|
</div>
|
||||||
@ -440,9 +326,6 @@ export default {
|
|||||||
fetchPolicy: 'cache-and-network',
|
fetchPolicy: 'cache-and-network',
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
deletePost(index) {
|
|
||||||
this.user.contributions.splice(index, 1)
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
apollo: {
|
apollo: {
|
||||||
User: {
|
User: {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user