main
vue 111 lines 3.05 KB
Raw
1 <template>
2 <div>
3 <!-- Header: counts + actions -->
4 <div class="flex items-center justify-between gap-4">
5 <div class="flex items-center gap-3 text-sm">
6 <Badge type="splitted">
7 <template #label>Tasks</template>
8 <template #value>
9 {{ tasks.length }}
10 </template>
11 </Badge>
12 <Badge v-if="mandatoryIncomplete > 0" color="warning" type="splitted" bright>
13 <template #label>Mandatory incomplete</template>
14 <template #value>
15 {{ mandatoryIncomplete }}
16 </template>
17 </Badge>
18 <Badge v-if="totalDone > 0" color="success" type="splitted" bright>
19 <template #label>Done</template>
20 <template #value>{{ totalDone }}</template>
21 </Badge>
22 </div>
23 <div v-if="canEdit" class="flex items-center gap-2">
24 <n-button size="small" secondary @click="openApplyTemplate">
25 <template #icon>
26 <Icon :name="ApplyIcon" />
27 </template>
28 Apply template
29 </n-button>
30 <n-button size="small" type="primary" @click="openAddTask">
31 <template #icon>
32 <Icon :name="AddIcon" />
33 </template>
34 Add task
35 </n-button>
36 </div>
37 </div>
38
39 <!-- Add custom task modal -->
40 <n-modal
41 v-model:show="showAddModal"
42 preset="card"
43 display-directive="show"
44 title="Add custom task"
45 :style="{ maxWidth: 'min(600px, 90vw)', overflow: 'hidden' }"
46 >
47 <CaseTasksCreateForm :case-id :linked-alerts="linkedAlerts || []" @success="handleAddTaskSuccess" />
48 </n-modal>
49
50 <!-- Apply template modal -->
51 <n-modal
52 v-model:show="showApplyModal"
53 preset="card"
54 display-directive="show"
55 title="Apply template"
56 :style="{ maxWidth: 'min(600px, 90vw)', overflow: 'hidden' }"
57 >
58 <CaseTasksToolbarApplyTemplateForm :case-id :customer-code @success="handleApplyTemplateSuccess" />
59 </n-modal>
60 </div>
61 </template>
62
63 <script setup lang="ts">
64 import type { Alert } from "@/types/incidentManagement/alerts.d"
65 import type { CaseTask } from "@/types/incidentManagement/caseTemplates.d"
66 import { NButton, NModal } from "naive-ui"
67 import { computed, ref } from "vue"
68 import Badge from "@/components/common/Badge.vue"
69 import Icon from "@/components/common/Icon.vue"
70 import CaseTasksCreateForm from "./CaseTasksCreateForm.vue"
71 import CaseTasksToolbarApplyTemplateForm from "./CaseTasksToolbarApplyTemplateForm.vue"
72
73 const props = defineProps<{
74 caseId: number
75 customerCode?: string | null
76 canEdit: boolean
77 tasks: CaseTask[]
78 linkedAlerts?: Alert[]
79 }>()
80
81 const emit = defineEmits<{
82 (e: "updated"): void
83 }>()
84
85 const AddIcon = "carbon:add"
86 const ApplyIcon = "carbon:flow"
87
88 const totalDone = computed(() => props.tasks.filter(t => t.status === "DONE").length)
89 const mandatoryIncomplete = computed(() => props.tasks.filter(t => t.mandatory && t.status !== "DONE").length)
90
91 const showAddModal = ref(false)
92 const showApplyModal = ref(false)
93
94 function openAddTask() {
95 showAddModal.value = true
96 }
97
98 function openApplyTemplate() {
99 showApplyModal.value = true
100 }
101
102 function handleAddTaskSuccess() {
103 emit("updated")
104 showAddModal.value = false
105 }
106
107 function handleApplyTemplateSuccess() {
108 emit("updated")
109 showApplyModal.value = false
110 }
111 </script>