37
common/resources/client/datatable/requests/delete-selected-rows.ts
Executable file
37
common/resources/client/datatable/requests/delete-selected-rows.ts
Executable file
@@ -0,0 +1,37 @@
|
||||
import {useMutation} from '@tanstack/react-query';
|
||||
import {apiClient, queryClient} from '../../http/query-client';
|
||||
import {BackendResponse} from '../../http/backend-response/backend-response';
|
||||
import {toast} from '../../ui/toast/toast';
|
||||
import {DatatableDataQueryKey} from './paginated-resources';
|
||||
import {useDataTable} from '../page/data-table-context';
|
||||
import {message} from '../../i18n/message';
|
||||
import {showHttpErrorToast} from '../../utils/http/show-http-error-toast';
|
||||
import {Key} from 'react';
|
||||
|
||||
interface Response extends BackendResponse {
|
||||
//
|
||||
}
|
||||
|
||||
export function useDeleteSelectedRows() {
|
||||
const {endpoint, selectedRows, setSelectedRows} = useDataTable();
|
||||
return useMutation({
|
||||
mutationFn: () => deleteSelectedRows(endpoint, selectedRows),
|
||||
onSuccess: async () => {
|
||||
await queryClient.invalidateQueries({
|
||||
queryKey: DatatableDataQueryKey(endpoint),
|
||||
});
|
||||
toast(
|
||||
message('Deleted [one 1 record|other :count records]', {
|
||||
values: {count: selectedRows.length},
|
||||
}),
|
||||
);
|
||||
setSelectedRows([]);
|
||||
},
|
||||
onError: err =>
|
||||
showHttpErrorToast(err, message('Could not delete records')),
|
||||
});
|
||||
}
|
||||
|
||||
function deleteSelectedRows(endpoint: string, ids: Key[]): Promise<Response> {
|
||||
return apiClient.delete(`${endpoint}/${ids.join(',')}`).then(r => r.data);
|
||||
}
|
||||
73
common/resources/client/datatable/requests/paginated-resources.ts
Executable file
73
common/resources/client/datatable/requests/paginated-resources.ts
Executable file
@@ -0,0 +1,73 @@
|
||||
import {
|
||||
keepPreviousData,
|
||||
useQuery,
|
||||
UseQueryOptions,
|
||||
} from '@tanstack/react-query';
|
||||
import {PaginatedBackendResponse} from '../../http/backend-response/pagination-response';
|
||||
import {apiClient} from '../../http/query-client';
|
||||
|
||||
export interface GetDatatableDataParams {
|
||||
orderBy?: string;
|
||||
orderDir?: 'asc' | 'desc';
|
||||
filters?: string | null;
|
||||
query?: string;
|
||||
with?: string;
|
||||
perPage?: number | string | null;
|
||||
page?: number | string;
|
||||
paginate?: 'simple' | 'lengthAware' | 'cursor';
|
||||
[key: string]: string | number | boolean | undefined | null;
|
||||
}
|
||||
|
||||
export const DatatableDataQueryKey = (
|
||||
endpoint: string,
|
||||
params?: GetDatatableDataParams | Record<string, string | number | boolean>,
|
||||
) => {
|
||||
// split endpoint by slash, so we can clear cache from the root later,
|
||||
// for example, 'link-group' will clear 'link-group/1/links' endpoint
|
||||
const key: (string | GetDatatableDataParams)[] = endpoint.split('/');
|
||||
if (params) {
|
||||
key.push(params);
|
||||
}
|
||||
return key;
|
||||
};
|
||||
|
||||
export function useDatatableData<T = object>(
|
||||
endpoint: string,
|
||||
params: GetDatatableDataParams,
|
||||
options?: Omit<
|
||||
UseQueryOptions<
|
||||
PaginatedBackendResponse<T>,
|
||||
unknown,
|
||||
PaginatedBackendResponse<T>,
|
||||
any[]
|
||||
>,
|
||||
'queryKey' | 'queryFn'
|
||||
>,
|
||||
onLoad?: (data: PaginatedBackendResponse<T>) => void,
|
||||
) {
|
||||
if (!params.paginate) {
|
||||
params.paginate = 'simple';
|
||||
}
|
||||
return useQuery({
|
||||
queryKey: DatatableDataQueryKey(endpoint, params),
|
||||
queryFn: ({signal}) => paginate<T>(endpoint, params, onLoad, signal),
|
||||
placeholderData: keepPreviousData,
|
||||
...options,
|
||||
});
|
||||
}
|
||||
|
||||
async function paginate<T>(
|
||||
endpoint: string,
|
||||
params: GetDatatableDataParams,
|
||||
onLoad?: (data: PaginatedBackendResponse<T>) => void,
|
||||
signal?: AbortSignal,
|
||||
): Promise<PaginatedBackendResponse<T>> {
|
||||
if (params.query) {
|
||||
await new Promise(resolve => setTimeout(resolve, 300));
|
||||
}
|
||||
const response = await apiClient
|
||||
.get(endpoint, {params, signal: params.query ? signal : undefined})
|
||||
.then(response => response.data);
|
||||
onLoad?.(response);
|
||||
return response;
|
||||
}
|
||||
25
common/resources/client/datatable/requests/use-export-csv.ts
Executable file
25
common/resources/client/datatable/requests/use-export-csv.ts
Executable file
@@ -0,0 +1,25 @@
|
||||
import {apiClient} from '../../http/query-client';
|
||||
import {BackendResponse} from '../../http/backend-response/backend-response';
|
||||
import {useMutation} from '@tanstack/react-query';
|
||||
import {showHttpErrorToast} from '../../utils/http/show-http-error-toast';
|
||||
|
||||
interface Response extends BackendResponse {
|
||||
downloadPath?: string;
|
||||
result?: 'jobQueued';
|
||||
}
|
||||
|
||||
export type ExportCsvPayload = Record<string, string | number | undefined>;
|
||||
|
||||
export function useExportCsv(endpoint: string) {
|
||||
return useMutation({
|
||||
mutationFn: (payload?: ExportCsvPayload) => exportCsv(endpoint, payload),
|
||||
onError: err => showHttpErrorToast(err),
|
||||
});
|
||||
}
|
||||
|
||||
function exportCsv(
|
||||
endpoint: string,
|
||||
payload: ExportCsvPayload | undefined,
|
||||
): Promise<Response> {
|
||||
return apiClient.post(endpoint, payload).then(r => r.data);
|
||||
}
|
||||
Reference in New Issue
Block a user