mirror of
https://github.com/IT4Change/Ocelot-Social.git
synced 2025-12-13 07:45:56 +00:00
refactor backend and add UI
This commit is contained in:
parent
c76e18fae3
commit
8a8ed5131e
@ -22,10 +22,29 @@ const validateUrl = async (resolve, root, args, context, info) => {
|
||||
}
|
||||
}
|
||||
|
||||
const validateComment = async (resolve, root, args, context, info) => {
|
||||
const COMMENT_MIN_LENGTH = 1
|
||||
const content = args.content.replace(/<(?:.|\n)*?>/gm, '').trim()
|
||||
if (!args.content || content.length < COMMENT_MIN_LENGTH) {
|
||||
throw new UserInputError(
|
||||
`Comment must be at least ${COMMENT_MIN_LENGTH} character long!`
|
||||
)
|
||||
}
|
||||
const NO_POST_ERR_MESSAGE = 'Comment cannot be created without a post!'
|
||||
const { postId } = args
|
||||
if (!postId) {
|
||||
throw new UserInputError(NO_POST_ERR_MESSAGE)
|
||||
}
|
||||
|
||||
return await resolve(root, args, context, info)
|
||||
}
|
||||
|
||||
export default {
|
||||
Mutation: {
|
||||
CreateUser: validateUsername,
|
||||
UpdateUser: validateUsername,
|
||||
CreateSocialMedia: validateUrl
|
||||
CreateSocialMedia: validateUrl,
|
||||
CreateComment: validateComment,
|
||||
UpdateComment: validateComment
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,13 +1,9 @@
|
||||
import { neo4jgraphql } from 'neo4j-graphql-js'
|
||||
import { UserInputError } from 'apollo-server'
|
||||
|
||||
const COMMENT_MIN_LENGTH = 1
|
||||
const NO_POST_ERR_MESSAGE = 'Comment cannot be created without a post!'
|
||||
|
||||
export default {
|
||||
Mutation: {
|
||||
CreateComment: async (object, params, context, resolveInfo) => {
|
||||
const content = params.content.replace(/<(?:.|\n)*?>/gm, '').trim()
|
||||
const { postId } = params
|
||||
// Adding relationship from comment to post by passing in the postId,
|
||||
// but we do not want to create the comment with postId as an attribute
|
||||
@ -15,15 +11,6 @@ export default {
|
||||
// before comment creation.
|
||||
delete params.postId
|
||||
|
||||
if (!params.content || content.length < COMMENT_MIN_LENGTH) {
|
||||
throw new UserInputError(
|
||||
`Comment must be at least ${COMMENT_MIN_LENGTH} character long!`
|
||||
)
|
||||
}
|
||||
if (!postId.trim()) {
|
||||
throw new UserInputError(NO_POST_ERR_MESSAGE)
|
||||
}
|
||||
|
||||
const session = context.driver.session()
|
||||
const postQueryRes = await session.run(
|
||||
`
|
||||
@ -65,38 +52,6 @@ export default {
|
||||
return comment
|
||||
},
|
||||
UpdateComment: async (object, params, context, resolveInfo) => {
|
||||
// Strip element tags and remove leading/trailing white spaces from content
|
||||
const content = params.content.replace(/<(?:.|\n)*?>/gm, '').trim()
|
||||
const { id } = params
|
||||
// Check length of content
|
||||
if (!params.content || content.length < COMMENT_MIN_LENGTH) {
|
||||
throw new UserInputError(
|
||||
`Comment must be at least ${COMMENT_MIN_LENGTH} character long!`
|
||||
)
|
||||
}
|
||||
|
||||
// Check if comment exists
|
||||
const session = context.driver.session()
|
||||
const commentQueryRes = await session.run(
|
||||
`
|
||||
MATCH (comment: Comment { id:$id})
|
||||
RETURN comment`,
|
||||
{
|
||||
id
|
||||
}
|
||||
)
|
||||
|
||||
// Destructure content from session results array
|
||||
const [comment] = commentQueryRes.records.map(record => {
|
||||
return record.get('comment')
|
||||
})
|
||||
|
||||
// Send error message if cannot find a matching comment.
|
||||
if (!comment) {
|
||||
throw new UserInputError(NO_COMMENT_ERR_MESSAGE)
|
||||
}
|
||||
|
||||
// Update comment.
|
||||
const commentRev = await neo4jgraphql(
|
||||
object,
|
||||
params,
|
||||
@ -104,20 +59,6 @@ export default {
|
||||
resolveInfo,
|
||||
false
|
||||
)
|
||||
|
||||
await session.run(
|
||||
`
|
||||
MATCH (comment: Comment { id:$id})
|
||||
SET comment.content = $content
|
||||
`,
|
||||
{
|
||||
id,
|
||||
content
|
||||
}
|
||||
)
|
||||
session.close()
|
||||
|
||||
return commentRev
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -22,15 +22,20 @@
|
||||
:resource="comment"
|
||||
style="float-right"
|
||||
:is-owner="isAuthor(author.id)"
|
||||
v-on:showEditCommentMenu="editCommentMenu"
|
||||
/>
|
||||
</no-ssr>
|
||||
<!-- eslint-disable vue/no-v-html -->
|
||||
<!-- TODO: replace editor content with tiptap render view -->
|
||||
<ds-space margin-bottom="small" />
|
||||
<div
|
||||
style="padding-left: 40px;"
|
||||
v-html="comment.contentExcerpt"
|
||||
/>
|
||||
<ds-space margin-bottom="small"/>
|
||||
<div v-if="openEditCommentMenu">
|
||||
<hc-edit-comment-form
|
||||
v-bind:comment="comment"
|
||||
v-bind:post="post"
|
||||
v-on:showEditCommentMenu="editCommentMenu"
|
||||
/>
|
||||
</div>
|
||||
<div v-else style="padding-left: 40px;" v-html="comment.contentExcerpt"/>
|
||||
<!-- eslint-enable vue/no-v-html -->
|
||||
</div>
|
||||
</template>
|
||||
@ -39,13 +44,22 @@
|
||||
import { mapGetters } from 'vuex'
|
||||
import HcUser from '~/components/User'
|
||||
import ContentMenu from '~/components/ContentMenu'
|
||||
import HcEditCommentForm from '~/components/comments/EditCommentForm'
|
||||
import gql from 'graphql-tag'
|
||||
|
||||
export default {
|
||||
components: {
|
||||
HcUser,
|
||||
ContentMenu
|
||||
ContentMenu,
|
||||
HcEditCommentForm
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
openEditCommentMenu: false
|
||||
}
|
||||
},
|
||||
props: {
|
||||
post: { type: Object, default: () => {} },
|
||||
comment: {
|
||||
type: Object,
|
||||
default() {
|
||||
@ -69,6 +83,9 @@ export default {
|
||||
methods: {
|
||||
isAuthor(id) {
|
||||
return this.user.id === id
|
||||
},
|
||||
editCommentMenu(showMenu) {
|
||||
this.openEditCommentMenu = showMenu
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -90,7 +90,7 @@ export default {
|
||||
name: this.$t(`comment.edit`),
|
||||
callback: () => {
|
||||
/* eslint-disable-next-line no-console */
|
||||
console.log('EDIT COMMENT')
|
||||
this.$emit('showEditCommentMenu', true)
|
||||
},
|
||||
icon: 'edit'
|
||||
})
|
||||
|
||||
@ -12,23 +12,11 @@
|
||||
>{{ comments.length }}</ds-tag> Comments
|
||||
</span>
|
||||
</h3>
|
||||
<ds-space margin-bottom="large" />
|
||||
<div
|
||||
v-if="comments && comments.length"
|
||||
id="comments"
|
||||
class="comments"
|
||||
>
|
||||
<comment
|
||||
v-for="comment in comments"
|
||||
:key="comment.id"
|
||||
:comment="comment"
|
||||
/>
|
||||
<ds-space margin-bottom="large"/>
|
||||
<div v-if="comments && comments.length" id="comments" class="comments">
|
||||
<comment v-for="comment in comments" :key="comment.id" :comment="comment" :post="post"/>
|
||||
</div>
|
||||
<hc-empty
|
||||
v-else
|
||||
name="empty"
|
||||
icon="messages"
|
||||
/>
|
||||
<hc-empty v-else name="empty" icon="messages"/>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
|
||||
122
webapp/components/comments/EditCommentForm/index.vue
Normal file
122
webapp/components/comments/EditCommentForm/index.vue
Normal file
@ -0,0 +1,122 @@
|
||||
<template>
|
||||
<ds-form v-model="form" @submit="handleSubmit">
|
||||
<template slot-scope="{ errors }">
|
||||
<ds-card>
|
||||
<!-- <no-ssr> -->
|
||||
<hc-editor ref="editor" :users="users" :value="form.content" @input="updateEditorContent"/>
|
||||
<!-- </no-ssr> -->
|
||||
<ds-space/>
|
||||
<ds-flex :gutter="{ base: 'small', md: 'small', sm: 'x-large', xs: 'x-large' }">
|
||||
<ds-flex-item :width="{ base: '0%', md: '50%', sm: '0%', xs: '0%' }"/>
|
||||
<ds-flex-item :width="{ base: '40%', md: '20%', sm: '30%', xs: '30%' }">
|
||||
<ds-button
|
||||
:disabled="disabled"
|
||||
ghost
|
||||
class="cancelBtn"
|
||||
@click.prevent="closeEditWindow"
|
||||
>{{ $t('actions.cancel') }}</ds-button>
|
||||
</ds-flex-item>
|
||||
<ds-flex-item :width="{ base: '40%', md: '20%', sm: '40%', xs: '40%' }">
|
||||
<ds-button
|
||||
type="submit"
|
||||
:loading="loading"
|
||||
:disabled="disabled || errors"
|
||||
primary
|
||||
>{{ $t('post.comment.submit') }}</ds-button>
|
||||
</ds-flex-item>
|
||||
</ds-flex>
|
||||
</ds-card>
|
||||
</template>
|
||||
</ds-form>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import gql from 'graphql-tag'
|
||||
import HcEditor from '~/components/Editor'
|
||||
|
||||
export default {
|
||||
components: {
|
||||
HcEditor
|
||||
},
|
||||
props: {
|
||||
post: { type: Object, default: () => {} },
|
||||
comments: { type: Array, default: () => [] },
|
||||
comment: {
|
||||
type: Object,
|
||||
default() {
|
||||
return {}
|
||||
}
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
disabled: false,
|
||||
loading: false,
|
||||
form: {
|
||||
content: this.comment.contentExcerpt
|
||||
},
|
||||
users: []
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
updateEditorContent(value) {
|
||||
const content = value.replace(/<(?:.|\n)*?>/gm, '').trim()
|
||||
if (content.length < 1) {
|
||||
this.disabled = true
|
||||
} else {
|
||||
this.disabled = false
|
||||
}
|
||||
this.form.content = value
|
||||
},
|
||||
closeEditWindow() {
|
||||
this.$emit('showEditCommentMenu', false)
|
||||
},
|
||||
handleSubmit() {
|
||||
this.loading = true
|
||||
this.disabled = true
|
||||
this.$apollo
|
||||
.mutate({
|
||||
mutation: gql`
|
||||
mutation($postId: ID, $content: String!, $id: ID!) {
|
||||
UpdateComment(postId: $postId, content: $content, id: $id) {
|
||||
id
|
||||
content
|
||||
}
|
||||
}
|
||||
`,
|
||||
variables: {
|
||||
postId: this.post.id,
|
||||
content: this.form.content,
|
||||
id: this.comment.id
|
||||
}
|
||||
})
|
||||
.then(res => {
|
||||
this.loading = false
|
||||
this.$root.$emit('refetchPostComments')
|
||||
this.$toast.success(this.$t('post.comment.submitted'))
|
||||
this.disabled = false
|
||||
this.$emit('showEditCommentMenu', false)
|
||||
})
|
||||
//@Todo close edit comment window
|
||||
.catch(err => {
|
||||
this.$toast.error(err.message)
|
||||
})
|
||||
}
|
||||
},
|
||||
apollo: {
|
||||
User: {
|
||||
query() {
|
||||
return gql(`{
|
||||
User(orderBy: slug_asc) {
|
||||
id
|
||||
slug
|
||||
}
|
||||
}`)
|
||||
},
|
||||
result(result) {
|
||||
this.users = result.data.User
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
Loading…
x
Reference in New Issue
Block a user