Break out some of the component logic

This commit is contained in:
Dane Everitt 2022-03-12 12:05:09 -05:00
parent 28608831a4
commit c2136ae1d9
No known key found for this signature in database
GPG Key ID: EEA66103B3D71F53
3 changed files with 54 additions and 46 deletions

View File

@ -1,5 +1,12 @@
import http, { QueryBuilderParams, withQueryBuilderParams } from '@/api/http';
import http, {
FractalPaginatedResponse,
PaginatedResult,
QueryBuilderParams, toPaginatedSet,
withQueryBuilderParams,
} from '@/api/http';
import { Transformers, User } from '@definitions/admin';
import useSWR, { SWRConfiguration, SWRResponse } from 'swr';
import { AxiosError } from 'axios';
export interface UpdateUserValues {
externalId: string;
@ -10,6 +17,23 @@ export interface UpdateUserValues {
rootAdmin: boolean;
}
const filters = [ 'id', 'uuid', 'external_id', 'username', 'email' ] as const;
type Filters = typeof filters[number];
const useGetUsers = (
params?: QueryBuilderParams<Filters>,
config?: SWRConfiguration,
): SWRResponse<PaginatedResult<User>, AxiosError> => {
return useSWR<PaginatedResult<User>>([ '/api/application/users', JSON.stringify(params) ], async () => {
const { data } = await http.get<FractalPaginatedResponse>(
'/api/application/users',
{ params: withQueryBuilderParams(params) },
);
return toPaginatedSet(data, Transformers.toUser);
}, config || { revalidateOnMount: true, revalidateOnFocus: false });
};
const getUser = (id: number, include: string[] = []): Promise<User> => {
return new Promise((resolve, reject) => {
http.get(`/api/application/users/${id}`, { params: { include: include.join(',') } })
@ -66,6 +90,7 @@ const deleteUser = (id: number): Promise<void> => {
};
export {
useGetUsers,
getUser,
searchUserAccounts,
createUser,

View File

@ -1,59 +1,19 @@
import React, { Fragment, useCallback, useEffect, useState } from 'react';
import http, {
FractalPaginatedResponse,
PaginatedResult,
PaginationDataSet,
QueryBuilderParams,
toPaginatedSet,
withQueryBuilderParams,
} from '@/api/http';
import { QueryBuilderParams } from '@/api/http';
import { UUID } from '@/api/definitions';
import { Transformers, User } from '@definitions/admin';
import { User } from '@definitions/admin';
import { Transition } from '@/components/elements/transitions';
import { LockOpenIcon, PlusIcon, SupportIcon, TrashIcon } from '@heroicons/react/solid';
import { Button } from '@/components/elements/button/index';
import { Checkbox, InputField } from '@/components/elements/inputs';
import UserTableRow from '@/components/admin/users/UserTableRow';
import useSWR, { SWRConfiguration, SWRResponse } from 'swr';
import { AxiosError } from 'axios';
import debounce from 'debounce';
import { useGetUsers } from '@/api/admin/users';
import TFootPaginated from '@/components/elements/table/TFootPaginated';
const filters = [ 'id', 'uuid', 'external_id', 'username', 'email' ] as const;
type Filters = typeof filters[number];
const useGetUsers = (
params?: QueryBuilderParams<Filters>,
config?: SWRConfiguration,
): SWRResponse<PaginatedResult<User>, AxiosError> => {
return useSWR<PaginatedResult<User>>([ '/api/application/users', JSON.stringify(params) ], async () => {
const { data } = await http.get<FractalPaginatedResponse>(
'/api/application/users',
{ params: withQueryBuilderParams(params) },
);
return toPaginatedSet(data, Transformers.toUser);
}, config || { revalidateOnMount: true, revalidateOnFocus: false });
};
const PaginationFooter = ({ pagination, span }: { span: number; pagination: PaginationDataSet }) => {
const start = (pagination.currentPage - 1) * pagination.perPage;
const end = ((pagination.currentPage - 1) * pagination.perPage) + pagination.count;
return (
<tfoot>
<tr className={'bg-neutral-800'}>
<td scope={'col'} colSpan={span} className={'px-4 py-2'}>
<p className={'text-sm text-neutral-500'}>
Showing <span className={'font-semibold text-neutral-400'}>{Math.max(start, Math.min(pagination.total, 1))}</span> to&nbsp;
<span className={'font-semibold text-neutral-400'}>{end}</span> of&nbsp;
<span className={'font-semibold text-neutral-400'}>{pagination.total}</span> results.
</p>
</td>
</tr>
</tfoot>
);
};
const extractFiltersFromString = (str: string, params: (keyof Filters)[]): QueryBuilderParams => {
const filters: Partial<Record<string, string[]>> = {};
@ -163,7 +123,7 @@ const UsersContainer = () => {
/>
))}
</tbody>
{users && <PaginationFooter span={4} pagination={users.pagination}/>}
{users && <TFootPaginated span={4} pagination={users.pagination}/>}
</table>
</div>
);

View File

@ -0,0 +1,23 @@
import React from 'react';
import { PaginationDataSet } from '@/api/http';
const TFootPaginated = ({ pagination, span }: { span: number; pagination: PaginationDataSet }) => {
const start = (pagination.currentPage - 1) * pagination.perPage;
const end = ((pagination.currentPage - 1) * pagination.perPage) + pagination.count;
return (
<tfoot>
<tr className={'bg-neutral-800'}>
<td scope={'col'} colSpan={span} className={'px-4 py-2'}>
<p className={'text-sm text-neutral-500'}>
Showing <span className={'font-semibold text-neutral-400'}>{Math.max(start, Math.min(pagination.total, 1))}</span> to&nbsp;
<span className={'font-semibold text-neutral-400'}>{end}</span> of&nbsp;
<span className={'font-semibold text-neutral-400'}>{pagination.total}</span> results.
</p>
</td>
</tr>
</tfoot>
);
};
export default TFootPaginated;