Files

179 lines
5.2 KiB
TypeScript

import { HStack } from '@chakra-ui/react';
import { useRouter } from 'next/router';
import React from 'react';
import CsvExport from 'client/features/csv-export/components/CsvExport';
import config from 'configs/app';
import useIsMobile from 'lib/hooks/useIsMobile';
import useIsMounted from 'lib/hooks/useIsMounted';
import getQueryParamString from 'lib/router/getQueryParamString';
import { INTERCHAIN_MESSAGE } from 'stubs/interchainIndexer';
import { generateListStub } from 'stubs/utils';
import RoutedTabs from 'toolkit/components/RoutedTabs/RoutedTabs';
import AddressTxsCrossChain from 'ui/crossChain/address/AddressTxsCrossChain';
import { ACTION_BAR_HEIGHT_DESKTOP } from 'ui/shared/ActionBar';
import Pagination from 'ui/shared/pagination/Pagination';
import useQueryWithPages from 'ui/shared/pagination/useQueryWithPages';
import TxsWithAPISorting from 'ui/txs/TxsWithAPISorting';
import AddressTxsFilter from './AddressTxsFilter';
import useAddressTxsQuery from './useAddressTxsQuery';
export const ADDRESS_TXS_TAB_IDS = [ 'txs_local' as const, 'txs_cross_chain' as const ];
const TAB_LIST_PROPS = {
marginBottom: 0,
pt: 6,
pb: 3,
marginTop: -6,
};
interface Props {
shouldRender?: boolean;
isQueryEnabled?: boolean;
}
const AddressTxs = ({ shouldRender = true, isQueryEnabled = true }: Props) => {
const router = useRouter();
const isMounted = useIsMounted();
const isMobile = useIsMobile();
const hash = getQueryParamString(router.query.hash);
const tab = getQueryParamString(router.query.tab) as typeof ADDRESS_TXS_TAB_IDS[number] | 'txs' | undefined;
const isLocalTab = tab === 'txs_local' || tab === 'txs';
const localQuery = useAddressTxsQuery({
addressHash: hash,
enabled: isQueryEnabled && isLocalTab,
});
const crossChainQuery = useQueryWithPages({
resourceName: 'interchainIndexer:address_messages',
pathParams: { hash },
options: {
placeholderData: generateListStub<'interchainIndexer:address_messages'>(INTERCHAIN_MESSAGE, 50, { next_page_params: undefined }),
enabled: isQueryEnabled && !isLocalTab,
},
});
const handleTabValueChange = React.useCallback(({ value }: { value: string }) => {
if (value === 'txs_local') {
localQuery.setFilterValue(undefined);
}
}, [ localQuery ]);
const txsLocalFilter = isLocalTab ? (
<AddressTxsFilter
initialValue={ localQuery.initialFilterValue }
onFilterChange={ localQuery.onFilterChange }
hasActiveFilter={ Boolean(localQuery.filterValue) }
isLoading={ localQuery.query.pagination.isLoading }
/>
) : null;
if (!isMounted || !shouldRender) {
return null;
}
const tabs = [
{
id: [ 'txs_local', 'txs' ],
title: 'Txns',
component: (
<TxsWithAPISorting
filter={ txsLocalFilter }
filterValue={ localQuery.filterValue }
query={ localQuery.query }
currentAddress={ hash }
enableTimeIncrement
socketType="address_txs"
top={ ACTION_BAR_HEIGHT_DESKTOP }
sorting={ localQuery.sort }
setSort={ localQuery.setSort }
showBlockInfo
showTableViewButton
/>
),
},
config.features.crossChainTxs.isEnabled && {
id: 'txs_cross_chain',
title: 'Cross-chain txns',
component: (
<AddressTxsCrossChain
pagination={ crossChainQuery.pagination }
items={ crossChainQuery.data?.items }
isLoading={ crossChainQuery.isPlaceholderData }
isError={ crossChainQuery.isError }
currentAddress={ hash }
/>
),
},
].filter(Boolean);
const rightSlot = (() => {
if (isLocalTab) {
if (isMobile) {
return null;
}
if (!localQuery.query.data?.items.length && !localQuery.filterValue) {
return null;
}
return (
<>
<HStack gap={ 3 }>
{ txsLocalFilter }
<CsvExport
type="address_txs"
resourceName="general:address_csv_export_txs"
pathParams={{ hash }}
queryParams={ localQuery.filterValue ? {
filter_type: 'address',
filter_value: localQuery.filterValue,
} : undefined }
loadingInitial={ localQuery.query.pagination.isLoading }
/>
</HStack>
<HStack gap={ 6 }>
<Pagination { ...localQuery.query.pagination }/>
</HStack>
</>
);
}
if (config.features.crossChainTxs.isEnabled) {
if (isMobile) {
return null;
}
return <Pagination { ...crossChainQuery.pagination } ml="auto"/>;
}
return null;
})();
const rightSlotProps = (() => {
return {
display: 'flex',
justifyContent: { base: 'flex-end', lg: 'space-between' },
ml: tabs.length > 1 ? { base: 0, lg: 4 } : 0,
widthAllocation: 'available' as const,
};
})();
return (
<RoutedTabs
variant="secondary"
size="sm"
tabs={ tabs }
onValueChange={ handleTabValueChange }
defaultTabId="txs_local"
rightSlot={ rightSlot }
rightSlotProps={ rightSlotProps }
listProps={ isMobile ? undefined : TAB_LIST_PROPS }
stickyEnabled={ !isMobile }
/>
);
};
export default React.memo(AddressTxs);