feat: comments script setup (#1930)
continuous-integration/drone/push Build is passing Details

Co-authored-by: Dominik Pschenitschni <mail@celement.de>
Reviewed-on: #1930
Co-authored-by: Dominik Pschenitschni <dpschen@noreply.kolaente.de>
Co-committed-by: Dominik Pschenitschni <dpschen@noreply.kolaente.de>
This commit is contained in:
Dominik Pschenitschni 2022-05-14 14:55:17 +00:00 committed by konrad
parent 72e43b7bbf
commit 9a42713b04
1 changed files with 138 additions and 147 deletions

View File

@ -151,22 +151,19 @@
</div> </div>
</template> </template>
<script lang="ts"> <script setup lang="ts">
import {defineComponent} from 'vue' import {ref, reactive, computed, shallowReactive, watch, nextTick} from 'vue'
import {useStore} from 'vuex'
import {useI18n} from 'vue-i18n'
import AsyncEditor from '@/components/input/AsyncEditor' import Editor from '@/components/input/AsyncEditor'
import TaskCommentService from '../../../services/taskComment' import TaskCommentService from '@/services/taskComment'
import TaskCommentModel from '../../../models/taskComment' import TaskCommentModel from '@/models/taskComment'
import {uploadFile} from '@/helpers/attachments' import {uploadFile} from '@/helpers/attachments'
import {mapState} from 'vuex' import {success} from '@/message'
export default defineComponent({ const props = defineProps({
name: 'comments',
components: {
Editor: AsyncEditor,
},
props: {
taskId: { taskId: {
type: Number, type: Number,
required: true, required: true,
@ -174,69 +171,65 @@ export default defineComponent({
canWrite: { canWrite: {
default: true, default: true,
}, },
}, })
data() {
return {
comments: [],
showDeleteModal: false, const {t} = useI18n()
commentToDelete: new TaskCommentModel(), const store = useStore()
isCommentEdit: false, const comments = ref<TaskCommentModel[]>([])
commentEdit: new TaskCommentModel(),
taskCommentService: new TaskCommentService(), const showDeleteModal = ref(false)
newComment: new TaskCommentModel(), const commentToDelete = reactive(new TaskCommentModel())
editorActive: true,
saved: null, const isCommentEdit = ref(false)
saving: null, const commentEdit = reactive(new TaskCommentModel())
creating: false,
} const newComment = reactive(new TaskCommentModel())
},
watch: { const saved = ref(null)
taskId: { const saving = ref(null)
handler: 'loadComments',
immediate: true, const userAvatar = computed(() => store.state.auth.info.getAvatarUrl(48))
}, const enabled = computed(() => store.state.config.taskCommentsEnabled)
}, const actions = computed(() => {
computed: { if (!props.canWrite) {
...mapState({
userAvatar: state => state.auth.info.getAvatarUrl(48),
enabled: state => state.config.taskCommentsEnabled,
}),
actions() {
if (!this.canWrite) {
return {} return {}
} }
return Object.fromEntries(this.comments.map((c) => ([ return Object.fromEntries(comments.value.map((comment) => ([
c.id, comment.id,
[{ [{
action: () => this.toggleDelete(c.id), action: () => toggleDelete(comment.id),
title: this.$t('misc.delete'), title: t('misc.delete'),
}], }],
]))) ])))
}, })
},
methods: { function attachmentUpload(...args) {
attachmentUpload(...args) { return uploadFile(props.taskId, ...args)
return uploadFile(this.taskId, ...args) }
},
async loadComments(taskId) { const taskCommentService = shallowReactive(new TaskCommentService())
if (!this.enabled) { async function loadComments(taskId) {
if (!enabled.value) {
return return
} }
this.newComment.taskId = taskId newComment.taskId = taskId
this.commentEdit.taskId = taskId commentEdit.taskId = taskId
this.commentToDelete.taskId = taskId commentToDelete.taskId = taskId
this.comments = await this.taskCommentService.getAll({taskId}) comments.value = await taskCommentService.getAll({taskId})
}, }
async addComment() { watch(
if (this.newComment.comment === '') { () => props.taskId,
loadComments,
{immediate: true},
)
const editorActive = ref(true)
const creating = ref(false)
async function addComment() {
if (newComment.comment === '') {
return return
} }
@ -245,66 +238,64 @@ export default defineComponent({
// which made it impossible to detect change from the outside. Therefore the component would // which made it impossible to detect change from the outside. Therefore the component would
// not update if new content from the outside was made available. // not update if new content from the outside was made available.
// See https://github.com/NikulinIlya/vue-easymde/issues/3 // See https://github.com/NikulinIlya/vue-easymde/issues/3
this.editorActive = false editorActive.value = false
this.$nextTick(() => (this.editorActive = true)) nextTick(() => (editorActive.value = true))
this.creating = true creating.value = true
try { try {
const comment = await this.taskCommentService.create(this.newComment) const comment = await taskCommentService.create(newComment)
this.comments.push(comment) comments.value.push(comment)
this.newComment.comment = '' newComment.comment = ''
this.$message.success({message: this.$t('task.comment.addedSuccess')}) success({message: t('task.comment.addedSuccess')})
} finally { } finally {
this.creating = false creating.value = false
} }
}, }
toggleEdit(comment) { function toggleEdit(comment: TaskCommentModel) {
this.isCommentEdit = !this.isCommentEdit isCommentEdit.value = !isCommentEdit.value
this.commentEdit = comment Object.assign(commentEdit, comment)
}, }
toggleDelete(commentId) { function toggleDelete(commentId) {
this.showDeleteModal = !this.showDeleteModal showDeleteModal.value = !showDeleteModal.value
this.commentToDelete.id = commentId commentToDelete.id = commentId
}, }
async editComment() { async function editComment() {
if (this.commentEdit.comment === '') { if (commentEdit.comment === '') {
return return
} }
this.saving = this.commentEdit.id saving.value = commentEdit.id
this.commentEdit.taskId = this.taskId commentEdit.taskId = props.taskId
try { try {
const comment = await this.taskCommentService.update(this.commentEdit) const comment = await taskCommentService.update(commentEdit)
for (const c in this.comments) { for (const c in comments.value) {
if (this.comments[c].id === this.commentEdit.id) { if (comments.value[c].id === commentEdit.id) {
this.comments[c] = comment comments.value[c] = comment
} }
} }
this.saved = this.commentEdit.id saved.value = commentEdit.id
setTimeout(() => { setTimeout(() => {
this.saved = null saved.value = null
}, 2000) }, 2000)
} finally { } finally {
this.isCommentEdit = false isCommentEdit.value = false
this.saving = null saving.value = null
} }
}, }
async deleteComment(commentToDelete) { async function deleteComment(commentToDelete: TaskCommentModel) {
try { try {
await this.taskCommentService.delete(commentToDelete) await taskCommentService.delete(commentToDelete)
const index = this.comments.findIndex(({id}) => id === commentToDelete.id) const index = comments.value.findIndex(({id}) => id === commentToDelete.id)
this.comments.splice(index, 1) comments.value.splice(index, 1)
} finally { } finally {
this.showDeleteModal = false showDeleteModal.value = false
} }
}, }
},
})
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>