@xyo-network/react-payload-table 2.37.23 → 2.37.25
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/cjs/components/Table/Table.d.ts +7 -1
- package/dist/cjs/components/Table/Table.d.ts.map +1 -1
- package/dist/cjs/components/Table/Table.js +38 -32
- package/dist/cjs/components/Table/Table.js.map +1 -1
- package/dist/cjs/components/Table/TablePagination.d.ts +12 -0
- package/dist/cjs/components/Table/TablePagination.d.ts.map +1 -0
- package/dist/cjs/components/Table/TablePagination.js +28 -0
- package/dist/cjs/components/Table/TablePagination.js.map +1 -0
- package/dist/docs.json +216 -99
- package/dist/esm/components/Table/Table.d.ts +7 -1
- package/dist/esm/components/Table/Table.d.ts.map +1 -1
- package/dist/esm/components/Table/Table.js +39 -33
- package/dist/esm/components/Table/Table.js.map +1 -1
- package/dist/esm/components/Table/TablePagination.d.ts +12 -0
- package/dist/esm/components/Table/TablePagination.d.ts.map +1 -0
- package/dist/esm/components/Table/TablePagination.js +23 -0
- package/dist/esm/components/Table/TablePagination.js.map +1 -0
- package/package.json +6 -6
- package/src/components/Table/FetchMoreTable.stories.tsx +94 -0
- package/src/components/Table/Table.tsx +54 -63
- package/src/components/Table/TablePagination.tsx +54 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
|
+
/// <reference types="react" />
|
|
1
2
|
import { XyoPayload } from '@xyo-network/payload';
|
|
2
3
|
import { TableExProps } from '@xyo-network/react-table';
|
|
3
|
-
import * as React from 'react';
|
|
4
4
|
import { PayloadTableColumnConfig } from './PayloadTableColumnConfig';
|
|
5
5
|
export interface PayloadTableProps extends TableExProps {
|
|
6
6
|
exploreDomain?: string;
|
|
@@ -8,8 +8,14 @@ export interface PayloadTableProps extends TableExProps {
|
|
|
8
8
|
onRowClick?: (value: XyoPayload) => void;
|
|
9
9
|
rowsPerPage?: number;
|
|
10
10
|
payloads?: XyoPayload[] | null;
|
|
11
|
+
loading?: boolean;
|
|
11
12
|
columns?: PayloadTableColumnConfig;
|
|
13
|
+
/** External trigger to fetch more payloads */
|
|
14
|
+
fetchMorePayloads?: () => void;
|
|
15
|
+
/** set number of schema parts to display starting from the end */
|
|
12
16
|
maxSchemaDepth?: number;
|
|
17
|
+
/** Total number of payloads passed */
|
|
18
|
+
count?: number;
|
|
13
19
|
}
|
|
14
20
|
export declare const PayloadTable: React.FC<PayloadTableProps>;
|
|
15
21
|
//# sourceMappingURL=Table.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Table.d.ts","sourceRoot":"","sources":["../../../../src/components/Table/Table.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"Table.d.ts","sourceRoot":"","sources":["../../../../src/components/Table/Table.tsx"],"names":[],"mappings":";AAEA,OAAO,EAAkB,UAAU,EAAE,MAAM,sBAAsB,CAAA;AAEjE,OAAO,EAAW,YAAY,EAAiB,MAAM,0BAA0B,CAAA;AAG/E,OAAO,EAAsB,wBAAwB,EAAoC,MAAM,4BAA4B,CAAA;AAI3H,MAAM,WAAW,iBAAkB,SAAQ,YAAY;IACrD,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,UAAU,CAAC,EAAE,CAAC,KAAK,EAAE,UAAU,KAAK,IAAI,CAAA;IACxC,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,QAAQ,CAAC,EAAE,UAAU,EAAE,GAAG,IAAI,CAAA;IAC9B,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,OAAO,CAAC,EAAE,wBAAwB,CAAA;IAClC,8CAA8C;IAC9C,iBAAiB,CAAC,EAAE,MAAM,IAAI,CAAA;IAC9B,kEAAkE;IAClE,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,sCAAsC;IACtC,KAAK,CAAC,EAAE,MAAM,CAAA;CACf;AAED,eAAO,MAAM,YAAY,EAAE,KAAK,CAAC,EAAE,CAAC,iBAAiB,CAkIpD,CAAA"}
|
|
@@ -1,48 +1,48 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
import
|
|
3
|
-
import KeyboardArrowLeft from '@mui/icons-material/KeyboardArrowLeft';
|
|
4
|
-
import KeyboardArrowRight from '@mui/icons-material/KeyboardArrowRight';
|
|
5
|
-
import LastPageIcon from '@mui/icons-material/LastPage';
|
|
6
|
-
import { Alert, TableBody, TableCell, TableHead, TablePagination, TableRow, Typography } from '@mui/material';
|
|
7
|
-
import Box from '@mui/material/Box';
|
|
8
|
-
import IconButton from '@mui/material/IconButton';
|
|
9
|
-
import { useTheme } from '@mui/material/styles';
|
|
2
|
+
import { Alert, styled, TableBody, TableCell, TableHead, TablePagination, TableRow, Typography } from '@mui/material';
|
|
10
3
|
import { useBreakpoint } from '@xylabs/react-shared';
|
|
11
4
|
import { PayloadWrapper } from '@xyo-network/payload';
|
|
12
5
|
import { XyoApiThrownErrorBoundary } from '@xyo-network/react-auth-service';
|
|
13
6
|
import { TableEx, TableFooterEx } from '@xyo-network/react-table';
|
|
14
7
|
import { useEffect, useState } from 'react';
|
|
15
8
|
import { payloadColumnNames, payloadTableColumnConfigDefaults } from './PayloadTableColumnConfig';
|
|
9
|
+
import { TablePaginationActions } from './TablePagination';
|
|
16
10
|
import { PayloadTableRow } from './TableRow';
|
|
17
|
-
|
|
18
|
-
const theme = useTheme();
|
|
19
|
-
const { count, page, rowsPerPage, onPageChange } = props;
|
|
20
|
-
const handleFirstPageButtonClick = (event) => {
|
|
21
|
-
onPageChange(event, 0);
|
|
22
|
-
};
|
|
23
|
-
const handleBackButtonClick = (event) => {
|
|
24
|
-
onPageChange(event, page - 1);
|
|
25
|
-
};
|
|
26
|
-
const handleNextButtonClick = (event) => {
|
|
27
|
-
onPageChange(event, page + 1);
|
|
28
|
-
};
|
|
29
|
-
const handleLastPageButtonClick = (event) => {
|
|
30
|
-
onPageChange(event, Math.max(0, Math.ceil(count / rowsPerPage) - 1));
|
|
31
|
-
};
|
|
32
|
-
return (_jsxs(Box, { sx: { flexShrink: 0, ml: 2.5 }, children: [_jsx(IconButton, { onClick: handleFirstPageButtonClick, disabled: page === 0, "aria-label": "first page", children: theme.direction === 'rtl' ? _jsx(LastPageIcon, {}) : _jsx(FirstPageIcon, {}) }), _jsx(IconButton, { onClick: handleBackButtonClick, disabled: page === 0, "aria-label": "previous page", children: theme.direction === 'rtl' ? _jsx(KeyboardArrowRight, {}) : _jsx(KeyboardArrowLeft, {}) }), _jsx(IconButton, { onClick: handleNextButtonClick, disabled: page >= Math.ceil(count / rowsPerPage) - 1, "aria-label": "next page", children: theme.direction === 'rtl' ? _jsx(KeyboardArrowLeft, {}) : _jsx(KeyboardArrowRight, {}) }), _jsx(IconButton, { onClick: handleLastPageButtonClick, disabled: page >= Math.ceil(count / rowsPerPage) - 1, "aria-label": "last page", children: theme.direction === 'rtl' ? _jsx(FirstPageIcon, {}) : _jsx(LastPageIcon, {}) })] }));
|
|
33
|
-
}
|
|
34
|
-
export const PayloadTable = ({ exploreDomain, archive, onRowClick, rowsPerPage: rowsPerPageProp = 25, payloads, children, columns = payloadTableColumnConfigDefaults(), maxSchemaDepth, variant = 'scrollable', ...props }) => {
|
|
35
|
-
const theme = useTheme();
|
|
11
|
+
export const PayloadTable = ({ exploreDomain, archive, onRowClick, fetchMorePayloads, rowsPerPage: rowsPerPageProp = 25, payloads, children, columns = payloadTableColumnConfigDefaults(), maxSchemaDepth, count = 0, loading = false, variant = 'scrollable', ...props }) => {
|
|
36
12
|
const breakPoint = useBreakpoint();
|
|
37
13
|
const [page, setPage] = useState(0);
|
|
38
14
|
const [rowsPerPage, setRowsPerPage] = useState(rowsPerPageProp);
|
|
39
|
-
const
|
|
15
|
+
const [visiblePayloads, setVisiblePayloads] = useState([]);
|
|
40
16
|
// Avoid a layout jump when reaching the last page with empty rows.
|
|
41
|
-
const emptyRows = page > 0 ? Math.max(0, (1 + page) * rowsPerPage -
|
|
17
|
+
const emptyRows = page > 0 ? Math.max(0, (1 + page) * rowsPerPage - count || 0) : 0;
|
|
42
18
|
useEffect(() => {
|
|
43
19
|
setRowsPerPage(rowsPerPageProp);
|
|
44
20
|
}, [rowsPerPageProp]);
|
|
21
|
+
// React to various prop changes to derive new visible payloads
|
|
22
|
+
// count is needed to show initial payloads added async to the same payloads reference
|
|
23
|
+
useEffect(() => {
|
|
24
|
+
if (payloads) {
|
|
25
|
+
setVisiblePayloads(payloads.slice(page * rowsPerPage, page * rowsPerPage + rowsPerPage));
|
|
26
|
+
}
|
|
27
|
+
}, [count, page, payloads, rowsPerPage]);
|
|
28
|
+
// If the payload reference changes, assume we have a new list and reset current page
|
|
29
|
+
useEffect(() => {
|
|
30
|
+
setPage(0);
|
|
31
|
+
}, [payloads]);
|
|
32
|
+
const handleAdditionalPayloads = () => {
|
|
33
|
+
if (fetchMorePayloads && payloads) {
|
|
34
|
+
const buffer = rowsPerPage * 2;
|
|
35
|
+
const lastVisiblePayload = visiblePayloads?.at(-1);
|
|
36
|
+
if (lastVisiblePayload) {
|
|
37
|
+
const lastVisibleIndex = payloads?.indexOf(lastVisiblePayload);
|
|
38
|
+
if (lastVisibleIndex !== undefined && payloads.length - (lastVisibleIndex + 1) <= buffer) {
|
|
39
|
+
fetchMorePayloads();
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
};
|
|
45
44
|
const handleChangePage = (event, newPage) => {
|
|
45
|
+
handleAdditionalPayloads();
|
|
46
46
|
setPage(newPage);
|
|
47
47
|
};
|
|
48
48
|
const handleChangeRowsPerPage = (event) => {
|
|
@@ -51,19 +51,25 @@ export const PayloadTable = ({ exploreDomain, archive, onRowClick, rowsPerPage:
|
|
|
51
51
|
};
|
|
52
52
|
return breakPoint ? (_jsxs(TableEx, { variant: variant, ...props, children: [_jsx(TableHead, { children: _jsx(TableRow, { children: columns[breakPoint]?.map((column, index) => {
|
|
53
53
|
return (_jsx(TableCell, { width: index === 0 ? '100%' : undefined, align: index === 0 ? 'left' : 'center', children: _jsx(Typography, { variant: "body2", noWrap: true, children: payloadColumnNames[column] }) }, index));
|
|
54
|
-
}) }) }), _jsxs(TableBody, { children: [
|
|
55
|
-
// {payloads?.map((payload, index) => {
|
|
54
|
+
}) }) }), _jsxs(TableBody, { children: [visiblePayloads?.map((payload, index) => {
|
|
56
55
|
const wrapper = new PayloadWrapper(payload);
|
|
57
56
|
return (_jsx(XyoApiThrownErrorBoundary, { errorComponent: (e) => (_jsxs(Alert, { severity: "error", children: ["Error Loading Payload: ", _jsx(Typography, { fontWeight: "bold", children: e.message })] })), children: _jsx(PayloadTableRow, { maxSchemaDepth: maxSchemaDepth, archive: archive, onClick: onRowClick
|
|
58
57
|
? () => {
|
|
59
58
|
onRowClick(payload);
|
|
60
59
|
}
|
|
61
60
|
: undefined, exploreDomain: exploreDomain, payload: payload }) }, `${wrapper.hash}-${index}`));
|
|
62
|
-
}), children, emptyRows > 0 && Array(emptyRows).fill(_jsx(PayloadTableRow, {}))] }), _jsx(TableFooterEx, { variant: variant, children: _jsx(TableRow, { children: _jsx(
|
|
61
|
+
}), children, emptyRows > 0 && Array(emptyRows).fill(_jsx(PayloadTableRow, {}))] }), _jsx(TableFooterEx, { variant: variant, children: _jsx(TableRow, { children: _jsx(StyledTablePagination, { rowsPerPageOptions: [5, 10, 25, { label: 'All', value: -1 }], count: count ?? 0, rowsPerPage: rowsPerPage, page: page, SelectProps: {
|
|
63
62
|
inputProps: {
|
|
64
63
|
'aria-label': 'rows per page',
|
|
65
64
|
},
|
|
66
65
|
native: true,
|
|
67
|
-
}, onPageChange: handleChangePage, onRowsPerPageChange: handleChangeRowsPerPage, ActionsComponent: TablePaginationActions }) }) })] })) : null;
|
|
66
|
+
}, onPageChange: handleChangePage, onRowsPerPageChange: handleChangeRowsPerPage, ActionsComponent: (props) => _jsx(TablePaginationActions, { enableNextPage: !!fetchMorePayloads, loading: loading, ...props }) }) }) })] })) : null;
|
|
68
67
|
};
|
|
68
|
+
const StyledTablePagination = styled(TablePagination)(({ theme }) => ({
|
|
69
|
+
'& > .MuiToolbar-root': {
|
|
70
|
+
paddingLeft: theme.spacing(1),
|
|
71
|
+
},
|
|
72
|
+
borderTop: '1px solid',
|
|
73
|
+
borderTopColor: theme.palette.divider,
|
|
74
|
+
}));
|
|
69
75
|
//# sourceMappingURL=Table.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Table.js","sourceRoot":"","sources":["../../../../src/components/Table/Table.tsx"],"names":[],"mappings":";AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"Table.js","sourceRoot":"","sources":["../../../../src/components/Table/Table.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/// <reference types="react" />
|
|
2
|
+
interface TablePaginationActionsProps {
|
|
3
|
+
count: number;
|
|
4
|
+
enableNextPage?: boolean;
|
|
5
|
+
page: number;
|
|
6
|
+
rowsPerPage: number;
|
|
7
|
+
loading?: boolean;
|
|
8
|
+
onPageChange: (event: React.MouseEvent<HTMLButtonElement>, newPage: number) => void;
|
|
9
|
+
}
|
|
10
|
+
export declare function TablePaginationActions({ count, page, rowsPerPage, onPageChange, enableNextPage, loading }: TablePaginationActionsProps): JSX.Element;
|
|
11
|
+
export {};
|
|
12
|
+
//# sourceMappingURL=TablePagination.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TablePagination.d.ts","sourceRoot":"","sources":["../../../../src/components/Table/TablePagination.tsx"],"names":[],"mappings":";AAMA,UAAU,2BAA2B;IACnC,KAAK,EAAE,MAAM,CAAA;IACb,cAAc,CAAC,EAAE,OAAO,CAAA;IACxB,IAAI,EAAE,MAAM,CAAA;IACZ,WAAW,EAAE,MAAM,CAAA;IACnB,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,YAAY,EAAE,CAAC,KAAK,EAAE,KAAK,CAAC,UAAU,CAAC,iBAAiB,CAAC,EAAE,OAAO,EAAE,MAAM,KAAK,IAAI,CAAA;CACpF;AAED,wBAAgB,sBAAsB,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,WAAW,EAAE,YAAY,EAAE,cAAc,EAAE,OAAO,EAAE,EAAE,2BAA2B,eAsCtI"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
+
import FirstPageIcon from '@mui/icons-material/FirstPage';
|
|
3
|
+
import KeyboardArrowLeft from '@mui/icons-material/KeyboardArrowLeft';
|
|
4
|
+
import KeyboardArrowRight from '@mui/icons-material/KeyboardArrowRight';
|
|
5
|
+
import LastPageIcon from '@mui/icons-material/LastPage';
|
|
6
|
+
import { Box, CircularProgress, IconButton, useTheme } from '@mui/material';
|
|
7
|
+
export function TablePaginationActions({ count, page, rowsPerPage, onPageChange, enableNextPage, loading }) {
|
|
8
|
+
const theme = useTheme();
|
|
9
|
+
const handleFirstPageButtonClick = (event) => {
|
|
10
|
+
onPageChange(event, 0);
|
|
11
|
+
};
|
|
12
|
+
const handleBackButtonClick = (event) => {
|
|
13
|
+
onPageChange(event, page - 1);
|
|
14
|
+
};
|
|
15
|
+
const handleNextButtonClick = (event) => {
|
|
16
|
+
onPageChange(event, page + 1);
|
|
17
|
+
};
|
|
18
|
+
const handleLastPageButtonClick = (event) => {
|
|
19
|
+
onPageChange(event, Math.max(0, Math.ceil(count / rowsPerPage) - 1));
|
|
20
|
+
};
|
|
21
|
+
return (_jsxs(_Fragment, { children: [loading ? _jsx(CircularProgress, { size: 'small', sx: { height: theme.spacing(2), position: 'absolute', width: theme.spacing(2) } }) : null, _jsxs(Box, { sx: { flexShrink: 0, ml: 2.5 }, children: [_jsx(IconButton, { onClick: handleFirstPageButtonClick, disabled: page === 0, "aria-label": "first page", children: theme.direction === 'rtl' ? _jsx(LastPageIcon, {}) : _jsx(FirstPageIcon, {}) }), _jsx(IconButton, { onClick: handleBackButtonClick, disabled: page === 0, "aria-label": "previous page", children: theme.direction === 'rtl' ? _jsx(KeyboardArrowRight, {}) : _jsx(KeyboardArrowLeft, {}) }), _jsx(IconButton, { onClick: handleNextButtonClick, disabled: !enableNextPage && page >= Math.ceil(count / rowsPerPage) - 1, "aria-label": "next page", children: theme.direction === 'rtl' ? _jsx(KeyboardArrowLeft, {}) : _jsx(KeyboardArrowRight, {}) }), _jsx(IconButton, { onClick: handleLastPageButtonClick, disabled: page >= Math.ceil(count / rowsPerPage) - 1, "aria-label": "last page", children: theme.direction === 'rtl' ? _jsx(FirstPageIcon, {}) : _jsx(LastPageIcon, {}) })] })] }));
|
|
22
|
+
}
|
|
23
|
+
//# sourceMappingURL=TablePagination.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TablePagination.js","sourceRoot":"","sources":["../../../../src/components/Table/TablePagination.tsx"],"names":[],"mappings":";AAAA,OAAO,aAAa,MAAM,+BAA+B,CAAA;AACzD,OAAO,iBAAiB,MAAM,uCAAuC,CAAA;AACrE,OAAO,kBAAkB,MAAM,wCAAwC,CAAA;AACvE,OAAO,YAAY,MAAM,8BAA8B,CAAA;AACvD,OAAO,EAAE,GAAG,EAAE,gBAAgB,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAA;AAW3E,MAAM,UAAU,sBAAsB,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,WAAW,EAAE,YAAY,EAAE,cAAc,EAAE,OAAO,EAA+B;IACrI,MAAM,KAAK,GAAG,QAAQ,EAAE,CAAA;IAExB,MAAM,0BAA0B,GAAG,CAAC,KAA0C,EAAE,EAAE;QAChF,YAAY,CAAC,KAAK,EAAE,CAAC,CAAC,CAAA;IACxB,CAAC,CAAA;IAED,MAAM,qBAAqB,GAAG,CAAC,KAA0C,EAAE,EAAE;QAC3E,YAAY,CAAC,KAAK,EAAE,IAAI,GAAG,CAAC,CAAC,CAAA;IAC/B,CAAC,CAAA;IAED,MAAM,qBAAqB,GAAG,CAAC,KAA0C,EAAE,EAAE;QAC3E,YAAY,CAAC,KAAK,EAAE,IAAI,GAAG,CAAC,CAAC,CAAA;IAC/B,CAAC,CAAA;IAED,MAAM,yBAAyB,GAAG,CAAC,KAA0C,EAAE,EAAE;QAC/E,YAAY,CAAC,KAAK,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,IAAI,CAAC,KAAK,GAAG,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC,CAAA;IACtE,CAAC,CAAA;IAED,OAAO,CACL,8BACG,OAAO,CAAC,CAAC,CAAC,KAAC,gBAAgB,IAAC,IAAI,EAAE,OAAO,EAAE,EAAE,EAAE,EAAE,MAAM,EAAE,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,UAAU,EAAE,KAAK,EAAE,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,GAAI,CAAC,CAAC,CAAC,IAAI,EACtI,MAAC,GAAG,IAAC,EAAE,EAAE,EAAE,UAAU,EAAE,CAAC,EAAE,EAAE,EAAE,GAAG,EAAE,aACjC,KAAC,UAAU,IAAC,OAAO,EAAE,0BAA0B,EAAE,QAAQ,EAAE,IAAI,KAAK,CAAC,gBAAa,YAAY,YAC3F,KAAK,CAAC,SAAS,KAAK,KAAK,CAAC,CAAC,CAAC,KAAC,YAAY,KAAG,CAAC,CAAC,CAAC,KAAC,aAAa,KAAG,GACtD,EACb,KAAC,UAAU,IAAC,OAAO,EAAE,qBAAqB,EAAE,QAAQ,EAAE,IAAI,KAAK,CAAC,gBAAa,eAAe,YACzF,KAAK,CAAC,SAAS,KAAK,KAAK,CAAC,CAAC,CAAC,KAAC,kBAAkB,KAAG,CAAC,CAAC,CAAC,KAAC,iBAAiB,KAAG,GAChE,EACb,KAAC,UAAU,IAAC,OAAO,EAAE,qBAAqB,EAAE,QAAQ,EAAE,CAAC,cAAc,IAAI,IAAI,IAAI,IAAI,CAAC,IAAI,CAAC,KAAK,GAAG,WAAW,CAAC,GAAG,CAAC,gBAAa,WAAW,YACxI,KAAK,CAAC,SAAS,KAAK,KAAK,CAAC,CAAC,CAAC,KAAC,iBAAiB,KAAG,CAAC,CAAC,CAAC,KAAC,kBAAkB,KAAG,GAChE,EACb,KAAC,UAAU,IAAC,OAAO,EAAE,yBAAyB,EAAE,QAAQ,EAAE,IAAI,IAAI,IAAI,CAAC,IAAI,CAAC,KAAK,GAAG,WAAW,CAAC,GAAG,CAAC,gBAAa,WAAW,YACzH,KAAK,CAAC,SAAS,KAAK,KAAK,CAAC,CAAC,CAAC,KAAC,aAAa,KAAG,CAAC,CAAC,CAAC,KAAC,YAAY,KAAG,GACtD,IACT,IACL,CACJ,CAAA;AACH,CAAC"}
|
package/package.json
CHANGED
|
@@ -11,11 +11,11 @@
|
|
|
11
11
|
},
|
|
12
12
|
"dependencies": {
|
|
13
13
|
"@xylabs/react-shared": "^2.15.1",
|
|
14
|
-
"@xyo-network/react-auth-service": "^2.37.
|
|
15
|
-
"@xyo-network/react-network": "^2.37.
|
|
16
|
-
"@xyo-network/react-payload-plugin": "^2.37.
|
|
17
|
-
"@xyo-network/react-shared": "^2.37.
|
|
18
|
-
"@xyo-network/react-table": "^2.36.
|
|
14
|
+
"@xyo-network/react-auth-service": "^2.37.25",
|
|
15
|
+
"@xyo-network/react-network": "^2.37.25",
|
|
16
|
+
"@xyo-network/react-payload-plugin": "^2.37.25",
|
|
17
|
+
"@xyo-network/react-shared": "^2.37.25",
|
|
18
|
+
"@xyo-network/react-table": "^2.36.25",
|
|
19
19
|
"tslib": "^2.4.0"
|
|
20
20
|
},
|
|
21
21
|
"peerDependencies": {
|
|
@@ -77,5 +77,5 @@
|
|
|
77
77
|
},
|
|
78
78
|
"sideEffects": false,
|
|
79
79
|
"types": "dist/esm/index.d.ts",
|
|
80
|
-
"version": "2.37.
|
|
80
|
+
"version": "2.37.25"
|
|
81
81
|
}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import { Button, Typography } from '@mui/material'
|
|
2
|
+
import { useEffect } from '@storybook/addons'
|
|
3
|
+
import { ComponentMeta, ComponentStory, DecoratorFn } from '@storybook/react'
|
|
4
|
+
import { delay } from '@xylabs/sdk-js'
|
|
5
|
+
import { XyoPayload } from '@xyo-network/payload'
|
|
6
|
+
import { useState } from 'react'
|
|
7
|
+
import { BrowserRouter } from 'react-router-dom'
|
|
8
|
+
|
|
9
|
+
import { PayloadTable } from './Table'
|
|
10
|
+
|
|
11
|
+
const newPayloads = () =>
|
|
12
|
+
Array(50)
|
|
13
|
+
.fill(undefined)
|
|
14
|
+
.map((_, index) => ({ index, random: Math.random(), schema: 'network.xyo.stories.test' }))
|
|
15
|
+
|
|
16
|
+
// simulating the end of the list
|
|
17
|
+
const maxPayloads = 200
|
|
18
|
+
|
|
19
|
+
const NewPayloadsDecorator: DecoratorFn = (Story, args) => {
|
|
20
|
+
const testPayloads = newPayloads()
|
|
21
|
+
const [payloads, setPayloads] = useState<XyoPayload[]>([])
|
|
22
|
+
const [count, setCount] = useState(0)
|
|
23
|
+
|
|
24
|
+
const addToTotalPayloads = (payloads: XyoPayload[]) =>
|
|
25
|
+
setPayloads((previous) => {
|
|
26
|
+
previous.push(...payloads)
|
|
27
|
+
setCount(previous.length)
|
|
28
|
+
return previous
|
|
29
|
+
})
|
|
30
|
+
|
|
31
|
+
useEffect(() => {
|
|
32
|
+
// simulate initial async payloads
|
|
33
|
+
setTimeout(() => {
|
|
34
|
+
addToTotalPayloads(testPayloads)
|
|
35
|
+
}, 500)
|
|
36
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
37
|
+
}, [])
|
|
38
|
+
|
|
39
|
+
const addPayloads = () => {
|
|
40
|
+
addToTotalPayloads(newPayloads())
|
|
41
|
+
return true
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
const newPayloadList = async () => {
|
|
45
|
+
// Simulating delay fetching new payloads
|
|
46
|
+
await delay(800)
|
|
47
|
+
const newPayloadList = newPayloads()
|
|
48
|
+
setCount(newPayloadList.length)
|
|
49
|
+
setPayloads(newPayloadList)
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
args.args = {
|
|
53
|
+
...args.args,
|
|
54
|
+
count,
|
|
55
|
+
fetchMorePayloads: payloads.length < maxPayloads ? addPayloads : null,
|
|
56
|
+
payloads,
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
return (
|
|
60
|
+
<>
|
|
61
|
+
<Typography>Max Payloads: {maxPayloads}</Typography>
|
|
62
|
+
<Button variant="contained" onClick={newPayloadList}>
|
|
63
|
+
Simulate Network Change
|
|
64
|
+
</Button>
|
|
65
|
+
<Story {...args} />
|
|
66
|
+
</>
|
|
67
|
+
)
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
const StorybookEntry = {
|
|
71
|
+
argTypes: {},
|
|
72
|
+
component: PayloadTable,
|
|
73
|
+
parameters: {
|
|
74
|
+
docs: {
|
|
75
|
+
page: null,
|
|
76
|
+
},
|
|
77
|
+
},
|
|
78
|
+
title: 'payload/FetchMoreTable',
|
|
79
|
+
} as ComponentMeta<typeof PayloadTable>
|
|
80
|
+
|
|
81
|
+
const Template: ComponentStory<typeof PayloadTable> = (args) => (
|
|
82
|
+
<BrowserRouter>
|
|
83
|
+
<PayloadTable {...args}></PayloadTable>
|
|
84
|
+
</BrowserRouter>
|
|
85
|
+
)
|
|
86
|
+
|
|
87
|
+
const Default = Template.bind({})
|
|
88
|
+
Default.args = {}
|
|
89
|
+
Default.decorators = [NewPayloadsDecorator]
|
|
90
|
+
|
|
91
|
+
export { Default }
|
|
92
|
+
|
|
93
|
+
// eslint-disable-next-line import/no-default-export
|
|
94
|
+
export default StorybookEntry
|
|
@@ -1,100 +1,85 @@
|
|
|
1
|
-
import
|
|
2
|
-
import KeyboardArrowLeft from '@mui/icons-material/KeyboardArrowLeft'
|
|
3
|
-
import KeyboardArrowRight from '@mui/icons-material/KeyboardArrowRight'
|
|
4
|
-
import LastPageIcon from '@mui/icons-material/LastPage'
|
|
5
|
-
import { Alert, TableBody, TableCell, TableHead, TablePagination, TableRow, Typography } from '@mui/material'
|
|
6
|
-
import Box from '@mui/material/Box'
|
|
7
|
-
import IconButton from '@mui/material/IconButton'
|
|
8
|
-
import { useTheme } from '@mui/material/styles'
|
|
1
|
+
import { Alert, styled, TableBody, TableCell, TableHead, TablePagination, TableRow, Typography } from '@mui/material'
|
|
9
2
|
import { useBreakpoint } from '@xylabs/react-shared'
|
|
10
3
|
import { PayloadWrapper, XyoPayload } from '@xyo-network/payload'
|
|
11
4
|
import { XyoApiThrownErrorBoundary } from '@xyo-network/react-auth-service'
|
|
12
5
|
import { TableEx, TableExProps, TableFooterEx } from '@xyo-network/react-table'
|
|
13
|
-
import * as React from 'react'
|
|
14
6
|
import { useEffect, useState } from 'react'
|
|
15
7
|
|
|
16
8
|
import { payloadColumnNames, PayloadTableColumnConfig, payloadTableColumnConfigDefaults } from './PayloadTableColumnConfig'
|
|
9
|
+
import { TablePaginationActions } from './TablePagination'
|
|
17
10
|
import { PayloadTableRow } from './TableRow'
|
|
11
|
+
|
|
18
12
|
export interface PayloadTableProps extends TableExProps {
|
|
19
13
|
exploreDomain?: string
|
|
20
14
|
archive?: string
|
|
21
15
|
onRowClick?: (value: XyoPayload) => void
|
|
22
16
|
rowsPerPage?: number
|
|
23
17
|
payloads?: XyoPayload[] | null
|
|
18
|
+
loading?: boolean
|
|
24
19
|
columns?: PayloadTableColumnConfig
|
|
20
|
+
/** External trigger to fetch more payloads */
|
|
21
|
+
fetchMorePayloads?: () => void
|
|
22
|
+
/** set number of schema parts to display starting from the end */
|
|
25
23
|
maxSchemaDepth?: number
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
interface TablePaginationActionsProps {
|
|
29
|
-
count: number
|
|
30
|
-
page: number
|
|
31
|
-
rowsPerPage: number
|
|
32
|
-
onPageChange: (event: React.MouseEvent<HTMLButtonElement>, newPage: number) => void
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
function TablePaginationActions(props: TablePaginationActionsProps) {
|
|
36
|
-
const theme = useTheme()
|
|
37
|
-
const { count, page, rowsPerPage, onPageChange } = props
|
|
38
|
-
|
|
39
|
-
const handleFirstPageButtonClick = (event: React.MouseEvent<HTMLButtonElement>) => {
|
|
40
|
-
onPageChange(event, 0)
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
const handleBackButtonClick = (event: React.MouseEvent<HTMLButtonElement>) => {
|
|
44
|
-
onPageChange(event, page - 1)
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
const handleNextButtonClick = (event: React.MouseEvent<HTMLButtonElement>) => {
|
|
48
|
-
onPageChange(event, page + 1)
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
const handleLastPageButtonClick = (event: React.MouseEvent<HTMLButtonElement>) => {
|
|
52
|
-
onPageChange(event, Math.max(0, Math.ceil(count / rowsPerPage) - 1))
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
return (
|
|
56
|
-
<Box sx={{ flexShrink: 0, ml: 2.5 }}>
|
|
57
|
-
<IconButton onClick={handleFirstPageButtonClick} disabled={page === 0} aria-label="first page">
|
|
58
|
-
{theme.direction === 'rtl' ? <LastPageIcon /> : <FirstPageIcon />}
|
|
59
|
-
</IconButton>
|
|
60
|
-
<IconButton onClick={handleBackButtonClick} disabled={page === 0} aria-label="previous page">
|
|
61
|
-
{theme.direction === 'rtl' ? <KeyboardArrowRight /> : <KeyboardArrowLeft />}
|
|
62
|
-
</IconButton>
|
|
63
|
-
<IconButton onClick={handleNextButtonClick} disabled={page >= Math.ceil(count / rowsPerPage) - 1} aria-label="next page">
|
|
64
|
-
{theme.direction === 'rtl' ? <KeyboardArrowLeft /> : <KeyboardArrowRight />}
|
|
65
|
-
</IconButton>
|
|
66
|
-
<IconButton onClick={handleLastPageButtonClick} disabled={page >= Math.ceil(count / rowsPerPage) - 1} aria-label="last page">
|
|
67
|
-
{theme.direction === 'rtl' ? <FirstPageIcon /> : <LastPageIcon />}
|
|
68
|
-
</IconButton>
|
|
69
|
-
</Box>
|
|
70
|
-
)
|
|
24
|
+
/** Total number of payloads passed */
|
|
25
|
+
count?: number
|
|
71
26
|
}
|
|
72
27
|
|
|
73
28
|
export const PayloadTable: React.FC<PayloadTableProps> = ({
|
|
74
29
|
exploreDomain,
|
|
75
30
|
archive,
|
|
76
31
|
onRowClick,
|
|
32
|
+
fetchMorePayloads,
|
|
77
33
|
rowsPerPage: rowsPerPageProp = 25,
|
|
78
34
|
payloads,
|
|
79
35
|
children,
|
|
80
36
|
columns = payloadTableColumnConfigDefaults(),
|
|
81
37
|
maxSchemaDepth,
|
|
38
|
+
count = 0,
|
|
39
|
+
loading = false,
|
|
82
40
|
variant = 'scrollable',
|
|
83
41
|
...props
|
|
84
42
|
}) => {
|
|
85
|
-
const theme = useTheme()
|
|
86
43
|
const breakPoint = useBreakpoint()
|
|
87
44
|
const [page, setPage] = useState(0)
|
|
88
45
|
const [rowsPerPage, setRowsPerPage] = useState(rowsPerPageProp)
|
|
89
|
-
const
|
|
46
|
+
const [visiblePayloads, setVisiblePayloads] = useState<XyoPayload[]>([])
|
|
47
|
+
|
|
90
48
|
// Avoid a layout jump when reaching the last page with empty rows.
|
|
91
|
-
const emptyRows = page > 0 ? Math.max(0, (1 + page) * rowsPerPage -
|
|
49
|
+
const emptyRows = page > 0 ? Math.max(0, (1 + page) * rowsPerPage - count || 0) : 0
|
|
92
50
|
|
|
93
51
|
useEffect(() => {
|
|
94
52
|
setRowsPerPage(rowsPerPageProp)
|
|
95
53
|
}, [rowsPerPageProp])
|
|
96
54
|
|
|
55
|
+
// React to various prop changes to derive new visible payloads
|
|
56
|
+
// count is needed to show initial payloads added async to the same payloads reference
|
|
57
|
+
useEffect(() => {
|
|
58
|
+
if (payloads) {
|
|
59
|
+
setVisiblePayloads(payloads.slice(page * rowsPerPage, page * rowsPerPage + rowsPerPage))
|
|
60
|
+
}
|
|
61
|
+
}, [count, page, payloads, rowsPerPage])
|
|
62
|
+
|
|
63
|
+
// If the payload reference changes, assume we have a new list and reset current page
|
|
64
|
+
useEffect(() => {
|
|
65
|
+
setPage(0)
|
|
66
|
+
}, [payloads])
|
|
67
|
+
|
|
68
|
+
const handleAdditionalPayloads = () => {
|
|
69
|
+
if (fetchMorePayloads && payloads) {
|
|
70
|
+
const buffer = rowsPerPage * 2
|
|
71
|
+
const lastVisiblePayload = visiblePayloads?.at(-1)
|
|
72
|
+
if (lastVisiblePayload) {
|
|
73
|
+
const lastVisibleIndex = payloads?.indexOf(lastVisiblePayload)
|
|
74
|
+
if (lastVisibleIndex !== undefined && payloads.length - (lastVisibleIndex + 1) <= buffer) {
|
|
75
|
+
fetchMorePayloads()
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
|
|
97
81
|
const handleChangePage = (event: React.MouseEvent<HTMLButtonElement> | null, newPage: number) => {
|
|
82
|
+
handleAdditionalPayloads()
|
|
98
83
|
setPage(newPage)
|
|
99
84
|
}
|
|
100
85
|
|
|
@@ -119,8 +104,7 @@ export const PayloadTable: React.FC<PayloadTableProps> = ({
|
|
|
119
104
|
</TableRow>
|
|
120
105
|
</TableHead>
|
|
121
106
|
<TableBody>
|
|
122
|
-
{
|
|
123
|
-
// {payloads?.map((payload, index) => {
|
|
107
|
+
{visiblePayloads?.map((payload, index) => {
|
|
124
108
|
const wrapper = new PayloadWrapper(payload)
|
|
125
109
|
return (
|
|
126
110
|
<XyoApiThrownErrorBoundary
|
|
@@ -152,12 +136,11 @@ export const PayloadTable: React.FC<PayloadTableProps> = ({
|
|
|
152
136
|
</TableBody>
|
|
153
137
|
<TableFooterEx variant={variant}>
|
|
154
138
|
<TableRow>
|
|
155
|
-
<
|
|
139
|
+
<StyledTablePagination
|
|
156
140
|
rowsPerPageOptions={[5, 10, 25, { label: 'All', value: -1 }]}
|
|
157
|
-
count={
|
|
141
|
+
count={count ?? 0}
|
|
158
142
|
rowsPerPage={rowsPerPage}
|
|
159
143
|
page={page}
|
|
160
|
-
style={{ borderTop: '1px solid', borderTopColor: theme.palette.divider }}
|
|
161
144
|
SelectProps={{
|
|
162
145
|
inputProps: {
|
|
163
146
|
'aria-label': 'rows per page',
|
|
@@ -166,10 +149,18 @@ export const PayloadTable: React.FC<PayloadTableProps> = ({
|
|
|
166
149
|
}}
|
|
167
150
|
onPageChange={handleChangePage}
|
|
168
151
|
onRowsPerPageChange={handleChangeRowsPerPage}
|
|
169
|
-
ActionsComponent={TablePaginationActions}
|
|
152
|
+
ActionsComponent={(props) => <TablePaginationActions enableNextPage={!!fetchMorePayloads} loading={loading} {...props} />}
|
|
170
153
|
/>
|
|
171
154
|
</TableRow>
|
|
172
155
|
</TableFooterEx>
|
|
173
156
|
</TableEx>
|
|
174
157
|
) : null
|
|
175
158
|
}
|
|
159
|
+
|
|
160
|
+
const StyledTablePagination = styled(TablePagination)(({ theme }) => ({
|
|
161
|
+
'& > .MuiToolbar-root': {
|
|
162
|
+
paddingLeft: theme.spacing(1),
|
|
163
|
+
},
|
|
164
|
+
borderTop: '1px solid',
|
|
165
|
+
borderTopColor: theme.palette.divider,
|
|
166
|
+
}))
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import FirstPageIcon from '@mui/icons-material/FirstPage'
|
|
2
|
+
import KeyboardArrowLeft from '@mui/icons-material/KeyboardArrowLeft'
|
|
3
|
+
import KeyboardArrowRight from '@mui/icons-material/KeyboardArrowRight'
|
|
4
|
+
import LastPageIcon from '@mui/icons-material/LastPage'
|
|
5
|
+
import { Box, CircularProgress, IconButton, useTheme } from '@mui/material'
|
|
6
|
+
|
|
7
|
+
interface TablePaginationActionsProps {
|
|
8
|
+
count: number
|
|
9
|
+
enableNextPage?: boolean
|
|
10
|
+
page: number
|
|
11
|
+
rowsPerPage: number
|
|
12
|
+
loading?: boolean
|
|
13
|
+
onPageChange: (event: React.MouseEvent<HTMLButtonElement>, newPage: number) => void
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export function TablePaginationActions({ count, page, rowsPerPage, onPageChange, enableNextPage, loading }: TablePaginationActionsProps) {
|
|
17
|
+
const theme = useTheme()
|
|
18
|
+
|
|
19
|
+
const handleFirstPageButtonClick = (event: React.MouseEvent<HTMLButtonElement>) => {
|
|
20
|
+
onPageChange(event, 0)
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
const handleBackButtonClick = (event: React.MouseEvent<HTMLButtonElement>) => {
|
|
24
|
+
onPageChange(event, page - 1)
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
const handleNextButtonClick = (event: React.MouseEvent<HTMLButtonElement>) => {
|
|
28
|
+
onPageChange(event, page + 1)
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
const handleLastPageButtonClick = (event: React.MouseEvent<HTMLButtonElement>) => {
|
|
32
|
+
onPageChange(event, Math.max(0, Math.ceil(count / rowsPerPage) - 1))
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
return (
|
|
36
|
+
<>
|
|
37
|
+
{loading ? <CircularProgress size={'small'} sx={{ height: theme.spacing(2), position: 'absolute', width: theme.spacing(2) }} /> : null}
|
|
38
|
+
<Box sx={{ flexShrink: 0, ml: 2.5 }}>
|
|
39
|
+
<IconButton onClick={handleFirstPageButtonClick} disabled={page === 0} aria-label="first page">
|
|
40
|
+
{theme.direction === 'rtl' ? <LastPageIcon /> : <FirstPageIcon />}
|
|
41
|
+
</IconButton>
|
|
42
|
+
<IconButton onClick={handleBackButtonClick} disabled={page === 0} aria-label="previous page">
|
|
43
|
+
{theme.direction === 'rtl' ? <KeyboardArrowRight /> : <KeyboardArrowLeft />}
|
|
44
|
+
</IconButton>
|
|
45
|
+
<IconButton onClick={handleNextButtonClick} disabled={!enableNextPage && page >= Math.ceil(count / rowsPerPage) - 1} aria-label="next page">
|
|
46
|
+
{theme.direction === 'rtl' ? <KeyboardArrowLeft /> : <KeyboardArrowRight />}
|
|
47
|
+
</IconButton>
|
|
48
|
+
<IconButton onClick={handleLastPageButtonClick} disabled={page >= Math.ceil(count / rowsPerPage) - 1} aria-label="last page">
|
|
49
|
+
{theme.direction === 'rtl' ? <FirstPageIcon /> : <LastPageIcon />}
|
|
50
|
+
</IconButton>
|
|
51
|
+
</Box>
|
|
52
|
+
</>
|
|
53
|
+
)
|
|
54
|
+
}
|