1<template>
2 <div class="flex flex-col">
3 <LayoutHeader>
4 <template #left-header>
5 <div class="text-lg-medium text-ink-gray-9">
6 {{ __("Contacts") }}
7 </div>
8 </template>
9 <template #right-header>
10 <Button
11 :label="__('Create')"
12 theme="gray"
13 variant="solid"
14 @click="showNewContactModal = !showNewContactModal"
15 >
16 <template #prefix>
17 <LucidePlus class="h-4 w-4" />
18 </template>
19 </Button>
20 </template>
21 </LayoutHeader>
22 <ListViewBuilder ref="listViewRef" :options="options" />
23 <NewContactDialog v-model="showNewContactModal" />
24 </div>
25</template>
26<script setup lang="ts">
27import { LayoutHeader, ListViewBuilder } from "@/components";
28import NewContactDialog from "@/components/contact/NewContactDialog.vue";
29import { PhoneIcon } from "@/components/icons";
30import { __ } from "@/translation";
31import { Avatar, usePageMeta } from "frappe-ui";
32import { computed, h, ref } from "vue";
33import LucideContact2 from "~icons/lucide/contact-2";
34import { showNewContactModal } from "./dialogState";
35
36const hasActiveFilters = computed(
37 () => Object.keys(listViewRef.value?.list?.params?.filters || {}).length > 0
38);
39const listViewRef = ref(null);
40const options = computed(() => {
41 return {
42 doctype: "Contact",
43 selectable: true,
44 showSelectBanner: true,
45 columnConfig: {
46 full_name: {
47 prefix: ({ row }) => {
48 return h(Avatar, {
49 shape: "circle",
50 image: row.image,
51 label: row.name,
52 size: "sm",
53 });
54 },
55 },
56 mobile_no: {
57 prefix: ({ row }) => (row.mobile_no ? h(PhoneIcon) : null),
58 },
59 },
60 emptyState: {
61 title: "No contacts found",
62 icon: h(LucideContact2, {
63 class: "h-10 w-10",
64 }),
65 description: hasActiveFilters.value
66 ? __(
67 "No contacts found for the applied filters. Try adjusting or clearing your filters."
68 )
69 : undefined,
70 },
71 rowRoute: {
72 name: "Contact",
73 prop: "id",
74 },
75 };
76});
77
78usePageMeta(() => {
79 return {
80 title: "Contacts",
81 };
82});
83</script>
84