@xyo-network/react-payload-table 2.37.22 → 2.37.24

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,15 +1,18 @@
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;
7
7
  archive?: string;
8
8
  onRowClick?: (value: XyoPayload) => void;
9
+ fetchMorePayloads?: () => boolean;
9
10
  rowsPerPage?: number;
10
11
  payloads?: XyoPayload[] | null;
11
12
  columns?: PayloadTableColumnConfig;
12
13
  maxSchemaDepth?: number;
14
+ count?: number | null;
15
+ loading?: boolean;
13
16
  }
14
17
  export declare const PayloadTable: React.FC<PayloadTableProps>;
15
18
  //# 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,iBAAiB,CAAC,EAAE,MAAM,OAAO,CAAA;IACjC,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;IACvB,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACrB,OAAO,CAAC,EAAE,OAAO,CAAA;CAClB;AAED,eAAO,MAAM,YAAY,EAAE,KAAK,CAAC,EAAE,CAAC,iBAAiB,CA4HpD,CAAA"}
@@ -1,48 +1,43 @@
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
- import { useEffect, useState } from 'react';
7
+ import { useEffect, useMemo, 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, 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 [payloadCount, setPayloadCount] = useState(0);
16
+ const visiblePayloads = useMemo(() => payloads?.slice(page * rowsPerPage, page * rowsPerPage + rowsPerPage), [payloads, rowsPerPage, page]);
40
17
  // 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;
18
+ const emptyRows = page > 0 ? Math.max(0, (1 + page) * rowsPerPage - payloadCount || 0) : 0;
19
+ // when the count changes but the payload reference does not, update the count manually
20
+ useEffect(() => {
21
+ setPayloadCount(payloads !== undefined ? payloads?.length ?? 0 : 0);
22
+ }, [count, payloads]);
42
23
  useEffect(() => {
43
24
  setRowsPerPage(rowsPerPageProp);
44
25
  }, [rowsPerPageProp]);
26
+ // If the payload reference changes, assume we have a new list and reset current page
27
+ useEffect(() => {
28
+ setPage(0);
29
+ }, [payloads]);
45
30
  const handleChangePage = (event, newPage) => {
31
+ if (fetchMorePayloads) {
32
+ const buffer = rowsPerPage * 2;
33
+ const lastVisiblePayload = visiblePayloads?.at(-1);
34
+ if (lastVisiblePayload) {
35
+ const lastVisibleIndex = payloads?.indexOf(lastVisiblePayload);
36
+ if (payloads && lastVisibleIndex !== undefined && payloads?.length - (lastVisibleIndex + 1) <= buffer) {
37
+ fetchMorePayloads();
38
+ }
39
+ }
40
+ }
46
41
  setPage(newPage);
47
42
  };
48
43
  const handleChangeRowsPerPage = (event) => {
@@ -51,19 +46,25 @@ export const PayloadTable = ({ exploreDomain, archive, onRowClick, rowsPerPage:
51
46
  };
52
47
  return breakPoint ? (_jsxs(TableEx, { variant: variant, ...props, children: [_jsx(TableHead, { children: _jsx(TableRow, { children: columns[breakPoint]?.map((column, index) => {
53
48
  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) => {
49
+ }) }) }), _jsxs(TableBody, { children: [visiblePayloads?.map((payload, index) => {
56
50
  const wrapper = new PayloadWrapper(payload);
57
51
  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
52
  ? () => {
59
53
  onRowClick(payload);
60
54
  }
61
55
  : 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: {
56
+ }), 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: payloadCount, rowsPerPage: rowsPerPage, page: page, SelectProps: {
63
57
  inputProps: {
64
58
  'aria-label': 'rows per page',
65
59
  },
66
60
  native: true,
67
- }, onPageChange: handleChangePage, onRowsPerPageChange: handleChangeRowsPerPage, ActionsComponent: TablePaginationActions }) }) })] })) : null;
61
+ }, onPageChange: handleChangePage, onRowsPerPageChange: handleChangeRowsPerPage, ActionsComponent: (props) => _jsx(TablePaginationActions, { enableNextPage: !!fetchMorePayloads, loading: loading, ...props }) }) }) })] })) : null;
68
62
  };
63
+ const StyledTablePagination = styled(TablePagination)(({ theme }) => ({
64
+ '& > .MuiToolbar-root': {
65
+ paddingLeft: theme.spacing(1),
66
+ },
67
+ borderTop: '1px solid',
68
+ borderTopColor: theme.palette.divider,
69
+ }));
69
70
  //# 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.22",
15
- "@xyo-network/react-network": "^2.37.22",
16
- "@xyo-network/react-payload-plugin": "^2.37.22",
17
- "@xyo-network/react-shared": "^2.37.22",
18
- "@xyo-network/react-table": "^2.36.22",
14
+ "@xyo-network/react-auth-service": "^2.37.24",
15
+ "@xyo-network/react-network": "^2.37.24",
16
+ "@xyo-network/react-payload-plugin": "^2.37.24",
17
+ "@xyo-network/react-shared": "^2.37.24",
18
+ "@xyo-network/react-table": "^2.36.24",
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.22"
80
+ "version": "2.37.24"
81
81
  }
@@ -0,0 +1,81 @@
1
+ import { Button, Typography } from '@mui/material'
2
+ import { ComponentMeta, ComponentStory, DecoratorFn } from '@storybook/react'
3
+ import { delay } from '@xylabs/sdk-js'
4
+ import { XyoPayload } from '@xyo-network/payload'
5
+ import { useState } from 'react'
6
+ import { BrowserRouter } from 'react-router-dom'
7
+
8
+ import { PayloadTable } from './Table'
9
+
10
+ const newPayloads = () =>
11
+ Array(50)
12
+ .fill(undefined)
13
+ .map((_, index) => ({ index, random: Math.random(), schema: 'network.xyo.stories.test' }))
14
+
15
+ // simulating the end of the list
16
+ const maxPayloads = 200
17
+
18
+ const NewPayloadsDecorator: DecoratorFn = (Story, args) => {
19
+ const testPayloads = newPayloads()
20
+ const [payloads, setPayloads] = useState<XyoPayload[]>(testPayloads)
21
+ const [count, setCount] = useState(testPayloads.length)
22
+
23
+ const addPayloads = () => {
24
+ setPayloads((previous) => {
25
+ previous.push(...newPayloads())
26
+ setCount(previous.length)
27
+ return previous
28
+ })
29
+ return true
30
+ }
31
+
32
+ const newPayloadList = async () => {
33
+ // Simulating delay fetching new payloads
34
+ await delay(800)
35
+ const newPayloadList = newPayloads()
36
+ setPayloads(newPayloadList)
37
+ }
38
+
39
+ args.args = {
40
+ ...args.args,
41
+ count,
42
+ fetchMorePayloads: payloads.length < maxPayloads ? addPayloads : null,
43
+ payloads,
44
+ }
45
+
46
+ return (
47
+ <>
48
+ <Typography>Max Payloads: {maxPayloads}</Typography>
49
+ <Button variant="contained" onClick={newPayloadList}>
50
+ Simulate Network Change
51
+ </Button>
52
+ <Story {...args} />
53
+ </>
54
+ )
55
+ }
56
+
57
+ const StorybookEntry = {
58
+ argTypes: {},
59
+ component: PayloadTable,
60
+ parameters: {
61
+ docs: {
62
+ page: null,
63
+ },
64
+ },
65
+ title: 'payload/FetchMoreTable',
66
+ } as ComponentMeta<typeof PayloadTable>
67
+
68
+ const Template: ComponentStory<typeof PayloadTable> = (args) => (
69
+ <BrowserRouter>
70
+ <PayloadTable {...args}></PayloadTable>
71
+ </BrowserRouter>
72
+ )
73
+
74
+ const Default = Template.bind({})
75
+ Default.args = {}
76
+ Default.decorators = [NewPayloadsDecorator]
77
+
78
+ export { Default }
79
+
80
+ // eslint-disable-next-line import/no-default-export
81
+ export default StorybookEntry
@@ -1,100 +1,76 @@
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
- import { useEffect, useState } from 'react'
6
+ import { useEffect, useMemo, 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
16
+ fetchMorePayloads?: () => boolean
22
17
  rowsPerPage?: number
23
18
  payloads?: XyoPayload[] | null
24
19
  columns?: PayloadTableColumnConfig
25
20
  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
- )
21
+ count?: number | null
22
+ loading?: boolean
71
23
  }
72
24
 
73
25
  export const PayloadTable: React.FC<PayloadTableProps> = ({
74
26
  exploreDomain,
75
27
  archive,
76
28
  onRowClick,
29
+ fetchMorePayloads,
77
30
  rowsPerPage: rowsPerPageProp = 25,
78
31
  payloads,
79
32
  children,
80
33
  columns = payloadTableColumnConfigDefaults(),
81
34
  maxSchemaDepth,
35
+ count,
36
+ loading = false,
82
37
  variant = 'scrollable',
83
38
  ...props
84
39
  }) => {
85
- const theme = useTheme()
86
40
  const breakPoint = useBreakpoint()
87
41
  const [page, setPage] = useState(0)
88
42
  const [rowsPerPage, setRowsPerPage] = useState(rowsPerPageProp)
89
- const payloadCount = payloads ? payloads.length : 0
43
+ const [payloadCount, setPayloadCount] = useState(0)
44
+
45
+ const visiblePayloads = useMemo(() => payloads?.slice(page * rowsPerPage, page * rowsPerPage + rowsPerPage), [payloads, rowsPerPage, page])
90
46
  // 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
47
+ const emptyRows = page > 0 ? Math.max(0, (1 + page) * rowsPerPage - payloadCount || 0) : 0
48
+
49
+ // when the count changes but the payload reference does not, update the count manually
50
+ useEffect(() => {
51
+ setPayloadCount(payloads !== undefined ? payloads?.length ?? 0 : 0)
52
+ }, [count, payloads])
92
53
 
93
54
  useEffect(() => {
94
55
  setRowsPerPage(rowsPerPageProp)
95
56
  }, [rowsPerPageProp])
96
57
 
58
+ // If the payload reference changes, assume we have a new list and reset current page
59
+ useEffect(() => {
60
+ setPage(0)
61
+ }, [payloads])
62
+
97
63
  const handleChangePage = (event: React.MouseEvent<HTMLButtonElement> | null, newPage: number) => {
64
+ if (fetchMorePayloads) {
65
+ const buffer = rowsPerPage * 2
66
+ const lastVisiblePayload = visiblePayloads?.at(-1)
67
+ if (lastVisiblePayload) {
68
+ const lastVisibleIndex = payloads?.indexOf(lastVisiblePayload)
69
+ if (payloads && lastVisibleIndex !== undefined && payloads?.length - (lastVisibleIndex + 1) <= buffer) {
70
+ fetchMorePayloads()
71
+ }
72
+ }
73
+ }
98
74
  setPage(newPage)
99
75
  }
100
76
 
@@ -119,8 +95,7 @@ export const PayloadTable: React.FC<PayloadTableProps> = ({
119
95
  </TableRow>
120
96
  </TableHead>
121
97
  <TableBody>
122
- {payloads?.slice(page * rowsPerPage, page * rowsPerPage + rowsPerPage).map((payload, index) => {
123
- // {payloads?.map((payload, index) => {
98
+ {visiblePayloads?.map((payload, index) => {
124
99
  const wrapper = new PayloadWrapper(payload)
125
100
  return (
126
101
  <XyoApiThrownErrorBoundary
@@ -152,12 +127,11 @@ export const PayloadTable: React.FC<PayloadTableProps> = ({
152
127
  </TableBody>
153
128
  <TableFooterEx variant={variant}>
154
129
  <TableRow>
155
- <TablePagination
130
+ <StyledTablePagination
156
131
  rowsPerPageOptions={[5, 10, 25, { label: 'All', value: -1 }]}
157
132
  count={payloadCount}
158
133
  rowsPerPage={rowsPerPage}
159
134
  page={page}
160
- style={{ borderTop: '1px solid', borderTopColor: theme.palette.divider }}
161
135
  SelectProps={{
162
136
  inputProps: {
163
137
  'aria-label': 'rows per page',
@@ -166,10 +140,18 @@ export const PayloadTable: React.FC<PayloadTableProps> = ({
166
140
  }}
167
141
  onPageChange={handleChangePage}
168
142
  onRowsPerPageChange={handleChangeRowsPerPage}
169
- ActionsComponent={TablePaginationActions}
143
+ ActionsComponent={(props) => <TablePaginationActions enableNextPage={!!fetchMorePayloads} loading={loading} {...props} />}
170
144
  />
171
145
  </TableRow>
172
146
  </TableFooterEx>
173
147
  </TableEx>
174
148
  ) : null
175
149
  }
150
+
151
+ const StyledTablePagination = styled(TablePagination)(({ theme }) => ({
152
+ '& > .MuiToolbar-root': {
153
+ paddingLeft: theme.spacing(1),
154
+ },
155
+ borderTop: '1px solid',
156
+ borderTopColor: theme.palette.divider,
157
+ }))
@@ -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
+ }