Skip to content

Commit

Permalink
search pagination refactoring
Browse files Browse the repository at this point in the history
  • Loading branch information
uiii committed Oct 30, 2023
1 parent e7f970d commit f0c7e05
Show file tree
Hide file tree
Showing 29 changed files with 456 additions and 264 deletions.
6 changes: 1 addition & 5 deletions src/components/AccountAddress.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import { AccountAvatar } from "./AccountAvatar";
import CopyToClipboardButton, { CopyToClipboardButtonProps } from "./CopyToClipboardButton";

const accountAddressStyle = css`
display: inline-flex;
display: flex;
align-items: center;
`;

Expand Down Expand Up @@ -72,10 +72,6 @@ export const AccountAddress = (props: AccountLinkProps) => {
return content;
}, [network, address, encodeAddress, link]);

/*if (!icon) {
return <>{content}</>;
}*/

return (
<div css={accountAddressStyle}>
{icon && (
Expand Down
18 changes: 16 additions & 2 deletions src/components/ItemsTable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@ import { TablePagination } from "./TablePagination";
import { TableSortOptions, TableSortOptionsProps } from "./TableSortOptions";
import { TableSortToggle } from "./TableSortToggle";

const containerStyle = css`
position: relative;
`;

const tableStyle = css`
table-layout: fixed;
min-width: 860px;
Expand All @@ -35,6 +39,15 @@ const cellStyle = css`
}
`;

const loadingOverlayStyle = css`
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: rgba(255, 255, 255, .5);
`;

type ItemsTableItem = {
id: string;
}
Expand Down Expand Up @@ -106,7 +119,7 @@ export const ItemsTable = <T extends ItemsTableItem, S = any, A extends any[] =
...restProps
} = props;

if (loading) {
if (!data && loading) {
return <Loading />;
}

Expand All @@ -126,7 +139,7 @@ export const ItemsTable = <T extends ItemsTableItem, S = any, A extends any[] =

return (
<div {...restProps} data-class="table">
<TableContainer>
<TableContainer css={containerStyle}>
<Table css={tableStyle}>
<colgroup>
{Children.map(children, (child) => child && <col css={child.props.colCss} />)}
Expand Down Expand Up @@ -172,6 +185,7 @@ export const ItemsTable = <T extends ItemsTableItem, S = any, A extends any[] =
)}
</TableBody>
</Table>
{loading && <Loading css={loadingOverlayStyle} />}
</TableContainer>
{pageInfo && (
<TablePagination
Expand Down
11 changes: 8 additions & 3 deletions src/components/Loading.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,19 @@
import { css } from "@emotion/react";

import Spinner from "./Spinner";
import { HTMLAttributes } from "react";

const loadingStyle = css`
text-align: center;
display: flex;
align-items: center;
justify-content: center;
`;

const Loading = () => {
export interface LoadingProps extends HTMLAttributes<HTMLDivElement> {}

const Loading = (props: LoadingProps) => {
return (
<div css={loadingStyle}>
<div {...props} css={loadingStyle}>
<Spinner />
</div>
);
Expand Down
4 changes: 2 additions & 2 deletions src/components/TabbedContent.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ export const TabbedContent = (props: TabbedContentProps) => {
<>
<span>{label}</span>
{count !== undefined && <span data-test="count" css={tabCountStyle}>({formatNumber(count)})</span>}
{(loading) && <CircularProgress css={tabLoadingStyle} size={14} />}
{(count === undefined && loading) && <CircularProgress css={tabLoadingStyle} size={14} />}
{!!error && <ErrorIcon css={tabErrorStyle} />}
</>
}
Expand All @@ -125,7 +125,7 @@ export const TabbedContent = (props: TabbedContentProps) => {
if (!currentTabPane) {
tabHandles[0] && onTabChange?.(tabHandles[0].props.value);
}
}, [currentTabPane, tabPanes, onTabChange]);
}, [currentTabPane, tabHandles, onTabChange]);

return (
<>
Expand Down
10 changes: 7 additions & 3 deletions src/components/Time.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { useEffect, useMemo, useState } from "react";
import { useCallback, useEffect, useMemo, useState } from "react";
import { formatDistanceToNowStrict } from "date-fns";
import enGB from "date-fns/locale/en-GB";
import { format as formatTime, formatInTimeZone as formatTimeInTimeZone } from "date-fns-tz";
Expand All @@ -23,7 +23,11 @@ export const Time = (props: TimeProps) => {
tooltip = false
} = props;

const [fromNowFormatted, setFromNowFormatted] = useState<string>();
const formatFromNow = useCallback((time: string|Date|number) => {
return formatDistanceToNowStrict(new Date(time), {addSuffix: true, locale: enGB});
}, []);

const [fromNowFormatted, setFromNowFormatted] = useState<string>(formatFromNow(time));

const formatted = useMemo(() => {
let format = formatProp;
Expand All @@ -42,7 +46,7 @@ export const Time = (props: TimeProps) => {
useEffect(() => {
if (fromNow) {
const interval = setInterval(() =>
setFromNowFormatted(formatDistanceToNowStrict(new Date(time), {addSuffix: true, locale: enGB}))
setFromNowFormatted(formatFromNow(time))
);

return () => clearInterval(interval);
Expand Down
6 changes: 4 additions & 2 deletions src/components/account/AccountBalancesTable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { css } from "@emotion/react";
import Decimal from "decimal.js";

import { AccountBalance } from "../../model/accountBalance";
import { PageInfo } from "../../model/pageInfo";
import { PaginationOptions } from "../../model/paginationOptions";
import { Resource } from "../../model/resource";
import { SortDirection } from "../../model/sortDirection";
Expand Down Expand Up @@ -96,10 +97,11 @@ export const AccountBalancesTable = (props: AccountBalancesTableProps) => {
return data?.slice((pagination.page - 1) * pagination.pageSize, pagination.page * pagination.pageSize);
}, [data, pagination.page, pagination.pageSize]);

const pageInfo = useMemo(() => ({
const pageInfo = useMemo<PageInfo>(() => ({
page: pagination.page,
pageSize: pagination.pageSize,
hasNextPage: pagination.page * pagination.pageSize < data.length
hasNextPage: pagination.page * pagination.pageSize < data.length,
totalPageCount: Math.ceil(data.length / pagination.pageSize)
}), [data, pagination]);

const handleSortSelected = useCallback((value: SortOrder<SortProperty<AccountBalance>>) => {
Expand Down
21 changes: 12 additions & 9 deletions src/components/search/AccountSearchResultsTable.tsx
Original file line number Diff line number Diff line change
@@ -1,27 +1,30 @@
import { Account } from "../../model/account";
import { ItemsResponse } from "../../model/itemsResponse";
import { PaginatedResource } from "../../model/paginatedResource";
import { SearchResultItem } from "../../model/searchResultItem";
import { encodeAddress } from "../../utils/address";

import { AccountAddress } from "../AccountAddress";

import { SearchResultsTable, SearchResultsTableItemAttribute } from "./SearchResultsTable";
import { SearchResultsTable, SearchResultsTableItemAttribute, SearchResultsTableProps } from "./SearchResultsTable";

export interface AccountSearchResultsTable {
query: string;
items: ItemsResponse<SearchResultItem<Account>, true>;
onPageChange?: (page: number) => void;
export interface AccountSearchResultsTable
extends Pick<SearchResultsTableProps<Account>, "query" | "onPageChange"> {
accounts: PaginatedResource<SearchResultItem<Account>>;
}

export const AccountSearchResultsTable = (props: AccountSearchResultsTable) => {
const {query, items, onPageChange} = props;
const {accounts, ...tableProps} = props;

return (
<SearchResultsTable<Account>
query={query}
items={items}
data={accounts.data}
loading={accounts.loading}
pageInfo={accounts.pageInfo}
notFound={accounts.notFound}
error={accounts.error}
itemsPlural="accounts"
onPageChange={onPageChange}
{...tableProps}
>
<SearchResultsTableItemAttribute<Account>
label="Account"
Expand Down
22 changes: 12 additions & 10 deletions src/components/search/BlockSearchResultsTable.tsx
Original file line number Diff line number Diff line change
@@ -1,28 +1,30 @@
import { Block } from "../../model/block";
import { ItemsResponse } from "../../model/itemsResponse";
import { PaginatedResource } from "../../model/paginatedResource";
import { SearchResultItem } from "../../model/searchResultItem";

import { AccountAddress } from "../AccountAddress";
import { Link } from "../Link";
import { Time } from "../Time";

import { SearchResultsTable, SearchResultsTableItemAttribute } from "./SearchResultsTable";
import { SearchResultsTable, SearchResultsTableItemAttribute, SearchResultsTableProps } from "./SearchResultsTable";

export interface BlockSearchResultsTable {
query: string;
items: ItemsResponse<SearchResultItem<Block>, true>;
onPageChange?: (page: number) => void;
export interface BlockSearchResultsTable
extends Pick<SearchResultsTableProps<Block>, "query" | "onPageChange"> {
blocks: PaginatedResource<SearchResultItem<Block>>;
}

export const BlockSearchResultsTable = (props: BlockSearchResultsTable) => {
const {query, items, onPageChange} = props;
const {blocks, ...tableProps} = props;

return (
<SearchResultsTable<Block>
query={query}
items={items}
data={blocks.data}
loading={blocks.loading}
pageInfo={blocks.pageInfo}
notFound={blocks.notFound}
error={blocks.error}
itemsPlural="blocks"
onPageChange={onPageChange}
{...tableProps}
>
<SearchResultsTableItemAttribute<Block>
label="Block (Height)"
Expand Down
21 changes: 12 additions & 9 deletions src/components/search/EventSearchResultsTable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,27 +8,30 @@ import { ButtonLink } from "../ButtonLink";
import { DataViewer } from "../DataViewer";
import { Link } from "../Link";

import { SearchResultsTable, SearchResultsTableItemAttribute } from "./SearchResultsTable";
import { SearchResultsTable, SearchResultsTableItemAttribute, SearchResultsTableProps } from "./SearchResultsTable";
import { PaginatedResource } from "../../model/paginatedResource";

const eventArgsColCss = css`
width: 35%;
`;

export interface EventSearchResultsTable {
query: string;
items: ItemsResponse<SearchResultItem<Event>, true>;
onPageChange?: (page: number) => void;
export interface EventSearchResultsTable
extends Pick<SearchResultsTableProps<Event>, "query" | "onPageChange"> {
events: PaginatedResource<SearchResultItem<Event>>;
}

export const EventSearchResultsTable = (props: EventSearchResultsTable) => {
const {query, items, onPageChange} = props;
const {events, ...tableProps} = props;

return (
<SearchResultsTable<Event>
query={query}
items={items}
data={events.data}
loading={events.loading}
pageInfo={events.pageInfo}
notFound={events.notFound}
error={events.error}
itemsPlural="events"
onPageChange={onPageChange}
{...tableProps}
>
<SearchResultsTableItemAttribute<Event>
label="Event (ID)"
Expand Down
21 changes: 12 additions & 9 deletions src/components/search/ExtrinsicSearchResultsTable.tsx
Original file line number Diff line number Diff line change
@@ -1,29 +1,32 @@
import { Extrinsic } from "../../model/extrinsic";
import { ItemsResponse } from "../../model/itemsResponse";
import { PaginatedResource } from "../../model/paginatedResource";
import { SearchResultItem } from "../../model/searchResultItem";

import { AccountAddress } from "../AccountAddress";
import { ButtonLink } from "../ButtonLink";
import { Link } from "../Link";
import { Time } from "../Time";

import { SearchResultsTable, SearchResultsTableItemAttribute } from "./SearchResultsTable";
import { SearchResultsTable, SearchResultsTableItemAttribute, SearchResultsTableProps } from "./SearchResultsTable";

export interface ExtrinsicSearchResultsTable {
query: string;
items: ItemsResponse<SearchResultItem<Extrinsic>, true>;
onPageChange?: (page: number) => void;
export interface ExtrinsicSearchResultsTable
extends Pick<SearchResultsTableProps<Extrinsic>, "query" | "onPageChange"> {
extrinsics: PaginatedResource<SearchResultItem<Extrinsic>>;
}

export const ExtrinsicSearchResultsTable = (props: ExtrinsicSearchResultsTable) => {
const {query, items, onPageChange} = props;
const {extrinsics, ...tableProps} = props;

return (
<SearchResultsTable<Extrinsic>
query={query}
items={items}
data={extrinsics.data}
loading={extrinsics.loading}
pageInfo={extrinsics.pageInfo}
notFound={extrinsics.notFound}
error={extrinsics.error}
itemsPlural="extrinsics"
onPageChange={onPageChange}
{...tableProps}
>
<SearchResultsTableItemAttribute<Extrinsic>
label="Extrinsic (ID)"
Expand Down
21 changes: 5 additions & 16 deletions src/components/search/SearchResultsTable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { Network } from "../../model/network";
import { ItemsResponse } from "../../model/itemsResponse";
import { formatNumber } from "../../utils/number";

import { ItemsTable, ItemsTableAttribute, ItemsTableAttributeProps } from "../ItemsTable";
import { ItemsTable, ItemsTableAttribute, ItemsTableAttributeProps, ItemsTableProps } from "../ItemsTable";
import { Link } from "../Link";
import { SearchResultItem } from "../../model/searchResultItem";

Expand All @@ -31,29 +31,22 @@ const networkIconStyle = css`
height: 20px;
object-fit: contain;
margin-right: 16px;
float: left;
flex: 0 0 auto;
`;

type SearchResultsTableChild<T> = ReactElement<ItemsTableAttributeProps<T, [Network], []>>;


export const SearchResultsTableItemAttribute = <T extends object>(props: ItemsTableAttributeProps<T, [], []>) => <ItemsTableAttribute {...props} />;

export interface SearchResultsTableProps<T> {
export interface SearchResultsTableProps<T> extends Omit<ItemsTableProps<SearchResultItem<T>>, "children"> {
children: SearchResultsTableChild<T>|(SearchResultsTableChild<T>|false|undefined|null)[];
query: string;
items: ItemsResponse<SearchResultItem<T>, true>;
itemsPlural: string
onPageChange?: (page: number) => void;
}

export const SearchResultsTable = <T extends {id: string, network: Network}>(props: SearchResultsTableProps<T>) => {
const { children, query, items, itemsPlural, onPageChange } = props;

const data = useMemo(() => items.data.map(it => ({
...it,
id: `${it.network.name}-${it.data?.id || "grouped"}`
})), [items]);
const { children, query, itemsPlural, ...itemsTableProps } = props;

const itemAttributes = useMemo(() => Children.map(children, (child, index) => {
if (!child) {
Expand Down Expand Up @@ -114,12 +107,8 @@ export const SearchResultsTable = <T extends {id: string, network: Network}>(pro

return (
<ItemsTable
data={data}
{...itemsTableProps}
css={tableStyle}
notFound={items.totalCount === 0}
pageInfo={items.pageInfo}
onPageChange={onPageChange}
data-test="search-results-table"
>
<ItemsTableAttribute<SearchResultItem<T>>
label="Network"
Expand Down
Loading

0 comments on commit f0c7e05

Please sign in to comment.