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