main
vue 120 lines 3.12 KB
Raw
1 <template>
2 <div class="flex flex-col gap-6">
3 <template v-if="commentsList.length">
4 <AlertCommentItem
5 v-for="comment of commentsList"
6 :key="comment.id"
7 :comment
8 embedded
9 @deleted="removeComment(comment)"
10 @updated="updateComment($event)"
11 />
12 </template>
13 <template v-else>
14 <n-empty description="No comments found" class="h-48 justify-center" />
15 </template>
16 <n-spin :show="submitting">
17 <div class="comment-form mt-6 flex flex-col gap-3">
18 <div class="editor-box">
19 <n-input
20 v-model:value="commentMessage"
21 placeholder="Write a new comment..."
22 type="textarea"
23 :autosize="{
24 minRows: 3,
25 maxRows: 10
26 }"
27 />
28 </div>
29 <div class="tool-box flex justify-end gap-2">
30 <n-button secondary :disabled="submitting" @click="reset()">Reset</n-button>
31 <n-button
32 type="primary"
33 :disabled="!trimmedValue || submitting"
34 :loading="submitting"
35 @click="submit()"
36 >
37 <template #icon>
38 <Icon :name="CommentsIcon" />
39 </template>
40 Send comment
41 </n-button>
42 </div>
43 </div>
44 </n-spin>
45 </div>
46 </template>
47
48 <script setup lang="ts">
49 import type { AlertComment } from "@/types/incidentManagement/alerts.d"
50 import _trim from "lodash/trim"
51 import { NButton, NEmpty, NInput, NSpin, useMessage } from "naive-ui"
52 import { computed, ref, toRefs } from "vue"
53 import Api from "@/api"
54 import Icon from "@/components/common/Icon.vue"
55 import { useAuthStore } from "@/stores/auth"
56 import AlertCommentItem from "./AlertComment.vue"
57
58 const props = defineProps<{ comments: AlertComment[]; alertId: number }>()
59 const emit = defineEmits<{
60 (e: "updated", value: AlertComment[]): void
61 }>()
62
63 const { comments, alertId } = toRefs(props)
64
65 const CommentsIcon = "carbon:chat"
66 const commentsList = ref<AlertComment[]>(comments.value)
67 const commentMessage = ref<string | null>(null)
68 const submitting = ref(false)
69 const message = useMessage()
70 const authStore = useAuthStore()
71 const trimmedValue = computed(() => _trim(commentMessage.value || ""))
72
73 function reset() {
74 commentMessage.value = ""
75 }
76
77 function updateComment(newComment: AlertComment) {
78 const comment = commentsList.value.find(o => o.id === newComment.id)
79 if (comment) {
80 comment.created_at = newComment.created_at
81 comment.comment = newComment.comment
82 }
83 }
84
85 function removeComment(comment: AlertComment) {
86 commentsList.value.splice(
87 commentsList.value.findIndex(o => o.id === comment.id),
88 1
89 )
90 }
91
92 function submit() {
93 if (trimmedValue.value) {
94 submitting.value = true
95
96 Api.incidentManagement.alerts
97 .newAlertComment({
98 alert_id: alertId.value,
99 comment: trimmedValue.value,
100 created_at: new Date(),
101 user_name: authStore.userName
102 })
103 .then(res => {
104 if (res.data.success) {
105 reset()
106 commentsList.value.push(res.data.comment)
107 emit("updated", commentsList.value)
108 } else {
109 message.warning(res.data?.message || "An error occurred. Please try again later.")
110 }
111 })
112 .catch(err => {
113 message.error(err.response?.data?.message || "An error occurred. Please try again later.")
114 })
115 .finally(() => {
116 submitting.value = false
117 })
118 }
119 }
120 </script>