1<template>
2 <div
3 class="flex items-center cursor-pointer hover:bg-surface-sidebar rounded-4"
4 >
5 <div
6 class="w-full ps-2 flex flex-col justify-center h-14"
7 @click="holidayListActiveScreen = { screen: 'view', data: data }"
8 >
9 <div class="text-base-medium text-ink-gray-7">{{ data.name }}</div>
10 <div
11 v-if="data.description && data.description.length > 0"
12 class="text-sm text-ink-gray-5 mt-1 truncate"
13 >
14 {{ data.description }}
15 </div>
16 </div>
17 <div class="flex justify-between items-center pe-2">
18 <div>
19 <Dropdown
20 align="end"
21 :options="dropdownOptions"
22 @update:open="(open) => open && (isConfirmingDelete = false)"
23 >
24 <Button icon="lucide-more-horizontal" variant="ghost" />
25 </Dropdown>
26 </div>
27 </div>
28 </div>
29 <Dialog
30 :title="__('Duplicate Holiday List')"
31 v-model:open="duplicateDialog.show"
32 >
33 <template #default>
34 <div class="flex flex-col gap-4">
35 <FormControl
36 :label="__('New Holiday List Name')"
37 type="text"
38 v-model="duplicateDialog.newName"
39 maxlength="100"
40 />
41 </div>
42 </template>
43 <template #actions>
44 <div class="flex gap-2 justify-end">
45 <Button
46 variant="subtle"
47 :label="__('Close')"
48 @click="duplicateDialog.show = false"
49 />
50 <Button variant="solid" :label="__('Duplicate')" @click="duplicate()" />
51 </div>
52 </template>
53 </Dialog>
54</template>
55<script setup lang="ts">
56import {
57 Button,
58 Dialog,
59 createResource,
60 Dropdown,
61 FormControl,
62 toast,
63} from "frappe-ui";
64import { inject, ref } from "vue";
65import { holidayListActiveScreen } from "@/stores/holidayList";
66import { ConfirmDelete } from "@/utils";
67import { __ } from "@/translation";
68import { HolidayListResourceSymbol } from "@/types";
69import { ODServiceHolidayList } from "@/types/doctypes";
70
71const props = defineProps({
72 data: {
73 type: Object,
74 required: true,
75 },
76});
77
78const holidayList = inject(HolidayListResourceSymbol);
79
80const duplicateDialog = ref({
81 show: false,
82 newName: "",
83 name: "",
84});
85
86const isConfirmingDelete = ref(false);
87
88const dropdownOptions = [
89 {
90 label: __("Duplicate"),
91 onClick: () => {
92 duplicateDialog.value = {
93 show: true,
94 newName: props.data.name + " (Copy)",
95 name: props.data.name,
96 };
97 },
98 icon: "lucide-copy",
99 },
100 ...ConfirmDelete({
101 onConfirmDelete: () => deleteHolidayList(),
102 isConfirmingDelete,
103 }),
104];
105
106const duplicate = () => {
107 createResource({
108 url: "frappe.client.get",
109 params: {
110 doctype: "OD Service Holiday List",
111 name: duplicateDialog.value.name,
112 },
113 onSuccess: (data: ODServiceHolidayList) => {
114 createResource({
115 url: "frappe.client.insert",
116 params: {
117 doc: {
118 ...data,
119 holiday_list_name: duplicateDialog.value.newName,
120 name: duplicateDialog.value.newName,
121 },
122 },
123 auto: true,
124 onSuccess(newHolidayListData: ODServiceHolidayList) {
125 holidayList?.reload();
126 toast.success(__("Holiday list duplicated successfully."));
127 duplicateDialog.value = {
128 show: false,
129 newName: "",
130 name: "",
131 };
132 setTimeout(() => {
133 holidayListActiveScreen.value = {
134 screen: "view",
135 data: newHolidayListData,
136 };
137 }, 250);
138 },
139 });
140 },
141 auto: true,
142 });
143};
144
145const deleteHolidayList = () => {
146 if (!isConfirmingDelete.value) {
147 isConfirmingDelete.value = true;
148 return;
149 }
150
151 holidayList?.delete.submit(props.data.name, {
152 onSuccess: () => {
153 toast.success(__("Holiday list deleted successfully."));
154 },
155 });
156};
157</script>
158