@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.
@@ -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":"AASA,OAAO,EAAkB,UAAU,EAAE,MAAM,sBAAsB,CAAA;AAEjE,OAAO,EAAW,YAAY,EAAiB,MAAM,0BAA0B,CAAA;AAC/E,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAG9B,OAAO,EAAsB,wBAAwB,EAAoC,MAAM,4BAA4B,CAAA;AAE3H,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,wBAAwB,CAAA;IAClC,cAAc,CAAC,EAAE,MAAM,CAAA;CACxB;AA+CD,eAAO,MAAM,YAAY,EAAE,KAAK,CAAC,EAAE,CAAC,iBAAiB,CAsGpD,CAAA"}
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 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 { 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
- function TablePaginationActions(props) {
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 payloadCount = payloads ? payloads.length : 0;
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 - payloadCount) : 0;
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: [payloads?.slice(page * rowsPerPage, page * rowsPerPage + rowsPerPage).map((payload, index) => {
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(TablePagination, { rowsPerPageOptions: [5, 10, 25, { label: 'All', value: -1 }], count: payloadCount, rowsPerPage: rowsPerPage, page: page, style: { borderTop: '1px solid', borderTopColor: theme.palette.divider }, SelectProps: {
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":"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"}
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.23",
15
- "@xyo-network/react-network": "^2.37.23",
16
- "@xyo-network/react-payload-plugin": "^2.37.23",
17
- "@xyo-network/react-shared": "^2.37.23",
18
- "@xyo-network/react-table": "^2.36.23",
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.23"
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 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 { 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 payloadCount = payloads ? payloads.length : 0
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 - payloadCount) : 0
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
- {payloads?.slice(page * rowsPerPage, page * rowsPerPage + rowsPerPage).map((payload, index) => {
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
- <TablePagination
139
+ <StyledTablePagination
156
140
  rowsPerPageOptions={[5, 10, 25, { label: 'All', value: -1 }]}
157
- count={payloadCount}
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
+ }