mirror of
https://github.com/apache/superset.git
synced 2026-05-28 11:15:24 +00:00
115 lines
3.1 KiB
TypeScript
115 lines
3.1 KiB
TypeScript
/**
|
|
* Licensed to the Apache Software Foundation (ASF) under one
|
|
* or more contributor license agreements. See the NOTICE file
|
|
* distributed with this work for additional information
|
|
* regarding copyright ownership. The ASF licenses this file
|
|
* to you under the Apache License, Version 2.0 (the
|
|
* "License"); you may not use this file except in compliance
|
|
* with the License. You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing,
|
|
* software distributed under the License is distributed on an
|
|
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
|
* KIND, either express or implied. See the License for the
|
|
* specific language governing permissions and limitations
|
|
* under the License.
|
|
*/
|
|
|
|
import { t } from '@apache-superset/core/translation';
|
|
import { SupersetClient } from '@superset-ui/core';
|
|
import rison from 'rison';
|
|
import { Dispatch, SetStateAction } from 'react';
|
|
|
|
interface FetchPaginatedOptions {
|
|
endpoint: string;
|
|
pageSize?: number;
|
|
setData: (data: any[]) => void;
|
|
setLoadingState: Dispatch<SetStateAction<any>>;
|
|
filters?: SupersetFilter[];
|
|
loadingKey: string;
|
|
addDangerToast: (message: string) => void;
|
|
errorMessage?: string;
|
|
mapResult?: (item: any) => any;
|
|
}
|
|
|
|
interface QueryObj {
|
|
page_size: number;
|
|
page: number;
|
|
filters?: SupersetFilter[];
|
|
}
|
|
|
|
interface SupersetFilter {
|
|
col: string;
|
|
opr: string;
|
|
value: string | number | (string | number)[];
|
|
}
|
|
|
|
export const fetchPaginatedData = async ({
|
|
endpoint,
|
|
pageSize = 100,
|
|
setData,
|
|
filters,
|
|
setLoadingState,
|
|
loadingKey,
|
|
addDangerToast,
|
|
errorMessage = 'Error while fetching data',
|
|
mapResult = (item: any) => item,
|
|
}: FetchPaginatedOptions) => {
|
|
try {
|
|
const fetchPage = async (pageIndex: number) => {
|
|
const queryObj: QueryObj = {
|
|
page_size: pageSize,
|
|
page: pageIndex,
|
|
};
|
|
if (filters) {
|
|
queryObj.filters = filters;
|
|
}
|
|
const encodedQuery = rison.encode(queryObj);
|
|
|
|
const response = await SupersetClient.get({
|
|
endpoint: `${endpoint}?q=${encodedQuery}`,
|
|
});
|
|
|
|
return {
|
|
count: response.json.count,
|
|
results: response.json.result.map(mapResult),
|
|
};
|
|
};
|
|
|
|
const initialResponse = await fetchPage(0);
|
|
const totalItems = initialResponse.count;
|
|
const firstPageResults = initialResponse.results;
|
|
|
|
if (pageSize >= totalItems) {
|
|
setData(firstPageResults);
|
|
return;
|
|
}
|
|
|
|
const totalPages = Math.ceil(totalItems / pageSize);
|
|
|
|
const requests = Array.from({ length: totalPages - 1 }, (_, i) =>
|
|
fetchPage(i + 1),
|
|
);
|
|
const remainingResults = await Promise.all(requests);
|
|
|
|
setData([
|
|
...firstPageResults,
|
|
...remainingResults.flatMap(res => res.results),
|
|
]);
|
|
} catch (err) {
|
|
addDangerToast(t(errorMessage));
|
|
} finally {
|
|
setLoadingState((prev: boolean | Record<string, boolean>) => {
|
|
if (typeof prev === 'boolean') {
|
|
return false;
|
|
}
|
|
return {
|
|
...prev,
|
|
[loadingKey]: false,
|
|
};
|
|
});
|
|
}
|
|
};
|