main
vue 96 lines 2.31 KB
Raw
1 <template>
2 <n-select
3 to="body"
4 :value="selectedAssignedTo"
5 :options="assignedToOptions"
6 :loading
7 size="small"
8 class="min-w-36"
9 :consistent-menu-width="false"
10 @update:value="handleAssignedToChange"
11 />
12 </template>
13
14 <script setup lang="ts">
15 import type { ApiError } from "@/types/common"
16 import { NSelect, useMessage } from "naive-ui"
17 import { onBeforeMount, ref, watch } from "vue"
18 import Api from "@/api"
19 import { getApiErrorMessage } from "@/utils"
20
21 export interface CaseAssignedUpdateSuccessPayload {
22 caseId: number
23 assignedTo: string
24 }
25
26 export interface CaseAssignedUpdateErrorPayload {
27 caseId: number
28 assignedTo: string | null
29 message: string
30 }
31
32 const props = defineProps<{
33 caseId: number
34 assignedTo: string | null
35 assignedAvailable?: string[]
36 }>()
37
38 const emit = defineEmits<{
39 success: [payload: CaseAssignedUpdateSuccessPayload]
40 error: [payload: CaseAssignedUpdateErrorPayload]
41 }>()
42
43 const message = useMessage()
44
45 const assignedToOptions = ref<{ label: string; value: string }[]>([])
46
47 const selectedAssignedTo = ref<string | null>(props.assignedTo)
48 const loading = ref(false)
49
50 watch(
51 () => props.assignedTo,
52 newAssignedTo => {
53 selectedAssignedTo.value = newAssignedTo
54 }
55 )
56
57 async function handleAssignedToChange(value: string) {
58 if (loading.value || value === selectedAssignedTo.value) return
59
60 const previousAssignedTo = selectedAssignedTo.value
61 selectedAssignedTo.value = value
62 loading.value = true
63
64 try {
65 await Api.cases.updateCaseAssignedTo(props.caseId, selectedAssignedTo.value)
66 message.success(`Assigned to updated to ${selectedAssignedTo.value}`)
67 emit("success", {
68 caseId: props.caseId,
69 assignedTo: selectedAssignedTo.value
70 })
71 } catch (err) {
72 selectedAssignedTo.value = previousAssignedTo
73 message.error(getApiErrorMessage(err as ApiError))
74 emit("error", {
75 caseId: props.caseId,
76 assignedTo: previousAssignedTo,
77 message: getApiErrorMessage(err as ApiError)
78 })
79 } finally {
80 loading.value = false
81 }
82 }
83
84 async function loadAssignedToOptions() {
85 const response = await Api.cases.getCasesFilters()
86 assignedToOptions.value = response.data.assigned_to.map(o => ({ label: o, value: o }))
87 }
88
89 onBeforeMount(() => {
90 if (props.assignedAvailable?.length) {
91 assignedToOptions.value = props.assignedAvailable.map(o => ({ label: o, value: o }))
92 } else {
93 loadAssignedToOptions()
94 }
95 })
96 </script>