Break out some of the component logic
This commit is contained in:
parent
28608831a4
commit
c2136ae1d9
|
@ -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 { Transformers, User } from '@definitions/admin';
|
||||||
|
import useSWR, { SWRConfiguration, SWRResponse } from 'swr';
|
||||||
|
import { AxiosError } from 'axios';
|
||||||
|
|
||||||
export interface UpdateUserValues {
|
export interface UpdateUserValues {
|
||||||
externalId: string;
|
externalId: string;
|
||||||
|
@ -10,6 +17,23 @@ export interface UpdateUserValues {
|
||||||
rootAdmin: boolean;
|
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> => {
|
const getUser = (id: number, include: string[] = []): Promise<User> => {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
http.get(`/api/application/users/${id}`, { params: { include: include.join(',') } })
|
http.get(`/api/application/users/${id}`, { params: { include: include.join(',') } })
|
||||||
|
@ -66,6 +90,7 @@ const deleteUser = (id: number): Promise<void> => {
|
||||||
};
|
};
|
||||||
|
|
||||||
export {
|
export {
|
||||||
|
useGetUsers,
|
||||||
getUser,
|
getUser,
|
||||||
searchUserAccounts,
|
searchUserAccounts,
|
||||||
createUser,
|
createUser,
|
||||||
|
|
|
@ -1,59 +1,19 @@
|
||||||
import React, { Fragment, useCallback, useEffect, useState } from 'react';
|
import React, { Fragment, useCallback, useEffect, useState } from 'react';
|
||||||
import http, {
|
import { QueryBuilderParams } from '@/api/http';
|
||||||
FractalPaginatedResponse,
|
|
||||||
PaginatedResult,
|
|
||||||
PaginationDataSet,
|
|
||||||
QueryBuilderParams,
|
|
||||||
toPaginatedSet,
|
|
||||||
withQueryBuilderParams,
|
|
||||||
} from '@/api/http';
|
|
||||||
import { UUID } from '@/api/definitions';
|
import { UUID } from '@/api/definitions';
|
||||||
import { Transformers, User } from '@definitions/admin';
|
import { User } from '@definitions/admin';
|
||||||
import { Transition } from '@/components/elements/transitions';
|
import { Transition } from '@/components/elements/transitions';
|
||||||
import { LockOpenIcon, PlusIcon, SupportIcon, TrashIcon } from '@heroicons/react/solid';
|
import { LockOpenIcon, PlusIcon, SupportIcon, TrashIcon } from '@heroicons/react/solid';
|
||||||
import { Button } from '@/components/elements/button/index';
|
import { Button } from '@/components/elements/button/index';
|
||||||
import { Checkbox, InputField } from '@/components/elements/inputs';
|
import { Checkbox, InputField } from '@/components/elements/inputs';
|
||||||
import UserTableRow from '@/components/admin/users/UserTableRow';
|
import UserTableRow from '@/components/admin/users/UserTableRow';
|
||||||
import useSWR, { SWRConfiguration, SWRResponse } from 'swr';
|
|
||||||
import { AxiosError } from 'axios';
|
|
||||||
import debounce from 'debounce';
|
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;
|
const filters = [ 'id', 'uuid', 'external_id', 'username', 'email' ] as const;
|
||||||
type Filters = typeof filters[number];
|
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
|
|
||||||
<span className={'font-semibold text-neutral-400'}>{end}</span> of
|
|
||||||
<span className={'font-semibold text-neutral-400'}>{pagination.total}</span> results.
|
|
||||||
</p>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</tfoot>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
const extractFiltersFromString = (str: string, params: (keyof Filters)[]): QueryBuilderParams => {
|
const extractFiltersFromString = (str: string, params: (keyof Filters)[]): QueryBuilderParams => {
|
||||||
const filters: Partial<Record<string, string[]>> = {};
|
const filters: Partial<Record<string, string[]>> = {};
|
||||||
|
|
||||||
|
@ -163,7 +123,7 @@ const UsersContainer = () => {
|
||||||
/>
|
/>
|
||||||
))}
|
))}
|
||||||
</tbody>
|
</tbody>
|
||||||
{users && <PaginationFooter span={4} pagination={users.pagination}/>}
|
{users && <TFootPaginated span={4} pagination={users.pagination}/>}
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
|
@ -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
|
||||||
|
<span className={'font-semibold text-neutral-400'}>{end}</span> of
|
||||||
|
<span className={'font-semibold text-neutral-400'}>{pagination.total}</span> results.
|
||||||
|
</p>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tfoot>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default TFootPaginated;
|
Loading…
Reference in New Issue