1<template>
2 <div class="rounded-5 border px-2 border-outline-gray-2 text-sm">
3 <div
4 class="grid p-2 px-4 items-center gap-2"
5 :style="{
6 gridTemplateColumns: '1fr 4fr 22px',
7 }"
8 >
9 <div
10 v-for="column in columns"
11 :key="column.key"
12 class="text-ink-gray-5 overflow-hidden whitespace-nowrap text-ellipsis"
13 >
14 {{ column.label }}
15 </div>
16 </div>
17 <hr />
18 <div v-for="(holiday, index) in holidays" :key="holiday.name">
19 <div
20 class="grid gap-2 py-3.5 px-4 items-center"
21 :style="{ gridTemplateColumns: '1fr 4fr 22px' }"
22 >
23 <div
24 v-for="column in columns"
25 :key="column.key"
26 class="w-full overflow-hidden whitespace-nowrap text-ellipsis"
27 >
28 <input
29 v-if="column.key === 'description'"
30 :type="'text'"
31 placeholder="Description"
32 v-model="holiday[column.key]"
33 class="!bg-surface-base w-full text-base px-0 focus:!ring-0 border-none hover:bg-surface-base outline-none no-underline focus:!outline-none"
34 />
35 <div v-else>
36 {{ dayjs(holiday[column.key]).format("DD MMM YYYY") }}
37 </div>
38 </div>
39 <div class="flex justify-end">
40 <Dropdown
41 align="end"
42 :options="dropdownOptions(holiday)"
43 @update:open="(open) => open && (isConfirmingDelete = false)"
44 >
45 <Button icon="lucide-more-horizontal" variant="ghost" />
46 </Dropdown>
47 </div>
48 </div>
49 <hr v-if="index !== holidays.length - 1" />
50 </div>
51 <div v-if="holidays?.length === 0" class="text-center p-4 text-ink-gray-5">
52 No items in the list
53 </div>
54 </div>
55 <AddHolidayModal v-model="dialog" />
56</template>
57
58<script setup lang="ts">
59import { computed, ref } from "vue";
60import { ConfirmDelete, getFormattedDate } from "@/utils";
61import { holidayData } from "@/stores/holidayList";
62import AddHolidayModal from "./Modals/AddHolidayModal.vue";
63import { dayjs, Dropdown } from "frappe-ui";
64
65const isConfirmingDelete = ref(false);
66
67interface Holiday {
68 holiday_date: string | null;
69 description: string;
70 weekly_off?: number;
71}
72
73const dropdownOptions = (holiday: Holiday) => [
74 {
75 label: "Edit",
76 onClick: () => editHoliday(holiday),
77 icon: "lucide-edit",
78 },
79 ...ConfirmDelete({
80 onConfirmDelete: () => deleteHoliday(holiday),
81 isConfirmingDelete,
82 }),
83];
84
85const dialog = ref({
86 show: false,
87 holiday_date: null,
88 description: "",
89 editing: null,
90});
91
92const holidays = computed(() => {
93 return holidayData.value.holidays.filter((item) => {
94 return item.weekly_off == 0;
95 });
96});
97
98const columns = [
99 {
100 label: "Date",
101 key: "holiday_date",
102 },
103 {
104 label: "Description",
105 key: "description",
106 },
107];
108
109const editHoliday = (holiday: Holiday) => {
110 dialog.value = {
111 show: true,
112 holiday_date: holiday.holiday_date,
113 description: holiday.description,
114 editing: holiday,
115 };
116};
117
118const deleteHoliday = (holidayToDelete?: Holiday) => {
119 if (!isConfirmingDelete.value) {
120 isConfirmingDelete.value = true;
121 return;
122 }
123 const index = holidayData.value.holidays.findIndex((h: Holiday) => {
124 const holidayDate = getFormattedDate(h.holiday_date);
125 const editDate = getFormattedDate(holidayToDelete?.holiday_date);
126 return holidayDate === editDate;
127 });
128
129 holidayData.value.holidays.splice(index, 1);
130 isConfirmingDelete.value = false;
131};
132</script>
133