mirror of
https://github.com/luxfi/explore.git
synced 2026-09-24 00:28:18 +00:00
mud mobile views
This commit is contained in:
@@ -1,8 +1,9 @@
|
||||
import { Grid, Box, useColorModeValue, chakra, HStack } from '@chakra-ui/react';
|
||||
import { Box, useColorModeValue, chakra, HStack } from '@chakra-ui/react';
|
||||
import React from 'react';
|
||||
|
||||
import { route } from 'nextjs-routes';
|
||||
|
||||
import useIsMobile from 'lib/hooks/useIsMobile';
|
||||
import CopyToClipboard from 'ui/shared/CopyToClipboard';
|
||||
import IconSvg from 'ui/shared/IconSvg';
|
||||
import LinkInternal from 'ui/shared/links/LinkInternal';
|
||||
@@ -70,8 +71,18 @@ const BreadcrumbItem = ({ text, href, isLast, scrollRef }: BreadcrumbItemProps)
|
||||
|
||||
const AddressMudBreadcrumbs = (props: TableViewProps | RecordViewProps) => {
|
||||
const queryParams = { tab: 'mud', hash: props.hash };
|
||||
const isMobile = useIsMobile();
|
||||
|
||||
return (
|
||||
<Grid templateColumns="20px auto auto auto" gap={ 2 } alignItems="center" className={ props.className }>
|
||||
<Box
|
||||
display={ isMobile ? 'flex' : 'grid' }
|
||||
flexWrap="wrap"
|
||||
gridTemplateColumns="20px auto auto auto"
|
||||
gap={ 2 }
|
||||
alignItems="center"
|
||||
className={ props.className }
|
||||
width="fit-content"
|
||||
>
|
||||
<IconSvg name="MUD" boxSize={ 5 } color="green.500"/>
|
||||
<BreadcrumbItem
|
||||
text="MUD World"
|
||||
@@ -93,7 +104,7 @@ const AddressMudBreadcrumbs = (props: TableViewProps | RecordViewProps) => {
|
||||
|
||||
/>
|
||||
) }
|
||||
</Grid>
|
||||
</Box>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Box, Td, Tr, Flex, useColorModeValue, Table } from '@chakra-ui/react';
|
||||
import { Box, Td, Tr, Flex, Text, Table, Show, Hide, Divider, VStack } from '@chakra-ui/react';
|
||||
import { useRouter } from 'next/router';
|
||||
import React from 'react';
|
||||
|
||||
@@ -9,6 +9,7 @@ import ContentLoader from 'ui/shared/ContentLoader';
|
||||
import TruncatedValue from 'ui/shared/TruncatedValue';
|
||||
|
||||
import AddressMudBreadcrumbs from './AddressMudBreadcrumbs';
|
||||
import AddressMudRecordValues from './AddressMudRecordValues';
|
||||
|
||||
type Props ={
|
||||
scrollRef?: React.RefObject<HTMLDivElement>;
|
||||
@@ -22,8 +23,6 @@ const AddressMudRecord = ({ tableId, recordId, isQueryEnabled = true, scrollRef
|
||||
|
||||
const hash = getQueryParamString(router.query.hash);
|
||||
|
||||
const valuesBgColor = useColorModeValue('blackAlpha.50', 'whiteAlpha.50');
|
||||
|
||||
const { data, isLoading, isError } = useApiQuery('address_mud_record', {
|
||||
pathParams: { hash, table_id: tableId, record_id: recordId },
|
||||
queryOptions: {
|
||||
@@ -52,42 +51,41 @@ const AddressMudRecord = ({ tableId, recordId, isQueryEnabled = true, scrollRef
|
||||
scrollRef={ scrollRef }
|
||||
/>
|
||||
) }
|
||||
|
||||
<Table borderRadius="8px" style={{ tableLayout: 'auto' }} width="100%">
|
||||
{ data?.schema.key_names.length && data?.schema.key_names.map((keyName, index) => (
|
||||
<Tr key={ keyName } borderBottomStyle={ index === data.schema.key_names.length - 1 ? 'hidden' : 'solid' }>
|
||||
<Td fontWeight={ 600 } whiteSpace="nowrap">
|
||||
{ keyName } ({ data.schema.key_types[index] })
|
||||
</Td>
|
||||
<Td colSpan={ 2 }>
|
||||
<Flex justifyContent="space-between">
|
||||
<TruncatedValue value={ data.record.decoded[keyName] } mr={ 2 }/>
|
||||
{ index === 0 && <Box color="text_secondary">{ dayjs(data.record.timestamp).format('lll') }</Box> }
|
||||
</Flex>
|
||||
</Td>
|
||||
</Tr>
|
||||
)) }
|
||||
{ data?.schema.value_names.length && (
|
||||
<>
|
||||
<Tr backgroundColor={ valuesBgColor } borderBottomStyle="hidden">
|
||||
<Td fontWeight={ 600 }>Field</Td>
|
||||
<Td fontWeight={ 600 }>Type</Td>
|
||||
<Td fontWeight={ 600 } w="100%" wordBreak="break-all">Value</Td>
|
||||
<Show above="lg" ssr={ false }>
|
||||
<Table borderRadius="8px" style={{ tableLayout: 'auto' }} width="100%" overflow="hidden">
|
||||
{ data?.schema.key_names.length && data?.schema.key_names.map((keyName, index) => (
|
||||
<Tr key={ keyName } borderBottomStyle={ index === data.schema.key_names.length - 1 ? 'hidden' : 'solid' }>
|
||||
<Td fontWeight={ 600 } whiteSpace="nowrap">
|
||||
{ keyName } ({ data.schema.key_types[index] })
|
||||
</Td>
|
||||
<Td colSpan={ 2 }>
|
||||
<Flex justifyContent="space-between">
|
||||
<TruncatedValue value={ data.record.decoded[keyName] } mr={ 2 }/>
|
||||
{ index === 0 && <Box color="text_secondary">{ dayjs(data.record.timestamp).format('lll') }</Box> }
|
||||
</Flex>
|
||||
</Td>
|
||||
</Tr>
|
||||
{ data?.schema.value_names.map((valName, index) => (
|
||||
<Tr key={ valName } backgroundColor={ valuesBgColor } borderBottomStyle="hidden">
|
||||
<Td whiteSpace="nowrap">{ valName }</Td>
|
||||
<Td>{ data.schema.value_types[index] }</Td>
|
||||
<Td w="100%" wordBreak="break-all">
|
||||
<Box>
|
||||
{ data.record.decoded[valName] }
|
||||
</Box>
|
||||
</Td>
|
||||
</Tr>
|
||||
)) }
|
||||
</>
|
||||
) }
|
||||
</Table>
|
||||
)) }
|
||||
<AddressMudRecordValues data={ data }/>
|
||||
</Table>
|
||||
</Show>
|
||||
<Hide above="lg" ssr={ false }>
|
||||
<>
|
||||
{ data?.schema.key_names.length && data?.schema.key_names.map((keyName, index) => (
|
||||
<VStack gap={ 1 } key={ keyName } alignItems="start">
|
||||
<Divider/>
|
||||
<Text fontWeight={ 600 } whiteSpace="nowrap">
|
||||
{ keyName } ({ data.schema.key_types[index] })
|
||||
</Text>
|
||||
<Text wordBreak="break-all">{ data.record.decoded[keyName] }</Text>
|
||||
{ index === 0 && <Box color="text_secondary">{ dayjs(data.record.timestamp).format('lll') }</Box> }
|
||||
</VStack>
|
||||
)) }
|
||||
<Table borderRadius="8px" style={{ tableLayout: 'auto' }} width="100%" mt={ 2 } overflow="hidden">
|
||||
<AddressMudRecordValues data={ data }/>
|
||||
</Table>
|
||||
</>
|
||||
</Hide>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
import { Box, Td, Tr, useColorModeValue } from '@chakra-ui/react';
|
||||
import React from 'react';
|
||||
|
||||
import type { AddressMudRecord } from 'types/api/address';
|
||||
|
||||
type Props ={
|
||||
data?: AddressMudRecord;
|
||||
}
|
||||
|
||||
const AddressMudRecordValues = ({ data }: Props) => {
|
||||
const valuesBgColor = useColorModeValue('blackAlpha.50', 'whiteAlpha.50');
|
||||
|
||||
if (!data?.schema.value_names.length) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<Tr backgroundColor={ valuesBgColor } borderBottomStyle="hidden">
|
||||
<Td fontWeight={ 600 }>Field</Td>
|
||||
<Td fontWeight={ 600 }>Type</Td>
|
||||
<Td fontWeight={ 600 } w="100%" wordBreak="break-all">Value</Td>
|
||||
</Tr>
|
||||
{
|
||||
data?.schema.value_names.map((valName, index) => (
|
||||
<Tr key={ valName } backgroundColor={ valuesBgColor } borderBottomStyle="hidden">
|
||||
<Td whiteSpace="nowrap" py={ 0 } pb={ 4 }>{ valName }</Td>
|
||||
<Td py={ 0 } pb={ 4 }>{ data.schema.value_types[index] }</Td>
|
||||
<Td w="100%" wordBreak="break-all" py={ 0 } pb={ 4 }>
|
||||
<Box>
|
||||
{ data.record.decoded[valName] }
|
||||
</Box>
|
||||
</Td>
|
||||
</Tr>
|
||||
))
|
||||
}
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default AddressMudRecordValues;
|
||||
@@ -7,6 +7,7 @@ import type { AddressMudRecords, AddressMudRecordsFilter, AddressMudRecordsSorti
|
||||
|
||||
import capitalizeFirstLetter from 'lib/capitalizeFirstLetter';
|
||||
import dayjs from 'lib/date/dayjs';
|
||||
import useIsMobile from 'lib/hooks/useIsMobile';
|
||||
import IconSvg from 'ui/shared/IconSvg';
|
||||
import { default as Thead } from 'ui/shared/TheadSticky';
|
||||
|
||||
@@ -14,7 +15,9 @@ import AddressMudRecordsKeyFilter from './AddressMudRecordsKeyFilter';
|
||||
import { getNameTypeText } from './utils';
|
||||
|
||||
const COL_MIN_WIDTH = 180;
|
||||
const COL_MIN_WIDTH_MOBILE = 140;
|
||||
const CUT_COL_WIDTH = 36;
|
||||
const MIN_CUT_COUNT = 2;
|
||||
|
||||
type Props = {
|
||||
data: AddressMudRecords;
|
||||
@@ -37,9 +40,11 @@ const AddressMudRecordsTable = ({
|
||||
toggleTableHasHorisontalScroll,
|
||||
scrollRef,
|
||||
}: Props) => {
|
||||
const [ colsCutCount, setColsCutCount ] = React.useState<number>(0);
|
||||
const totalColsCut = data.schema.key_names.length + data.schema.value_names.length;
|
||||
const isMobile = useIsMobile(false);
|
||||
const [ colsCutCount, setColsCutCount ] = React.useState<number>(isMobile ? 2 : 0);
|
||||
const [ isOpened, setIsOpened ] = useBoolean(false);
|
||||
const [ hasCut, setHasCut ] = useBoolean(true);
|
||||
const [ hasCut, setHasCut ] = useBoolean(isMobile ? totalColsCut > MIN_CUT_COUNT : true);
|
||||
|
||||
const tableRef = React.useRef<HTMLTableElement>(null);
|
||||
|
||||
@@ -56,10 +61,7 @@ const AddressMudRecordsTable = ({
|
||||
record_id: e.currentTarget.getAttribute('data-id') as string,
|
||||
};
|
||||
router.push({ pathname: router.pathname, query: newQuery }, undefined, { shallow: true });
|
||||
window.setTimeout(() => {
|
||||
// cannot do scroll instantly, have to wait a little
|
||||
scrollRef?.current?.scrollIntoView({ behavior: 'smooth' });
|
||||
}, 500);
|
||||
scrollRef?.current?.scrollIntoView();
|
||||
}, [ router, scrollRef ]);
|
||||
|
||||
const handleFilterChange = React.useCallback((field: keyof AddressMudRecordsFilter) => (val: string) => {
|
||||
@@ -80,39 +82,42 @@ const AddressMudRecordsTable = ({
|
||||
React.useEffect(() => {
|
||||
if (hasCut && !colsCutCount && tableRef.current) {
|
||||
const count = Math.floor((tableRef.current.getBoundingClientRect().width - CUT_COL_WIDTH) / COL_MIN_WIDTH);
|
||||
const total = data.schema.key_names.length + data.schema.value_names.length;
|
||||
if (total > 2 && count - 1 < total) {
|
||||
if (totalColsCut > 2 && count - 1 < totalColsCut) {
|
||||
setColsCutCount(count - 1);
|
||||
} else {
|
||||
setHasCut.off();
|
||||
}
|
||||
}
|
||||
}, [ colsCutCount, data.schema, hasCut, setHasCut ]);
|
||||
}, [ colsCutCount, data.schema, hasCut, setHasCut, totalColsCut ]);
|
||||
|
||||
const cutWidth = `${ CUT_COL_WIDTH }px `;
|
||||
|
||||
const colW = isMobile ? COL_MIN_WIDTH_MOBILE : COL_MIN_WIDTH;
|
||||
|
||||
const tdStyles: StyleProps = {
|
||||
wordBreak: 'break-all',
|
||||
whiteSpace: 'normal',
|
||||
minW: `${ COL_MIN_WIDTH }px`,
|
||||
w: `${ COL_MIN_WIDTH }px`,
|
||||
minW: `${ colW }px`,
|
||||
w: `${ colW }px`,
|
||||
};
|
||||
|
||||
const thStyles: StyleProps = {
|
||||
wordBreak: 'break-word',
|
||||
whiteSpace: 'normal',
|
||||
minW: `${ COL_MIN_WIDTH }px`,
|
||||
w: `${ COL_MIN_WIDTH }px`,
|
||||
minW: `${ colW }px`,
|
||||
w: `${ colW }px`,
|
||||
};
|
||||
|
||||
const keys = (isOpened || !hasCut) ? data.schema.key_names : data.schema.key_names.slice(0, colsCutCount);
|
||||
const values = (isOpened || !hasCut) ? data.schema.value_names : data.schema.value_names.slice(0, colsCutCount - data.schema.key_names.length);
|
||||
|
||||
const hasHorizontalScroll = isMobile || isOpened;
|
||||
|
||||
return (
|
||||
// can't implement both horisontal table scroll and sticky header
|
||||
<Box maxW="100%" overflowX={ isOpened ? 'scroll' : 'unset' } whiteSpace="nowrap">
|
||||
<Box maxW="100%" overflowX={ hasHorizontalScroll ? 'scroll' : 'unset' } whiteSpace="nowrap">
|
||||
<Table variant="simple" size="sm" style={{ tableLayout: 'fixed' }} ref={ tableRef }>
|
||||
<Thead top={ isOpened ? 0 : top } display={ isOpened ? 'table' : 'table-header-group' } w="100%">
|
||||
<Thead top={ hasHorizontalScroll ? 0 : top } display={ hasHorizontalScroll ? 'table' : 'table-header-group' } w="100%">
|
||||
<Tr >
|
||||
{ keys.map((keyName, index) => {
|
||||
const text = getNameTypeText(keyName, data.schema.key_types[index]);
|
||||
@@ -147,7 +152,7 @@ const AddressMudRecordsTable = ({
|
||||
{ hasCut && isOpened && <Th width={ cutWidth }><Link onClick={ toggleIsOpen }>...</Link></Th> }
|
||||
</Tr>
|
||||
</Thead>
|
||||
<Tbody display={ isOpened ? 'table' : 'table-row-group' } w="100%">
|
||||
<Tbody display={ hasHorizontalScroll ? 'table' : 'table-row-group' } w="100%">
|
||||
{ data.items.map((item) => (
|
||||
<Tr key={ item.id }>
|
||||
{ keys.map((keyName, index) => (
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
import { Box, HStack, Hide, Show, Tag, TagCloseButton, chakra, useBoolean } from '@chakra-ui/react';
|
||||
import { Box, HStack, Tag, TagCloseButton, chakra, useBoolean } from '@chakra-ui/react';
|
||||
import { useRouter } from 'next/router';
|
||||
import React from 'react';
|
||||
|
||||
import type { AddressMudRecordsFilter, AddressMudRecordsSorting } from 'types/api/address';
|
||||
|
||||
import useIsMobile from 'lib/hooks/useIsMobile';
|
||||
import { apos, nbsp } from 'lib/html-entities';
|
||||
import getQueryParamString from 'lib/router/getQueryParamString';
|
||||
import ActionBar, { ACTION_BAR_HEIGHT_DESKTOP } from 'ui/shared/ActionBar';
|
||||
@@ -31,7 +32,8 @@ const AddressMudTable = ({ scrollRef, tableId, isQueryEnabled = true }: Props) =
|
||||
const [ sorting, setSorting ] =
|
||||
React.useState<AddressMudRecordsSorting | undefined>(getSortParamsFromQuery<AddressMudRecordsSorting>(router.query, SORT_SEQUENCE));
|
||||
const [ filters, setFilters ] = React.useState<AddressMudRecordsFilter>({});
|
||||
const [ tableHasHorisontalScroll, setTableHasHorisontalScroll ] = useBoolean(false);
|
||||
const isMobile = useIsMobile();
|
||||
const [ tableHasHorisontalScroll, setTableHasHorisontalScroll ] = useBoolean(isMobile);
|
||||
|
||||
const hash = getQueryParamString(router.query.hash);
|
||||
|
||||
@@ -93,18 +95,20 @@ const AddressMudTable = ({ scrollRef, tableId, isQueryEnabled = true }: Props) =
|
||||
</HStack>
|
||||
) : null;
|
||||
|
||||
const actionBar = (
|
||||
const breadcrumbs = data ? (
|
||||
<AddressMudBreadcrumbs
|
||||
hash={ hash }
|
||||
tableId={ tableId }
|
||||
tableName={ data?.table.table_full_name }
|
||||
scrollRef={ scrollRef }
|
||||
mb={ hasActiveFilters ? 4 : 0 }
|
||||
/>
|
||||
) : null;
|
||||
|
||||
const actionBar = (!isMobile || hasActiveFilters || pagination.isVisible) && (
|
||||
<ActionBar mt={ -6 } showShadow={ tableHasHorisontalScroll } justifyContent="space-between" alignItems={ hasActiveFilters ? 'start' : 'center' }>
|
||||
<Box>
|
||||
{ data && (
|
||||
<AddressMudBreadcrumbs
|
||||
hash={ hash }
|
||||
tableId={ tableId }
|
||||
tableName={ data?.table.table_full_name }
|
||||
scrollRef={ scrollRef }
|
||||
mb={ hasActiveFilters ? 4 : 0 }
|
||||
/>
|
||||
) }
|
||||
{ !isMobile && breadcrumbs }
|
||||
{ filtersTags }
|
||||
</Box>
|
||||
<Pagination ml={{ base: 0, lg: 8 }} { ...pagination }/>
|
||||
@@ -112,45 +116,36 @@ const AddressMudTable = ({ scrollRef, tableId, isQueryEnabled = true }: Props) =
|
||||
);
|
||||
|
||||
const content = data?.items ? (
|
||||
<>
|
||||
<Hide below="lg" ssr={ false }>
|
||||
<AddressMudRecordsTable
|
||||
data={ data }
|
||||
top={ actionBatHeight }
|
||||
sorting={ sorting }
|
||||
toggleSorting={ toggleSorting }
|
||||
setFilters={ setFilters }
|
||||
filters={ filters }
|
||||
toggleTableHasHorisontalScroll={ setTableHasHorisontalScroll.toggle }
|
||||
scrollRef={ scrollRef }
|
||||
/>
|
||||
</Hide>
|
||||
<Show below="lg" ssr={ false }>
|
||||
waiting for mobile mockup
|
||||
{ /* { data.items.map((item, index) => (
|
||||
<AddressMudListItem
|
||||
key={ item.table.table_id + (isPlaceholderData ? String(index) : '') }
|
||||
item={ item }
|
||||
isLoading={ isPlaceholderData }
|
||||
/>
|
||||
)) } */ }
|
||||
</Show>
|
||||
</>
|
||||
<AddressMudRecordsTable
|
||||
data={ data }
|
||||
top={ actionBatHeight }
|
||||
sorting={ sorting }
|
||||
toggleSorting={ toggleSorting }
|
||||
setFilters={ setFilters }
|
||||
filters={ filters }
|
||||
toggleTableHasHorisontalScroll={ setTableHasHorisontalScroll.toggle }
|
||||
scrollRef={ scrollRef }
|
||||
/>
|
||||
) : null;
|
||||
|
||||
return (
|
||||
<DataListDisplay
|
||||
isError={ isError }
|
||||
items={ data?.items }
|
||||
emptyText="There are no records for this table."
|
||||
filterProps={{
|
||||
emptyFilteredText: `Couldn${ apos }t find records that match your filter query.`,
|
||||
hasActiveFilters: Object.values(filters).some(Boolean),
|
||||
}}
|
||||
content={ content }
|
||||
actionBar={ actionBar }
|
||||
showActionBarIfEmpty
|
||||
/>
|
||||
<>
|
||||
{ isMobile && (
|
||||
<Box mb={ 6 }>{ breadcrumbs }</Box>
|
||||
) }
|
||||
<DataListDisplay
|
||||
isError={ isError }
|
||||
items={ data?.items }
|
||||
emptyText="There are no records for this table."
|
||||
filterProps={{
|
||||
emptyFilteredText: `Couldn${ apos }t find records that match your filter query.`,
|
||||
hasActiveFilters: Object.values(filters).some(Boolean),
|
||||
}}
|
||||
content={ content }
|
||||
actionBar={ actionBar }
|
||||
showActionBarIfEmpty={ !isMobile }
|
||||
/>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
@@ -13,6 +13,7 @@ import FilterInput from 'ui/shared/filters/FilterInput';
|
||||
import Pagination from 'ui/shared/pagination/Pagination';
|
||||
import useQueryWithPages from 'ui/shared/pagination/useQueryWithPages';
|
||||
|
||||
import AddressMudTablesListItem from './AddressMudTablesListItem';
|
||||
import AddressMudTablesTable from './AddressMudTablesTable';
|
||||
|
||||
type Props ={
|
||||
@@ -73,14 +74,13 @@ const AddressMudTables = ({ scrollRef, isQueryEnabled = true }: Props) => {
|
||||
/>
|
||||
</Hide>
|
||||
<Show below="lg" ssr={ false }>
|
||||
waiting for mobile mockup
|
||||
{ /* { data.items.map((item, index) => (
|
||||
<AddressMudListItem
|
||||
{ data.items.map((item, index) => (
|
||||
<AddressMudTablesListItem
|
||||
key={ item.table.table_id + (isPlaceholderData ? String(index) : '') }
|
||||
item={ item }
|
||||
isLoading={ isPlaceholderData }
|
||||
/>
|
||||
)) } */ }
|
||||
)) }
|
||||
</Show>
|
||||
</>
|
||||
) : null;
|
||||
|
||||
@@ -0,0 +1,93 @@
|
||||
import { Divider, Text, Skeleton, useBoolean, Flex, Link, VStack, chakra, Box, Grid, GridItem } from '@chakra-ui/react';
|
||||
import { useRouter } from 'next/router';
|
||||
import React from 'react';
|
||||
|
||||
import type { AddressMudTableItem } from 'types/api/address';
|
||||
|
||||
import Tag from 'ui/shared/chakra/Tag';
|
||||
import HashStringShorten from 'ui/shared/HashStringShorten';
|
||||
import IconSvg from 'ui/shared/IconSvg';
|
||||
import ListItemMobile from 'ui/shared/ListItemMobile/ListItemMobile';
|
||||
|
||||
type Props = {
|
||||
item: AddressMudTableItem;
|
||||
isLoading: boolean;
|
||||
scrollRef?: React.RefObject<HTMLDivElement>;
|
||||
};
|
||||
|
||||
const AddressMudTablesListItem = ({ item, isLoading, scrollRef }: Props) => {
|
||||
const [ isOpened, setIsOpened ] = useBoolean(false);
|
||||
|
||||
const router = useRouter();
|
||||
|
||||
const onTableClick = React.useCallback((e: React.MouseEvent) => {
|
||||
const newQuery = {
|
||||
...router.query,
|
||||
table_id: e.currentTarget.getAttribute('data-id') as string,
|
||||
};
|
||||
router.push({ pathname: router.pathname, query: newQuery }, undefined, { shallow: true });
|
||||
scrollRef?.current?.scrollIntoView();
|
||||
}, [ router, scrollRef ]);
|
||||
|
||||
return (
|
||||
<ListItemMobile rowGap={ 3 } fontSize="sm" py={ 3 }>
|
||||
<Flex w="100%">
|
||||
<Skeleton isLoaded={ !isLoading }>
|
||||
<Link display="block">
|
||||
<IconSvg
|
||||
name="arrows/east-mini"
|
||||
transform={ isOpened ? 'rotate(270deg)' : 'rotate(180deg)' }
|
||||
boxSize={ 6 }
|
||||
cursor="pointer"
|
||||
onClick={ setIsOpened.toggle }
|
||||
transitionDuration="faster"
|
||||
/>
|
||||
</Link>
|
||||
</Skeleton>
|
||||
<Box flexGrow="1">
|
||||
<Flex justifyContent="space-between" height={ 6 } alignItems="center" mb={ 3 }>
|
||||
<Skeleton isLoaded={ !isLoading }>
|
||||
<Link onClick={ onTableClick } data-id={ item.table.table_id } fontWeight={ 500 }>
|
||||
{ item.table.table_full_name }
|
||||
</Link>
|
||||
</Skeleton>
|
||||
<Skeleton isLoaded={ !isLoading } color="text_secondary">
|
||||
{ item.table.table_type }
|
||||
</Skeleton>
|
||||
</Flex>
|
||||
<Skeleton isLoaded={ !isLoading } color="text_secondary">
|
||||
<HashStringShorten hash={ item.table.table_id } type="long"/>
|
||||
</Skeleton>
|
||||
</Box>
|
||||
</Flex>
|
||||
|
||||
{ isOpened && (
|
||||
<Grid templateColumns="48px 1fr" gap="8px 24px" fontWeight={ 500 } w="100%">
|
||||
{ Boolean(item.schema.key_names.length) && (
|
||||
<>
|
||||
<Text lineHeight="24px">Key</Text>
|
||||
<VStack gap={ 1 } alignItems="start">
|
||||
{ item.schema.key_names.map((name, index) => (
|
||||
<Tag key={ name }>
|
||||
<chakra.span fontWeight={ 700 }>{ item.schema.key_types[index] }</chakra.span> { name }
|
||||
</Tag>
|
||||
)) }
|
||||
</VStack>
|
||||
</>
|
||||
) }
|
||||
<GridItem colSpan={ 2 }><Divider/></GridItem>
|
||||
<Text lineHeight="24px">Value</Text>
|
||||
<VStack gap={ 1 } alignItems="start">
|
||||
{ item.schema.value_names.map((name, index) => (
|
||||
<Text key={ name }>
|
||||
<chakra.span fontWeight={ 700 }>{ item.schema.value_types[index] }</chakra.span> { name }
|
||||
</Text>
|
||||
)) }
|
||||
</VStack>
|
||||
</Grid>
|
||||
) }
|
||||
</ListItemMobile>
|
||||
);
|
||||
};
|
||||
|
||||
export default React.memo(AddressMudTablesListItem);
|
||||
@@ -24,10 +24,7 @@ const AddressMudTablesTableItem = ({ item, isLoading, scrollRef }: Props) => {
|
||||
table_id: e.currentTarget.getAttribute('data-id') as string,
|
||||
};
|
||||
router.push({ pathname: router.pathname, query: newQuery }, undefined, { shallow: true });
|
||||
window.setTimeout(() => {
|
||||
// cannot do scroll instantly, have to wait a little
|
||||
scrollRef?.current?.scrollIntoView({ behavior: 'smooth' });
|
||||
}, 500);
|
||||
scrollRef?.current?.scrollIntoView();
|
||||
}, [ router, scrollRef ]);
|
||||
|
||||
return (
|
||||
|
||||
Reference in New Issue
Block a user