mirror of
https://github.com/luxfi/explore.git
synced 2026-09-24 00:28:18 +00:00
166 lines
5.3 KiB
TypeScript
166 lines
5.3 KiB
TypeScript
import { useRouter } from 'next/router';
|
|
import React from 'react';
|
|
|
|
import type { AddressMudRecordsFilter, AddressMudRecordsSorting } from 'types/api/address';
|
|
|
|
import useIsMobile from 'lib/hooks/useIsMobile';
|
|
import { cn } from 'lib/utils/cn';
|
|
import getQueryParamString from 'lib/router/getQueryParamString';
|
|
import { Tag } from '@luxfi/ui/tag';
|
|
import { ContentLoader } from 'toolkit/components/loaders/ContentLoader';
|
|
import ActionBar, { ACTION_BAR_HEIGHT_DESKTOP } from 'ui/shared/ActionBar';
|
|
import DataListDisplay from 'ui/shared/DataListDisplay';
|
|
import Pagination from 'ui/shared/pagination/Pagination';
|
|
import useQueryWithPages from 'ui/shared/pagination/useQueryWithPages';
|
|
import { getNextOrderValue } from 'ui/shared/sort/getNextSortValue';
|
|
import getSortParamsFromQuery from 'ui/shared/sort/getSortParamsFromQuery';
|
|
|
|
import AddressMudBreadcrumbs from './AddressMudBreadcrumbs';
|
|
import AddressMudRecordsTable from './AddressMudRecordsTable';
|
|
import { getNameTypeText, SORT_SEQUENCE } from './utils';
|
|
|
|
const BREADCRUMBS_HEIGHT = 60;
|
|
const FILTERS_HEIGHT = 44;
|
|
|
|
type Props = {
|
|
isQueryEnabled?: boolean;
|
|
tableId: string;
|
|
};
|
|
|
|
type FilterKeys = keyof AddressMudRecordsFilter;
|
|
|
|
const AddressMudTable = ({ tableId, isQueryEnabled = true }: Props) => {
|
|
const router = useRouter();
|
|
const [ sorting, setSorting ] =
|
|
React.useState<AddressMudRecordsSorting | undefined>(getSortParamsFromQuery<AddressMudRecordsSorting>(router.query, SORT_SEQUENCE));
|
|
const [ filters, setFilters ] = React.useState<AddressMudRecordsFilter>({});
|
|
const isMobile = useIsMobile();
|
|
const [ tableHasHorizontalScroll, setTableHasHorizontalScroll ] = React.useState(isMobile);
|
|
|
|
const hash = getQueryParamString(router.query.hash);
|
|
|
|
const { data, isLoading, isError, pagination, onSortingChange } = useQueryWithPages({
|
|
resourceName: 'general:mud_records',
|
|
pathParams: { hash, table_id: tableId },
|
|
filters,
|
|
sorting,
|
|
options: {
|
|
// no placeholder data because the structure of a table is unpredictable
|
|
enabled: isQueryEnabled,
|
|
},
|
|
});
|
|
|
|
const handleTableHasHorizontalScroll = React.useCallback(() => {
|
|
setTableHasHorizontalScroll((prev) => !prev);
|
|
}, []);
|
|
|
|
const toggleSorting = React.useCallback((val: AddressMudRecordsSorting['sort']) => {
|
|
const newSorting = { sort: val, order: getNextOrderValue(sorting?.sort === val ? sorting.order : undefined) };
|
|
setSorting(newSorting);
|
|
onSortingChange(newSorting);
|
|
}, [ onSortingChange, sorting ]);
|
|
|
|
const onRemoveFilterClick = React.useCallback((key: FilterKeys) => () => {
|
|
setFilters(prev => {
|
|
const newFilters = { ...prev };
|
|
delete newFilters[key];
|
|
return newFilters;
|
|
});
|
|
}, []);
|
|
|
|
const hasActiveFilters = Object.values(filters).some(Boolean);
|
|
|
|
const actionBarHeight = React.useMemo(() => {
|
|
const heightWithoutFilters = pagination.isVisible ? ACTION_BAR_HEIGHT_DESKTOP : BREADCRUMBS_HEIGHT;
|
|
|
|
return hasActiveFilters ? heightWithoutFilters + FILTERS_HEIGHT : heightWithoutFilters;
|
|
}, [ pagination.isVisible, hasActiveFilters ]);
|
|
|
|
if (isLoading) {
|
|
return <ContentLoader/>;
|
|
}
|
|
|
|
const filtersTags = hasActiveFilters ? (
|
|
<div className="flex flex-row flex-wrap gap-3 mb-1">
|
|
{ Object.entries(filters).map(([ key, value ]) => {
|
|
const index = key as FilterKeys === 'filter_key0' ? 0 : 1;
|
|
return (
|
|
<Tag
|
|
key={ key }
|
|
variant="filter"
|
|
label={ getNameTypeText(data?.schema.key_names[index] || '', data?.schema.key_types[index] || '') }
|
|
closable
|
|
onClose={ onRemoveFilterClick(key as FilterKeys) }
|
|
className="max-w-[360px]"
|
|
>
|
|
{ value }
|
|
</Tag>
|
|
);
|
|
}) }
|
|
</div>
|
|
) : null;
|
|
|
|
const breadcrumbs = data ? (
|
|
<AddressMudBreadcrumbs
|
|
hash={ hash }
|
|
tableId={ tableId }
|
|
tableName={ data?.table.table_full_name }
|
|
|
|
/>
|
|
) : null;
|
|
|
|
const actionBar = (!isMobile || hasActiveFilters || pagination.isVisible) && (
|
|
<ActionBar className={ cn('-mt-6 justify-between', hasActiveFilters ? 'items-start' : 'items-center') } showShadow={ tableHasHorizontalScroll }>
|
|
<div>
|
|
{ !isMobile && breadcrumbs }
|
|
{ filtersTags }
|
|
</div>
|
|
<Pagination className="lg:ml-8" { ...pagination }/>
|
|
</ActionBar>
|
|
);
|
|
|
|
const content = data?.items ? (
|
|
<AddressMudRecordsTable
|
|
data={ data }
|
|
top={ actionBarHeight }
|
|
sorting={ sorting }
|
|
toggleSorting={ toggleSorting }
|
|
setFilters={ setFilters }
|
|
filters={ filters }
|
|
toggleTableHasHorizontalScroll={ handleTableHasHorizontalScroll }
|
|
hash={ hash }
|
|
/>
|
|
) : null;
|
|
|
|
const emptyText = (
|
|
<>
|
|
<span>There are no records for </span>
|
|
{ data?.table.table_full_name ? <span className="font-semibold">{ data?.table.table_full_name }</span> : 'this table' }
|
|
</>
|
|
);
|
|
|
|
return (
|
|
<>
|
|
{ isMobile && (
|
|
<div className="mb-6">{ breadcrumbs }</div>
|
|
) }
|
|
<DataListDisplay
|
|
isError={ isError }
|
|
itemsNum={ data?.items.length }
|
|
emptyText={ emptyText }
|
|
hasActiveFilters={ hasActiveFilters }
|
|
emptyStateProps={{
|
|
term: 'record',
|
|
}}
|
|
actionBar={ actionBar }
|
|
showActionBarIfEmpty={ !isMobile }
|
|
className={ data?.items.length ? 'mt-0' : 'mt-2' }
|
|
>
|
|
{ content }
|
|
</DataListDisplay>
|
|
</>
|
|
);
|
|
};
|
|
|
|
export default AddressMudTable;
|