1<template>
2 <Dialog
3 v-model:open="showDialog"
4 :title="dialogTitle"
5 :actions="getActionButton()"
6 >
7 <template #default>
8 <div class="flex flex-col flex-1 gap-4">
9 <div>
10 <div class="mb-1.5 text-base text-ink-gray-5">{{ __("Name") }}</div>
11 <textarea
12 class="text-base rounded-4 py-1.5 px-2 border border-[--surface-gray-2] bg-surface-gray-2 placeholder-ink-gray-4 hover:border-outline-elevation-2 hover:bg-surface-gray-3 focus:bg-surface-base focus:border-outline-gray-4 focus:shadow-sm focus:ring-0 focus-visible:ring-2 focus-visible:ring-outline-gray-3 text-ink-gray-8 transition-colors w-full block"
13 ref="titleRef"
14 placeholder="Support Issues"
15 v-model="newTitle"
16 :rows="1"
17 maxlength="50"
18 autofocus
19 @input="(e: Event) => {
20 const target = e.target as HTMLTextAreaElement;
21 target.style.height = `${target.scrollHeight}px`;
22 }"
23 />
24 </div>
25 <div>
26 <div class="mb-1.5 text-base text-ink-gray-5">{{ __("Icon") }}</div>
27 <Combobox
28 class="w-full"
29 v-model="icon"
30 :options="iconOptions"
31 :placeholder="__('Select an icon')"
32 />
33 </div>
34 </div>
35 </template>
36 </Dialog>
37</template>
38
39<script setup lang="ts">
40import { computed } from "vue";
41import { Combobox, Dialog } from "frappe-ui";
42import { CATEGORY_ICONS } from "@opendesk/shared/categoryIcons";
43import { __ } from "@/translation";
44import { ref } from "vue";
45import { watch } from "vue";
46
47const props = defineProps({
48 title: {
49 type: String,
50 default: "",
51 },
52 edit: {
53 type: Boolean,
54 default: false,
55 },
56});
57
58const emit = defineEmits(["update", "create"]);
59
60const showDialog = defineModel<boolean>();
61const newTitle = defineModel<string>("title");
62const icon = defineModel<string>("icon");
63
64const iconOptions = CATEGORY_ICONS.map((value) => ({
65 value,
66 icon: value,
67 label: value
68 .replace("lucide-", "")
69 .replace(/-/g, " ")
70 .replace(/^\w/, (c) => c.toUpperCase()),
71}));
72
73const dialogTitle = computed(() =>
74 props.edit ? "Edit Category" : "Create Category"
75);
76
77const titleRef = ref(null);
78watch(
79 () => titleRef.value,
80 (newVal) => {
81 if (!newVal) return;
82 titleRef.value.style.height =
83 newVal.scrollHeight > newVal.clientHeight
84 ? newVal.scrollHeight + "px"
85 : newVal.scrollHeight + "px";
86 }
87);
88
89function getActionButton() {
90 const action = [];
91 if (props.edit) {
92 action.push({
93 label: "Save",
94 variant: "solid",
95 onClick: () => {
96 emit("update");
97 },
98 });
99 } else {
100 action.push({
101 label: "Create",
102 variant: "solid",
103 onClick: () => {
104 emit("create");
105 },
106 });
107 }
108 return action;
109}
110</script>
111