Skip to content

Commit

Permalink
Refactor comment drawer into modal (halo-dev/console#463)
Browse files Browse the repository at this point in the history
* refactor: target comment list modal

* feat: support create comment

* refactor: modal title

* feat: support switch target

* feat: support publish and reply
  • Loading branch information
ruibaby authored Feb 24, 2022
1 parent 0f60183 commit e8248c8
Show file tree
Hide file tree
Showing 8 changed files with 511 additions and 372 deletions.
119 changes: 119 additions & 0 deletions src/components/Comment/CommentReplyModal.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
<template>
<a-modal v-model="modalVisible" destroyOnClose title="评论回复" @close="onClose">
<template #footer>
<ReactiveButton
:errored="submitErrored"
:loading="submitting"
erroredText="回复失败"
loadedText="回复成功"
text="回复"
type="primary"
@callback="handleSubmitCallback"
@click="handleSubmit"
></ReactiveButton>
</template>
<a-form-model ref="replyCommentForm" :model="model" :rules="rules" layout="vertical">
<a-form-model-item prop="content">
<a-input ref="contentInput" v-model="model.content" :autoSize="{ minRows: 8 }" type="textarea" />
</a-form-model-item>
</a-form-model>
</a-modal>
</template>
<script>
import apiClient from '@/utils/api-client'
export default {
name: 'CommentReplyModal',
props: {
visible: {
type: Boolean,
default: true
},
comment: {
type: Object,
default: null
},
targetId: {
type: Number,
default: 0
},
target: {
type: String,
required: true,
validator: value => {
return ['post', 'sheet', 'journal'].indexOf(value) !== -1
}
}
},
data() {
return {
model: {},
submitting: false,
submitErrored: false,
rules: {
content: [{ required: true, message: '* 内容不能为空', trigger: ['change'] }]
}
}
},
computed: {
modalVisible: {
get() {
return this.visible
},
set(value) {
this.$emit('update:visible', value)
}
}
},
watch: {
modalVisible(value) {
if (value) {
this.$nextTick(() => {
this.$refs.contentInput.focus()
})
}
}
},
methods: {
handleSubmit() {
const _this = this
_this.$refs.replyCommentForm.validate(async valid => {
if (valid) {
try {
_this.submitting = true
_this.model.postId = _this.targetId
if (_this.comment) {
_this.model.parentId = _this.comment.id
}
await apiClient.comment.create(`${_this.target}s`, _this.model)
} catch (e) {
_this.submitErrored = true
} finally {
setTimeout(() => {
_this.submitting = false
}, 400)
}
}
})
},
handleSubmitCallback() {
if (this.submitErrored) {
this.submitErrored = false
} else {
this.model = {}
this.modalVisible = false
this.$emit('succeed')
}
},
onClose() {
this.model = {}
this.modalVisible = false
}
}
}
</script>
157 changes: 157 additions & 0 deletions src/components/Comment/TargetCommentListModal.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,157 @@
<template>
<a-modal v-model="modalVisible" :afterClose="onClose" :title="title" :width="1024" destroyOnClose>
<a-spin :spinning="list.loading">
<TargetCommentTreeNode
v-for="(comment, index) in list.data"
:key="index"
:comment="comment"
:target="target"
:target-id="targetId"
@reload="handleGetComments"
/>
</a-spin>

<a-empty v-if="!list.loading && !list.data.length" />

<div class="page-wrapper">
<a-pagination
:current="pagination.page"
:defaultPageSize="pagination.size"
:pageSizeOptions="['10', '20', '50', '100']"
:total="pagination.total"
class="pagination"
showLessItems
showSizeChanger
@change="handlePageChange"
@showSizeChange="handlePageSizeChange"
/>
</div>

<template #footer>
<slot name="extraFooter" />
<a-button type="primary" @click="replyModalVisible = true">创建评论</a-button>
<a-button @click="modalVisible = false">关闭</a-button>
</template>

<CommentReplyModal
:target="target"
:target-id="targetId"
:visible.sync="replyModalVisible"
@succeed="handleGetComments"
/>
</a-modal>
</template>
<script>
// components
import TargetCommentTreeNode from './TargetCommentTreeNode'
import CommentReplyModal from './CommentReplyModal'
import apiClient from '@/utils/api-client'
export default {
name: 'TargetCommentListModal',
components: {
TargetCommentTreeNode,
CommentReplyModal
},
props: {
visible: {
type: Boolean,
default: true
},
title: {
type: String,
default: '评论'
},
target: {
type: String,
required: true,
validator: value => {
return ['post', 'sheet', 'journal'].indexOf(value) !== -1
}
},
targetId: {
type: Number,
required: true,
default: 0
}
},
data() {
return {
list: {
data: [],
loading: false,
params: {
page: 0,
size: 10
},
total: 0
},
replyModalVisible: false
}
},
computed: {
modalVisible: {
get() {
return this.visible
},
set(value) {
this.$emit('update:visible', value)
}
},
pagination() {
return {
page: this.list.params.page + 1,
size: this.list.params.size,
total: this.list.total
}
}
},
watch: {
modalVisible(value) {
if (value) {
this.handleGetComments()
}
},
targetId() {
this.handleGetComments()
}
},
methods: {
async handleGetComments() {
try {
this.list.loading = true
const response = await apiClient.comment.listAsTreeView(`${this.target}s`, this.targetId, this.list.params)
this.list.data = response.data.content
this.list.total = response.data.total
} catch (e) {
this.$log.error('Failed to get target comments', e)
} finally {
this.list.loading = false
}
},
/**
* Handle page change
*/
handlePageChange(page = 1) {
this.list.params.page = page - 1
this.handleGetComments()
},
/**
* Handle page size change
*/
handlePageSizeChange(current, size) {
this.list.params.page = 0
this.list.params.size = size
this.handleGetComments()
},
onClose() {
this.$emit('close')
}
}
}
</script>
Loading

0 comments on commit e8248c8

Please sign in to comment.