@xyo-network/react-payload-table 7.5.7 → 7.5.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/browser/components/Table/TableRowNoData.d.ts.map +1 -1
- package/dist/browser/index.mjs +438 -460
- package/dist/browser/index.mjs.map +1 -1
- package/package.json +182 -44
- package/src/components/DynamicTable/DynamicTable.stories.tsx +0 -72
- package/src/components/DynamicTable/DynamicTableRow.tsx +0 -134
- package/src/components/DynamicTable/PayloadDynamicTableColumnConfig.ts +0 -98
- package/src/components/DynamicTable/Table.tsx +0 -194
- package/src/components/DynamicTable/index.ts +0 -3
- package/src/components/Table/FetchMoreTable.stories.tsx +0 -100
- package/src/components/Table/PayloadTableColumnConfig.ts +0 -22
- package/src/components/Table/Table.stories.tsx +0 -98
- package/src/components/Table/Table.tsx +0 -139
- package/src/components/Table/TableBody.tsx +0 -64
- package/src/components/Table/TableFooter.tsx +0 -44
- package/src/components/Table/TableHead.tsx +0 -31
- package/src/components/Table/TablePagination.tsx +0 -88
- package/src/components/Table/TableRow.tsx +0 -135
- package/src/components/Table/TableRowNoData.tsx +0 -39
- package/src/components/Table/index.ts +0 -7
- package/src/components/Table/lib/TableColumns.ts +0 -12
- package/src/components/Table/lib/index.ts +0 -1
- package/src/components/Table/types/PaginationEventNouns.ts +0 -1
- package/src/components/Table/types/PayloadTableBodyProps.ts +0 -21
- package/src/components/Table/types/PayloadTableFooterProps.ts +0 -13
- package/src/components/Table/types/PayloadTableHeadProps.ts +0 -7
- package/src/components/Table/types/index.ts +0 -4
- package/src/components/index.ts +0 -2
- package/src/components/lib/index.ts +0 -3
- package/src/global.d.ts +0 -1
- package/src/index.ts +0 -1
|
@@ -1,72 +0,0 @@
|
|
|
1
|
-
import type { Meta, StoryFn } from '@storybook/react-vite'
|
|
2
|
-
import { UniswapPairsRenderPlugin } from '@xyo-network/react-crypto-market-uniswap-plugin'
|
|
3
|
-
import { DefaultPayloadRenderPlugin } from '@xyo-network/react-payload-plugin'
|
|
4
|
-
import { PayloadRenderPluginResolver, PayloadRenderPluginResolverProvider } from '@xyo-network/react-payload-plugin-resolver'
|
|
5
|
-
import {
|
|
6
|
-
sampleCoinGeckoPayload, sampleIdPayload, sampleSystemInfoBrowserPayload, sampleUniswapPayload,
|
|
7
|
-
} from '@xyo-network/react-storybook'
|
|
8
|
-
import React from 'react'
|
|
9
|
-
import { BrowserRouter } from 'react-router-dom'
|
|
10
|
-
|
|
11
|
-
import { PayloadDynamicTable } from './Table.tsx'
|
|
12
|
-
|
|
13
|
-
const StorybookEntry = {
|
|
14
|
-
argTypes: {},
|
|
15
|
-
component: PayloadDynamicTable,
|
|
16
|
-
parameters: { docs: { page: null } },
|
|
17
|
-
title: 'payload/DynamicTable',
|
|
18
|
-
} as Meta<typeof PayloadDynamicTable>
|
|
19
|
-
|
|
20
|
-
const Template: StoryFn<typeof PayloadDynamicTable> = args => (
|
|
21
|
-
<PayloadRenderPluginResolverProvider
|
|
22
|
-
resolver={new PayloadRenderPluginResolver().register(UniswapPairsRenderPlugin).register(DefaultPayloadRenderPlugin)}
|
|
23
|
-
>
|
|
24
|
-
<BrowserRouter>
|
|
25
|
-
<PayloadDynamicTable {...args}></PayloadDynamicTable>
|
|
26
|
-
</BrowserRouter>
|
|
27
|
-
</PayloadRenderPluginResolverProvider>
|
|
28
|
-
)
|
|
29
|
-
|
|
30
|
-
const Default = Template.bind({})
|
|
31
|
-
Default.args = {}
|
|
32
|
-
|
|
33
|
-
const WithData = Template.bind({})
|
|
34
|
-
WithData.args = {
|
|
35
|
-
payloads: [
|
|
36
|
-
sampleIdPayload,
|
|
37
|
-
sampleUniswapPayload,
|
|
38
|
-
sampleCoinGeckoPayload,
|
|
39
|
-
sampleSystemInfoBrowserPayload,
|
|
40
|
-
sampleIdPayload,
|
|
41
|
-
sampleUniswapPayload,
|
|
42
|
-
sampleIdPayload,
|
|
43
|
-
sampleUniswapPayload,
|
|
44
|
-
sampleCoinGeckoPayload,
|
|
45
|
-
sampleSystemInfoBrowserPayload,
|
|
46
|
-
sampleIdPayload,
|
|
47
|
-
sampleUniswapPayload,
|
|
48
|
-
sampleIdPayload,
|
|
49
|
-
sampleUniswapPayload,
|
|
50
|
-
sampleCoinGeckoPayload,
|
|
51
|
-
sampleSystemInfoBrowserPayload,
|
|
52
|
-
sampleIdPayload,
|
|
53
|
-
sampleUniswapPayload,
|
|
54
|
-
sampleIdPayload,
|
|
55
|
-
sampleUniswapPayload,
|
|
56
|
-
sampleSystemInfoBrowserPayload,
|
|
57
|
-
],
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
const WithError = Template.bind({})
|
|
61
|
-
|
|
62
|
-
const { ...badPayload } = sampleIdPayload
|
|
63
|
-
|
|
64
|
-
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
65
|
-
// @ts-ignore
|
|
66
|
-
WithError.args = { payloads: [sampleIdPayload, badPayload] }
|
|
67
|
-
|
|
68
|
-
export {
|
|
69
|
-
Default, WithData, WithError,
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
export default StorybookEntry
|
|
@@ -1,134 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
CheckCircleOutlineRounded as CheckCircleOutlineRoundedIcon,
|
|
3
|
-
ErrorOutlineRounded as ErrorOutlineRoundedIcon,
|
|
4
|
-
WarningAmberRounded as WarningAmberRoundedIcon,
|
|
5
|
-
} from '@mui/icons-material'
|
|
6
|
-
import type {
|
|
7
|
-
AvatarProps, TableCellProps, TableRowProps,
|
|
8
|
-
} from '@mui/material'
|
|
9
|
-
import {
|
|
10
|
-
TableCell, TableRow, Typography,
|
|
11
|
-
} from '@mui/material'
|
|
12
|
-
import { usePromise } from '@xylabs/react-promise'
|
|
13
|
-
import { useBreakpoint } from '@xylabs/react-shared'
|
|
14
|
-
import { PayloadBuilder } from '@xyo-network/payload-builder'
|
|
15
|
-
import type { Payload } from '@xyo-network/payload-model'
|
|
16
|
-
import { PayloadValidator } from '@xyo-network/payload-validator'
|
|
17
|
-
import { useNetwork } from '@xyo-network/react-network'
|
|
18
|
-
import type { PayloadRenderProps } from '@xyo-network/react-payload-plugin'
|
|
19
|
-
import { usePayloadRenderPluginResolver } from '@xyo-network/react-payload-plugin-resolver'
|
|
20
|
-
import { HashTableCell, usePayloadHash } from '@xyo-network/react-shared'
|
|
21
|
-
import type { ComponentType } from 'react'
|
|
22
|
-
import React, { useMemo } from 'react'
|
|
23
|
-
|
|
24
|
-
import type { TableCellRenderer } from '../lib/index.ts'
|
|
25
|
-
import type {
|
|
26
|
-
PayloadDynamicTableColumnConfig,
|
|
27
|
-
PayloadDynamicTableColumnSlug,
|
|
28
|
-
} from './PayloadDynamicTableColumnConfig.ts'
|
|
29
|
-
import { payloadDynamicTableColumnConfigDefaults } from './PayloadDynamicTableColumnConfig.ts'
|
|
30
|
-
|
|
31
|
-
export interface PayloadDynamicTableRowProps extends TableRowProps {
|
|
32
|
-
/** @deprecated - archives are no longer used */
|
|
33
|
-
archive?: string
|
|
34
|
-
columns?: PayloadDynamicTableColumnConfig
|
|
35
|
-
/** @deprecated - use event listeners instead of link building via props */
|
|
36
|
-
exploreDomain?: string
|
|
37
|
-
network?: string
|
|
38
|
-
payload?: Payload & { sources?: string[] }
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
export const PayloadDynamicTableRow: React.FC<PayloadDynamicTableRowProps> = ({
|
|
42
|
-
columns,
|
|
43
|
-
network: networkProp,
|
|
44
|
-
payload,
|
|
45
|
-
...props
|
|
46
|
-
}) => {
|
|
47
|
-
const breakPoint = useBreakpoint()
|
|
48
|
-
const payloadHash = usePayloadHash(payload)
|
|
49
|
-
const { network } = useNetwork()
|
|
50
|
-
const { resolver } = usePayloadRenderPluginResolver()
|
|
51
|
-
const [validationErrors = []] = usePromise(async () => (payload ? await new PayloadValidator(payload).validate() : undefined), [payload])
|
|
52
|
-
const isValid = validationErrors.length === 0
|
|
53
|
-
const payloadFieldCount = payload ? Object.keys(PayloadBuilder.hashableFields(payload)).length : 0
|
|
54
|
-
|
|
55
|
-
const hash: TableCellRenderer = props => (
|
|
56
|
-
<HashTableCell
|
|
57
|
-
key="hash"
|
|
58
|
-
align="left"
|
|
59
|
-
value={payloadHash}
|
|
60
|
-
dataType="payload"
|
|
61
|
-
network={networkProp ?? network?.slug}
|
|
62
|
-
{...props}
|
|
63
|
-
/>
|
|
64
|
-
)
|
|
65
|
-
|
|
66
|
-
const schema: TableCellRenderer = props => (
|
|
67
|
-
<TableCell key="payloads" align="left" {...props}>
|
|
68
|
-
<Typography fontFamily="monospace" variant="body2" noWrap>
|
|
69
|
-
{payload?.schema}
|
|
70
|
-
</Typography>
|
|
71
|
-
</TableCell>
|
|
72
|
-
)
|
|
73
|
-
|
|
74
|
-
const details: TableCellRenderer = props => (
|
|
75
|
-
<TableCell key="payloads" align="left" {...props}>
|
|
76
|
-
<Typography fontFamily="monospace" variant="body2" noWrap>
|
|
77
|
-
{payloadFieldCount}
|
|
78
|
-
</Typography>
|
|
79
|
-
</TableCell>
|
|
80
|
-
)
|
|
81
|
-
|
|
82
|
-
const render: TableCellRenderer = (props) => {
|
|
83
|
-
const Render: ComponentType<PayloadRenderProps & TableCellProps> | undefined
|
|
84
|
-
= payload ? resolver?.resolve(payload)?.components.table.cell : undefined
|
|
85
|
-
return Render ? <Render payload={payload} {...props} /> : <TableCell key="payloads" align="left" {...props}></TableCell>
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
const icon: TableCellRenderer = (props) => {
|
|
89
|
-
const Avatar: ComponentType<PayloadRenderProps & AvatarProps> | undefined
|
|
90
|
-
= payload ? resolver?.resolve(payload)?.components.avatar.image : undefined
|
|
91
|
-
|
|
92
|
-
return (
|
|
93
|
-
<TableCell key="payloads" align="left" {...props}>
|
|
94
|
-
{Avatar
|
|
95
|
-
? <Avatar payload={payload} />
|
|
96
|
-
: null}
|
|
97
|
-
</TableCell>
|
|
98
|
-
)
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
const valid: TableCellRenderer = props => (
|
|
102
|
-
<TableCell key="valid" align="center" {...props}>
|
|
103
|
-
{isValid === undefined && payload != undefined
|
|
104
|
-
? <WarningAmberRoundedIcon fontSize="small" color="warning" />
|
|
105
|
-
: isValid === true
|
|
106
|
-
? <CheckCircleOutlineRoundedIcon fontSize="small" color="success" />
|
|
107
|
-
: isValid === false
|
|
108
|
-
? <ErrorOutlineRoundedIcon color="error" fontSize="small" />
|
|
109
|
-
// nbsp to keep row height consistent even when no data is provided for the row
|
|
110
|
-
: <Typography> </Typography>}
|
|
111
|
-
</TableCell>
|
|
112
|
-
)
|
|
113
|
-
|
|
114
|
-
const tableCells: Record<PayloadDynamicTableColumnSlug, TableCellRenderer> = {
|
|
115
|
-
details,
|
|
116
|
-
hash,
|
|
117
|
-
icon,
|
|
118
|
-
render,
|
|
119
|
-
schema,
|
|
120
|
-
valid,
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
const columnsMemo = useMemo(() => columns ?? payloadDynamicTableColumnConfigDefaults(), [columns])
|
|
124
|
-
|
|
125
|
-
return breakPoint
|
|
126
|
-
? (
|
|
127
|
-
<TableRow style={{ maxWidth: '100vw' }} {...props}>
|
|
128
|
-
{columnsMemo[breakPoint]?.map((column) => {
|
|
129
|
-
return column.slug ? tableCells[column.slug]({}) : null
|
|
130
|
-
})}
|
|
131
|
-
</TableRow>
|
|
132
|
-
)
|
|
133
|
-
: null
|
|
134
|
-
}
|
|
@@ -1,98 +0,0 @@
|
|
|
1
|
-
export type PayloadDynamicTableColumnSlug = 'hash' | 'schema' | 'valid' | 'details' | 'render' | 'icon'
|
|
2
|
-
|
|
3
|
-
export interface PayloadDynamicTableColumnHeadData {
|
|
4
|
-
alignment?: 'left' | 'center' | 'right'
|
|
5
|
-
name?: string
|
|
6
|
-
slug?: 'hash' | 'schema' | 'valid' | 'details' | 'render' | 'icon'
|
|
7
|
-
width?: string | number
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
export interface PayloadDynamicTableColumnConfig {
|
|
11
|
-
xs?: PayloadDynamicTableColumnHeadData[]
|
|
12
|
-
// eslint-disable-next-line @typescript-eslint/member-ordering
|
|
13
|
-
sm?: PayloadDynamicTableColumnHeadData[]
|
|
14
|
-
// eslint-disable-next-line @typescript-eslint/member-ordering
|
|
15
|
-
md?: PayloadDynamicTableColumnHeadData[]
|
|
16
|
-
// eslint-disable-next-line @typescript-eslint/member-ordering
|
|
17
|
-
lg?: PayloadDynamicTableColumnHeadData[]
|
|
18
|
-
xl?: PayloadDynamicTableColumnHeadData[]
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
export const payloadDynamicTableColumnConfigDefaults = (): PayloadDynamicTableColumnConfig => {
|
|
22
|
-
const xs: PayloadDynamicTableColumnHeadData[] = [
|
|
23
|
-
{
|
|
24
|
-
alignment: 'left', name: 'Hash', slug: 'hash', width: '100%',
|
|
25
|
-
},
|
|
26
|
-
{
|
|
27
|
-
alignment: 'left', name: 'Schema', slug: 'schema', width: '50px',
|
|
28
|
-
},
|
|
29
|
-
{
|
|
30
|
-
alignment: 'left', name: 'Valid', slug: 'valid', width: '50px',
|
|
31
|
-
},
|
|
32
|
-
]
|
|
33
|
-
const sm: PayloadDynamicTableColumnHeadData[] = [
|
|
34
|
-
{
|
|
35
|
-
alignment: 'left', name: 'Icon', slug: 'icon', width: '50px',
|
|
36
|
-
},
|
|
37
|
-
{
|
|
38
|
-
alignment: 'left', name: 'Hash', slug: 'hash', width: '100%',
|
|
39
|
-
},
|
|
40
|
-
{
|
|
41
|
-
alignment: 'left', name: 'Schema', slug: 'schema', width: '50px',
|
|
42
|
-
},
|
|
43
|
-
{
|
|
44
|
-
alignment: 'left', name: 'Valid', slug: 'valid', width: '50px',
|
|
45
|
-
},
|
|
46
|
-
]
|
|
47
|
-
const md: PayloadDynamicTableColumnHeadData[] = [
|
|
48
|
-
{
|
|
49
|
-
alignment: 'left', name: 'Icon', slug: 'icon', width: '50px',
|
|
50
|
-
},
|
|
51
|
-
{
|
|
52
|
-
alignment: 'left', name: 'Hash', slug: 'hash', width: '100%',
|
|
53
|
-
},
|
|
54
|
-
{
|
|
55
|
-
alignment: 'left', name: 'Schema', slug: 'schema', width: '50px',
|
|
56
|
-
},
|
|
57
|
-
{
|
|
58
|
-
alignment: 'left', name: 'Valid', slug: 'valid', width: '50px',
|
|
59
|
-
},
|
|
60
|
-
]
|
|
61
|
-
const lg: PayloadDynamicTableColumnHeadData[] = [
|
|
62
|
-
{
|
|
63
|
-
alignment: 'left', name: 'Icon', slug: 'icon', width: '50px',
|
|
64
|
-
},
|
|
65
|
-
{
|
|
66
|
-
alignment: 'left', name: 'Hash', slug: 'hash', width: '100%',
|
|
67
|
-
},
|
|
68
|
-
{
|
|
69
|
-
alignment: 'left', name: 'Schema', slug: 'schema', width: '50px',
|
|
70
|
-
},
|
|
71
|
-
{
|
|
72
|
-
alignment: 'left', name: 'Render', slug: 'render', width: '50px',
|
|
73
|
-
},
|
|
74
|
-
{
|
|
75
|
-
alignment: 'left', name: 'Valid', slug: 'valid', width: '50px',
|
|
76
|
-
},
|
|
77
|
-
]
|
|
78
|
-
const xl: PayloadDynamicTableColumnHeadData[] = [
|
|
79
|
-
{
|
|
80
|
-
alignment: 'left', name: 'Icon', slug: 'icon', width: '50px',
|
|
81
|
-
},
|
|
82
|
-
{
|
|
83
|
-
alignment: 'left', name: 'Hash', slug: 'hash', width: '100%',
|
|
84
|
-
},
|
|
85
|
-
{
|
|
86
|
-
alignment: 'left', name: 'Schema', slug: 'schema', width: '50px',
|
|
87
|
-
},
|
|
88
|
-
{
|
|
89
|
-
alignment: 'left', name: 'Render', slug: 'render', width: '50px',
|
|
90
|
-
},
|
|
91
|
-
{
|
|
92
|
-
alignment: 'left', name: 'Valid', slug: 'valid', width: '50px',
|
|
93
|
-
},
|
|
94
|
-
]
|
|
95
|
-
return {
|
|
96
|
-
lg, md, sm, xl, xs,
|
|
97
|
-
}
|
|
98
|
-
}
|
|
@@ -1,194 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
FirstPage as FirstPageIcon, KeyboardArrowLeft, KeyboardArrowRight, LastPage as LastPageIcon,
|
|
3
|
-
} from '@mui/icons-material'
|
|
4
|
-
import type { TableProps } from '@mui/material'
|
|
5
|
-
import {
|
|
6
|
-
Alert,
|
|
7
|
-
Box,
|
|
8
|
-
IconButton,
|
|
9
|
-
Table,
|
|
10
|
-
TableBody,
|
|
11
|
-
TableCell,
|
|
12
|
-
TableFooter,
|
|
13
|
-
TableHead,
|
|
14
|
-
TablePagination,
|
|
15
|
-
TableRow,
|
|
16
|
-
Typography,
|
|
17
|
-
useTheme,
|
|
18
|
-
} from '@mui/material'
|
|
19
|
-
import { ThrownErrorBoundary } from '@xylabs/react-error'
|
|
20
|
-
import { useResetState } from '@xylabs/react-hooks'
|
|
21
|
-
import { useBreakpoint } from '@xylabs/react-shared'
|
|
22
|
-
import type { Payload } from '@xyo-network/payload-model'
|
|
23
|
-
import { usePayloadHashes } from '@xyo-network/react-shared'
|
|
24
|
-
import type { ReactNode } from 'react'
|
|
25
|
-
import React, { useMemo, useState } from 'react'
|
|
26
|
-
|
|
27
|
-
import { PayloadDynamicTableRow } from './DynamicTableRow.tsx'
|
|
28
|
-
import type { PayloadDynamicTableColumnConfig } from './PayloadDynamicTableColumnConfig.ts'
|
|
29
|
-
import { payloadDynamicTableColumnConfigDefaults } from './PayloadDynamicTableColumnConfig.ts'
|
|
30
|
-
|
|
31
|
-
export interface PayloadDynamicTableProps extends TableProps {
|
|
32
|
-
archive?: string
|
|
33
|
-
columns?: PayloadDynamicTableColumnConfig
|
|
34
|
-
exploreDomain?: string
|
|
35
|
-
onRowClick?: (value: Payload) => void
|
|
36
|
-
payloads?: Payload[] | null
|
|
37
|
-
rowsPerPage?: number
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
interface TablePaginationActionsProps {
|
|
41
|
-
count: number
|
|
42
|
-
onPageChange: (event: React.MouseEvent<HTMLButtonElement>, newPage: number) => void
|
|
43
|
-
page: number
|
|
44
|
-
rowsPerPage: number
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
const TablePaginationActions: React.FC<TablePaginationActionsProps> = (props) => {
|
|
48
|
-
const theme = useTheme()
|
|
49
|
-
const {
|
|
50
|
-
count, page, rowsPerPage, onPageChange,
|
|
51
|
-
} = props
|
|
52
|
-
|
|
53
|
-
const handleFirstPageButtonClick = (event: React.MouseEvent<HTMLButtonElement>) => {
|
|
54
|
-
onPageChange(event, 0)
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
const handleBackButtonClick = (event: React.MouseEvent<HTMLButtonElement>) => {
|
|
58
|
-
onPageChange(event, page - 1)
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
const handleNextButtonClick = (event: React.MouseEvent<HTMLButtonElement>) => {
|
|
62
|
-
onPageChange(event, page + 1)
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
const handleLastPageButtonClick = (event: React.MouseEvent<HTMLButtonElement>) => {
|
|
66
|
-
onPageChange(event, Math.max(0, Math.ceil(count / rowsPerPage) - 1))
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
return (
|
|
70
|
-
<Box sx={{ flexShrink: 0, ml: 2.5 }}>
|
|
71
|
-
<IconButton onClick={handleFirstPageButtonClick} disabled={page === 0} aria-label="first page">
|
|
72
|
-
{theme.direction === 'rtl'
|
|
73
|
-
? <LastPageIcon />
|
|
74
|
-
: <FirstPageIcon />}
|
|
75
|
-
</IconButton>
|
|
76
|
-
<IconButton onClick={handleBackButtonClick} disabled={page === 0} aria-label="previous page">
|
|
77
|
-
{theme.direction === 'rtl'
|
|
78
|
-
? <KeyboardArrowRight />
|
|
79
|
-
: <KeyboardArrowLeft />}
|
|
80
|
-
</IconButton>
|
|
81
|
-
<IconButton onClick={handleNextButtonClick} disabled={page >= Math.ceil(count / rowsPerPage) - 1} aria-label="next page">
|
|
82
|
-
{theme.direction === 'rtl'
|
|
83
|
-
? <KeyboardArrowLeft />
|
|
84
|
-
: <KeyboardArrowRight />}
|
|
85
|
-
</IconButton>
|
|
86
|
-
<IconButton onClick={handleLastPageButtonClick} disabled={page >= Math.ceil(count / rowsPerPage) - 1} aria-label="last page">
|
|
87
|
-
{theme.direction === 'rtl'
|
|
88
|
-
? <FirstPageIcon />
|
|
89
|
-
: <LastPageIcon />}
|
|
90
|
-
</IconButton>
|
|
91
|
-
</Box>
|
|
92
|
-
)
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
export const PayloadDynamicTable: React.FC<PayloadDynamicTableProps> = ({
|
|
96
|
-
archive,
|
|
97
|
-
children,
|
|
98
|
-
columns,
|
|
99
|
-
exploreDomain,
|
|
100
|
-
onRowClick,
|
|
101
|
-
rowsPerPage: rowsPerPageProp = 10,
|
|
102
|
-
payloads,
|
|
103
|
-
...props
|
|
104
|
-
}) => {
|
|
105
|
-
const breakPoint = useBreakpoint()
|
|
106
|
-
const [page, setPage] = useState(0)
|
|
107
|
-
const [rowsPerPage, setRowsPerPage] = useResetState(rowsPerPageProp)
|
|
108
|
-
const payloadCount = payloads ? payloads.length : 0
|
|
109
|
-
// Avoid a layout jump when reaching the last page with empty rows.
|
|
110
|
-
const emptyRows = page > 0 ? Math.max(0, (1 + page) * rowsPerPage - payloadCount) : 0
|
|
111
|
-
|
|
112
|
-
const pagedPayloads = useMemo(() => payloads?.slice(page * rowsPerPage, page * rowsPerPage + rowsPerPage), [payloads, page, rowsPerPage])
|
|
113
|
-
|
|
114
|
-
const payloadPairs = usePayloadHashes(pagedPayloads)
|
|
115
|
-
|
|
116
|
-
const handleChangePage = (event: React.MouseEvent<HTMLButtonElement> | null, newPage: number) => {
|
|
117
|
-
setPage(newPage)
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
const handleChangeRowsPerPage = (event: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>) => {
|
|
121
|
-
setRowsPerPage(Number.parseInt(event.target.value, 10))
|
|
122
|
-
setPage(0)
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
return breakPoint
|
|
126
|
-
? (
|
|
127
|
-
<Table stickyHeader {...props}>
|
|
128
|
-
<TableHead>
|
|
129
|
-
<TableRow>
|
|
130
|
-
{(columns ?? payloadDynamicTableColumnConfigDefaults())[breakPoint]?.map((column, index) => {
|
|
131
|
-
return (
|
|
132
|
-
<TableCell key={index} align={column.alignment ?? 'left'} width={column.width}>
|
|
133
|
-
<Typography variant="body2" noWrap>
|
|
134
|
-
{column.name}
|
|
135
|
-
</Typography>
|
|
136
|
-
</TableCell>
|
|
137
|
-
)
|
|
138
|
-
})}
|
|
139
|
-
</TableRow>
|
|
140
|
-
</TableHead>
|
|
141
|
-
<TableBody sx={{ overflowY: 'scroll ' }}>
|
|
142
|
-
{payloadPairs?.map(([payload, hash], index) => {
|
|
143
|
-
return (
|
|
144
|
-
<ThrownErrorBoundary
|
|
145
|
-
boundaryName="PayloadTableBody"
|
|
146
|
-
key={`${hash}-${index}`}
|
|
147
|
-
errorComponent={e => (
|
|
148
|
-
<Alert severity="error">
|
|
149
|
-
Error Loading Payload:
|
|
150
|
-
{' '}
|
|
151
|
-
<Typography fontWeight="bold">{e.message}</Typography>
|
|
152
|
-
</Alert>
|
|
153
|
-
)}
|
|
154
|
-
>
|
|
155
|
-
<PayloadDynamicTableRow
|
|
156
|
-
archive={archive}
|
|
157
|
-
onClick={
|
|
158
|
-
onRowClick
|
|
159
|
-
? () => {
|
|
160
|
-
onRowClick(payload)
|
|
161
|
-
}
|
|
162
|
-
: undefined
|
|
163
|
-
}
|
|
164
|
-
exploreDomain={exploreDomain}
|
|
165
|
-
payload={payload}
|
|
166
|
-
/>
|
|
167
|
-
</ThrownErrorBoundary>
|
|
168
|
-
)
|
|
169
|
-
})}
|
|
170
|
-
{children}
|
|
171
|
-
{emptyRows ? (Array.from({ length: emptyRows }).fill(<PayloadDynamicTableRow />) as ReactNode[]) : null}
|
|
172
|
-
</TableBody>
|
|
173
|
-
<TableFooter>
|
|
174
|
-
<TableRow>
|
|
175
|
-
<TablePagination
|
|
176
|
-
rowsPerPageOptions={[5, 10, 25, { label: 'All', value: -1 }]}
|
|
177
|
-
colSpan={5}
|
|
178
|
-
count={payloadCount}
|
|
179
|
-
rowsPerPage={rowsPerPage}
|
|
180
|
-
page={page}
|
|
181
|
-
SelectProps={{
|
|
182
|
-
inputProps: { 'aria-label': 'rows per page' },
|
|
183
|
-
native: true,
|
|
184
|
-
}}
|
|
185
|
-
onPageChange={handleChangePage}
|
|
186
|
-
onRowsPerPageChange={handleChangeRowsPerPage}
|
|
187
|
-
ActionsComponent={TablePaginationActions}
|
|
188
|
-
/>
|
|
189
|
-
</TableRow>
|
|
190
|
-
</TableFooter>
|
|
191
|
-
</Table>
|
|
192
|
-
)
|
|
193
|
-
: null
|
|
194
|
-
}
|
|
@@ -1,100 +0,0 @@
|
|
|
1
|
-
import { Button, Typography } from '@mui/material'
|
|
2
|
-
import type {
|
|
3
|
-
Decorator, Meta, StoryFn,
|
|
4
|
-
} from '@storybook/react-vite'
|
|
5
|
-
import { delay } from '@xylabs/sdk-js'
|
|
6
|
-
import { asSchema, type Payload } from '@xyo-network/payload-model'
|
|
7
|
-
import { useEvent } from '@xyo-network/react-event'
|
|
8
|
-
import React, { useEffect, useState } from 'react'
|
|
9
|
-
import { BrowserRouter } from 'react-router-dom'
|
|
10
|
-
|
|
11
|
-
import { PayloadTable } from './Table.tsx'
|
|
12
|
-
|
|
13
|
-
const newPayloads = () =>
|
|
14
|
-
Array(50)
|
|
15
|
-
// eslint-disable-next-line unicorn/no-useless-undefined
|
|
16
|
-
.fill(undefined)
|
|
17
|
-
.map((_, index) => ({
|
|
18
|
-
index, random: Math.random(), schema: asSchema('network.xyo.stories.test', true),
|
|
19
|
-
}))
|
|
20
|
-
|
|
21
|
-
// simulating the end of the list
|
|
22
|
-
const maxPayloads = 200
|
|
23
|
-
|
|
24
|
-
const NewPayloadsDecorator: Decorator = (Story, args) => {
|
|
25
|
-
const testPayloads = newPayloads()
|
|
26
|
-
const [payloads, setPayloads] = useState<Payload[]>([])
|
|
27
|
-
const [count, setCount] = useState(0)
|
|
28
|
-
|
|
29
|
-
const addToTotalPayloads = (payloads: Payload[]) =>
|
|
30
|
-
setPayloads((previous) => {
|
|
31
|
-
previous.push(...payloads)
|
|
32
|
-
setCount(previous.length)
|
|
33
|
-
return previous
|
|
34
|
-
})
|
|
35
|
-
|
|
36
|
-
useEffect(() => {
|
|
37
|
-
// simulate initial async payloads
|
|
38
|
-
const timeout = setTimeout(() => {
|
|
39
|
-
addToTotalPayloads(testPayloads)
|
|
40
|
-
}, 500)
|
|
41
|
-
return () => clearTimeout(timeout)
|
|
42
|
-
}, [])
|
|
43
|
-
|
|
44
|
-
const addPayloads = () => {
|
|
45
|
-
addToTotalPayloads(newPayloads())
|
|
46
|
-
return true
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
const newPayloadList = async () => {
|
|
50
|
-
// Simulating delay fetching new payloads
|
|
51
|
-
await delay(800)
|
|
52
|
-
const newPayloadList = newPayloads()
|
|
53
|
-
setCount(newPayloadList.length)
|
|
54
|
-
setPayloads(newPayloadList)
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
args.args = {
|
|
58
|
-
...args.args,
|
|
59
|
-
count,
|
|
60
|
-
fetchMorePayloads: payloads.length < maxPayloads ? addPayloads : null,
|
|
61
|
-
payloads,
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
return (
|
|
65
|
-
<>
|
|
66
|
-
<Typography>
|
|
67
|
-
Max Payloads:
|
|
68
|
-
{maxPayloads}
|
|
69
|
-
</Typography>
|
|
70
|
-
<Button variant="contained" onClick={newPayloadList}>
|
|
71
|
-
Simulate Network Change
|
|
72
|
-
</Button>
|
|
73
|
-
<Story {...args} />
|
|
74
|
-
</>
|
|
75
|
-
)
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
const StorybookEntry = {
|
|
79
|
-
argTypes: {},
|
|
80
|
-
component: PayloadTable,
|
|
81
|
-
parameters: { docs: { page: null } },
|
|
82
|
-
title: 'payload/FetchMoreTable',
|
|
83
|
-
} as Meta<typeof PayloadTable>
|
|
84
|
-
|
|
85
|
-
const Template: StoryFn<typeof PayloadTable> = (args) => {
|
|
86
|
-
const [ref] = useEvent<HTMLTableElement>((noun, verb, data) => console.log(`[${noun}|${verb}|${data}]`))
|
|
87
|
-
return (
|
|
88
|
-
<BrowserRouter>
|
|
89
|
-
<PayloadTable ref={ref} {...args}></PayloadTable>
|
|
90
|
-
</BrowserRouter>
|
|
91
|
-
)
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
const Default = Template.bind({})
|
|
95
|
-
Default.args = {}
|
|
96
|
-
Default.decorators = [NewPayloadsDecorator]
|
|
97
|
-
|
|
98
|
-
export { Default }
|
|
99
|
-
|
|
100
|
-
export default StorybookEntry
|
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
import type { TableColumnConfig, TableColumnNames } from './lib/index.ts'
|
|
2
|
-
|
|
3
|
-
export type PayloadTableColumnConfig = TableColumnConfig<PayloadTableColumnSlug>
|
|
4
|
-
|
|
5
|
-
export type PayloadTableColumnSlug = 'hash' | 'schema' | 'valid' | string
|
|
6
|
-
|
|
7
|
-
export const payloadColumnNames: TableColumnNames<PayloadTableColumnSlug> = {
|
|
8
|
-
hash: 'Hash',
|
|
9
|
-
schema: 'Schema',
|
|
10
|
-
valid: 'Valid',
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
export const payloadTableColumnConfigDefaults = (): PayloadTableColumnConfig => {
|
|
14
|
-
const xs: PayloadTableColumnSlug[] = ['hash', 'schema', 'valid']
|
|
15
|
-
const sm: PayloadTableColumnSlug[] = ['hash', 'schema', 'valid']
|
|
16
|
-
const md: PayloadTableColumnSlug[] = ['hash', 'schema', 'valid']
|
|
17
|
-
const lg: PayloadTableColumnSlug[] = ['hash', 'schema', 'valid']
|
|
18
|
-
const xl: PayloadTableColumnSlug[] = ['hash', 'schema', 'valid']
|
|
19
|
-
return {
|
|
20
|
-
lg, md, sm, xl, xs,
|
|
21
|
-
}
|
|
22
|
-
}
|