1
2import {
3 Accordion,
4 Box,
5 HStack,
6 Table,
7 TableProps,
8 Tbody,
9 Td,
10 Th,
11 Thead,
12 Tr,
13 useBreakpointValue,
14} from '@chakra-ui/react';
15
16import classNames from 'classnames';
17import { FC, useState, } from 'react';
18import { useTranslation } from 'react-i18next';
19import {
20 EmptySection,
21 handleSort,
22 Pagination,
23 Sort
24} from 'components/table';
25import { useServices } from 'stores';
26import { pageSizeManagers } from 'utils/userPreferenceStorage';
27
28type ExpandedIndex = number | number[];
29type ServicesTableProps = {} & TableProps;
30
31export const ServicesTable: FC<ServicesTableProps> = (props) => {
32 const {
33 servicesFilters: filters,
34 services,
35 onEditingService,
36 onCreateService,
37 onFilterChange,
38 } = useServices();
39 const useTable = useBreakpointValue({ base: false, md: true });
40 const { t } = useTranslation();
41 const [selectedRow,] = useState<ExpandedIndex | undefined>(
42 undefined
43 );
44
45 return (
46 <Box id="services-table" h="45vh" overflowX={{ base: 'unset', md: 'unset' }} >
47 <Accordion
48 allowMultiple
49 display={{ base: 'block', md: 'none' }}
50 index={selectedRow}
51 >
52 <Table orientation="vertical" zIndex="docked" {...props}>
53 <Thead zIndex="docked" position="relative">
54 <Tr>
55 <Tr>
56 <Th
57 position="sticky"
58 minW="200px"
59 pl={4}
60 pr={4}
61 cursor={'pointer'}
62 onClick={handleSort.bind(null, filters, 'name', onFilterChange)}
63 >
64 <HStack>
65 <span>{t('services')}</span>
66 <Sort sort={filters.sort} column="name" />
67 </HStack>
68 </Th>
69 <Th
70 position="sticky"
71 minW="50px"
72 cursor={'pointer'}
73 pr={0}
74 onClick={handleSort.bind(null, filters, 'users_number', onFilterChange)}
75 >
76 <HStack>
77 <span>{t('servicesTable.usersNumber')}</span>
78 <Sort sort={filters.sort} column="users_number" />
79 </HStack>
80 </Th>
81 <Th
82 position="sticky"
83 minW="50px"
84 cursor={'pointer'}
85 pr={0}
86 onClick={handleSort.bind(null, filters, 'inbounds_number', onFilterChange)}
87 >
88 <HStack>
89 <span>{t('servicesTable.inboundsNumber')}</span>
90 <Sort sort={filters.sort} column="inbounds_number" />
91 </HStack>
92 </Th>
93 </Tr>
94 </Tr>
95 </Thead>
96 <Tbody>
97 {!useTable &&
98 services?.map((service, i) => {
99 return (
100 <Tr
101 cursor="pointer"
102 key={service.id}
103 className={classNames('interactive', {
104 'last-row': i === (services.length - 1),
105 })}
106 onClick={(e) => {
107 e.stopPropagation();
108 onEditingService(service);
109 }}
110 >
111 <Td borderBottom={0} minW="100px" pl={4} pr={4}>
112 {service.name}
113 </Td>
114 <Td borderBottom={0} minW="50px" pl={6} pr={6}>
115 {service.users.length}
116 </Td>
117 <Td borderBottom={0} minW="50px" pr={0}>
118 {service.inbounds.length}
119 </Td>
120 </Tr>
121 );
122 })}
123 </Tbody>
124 </Table>
125 </Accordion>
126 <Table orientation="vertical" zIndex="docked" {...props}>
127 <Thead zIndex="docked" position="relative">
128 <Tr>
129 <Th
130 position="sticky"
131 minW="200px"
132 pl={4}
133 pr={4}
134 cursor={'pointer'}
135 onClick={handleSort.bind(null, filters, 'name', onFilterChange)}
136 >
137 <HStack>
138 <span>{t('services')}</span>
139 <Sort sort={filters.sort} column="name" />
140 </HStack>
141 </Th>
142 <Th
143 position="sticky"
144 minW="50px"
145 cursor={'pointer'}
146 pr={0}
147 onClick={handleSort.bind(null, filters, 'users_number', onFilterChange)}
148 >
149 <HStack>
150 <span>{t('servicesTable.usersNumber')}</span>
151 <Sort sort={filters.sort} column="users_number" />
152 </HStack>
153 </Th>
154 <Th
155 position="sticky"
156 minW="50px"
157 cursor={'pointer'}
158 pr={0}
159 onClick={handleSort.bind(null, filters, 'inbounds_number', onFilterChange)}
160 >
161 <HStack>
162 <span>{t('servicesTable.inboundsNumber')}</span>
163 <Sort sort={filters.sort} column="inbounds_number" />
164 </HStack>
165 </Th>
166 </Tr>
167 </Thead>
168 <Tbody>
169 {useTable &&
170 services?.map((service, i) => {
171 return (
172 <Tr
173 cursor="pointer"
174 key={service.id}
175 className={classNames('interactive', {
176 'last-row': i === (services.length - 1),
177 })}
178 onClick={(e) => {
179 e.stopPropagation();
180 onEditingService(service);
181 }}
182 >
183 <Td borderBottom={0} minW="100px" pl={4} pr={4}>
184 {service.name}
185 </Td>
186 <Td borderBottom={0} minW="50px" pl={6} pr={6}>
187 {service.users.length}
188 </Td>
189 <Td borderBottom={0} minW="50px" pr={0}>
190 {service.inbounds.length}
191 </Td>
192 </Tr>
193 );
194 })}
195 {services.length == 0 && (
196 <Tr>
197 <Td colSpan={3}>
198 <EmptySection
199 isFiltered={false}
200 createObjectT='createService'
201 onCreateObject={onCreateService}
202 noObjectT="servicesTable.noService"
203 noObjectMatchedT='servicesTable.noServiceMatched'
204 />
205 </Td>
206 </Tr>
207 )}
208 </Tbody>
209 </Table>
210 <Pagination
211 total={services.length}
212 onFilterChange={onFilterChange}
213 filters={filters}
214 pageSizeManager={pageSizeManagers.services}
215 />
216 </Box>
217 );
218};