-
-
Notifications
You must be signed in to change notification settings - Fork 5.3k
/
Copy pathContactList.tsx
109 lines (97 loc) · 3.14 KB
/
ContactList.tsx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
/* eslint-disable import/no-anonymous-default-export */
import { Card, Stack } from '@mui/material';
import jsonExport from 'jsonexport/dist';
import type { Exporter } from 'react-admin';
import {
BulkActionsToolbar,
BulkDeleteButton,
BulkExportButton,
CreateButton,
downloadCSV,
ExportButton,
ListBase,
ListToolbar,
Pagination,
SortButton,
Title,
TopToolbar,
useGetIdentity,
useListContext,
} from 'react-admin';
import { Company, Contact, Sale, Tag } from '../types';
import { ContactEmpty } from './ContactEmpty';
import { ContactImportButton } from './ContactImportButton';
import { ContactListContent } from './ContactListContent';
import { ContactListFilter } from './ContactListFilter';
export const ContactList = () => {
const { identity } = useGetIdentity();
if (!identity) return null;
return (
<ListBase
perPage={25}
sort={{ field: 'last_seen', order: 'DESC' }}
exporter={exporter}
>
<ContactListLayout />
</ListBase>
);
};
const ContactListLayout = () => {
const { data, isPending, filterValues } = useListContext();
const { identity } = useGetIdentity();
const hasFilters = filterValues && Object.keys(filterValues).length > 0;
if (!identity || isPending) return null;
if (!data?.length && !hasFilters) return <ContactEmpty />;
return (
<Stack direction="row">
<ContactListFilter />
<Stack sx={{ width: '100%' }}>
<Title title={'Contacts'} />
<ListToolbar actions={<ContactListActions />} />
<BulkActionsToolbar>
<BulkExportButton />
<BulkDeleteButton />
</BulkActionsToolbar>
<Card>
<ContactListContent />
</Card>
<Pagination rowsPerPageOptions={[10, 25, 50, 100]} />
</Stack>
</Stack>
);
};
const ContactListActions = () => (
<TopToolbar>
<SortButton fields={['last_name', 'first_name', 'last_seen']} />
<ContactImportButton />
<ExportButton />
<CreateButton
variant="contained"
label="New Contact"
sx={{ marginLeft: 2 }}
/>
</TopToolbar>
);
const exporter: Exporter<Contact> = async (records, fetchRelatedRecords) => {
const companies = await fetchRelatedRecords<Company>(
records,
'company_id',
'companies'
);
const sales = await fetchRelatedRecords<Sale>(records, 'sales_id', 'sales');
const tags = await fetchRelatedRecords<Tag>(records, 'tags', 'tags');
const contacts = records.map(contact => ({
...contact,
company:
contact.company_id != null
? companies[contact.company_id].name
: undefined,
sales: `${sales[contact.sales_id].first_name} ${
sales[contact.sales_id].last_name
}`,
tags: contact.tags.map(tagId => tags[tagId].name).join(', '),
}));
return jsonExport(contacts, {}, (_err: any, csv: string) => {
downloadCSV(csv, 'contacts');
});
};