Add pagination to Hub (#844)
This commit is contained in:
parent
72fa95ea20
commit
b978b051d4
|
@ -71,23 +71,24 @@ const useDb = () => {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const searchTunes = async (search?: string) => {
|
const searchTunes = async (search: string, page: number, perPage: number) => {
|
||||||
// TODO: add pagination
|
const phrases = search.length > 0 ? search.replace(/ +(?= )/g,'').split(' ') : [];
|
||||||
const batchSide = 100;
|
|
||||||
const phrases = search ? search.replace(/ +(?= )/g,'').split(' ') : [];
|
|
||||||
const filter = phrases
|
const filter = phrases
|
||||||
.filter((phrase) => phrase.length > 1)
|
.filter((phrase) => phrase.length > 1)
|
||||||
.map((phrase) => `textSearch ~ "${phrase}"`)
|
.map((phrase) => `textSearch ~ "${phrase}"`)
|
||||||
.join(' || ');
|
.join(' || ');
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const list = await client.records.getFullList(Collections.Tunes, batchSide, {
|
const list = await client.records.getList(Collections.Tunes, page, perPage, {
|
||||||
sort: '-created',
|
sort: '-created',
|
||||||
filter,
|
filter,
|
||||||
expand: 'userProfile',
|
expand: 'userProfile',
|
||||||
});
|
});
|
||||||
|
|
||||||
return Promise.resolve(list as TunesRecordFull[]);
|
return Promise.resolve({
|
||||||
|
items: list.items as TunesRecordFull[],
|
||||||
|
totalItems: list.totalItems,
|
||||||
|
});
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
Sentry.captureException(error);
|
Sentry.captureException(error);
|
||||||
databaseGenericError(new Error(formatError(error)));
|
databaseGenericError(new Error(formatError(error)));
|
||||||
|
@ -101,7 +102,7 @@ const useDb = () => {
|
||||||
createTune: (data: TunesRecord): Promise<TunesRecordFull> => createTune(data),
|
createTune: (data: TunesRecord): Promise<TunesRecordFull> => createTune(data),
|
||||||
getTune: (tuneId: string): Promise<TunesRecordFull | null> => getTune(tuneId),
|
getTune: (tuneId: string): Promise<TunesRecordFull | null> => getTune(tuneId),
|
||||||
getIni: (tuneId: string): Promise<IniFilesRecordFull | null> => getIni(tuneId),
|
getIni: (tuneId: string): Promise<IniFilesRecordFull | null> => getIni(tuneId),
|
||||||
searchTunes: (search?: string): Promise<TunesRecordFull[]> => searchTunes(search),
|
searchTunes: (search: string, page: number, perPage: number): Promise<{ items: TunesRecordFull[]; totalItems: number }> => searchTunes(search, page, perPage),
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -3,6 +3,7 @@ import {
|
||||||
Grid,
|
Grid,
|
||||||
Input,
|
Input,
|
||||||
InputRef,
|
InputRef,
|
||||||
|
Pagination,
|
||||||
Space,
|
Space,
|
||||||
Table,
|
Table,
|
||||||
Typography,
|
Typography,
|
||||||
|
@ -49,14 +50,16 @@ const Hub = () => {
|
||||||
const [dataSource, setDataSource] = useState<{}[]>([]); // TODO: fix this type
|
const [dataSource, setDataSource] = useState<{}[]>([]); // TODO: fix this type
|
||||||
const [isLoading, setIsLoading] = useState(true);
|
const [isLoading, setIsLoading] = useState(true);
|
||||||
const [searchQuery, setSearchQuery] = useState('');
|
const [searchQuery, setSearchQuery] = useState('');
|
||||||
|
const [page, setPage] = useState(1);
|
||||||
|
const [pageSize, setPageSize] = useState(5);
|
||||||
|
const [total, setTotal] = useState(0);
|
||||||
const searchRef = useRef<InputRef | null>(null);
|
const searchRef = useRef<InputRef | null>(null);
|
||||||
|
|
||||||
const loadData = debounce(async (searchText?: string) => {
|
const loadData = debounce(async (searchText: string) => {
|
||||||
setIsLoading(true);
|
setIsLoading(true);
|
||||||
const list = await searchTunes(searchText);
|
const { items, totalItems } = await searchTunes(searchText, page, pageSize);
|
||||||
|
setTotal(totalItems);
|
||||||
// set initial list
|
const mapped = items.map((tune) => ({
|
||||||
setDataSource(list.map((tune) => ({
|
|
||||||
...tune,
|
...tune,
|
||||||
key: tune.tuneId,
|
key: tune.tuneId,
|
||||||
year: tune.year,
|
year: tune.year,
|
||||||
|
@ -65,32 +68,34 @@ const Hub = () => {
|
||||||
aspiration: aspirationMapper[tune.aspiration],
|
aspiration: aspirationMapper[tune.aspiration],
|
||||||
published: formatTime(tune.updated),
|
published: formatTime(tune.updated),
|
||||||
stars: 0,
|
stars: 0,
|
||||||
})));
|
}));
|
||||||
|
setDataSource(mapped);
|
||||||
setIsLoading(false);
|
setIsLoading(false);
|
||||||
}, 300);
|
}, 300);
|
||||||
|
|
||||||
const debounceLoadData = useCallback((value: string) => {
|
const debounceLoadData = useCallback((value: string) => {
|
||||||
setSearchQuery(value);
|
setSearchQuery(value);
|
||||||
loadData(value);
|
loadData(value);
|
||||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
const handleGlobalKeyboard = useCallback((e: KeyboardEvent) => {
|
const handleGlobalKeyboard = useCallback((e: KeyboardEvent) => {
|
||||||
if (isEscape(e)) {
|
if (isEscape(e)) {
|
||||||
setSearchQuery('');
|
setSearchQuery('');
|
||||||
loadData();
|
loadData('');
|
||||||
}
|
}
|
||||||
}, [loadData]);
|
}, [loadData]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
loadData();
|
loadData('');
|
||||||
|
|
||||||
window.addEventListener('keydown', handleGlobalKeyboard);
|
window.addEventListener('keydown', handleGlobalKeyboard);
|
||||||
|
|
||||||
// searchRef.current?.focus(); // autofocus
|
// searchRef.current?.focus(); // autofocus
|
||||||
|
|
||||||
return () => window.removeEventListener('keydown', handleGlobalKeyboard);
|
return () => window.removeEventListener('keydown', handleGlobalKeyboard);
|
||||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
}, []);
|
}, [page]);
|
||||||
|
|
||||||
const columns: ColumnsType<any> = [
|
const columns: ColumnsType<any> = [
|
||||||
{
|
{
|
||||||
|
@ -200,6 +205,19 @@ const Hub = () => {
|
||||||
scroll={xs ? undefined : { x: 1360 }}
|
scroll={xs ? undefined : { x: 1360 }}
|
||||||
pagination={false}
|
pagination={false}
|
||||||
/>
|
/>
|
||||||
|
<div style={{ textAlign: 'right' }}>
|
||||||
|
<Pagination
|
||||||
|
style={{ marginTop: 10 }}
|
||||||
|
pageSize={pageSize}
|
||||||
|
current={page}
|
||||||
|
total={total}
|
||||||
|
onChange={(newPage, newPageSize) => {
|
||||||
|
setIsLoading(true);
|
||||||
|
setPage(newPage);
|
||||||
|
setPageSize(newPageSize);
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue