main
vue 148 lines 4 KB
Raw
1 <template>
2 <div class="flex items-center gap-2">
3 <n-date-picker
4 v-model:value="selectedMonth"
5 type="month"
6 clearable
7 placeholder="All time"
8 size="small"
9 style="width: 150px"
10 />
11 <n-dropdown placement="bottom-start" trigger="click" :options="customersOptions" @select="exportCases">
12 <n-button :size :loading="exporting" secondary @click="load()">
13 <template v-if="showIcon" #icon>
14 <Icon :name="DownloadIcon" :size="14" />
15 </template>
16 Export
17 </n-button>
18 </n-dropdown>
19 </div>
20 </template>
21
22 <script setup lang="ts">
23 import type { ButtonSize } from "naive-ui"
24 import type { DropdownMixedOption } from "naive-ui/es/dropdown/src/interface"
25 import type { Ref } from "vue"
26 import type { Customer } from "@/types/customers.d"
27 import { useWindowSize } from "@vueuse/core"
28 import { saveAs } from "file-saver"
29 import { NButton, NDatePicker, NDropdown, useMessage } from "naive-ui"
30 import { computed, h, inject, ref } from "vue"
31 import Api from "@/api"
32 import Icon from "@/components/common/Icon.vue"
33 import { useSettingsStore } from "@/stores/settings"
34 import { formatDate } from "@/utils/format"
35
36 const { size, showIcon } = defineProps<{ size?: ButtonSize; showIcon?: boolean }>()
37
38 const DownloadIcon = "carbon:cloud-download"
39 const loadingCustomersList = ref(false)
40 const dFormats = useSettingsStore().dateFormat
41 const exporting = ref(false)
42 const message = useMessage()
43 const selectedMonth = ref<number | null>(null)
44 const { width: winWidth } = useWindowSize()
45 const customersList = inject<Ref<Customer[]>>("customers-list", ref([]))
46
47 const customersOptions = computed(() => {
48 const options: DropdownMixedOption[] = [
49 {
50 label: "Export All Cases",
51 key: "--all--"
52 }
53 ]
54
55 if (winWidth.value > 550) {
56 options.push({
57 label: `Export by Customer${loadingCustomersList.value ? "..." : ""}`,
58 key: "customer",
59 disabled: loadingCustomersList.value,
60 children: loadingCustomersList.value
61 ? undefined
62 : [
63 {
64 label: () => h("div", { class: "pl-2" }, "Select a Customer"),
65 type: "group",
66 children: customersList.value.map(o => ({
67 label: `#${o.customer_code} - ${o.customer_name}`,
68 key: o.customer_code
69 }))
70 }
71 ]
72 })
73 } else {
74 options.push({
75 label: () => h("div", { class: "pl-2" }, "Select a Customer"),
76 type: "group",
77 children: customersList.value.map(o => ({
78 label: `#${o.customer_code} - ${o.customer_name}`,
79 key: o.customer_code
80 }))
81 })
82 }
83
84 return options
85 })
86
87 function exportCases(key: string) {
88 exporting.value = true
89
90 let year: number | undefined
91 let month: number | undefined
92
93 if (selectedMonth.value) {
94 const date = new Date(selectedMonth.value)
95 year = date.getFullYear()
96 month = date.getMonth() + 1
97 }
98
99 const monthSuffix = year && month ? `_${year}-${String(month).padStart(2, "0")}` : ""
100
101 const fileName =
102 key === "--all--"
103 ? `cases${monthSuffix}_${formatDate(new Date(), dFormats.datetimesec)}.csv`
104 : `cases_customer:${key}${monthSuffix}_${formatDate(new Date(), dFormats.datetimesec)}.csv`
105
106 Api.incidentManagement.cases
107 .exportCases(key === "--all--" ? undefined : key, year, month)
108 .then(res => {
109 if (res.data) {
110 saveAs(new Blob([res.data], { type: "text/csv;charset=utf-8" }), fileName)
111 } else {
112 message.warning("An error occurred. Please try again later.")
113 }
114 })
115 .catch(err => {
116 message.error(err.response?.data?.message || "An error occurred. Please try again later.")
117 })
118 .finally(() => {
119 exporting.value = false
120 })
121 }
122
123 function getCustomers() {
124 loadingCustomersList.value = true
125
126 Api.customers
127 .getCustomers()
128 .then(res => {
129 if (res.data.success) {
130 customersList.value = res.data?.customers || []
131 } else {
132 message.warning(res.data?.message || "An error occurred. Please try again later.")
133 }
134 })
135 .catch(err => {
136 message.error(err.response?.data?.message || "An error occurred. Please try again later.")
137 })
138 .finally(() => {
139 loadingCustomersList.value = false
140 })
141 }
142
143 function load() {
144 if (!customersList.value.length) {
145 getCustomers()
146 }
147 }
148 </script>