@bsol-oss/react-datatable5 12.0.0-beta.80 → 12.0.0-beta.81
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/index.d.ts +365 -353
- package/dist/index.js +1009 -831
- package/dist/index.mjs +1012 -834
- package/dist/types/components/DataTable/display/Table.d.ts +2 -1
- package/dist/types/components/DataTable/hooks/useResponsiveColumnVisibility.d.ts +13 -0
- package/dist/types/components/Form/components/fields/StringInputField.d.ts +4 -0
- package/dist/types/index.d.ts +64 -57
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
2
|
-
import { Button as Button$1, AbsoluteCenter, Spinner, Span, IconButton, Portal, Dialog, Flex, Text, useDisclosure, DialogBackdrop, RadioGroup as RadioGroup$1, Grid, Box, Slider as Slider$1, HStack, For, Tag as Tag$1, Input, Menu, createRecipeContext, createContext as createContext$1, Pagination as Pagination$1, usePaginationContext, CheckboxCard as CheckboxCard$1,
|
|
2
|
+
import { Button as Button$1, AbsoluteCenter, Spinner, Span, IconButton, Portal, Dialog, Flex, Text, useDisclosure, DialogBackdrop, RadioGroup as RadioGroup$1, Grid, Box, Slider as Slider$1, HStack, For, Tag as Tag$1, Input, Menu, createRecipeContext, createContext as createContext$1, Pagination as Pagination$1, usePaginationContext, CheckboxCard as CheckboxCard$1, Tooltip as Tooltip$1, Group, InputElement, Icon, EmptyState as EmptyState$2, VStack, List, Table as Table$1, Checkbox as Checkbox$1, Card, MenuRoot as MenuRoot$1, MenuTrigger as MenuTrigger$1, Image, Alert, Field as Field$1, Popover, NumberInput, Show, RadioCard, CheckboxGroup, Center, Heading, Skeleton } from '@chakra-ui/react';
|
|
3
3
|
import { AiOutlineColumnWidth } from 'react-icons/ai';
|
|
4
4
|
import * as React from 'react';
|
|
5
5
|
import React__default, { createContext, useContext, useState, useEffect, useRef, forwardRef } from 'react';
|
|
6
6
|
import { LuX, LuCheck, LuChevronRight, LuImage, LuFile, LuSearch } from 'react-icons/lu';
|
|
7
|
-
import { MdOutlineSort, MdFilterAlt, MdSearch, MdOutlineViewColumn, MdFilterListAlt, MdPushPin, MdCancel,
|
|
7
|
+
import { MdOutlineSort, MdFilterAlt, MdSearch, MdOutlineChecklist, MdClear, MdOutlineViewColumn, MdFilterListAlt, MdPushPin, MdCancel, MdDateRange } from 'react-icons/md';
|
|
8
8
|
import { FaUpDown, FaGripLinesVertical, FaTrash } from 'react-icons/fa6';
|
|
9
9
|
import { BiDownArrow, BiUpArrow, BiError } from 'react-icons/bi';
|
|
10
10
|
import { CgClose, CgTrash } from 'react-icons/cg';
|
|
@@ -17,13 +17,12 @@ import _defineProperty from '@babel/runtime/helpers/defineProperty';
|
|
|
17
17
|
import _toConsumableArray from '@babel/runtime/helpers/toConsumableArray';
|
|
18
18
|
import rafSchd from 'raf-schd';
|
|
19
19
|
import invariant from 'tiny-invariant';
|
|
20
|
-
import { HiColorSwatch, HiOutlineInformationCircle } from 'react-icons/hi';
|
|
21
|
-
import { flexRender, makeStateUpdater, functionalUpdate, useReactTable, getCoreRowModel, getFilteredRowModel, getSortedRowModel, getPaginationRowModel, createColumnHelper } from '@tanstack/react-table';
|
|
22
|
-
import { rankItem } from '@tanstack/match-sorter-utils';
|
|
23
|
-
import { BsExclamationCircleFill, BsClock } from 'react-icons/bs';
|
|
24
|
-
import { useDebounce } from '@uidotdev/usehooks';
|
|
25
20
|
import { useQueryClient, useQuery } from '@tanstack/react-query';
|
|
26
21
|
import { IoReload } from 'react-icons/io5';
|
|
22
|
+
import { useDebounce } from '@uidotdev/usehooks';
|
|
23
|
+
import { BsExclamationCircleFill, BsClock } from 'react-icons/bs';
|
|
24
|
+
import { HiColorSwatch, HiOutlineInformationCircle } from 'react-icons/hi';
|
|
25
|
+
import { flexRender, createColumnHelper, makeStateUpdater, functionalUpdate, useReactTable, getCoreRowModel, getFilteredRowModel, getSortedRowModel, getPaginationRowModel } from '@tanstack/react-table';
|
|
27
26
|
import { GrAscend, GrDescend } from 'react-icons/gr';
|
|
28
27
|
import { useTranslation } from 'react-i18next';
|
|
29
28
|
import axios from 'axios';
|
|
@@ -34,6 +33,7 @@ import dayjs from 'dayjs';
|
|
|
34
33
|
import utc from 'dayjs/plugin/utc';
|
|
35
34
|
import timezone from 'dayjs/plugin/timezone';
|
|
36
35
|
import { TiDeleteOutline } from 'react-icons/ti';
|
|
36
|
+
import { rankItem } from '@tanstack/match-sorter-utils';
|
|
37
37
|
|
|
38
38
|
const DataTableContext = createContext({
|
|
39
39
|
table: {},
|
|
@@ -2602,13 +2602,12 @@ const ViewDialog = ({ icon = jsx(IoMdEye, {}) }) => {
|
|
|
2602
2602
|
return (jsxs(DialogRoot, { children: [jsx(DialogBackdrop, {}), jsx(DialogTrigger, { asChild: true, children: jsxs(Button$1, { as: Box, variant: "ghost", onClick: viewModel.onOpen, children: [icon, " ", view] }) }), jsxs(DialogContent, { children: [jsx(DialogCloseTrigger, {}), jsx(DialogHeader, { children: jsx(DialogTitle, { children: view }) }), jsx(DialogBody, { children: jsx(TableViewer, {}) }), jsx(DialogFooter, {})] })] }));
|
|
2603
2603
|
};
|
|
2604
2604
|
|
|
2605
|
-
const
|
|
2606
|
-
|
|
2607
|
-
|
|
2608
|
-
|
|
2609
|
-
|
|
2610
|
-
|
|
2611
|
-
};
|
|
2605
|
+
const Tooltip = React.forwardRef(function Tooltip(props, ref) {
|
|
2606
|
+
const { showArrow, children, disabled, portalled, content, contentProps, portalRef, ...rest } = props;
|
|
2607
|
+
if (disabled)
|
|
2608
|
+
return children;
|
|
2609
|
+
return (jsxs(Tooltip$1.Root, { ...rest, children: [jsx(Tooltip$1.Trigger, { asChild: true, children: children }), jsx(Portal, { disabled: !portalled, container: portalRef, children: jsx(Tooltip$1.Positioner, { children: jsxs(Tooltip$1.Content, { ref: ref, ...contentProps, children: [showArrow && (jsx(Tooltip$1.Arrow, { children: jsx(Tooltip$1.ArrowTip, {}) })), content] }) }) })] }));
|
|
2610
|
+
});
|
|
2612
2611
|
|
|
2613
2612
|
const DataTableServerContext = createContext({
|
|
2614
2613
|
url: "",
|
|
@@ -2621,697 +2620,435 @@ const useDataTableServerContext = () => {
|
|
|
2621
2620
|
return { ...context, isEmpty };
|
|
2622
2621
|
};
|
|
2623
2622
|
|
|
2624
|
-
const
|
|
2625
|
-
const {
|
|
2626
|
-
|
|
2623
|
+
const ReloadButton = ({ variant = "icon", }) => {
|
|
2624
|
+
const { url } = useDataTableServerContext();
|
|
2625
|
+
const queryClient = useQueryClient();
|
|
2626
|
+
const { tableLabel } = useDataTableContext();
|
|
2627
|
+
const { reloadTooltip, reloadButtonText } = tableLabel;
|
|
2628
|
+
if (variant === "icon") {
|
|
2629
|
+
return (jsx(Tooltip, { showArrow: true, content: reloadTooltip, children: jsx(Button, { variant: "ghost", onClick: () => {
|
|
2630
|
+
queryClient.invalidateQueries({ queryKey: [url] });
|
|
2631
|
+
}, "aria-label": "refresh", children: jsx(IoReload, {}) }) }));
|
|
2632
|
+
}
|
|
2633
|
+
return (jsxs(Button, { variant: "ghost", onClick: () => {
|
|
2634
|
+
queryClient.invalidateQueries({ queryKey: [url] });
|
|
2635
|
+
}, children: [jsx(IoReload, {}), " ", reloadButtonText] }));
|
|
2627
2636
|
};
|
|
2628
2637
|
|
|
2629
|
-
const
|
|
2630
|
-
const {
|
|
2631
|
-
|
|
2632
|
-
|
|
2638
|
+
const InputGroup = React.forwardRef(function InputGroup(props, ref) {
|
|
2639
|
+
const { startElement, startElementProps, endElement, endElementProps, children, startOffset = "6px", endOffset = "6px", ...rest } = props;
|
|
2640
|
+
return (jsxs(Group, { ref: ref, ...rest, children: [startElement && (jsx(InputElement, { pointerEvents: "none", ...startElementProps, children: startElement })), React.cloneElement(children, {
|
|
2641
|
+
...(startElement && {
|
|
2642
|
+
ps: `calc(var(--input-height) - ${startOffset})`,
|
|
2643
|
+
}),
|
|
2644
|
+
...(endElement && { pe: `calc(var(--input-height) - ${endOffset})` }),
|
|
2645
|
+
// @ts-expect-error chakra generated files
|
|
2646
|
+
...children.props,
|
|
2647
|
+
}), endElement && (jsx(InputElement, { placement: "end", ...endElementProps, children: endElement }))] }));
|
|
2648
|
+
});
|
|
2649
|
+
|
|
2650
|
+
const GlobalFilter = () => {
|
|
2651
|
+
const { table, tableLabel } = useDataTableContext();
|
|
2652
|
+
const { globalFilterPlaceholder } = tableLabel;
|
|
2653
|
+
const [searchTerm, setSearchTerm] = useState("");
|
|
2654
|
+
const debouncedSearchTerm = useDebounce(searchTerm, 500);
|
|
2655
|
+
useEffect(() => {
|
|
2656
|
+
const searchHN = async () => {
|
|
2657
|
+
table.setGlobalFilter(debouncedSearchTerm);
|
|
2658
|
+
};
|
|
2659
|
+
searchHN();
|
|
2660
|
+
}, [debouncedSearchTerm]);
|
|
2661
|
+
return (jsx(Fragment, { children: jsx(InputGroup, { flex: "1", startElement: jsx(MdSearch, {}), children: jsx(Input, { placeholder: globalFilterPlaceholder, variant: "outline", onChange: (e) => {
|
|
2662
|
+
setSearchTerm(e.target.value);
|
|
2663
|
+
} }) }) }));
|
|
2633
2664
|
};
|
|
2634
2665
|
|
|
2635
|
-
const
|
|
2636
|
-
|
|
2637
|
-
|
|
2638
|
-
|
|
2639
|
-
|
|
2666
|
+
const SelectAllRowsToggle = ({ selectAllIcon = jsx(MdOutlineChecklist, {}), clearAllIcon = jsx(MdClear, {}), selectAllText = "", clearAllText = "", }) => {
|
|
2667
|
+
const { table } = useDataTableContext();
|
|
2668
|
+
return (jsxs(Fragment, { children: [!!selectAllText === false && (jsx(IconButton, { variant: "ghost", "aria-label": table.getIsAllRowsSelected() ? clearAllText : selectAllText, onClick: (event) => {
|
|
2669
|
+
table.getToggleAllRowsSelectedHandler()(event);
|
|
2670
|
+
}, children: table.getIsAllRowsSelected() ? clearAllIcon : selectAllIcon })), !!selectAllText !== false && (jsxs(Button$1, { variant: "ghost", onClick: (event) => {
|
|
2671
|
+
table.getToggleAllRowsSelectedHandler()(event);
|
|
2672
|
+
}, children: [table.getIsAllRowsSelected() ? clearAllIcon : selectAllIcon, table.getIsAllRowsSelected() ? clearAllText : selectAllText] }))] }));
|
|
2640
2673
|
};
|
|
2641
2674
|
|
|
2642
|
-
const
|
|
2643
|
-
const
|
|
2644
|
-
|
|
2645
|
-
|
|
2646
|
-
|
|
2647
|
-
return snakeToLabel(field);
|
|
2648
|
-
};
|
|
2649
|
-
if (object === null) {
|
|
2650
|
-
return jsx(Fragment, { children: "null" });
|
|
2651
|
-
}
|
|
2652
|
-
return (jsx(Grid, { rowGap: 1, padding: 1, overflow: "auto", ...boxProps, children: Object.entries(object).map(([field, value]) => {
|
|
2653
|
-
return (jsxs(Grid, { columnGap: 2, gridTemplateColumns: "auto 1fr", children: [jsx(Text, { color: "colorPalette.400", children: getColumn({ field }) }), typeof value === "object" ? (jsx(RecordDisplay, { object: value, prefix: `${prefix}${field}.`, translate: translate })) : (jsx(Text, { children: JSON.stringify(value) }))] }, field));
|
|
2654
|
-
}) }));
|
|
2675
|
+
const TableSelector = () => {
|
|
2676
|
+
const { table } = useDataTableContext();
|
|
2677
|
+
return (jsxs(Fragment, { children: [table.getSelectedRowModel().rows.length > 0 && (jsxs(Button$1, { onClick: () => { }, variant: "ghost", display: "flex", gap: "0.25rem", children: [jsx(Box, { fontSize: "sm", children: `${table.getSelectedRowModel().rows.length}` }), jsx(IoMdCheckbox, {})] })), !table.getIsAllPageRowsSelected() && jsx(SelectAllRowsToggle, {}), table.getSelectedRowModel().rows.length > 0 && (jsx(IconButton, { variant: "ghost", onClick: () => {
|
|
2678
|
+
table.resetRowSelection();
|
|
2679
|
+
}, "aria-label": "reset selection", children: jsx(MdClear, {}) }))] }));
|
|
2655
2680
|
};
|
|
2656
2681
|
|
|
2657
|
-
const
|
|
2658
|
-
const {
|
|
2659
|
-
|
|
2660
|
-
|
|
2661
|
-
|
|
2662
|
-
|
|
2663
|
-
|
|
2664
|
-
|
|
2665
|
-
|
|
2666
|
-
if (typeof value === "object") {
|
|
2667
|
-
return JSON.stringify(value);
|
|
2668
|
-
}
|
|
2669
|
-
if (typeof value === "string") {
|
|
2670
|
-
return value;
|
|
2671
|
-
}
|
|
2672
|
-
if (typeof value === "number" || typeof value === "boolean") {
|
|
2673
|
-
return `${value}`;
|
|
2674
|
-
}
|
|
2675
|
-
if (value === undefined) {
|
|
2676
|
-
if (translate !== undefined) {
|
|
2677
|
-
return translate.t(`undefined`);
|
|
2678
|
-
}
|
|
2679
|
-
return `undefined`;
|
|
2680
|
-
}
|
|
2681
|
-
throw new Error(`value is unknown, ${typeof value}`);
|
|
2682
|
-
};
|
|
2683
|
-
const showCustomDataDisplay = cell.column.columnDef.meta?.showCustomDisplay ?? false;
|
|
2684
|
-
const gridColumn = cell.column.columnDef.meta?.gridColumn ?? [
|
|
2685
|
-
"span 12",
|
|
2686
|
-
"span 6",
|
|
2687
|
-
"span 3",
|
|
2688
|
-
];
|
|
2689
|
-
const gridRow = cell.column.columnDef.meta?.gridRow ?? {};
|
|
2690
|
-
if (showCustomDataDisplay) {
|
|
2691
|
-
return (jsx(Flex, { gridColumn, gridRow, children: flexRender(cell.column.columnDef.cell, cell.getContext()) }, cell.id));
|
|
2692
|
-
}
|
|
2693
|
-
const value = cell.getValue();
|
|
2694
|
-
if (typeof value === "object") {
|
|
2695
|
-
return (jsxs(Box, { gridColumn, gridRow, children: [jsx(Box, { children: getLabel({ columnId: cell.column.id }) }), jsx(RecordDisplay, { boxProps: {
|
|
2696
|
-
borderWidth: 1,
|
|
2697
|
-
borderRadius: 4,
|
|
2698
|
-
borderColor: "gray.400",
|
|
2699
|
-
paddingX: 4,
|
|
2700
|
-
paddingY: 2,
|
|
2701
|
-
}, object: value })] }, cell.id));
|
|
2702
|
-
}
|
|
2703
|
-
return (jsxs(Box, { gridColumn, gridRow, children: [jsx(Box, { color: "colorPalette.400", children: getLabel({ columnId: cell.column.id }) }), jsx(Box, { wordBreak: "break-word", textOverflow: "ellipsis", overflow: "hidden", children: `${formatValue(cell.getValue())}` })] }, cell.id));
|
|
2682
|
+
const TableFilterTags = () => {
|
|
2683
|
+
const { table } = useDataTableContext();
|
|
2684
|
+
return (jsx(Flex, { gap: "0.5rem", flexFlow: "wrap", children: table.getState().columnFilters.map(({ id, value }) => {
|
|
2685
|
+
return (jsx(Tag, { gap: "0.5rem", closable: true, cursor: "pointer", onClick: () => {
|
|
2686
|
+
table.setColumnFilters(table.getState().columnFilters.filter((filter) => {
|
|
2687
|
+
return filter.value != value;
|
|
2688
|
+
}));
|
|
2689
|
+
}, children: `${id}: ${value}` }, `${id}-${value}`));
|
|
2690
|
+
}) }));
|
|
2704
2691
|
};
|
|
2705
|
-
|
|
2706
|
-
|
|
2707
|
-
|
|
2708
|
-
|
|
2709
|
-
|
|
2710
|
-
|
|
2711
|
-
|
|
2712
|
-
|
|
2713
|
-
|
|
2714
|
-
|
|
2715
|
-
if (!column.getIsVisible()) {
|
|
2716
|
-
return jsx(Fragment, {});
|
|
2692
|
+
|
|
2693
|
+
const TableControls = ({ fitTableWidth = false, fitTableHeight = false, children = jsx(Fragment, {}), showGlobalFilter = false, showFilter = false, showFilterName = false, showFilterTags = false, showReload = false, showPagination = true, showPageSizeControl = true, showPageCountText = true, showView = true, filterTagsOptions = [], extraItems = jsx(Fragment, {}), loading = false, hasError = false, gridProps = {}, }) => {
|
|
2694
|
+
const { tableLabel, table } = useDataTableContext();
|
|
2695
|
+
const { rowCountText, hasErrorText } = tableLabel;
|
|
2696
|
+
return (jsxs(Grid, { templateRows: "auto 1fr", width: fitTableWidth ? "fit-content" : "100%", height: fitTableHeight ? "fit-content" : "100%", gap: "0.5rem", ...gridProps, children: [jsxs(Flex, { flexFlow: "column", gap: 2, children: [jsxs(Flex, { justifyContent: "space-between", children: [jsx(Box, { children: showView && jsx(ViewDialog, { icon: jsx(MdOutlineViewColumn, {}) }) }), jsxs(Flex, { gap: "0.5rem", alignItems: "center", justifySelf: "end", children: [loading && jsx(Spinner, { size: "sm" }), hasError && (jsx(Tooltip, { content: hasErrorText, children: jsx(Icon, { as: BsExclamationCircleFill, color: "red.400" }) })), showGlobalFilter && jsx(GlobalFilter, {}), showFilter && jsx(FilterDialog, {}), showReload && jsx(ReloadButton, {}), extraItems] })] }), filterTagsOptions.length > 0 && (jsx(Flex, { flexFlow: "column", gap: "0.5rem", children: filterTagsOptions.map((option) => {
|
|
2697
|
+
const { column, options } = option;
|
|
2698
|
+
const tableColumn = table.getColumn(column);
|
|
2699
|
+
return (jsxs(Flex, { alignItems: "center", flexFlow: "wrap", gap: "0.5rem", children: [tableColumn?.columnDef.meta?.displayName && (jsx(Text, { children: tableColumn?.columnDef.meta?.displayName })), jsx(TagFilter, { availableTags: options, selectedTags: tableColumn?.getFilterValue() ?? [], selectOne: true, onTagChange: (tags) => {
|
|
2700
|
+
if (tags.length === 0) {
|
|
2701
|
+
return tableColumn?.setFilterValue(undefined);
|
|
2717
2702
|
}
|
|
2718
|
-
|
|
2719
|
-
|
|
2720
|
-
|
|
2721
|
-
return cell.id === `${rowId}_${column.id}`;
|
|
2722
|
-
});
|
|
2723
|
-
return jsx(CellRenderer, { cell: foundCell });
|
|
2724
|
-
}) })] }, `chakra-table-card-${childCell?.id}`));
|
|
2725
|
-
}
|
|
2726
|
-
return jsx(CellRenderer, { cell: childCell });
|
|
2727
|
-
}) }) }, `chakra-table-card-${rowId}`));
|
|
2728
|
-
}) }));
|
|
2703
|
+
tableColumn?.setFilterValue(tags);
|
|
2704
|
+
} })] }, column));
|
|
2705
|
+
}) })), showFilterTags && (jsx(Flex, { children: jsx(TableFilterTags, {}) }))] }), jsx(Grid, { overflow: "auto", bg: { base: "colorPalette.50", _dark: "colorPalette.950" }, children: children }), (showPageSizeControl || showPageCountText || showPagination) && (jsxs(Flex, { justifyContent: "space-between", children: [jsxs(Flex, { gap: "1rem", alignItems: "center", children: [showPageSizeControl && jsx(PageSizeControl, {}), showPageCountText && (jsxs(Flex, { children: [jsx(Text, { paddingRight: "0.5rem", children: rowCountText }), jsx(RowCountText, {})] }))] }), jsx(Box, { justifySelf: "end", children: showPagination && jsx(Pagination, {}) })] }))] }));
|
|
2729
2706
|
};
|
|
2730
2707
|
|
|
2731
|
-
|
|
2732
|
-
|
|
2733
|
-
|
|
2734
|
-
|
|
2735
|
-
|
|
2736
|
-
|
|
2737
|
-
|
|
2738
|
-
|
|
2739
|
-
|
|
2740
|
-
|
|
2741
|
-
|
|
2742
|
-
}
|
|
2743
|
-
|
|
2744
|
-
|
|
2745
|
-
|
|
2746
|
-
|
|
2747
|
-
|
|
2748
|
-
|
|
2749
|
-
|
|
2750
|
-
|
|
2751
|
-
|
|
2752
|
-
|
|
2753
|
-
|
|
2754
|
-
|
|
2755
|
-
|
|
2756
|
-
|
|
2757
|
-
|
|
2758
|
-
|
|
2759
|
-
|
|
2760
|
-
|
|
2761
|
-
|
|
2762
|
-
|
|
2763
|
-
|
|
2764
|
-
|
|
2765
|
-
|
|
2766
|
-
|
|
2767
|
-
|
|
2768
|
-
|
|
2708
|
+
const EmptyState$1 = React.forwardRef(function EmptyState(props, ref) {
|
|
2709
|
+
const { title, description, icon, children, ...rest } = props;
|
|
2710
|
+
return (jsx(EmptyState$2.Root, { ref: ref, ...rest, children: jsxs(EmptyState$2.Content, { children: [icon && (jsx(EmptyState$2.Indicator, { children: icon })), description ? (jsxs(VStack, { textAlign: "center", children: [jsx(EmptyState$2.Title, { children: title }), jsx(EmptyState$2.Description, { children: description })] })) : (jsx(EmptyState$2.Title, { children: title })), children] }) }));
|
|
2711
|
+
});
|
|
2712
|
+
|
|
2713
|
+
/**
|
|
2714
|
+
* Hook to automatically hide/show columns based on container width.
|
|
2715
|
+
* Columns are hidden based on their responsivePriority (lower = hide first).
|
|
2716
|
+
* Only activates when canResize={false}.
|
|
2717
|
+
*/
|
|
2718
|
+
const useResponsiveColumnVisibility = ({ containerRef, enabled, showSelector = false, }) => {
|
|
2719
|
+
const { table, setColumnVisibility } = useDataTableContext();
|
|
2720
|
+
const autoHiddenRef = useRef(new Set());
|
|
2721
|
+
const userBaselineRef = useRef(null);
|
|
2722
|
+
const SELECTION_BOX_WIDTH = 20;
|
|
2723
|
+
useEffect(() => {
|
|
2724
|
+
if (!enabled || !containerRef.current) {
|
|
2725
|
+
// Reset when disabled
|
|
2726
|
+
if (!enabled) {
|
|
2727
|
+
userBaselineRef.current = null;
|
|
2728
|
+
autoHiddenRef.current = new Set();
|
|
2729
|
+
}
|
|
2730
|
+
return;
|
|
2731
|
+
}
|
|
2732
|
+
// Capture baseline visibility when hook is first enabled
|
|
2733
|
+
if (userBaselineRef.current === null) {
|
|
2734
|
+
userBaselineRef.current = { ...table.getState().columnVisibility };
|
|
2735
|
+
}
|
|
2736
|
+
const updateColumnVisibility = () => {
|
|
2737
|
+
const container = containerRef.current;
|
|
2738
|
+
if (!container || !userBaselineRef.current)
|
|
2739
|
+
return;
|
|
2740
|
+
const containerWidth = container.clientWidth;
|
|
2741
|
+
// Get all columns
|
|
2742
|
+
const allColumns = table.getAllLeafColumns();
|
|
2743
|
+
// Get current visibility state
|
|
2744
|
+
const currentVisibility = table.getState().columnVisibility;
|
|
2745
|
+
// Determine user-hidden columns based on baseline
|
|
2746
|
+
// Columns that are hidden in baseline are considered user-hidden
|
|
2747
|
+
const userBaseline = userBaselineRef.current;
|
|
2748
|
+
const userHiddenColumns = new Set();
|
|
2749
|
+
for (const col of allColumns) {
|
|
2750
|
+
// If column was hidden in baseline, it's user-hidden
|
|
2751
|
+
if (userBaseline[col.id] === false) {
|
|
2752
|
+
userHiddenColumns.add(col.id);
|
|
2769
2753
|
}
|
|
2770
|
-
|
|
2771
|
-
|
|
2754
|
+
}
|
|
2755
|
+
// Consider all columns except those hidden by user in baseline
|
|
2756
|
+
const columnsToConsider = allColumns.filter((col) => {
|
|
2757
|
+
return !userHiddenColumns.has(col.id);
|
|
2758
|
+
});
|
|
2759
|
+
// Calculate priority for each column
|
|
2760
|
+
// Lower priority = hide first, Infinity = never auto-hide
|
|
2761
|
+
const columnsWithPriority = columnsToConsider.map((col, index) => {
|
|
2762
|
+
const priority = col.columnDef.meta?.responsivePriority ?? Infinity;
|
|
2763
|
+
return {
|
|
2764
|
+
column: col,
|
|
2765
|
+
priority,
|
|
2766
|
+
size: col.getSize(),
|
|
2767
|
+
index,
|
|
2768
|
+
};
|
|
2769
|
+
});
|
|
2770
|
+
// Sort by priority (ascending), then by index for stable ordering
|
|
2771
|
+
columnsWithPriority.sort((a, b) => {
|
|
2772
|
+
if (a.priority !== b.priority) {
|
|
2773
|
+
return a.priority - b.priority;
|
|
2772
2774
|
}
|
|
2773
|
-
return
|
|
2775
|
+
return a.index - b.index;
|
|
2774
2776
|
});
|
|
2775
|
-
|
|
2776
|
-
|
|
2777
|
-
|
|
2778
|
-
|
|
2779
|
-
|
|
2780
|
-
|
|
2781
|
-
|
|
2782
|
-
|
|
2777
|
+
// Calculate available width (account for selector column if present)
|
|
2778
|
+
const availableWidth = showSelector
|
|
2779
|
+
? containerWidth - SELECTION_BOX_WIDTH
|
|
2780
|
+
: containerWidth;
|
|
2781
|
+
// Calculate which columns can fit
|
|
2782
|
+
let totalWidth = 0;
|
|
2783
|
+
const columnsToShow = new Set();
|
|
2784
|
+
// Always keep at least one column visible
|
|
2785
|
+
let minColumnsShown = 0;
|
|
2786
|
+
for (const { column, priority } of columnsWithPriority) {
|
|
2787
|
+
// If this is the first column and we haven't shown any, always show it
|
|
2788
|
+
if (minColumnsShown === 0) {
|
|
2789
|
+
columnsToShow.add(column.id);
|
|
2790
|
+
totalWidth += column.getSize();
|
|
2791
|
+
minColumnsShown = 1;
|
|
2792
|
+
continue;
|
|
2793
|
+
}
|
|
2794
|
+
// Check if adding this column would exceed available width
|
|
2795
|
+
const newTotalWidth = totalWidth + column.getSize();
|
|
2796
|
+
// If priority is Infinity, always show (never auto-hide)
|
|
2797
|
+
if (priority === Infinity) {
|
|
2798
|
+
columnsToShow.add(column.id);
|
|
2799
|
+
totalWidth = newTotalWidth;
|
|
2800
|
+
}
|
|
2801
|
+
else if (newTotalWidth <= availableWidth) {
|
|
2802
|
+
// Column fits, show it
|
|
2803
|
+
columnsToShow.add(column.id);
|
|
2804
|
+
totalWidth = newTotalWidth;
|
|
2805
|
+
}
|
|
2806
|
+
else ;
|
|
2783
2807
|
}
|
|
2784
|
-
|
|
2785
|
-
|
|
2808
|
+
// Update auto-hidden columns
|
|
2809
|
+
const newAutoHidden = new Set();
|
|
2810
|
+
const newVisibility = { ...currentVisibility };
|
|
2811
|
+
// Update visibility for all columns
|
|
2812
|
+
for (const col of allColumns) {
|
|
2813
|
+
const isUserHidden = userHiddenColumns.has(col.id);
|
|
2814
|
+
if (isUserHidden) {
|
|
2815
|
+
// Respect user preference to hide
|
|
2816
|
+
newVisibility[col.id] = false;
|
|
2817
|
+
}
|
|
2818
|
+
else {
|
|
2819
|
+
const shouldBeVisible = columnsToShow.has(col.id);
|
|
2820
|
+
if (!shouldBeVisible) {
|
|
2821
|
+
// Column should be auto-hidden
|
|
2822
|
+
newAutoHidden.add(col.id);
|
|
2823
|
+
newVisibility[col.id] = false;
|
|
2824
|
+
}
|
|
2825
|
+
else {
|
|
2826
|
+
// Column should be visible
|
|
2827
|
+
newVisibility[col.id] = true;
|
|
2828
|
+
}
|
|
2829
|
+
}
|
|
2786
2830
|
}
|
|
2787
|
-
|
|
2788
|
-
|
|
2831
|
+
// Update auto-hidden ref
|
|
2832
|
+
autoHiddenRef.current = newAutoHidden;
|
|
2833
|
+
// Only update if visibility actually changed
|
|
2834
|
+
const visibilityChanged = Object.keys(newVisibility).some((key) => newVisibility[key] !== currentVisibility[key]) ||
|
|
2835
|
+
Object.keys(currentVisibility).some((key) => newVisibility[key] !== currentVisibility[key]);
|
|
2836
|
+
if (visibilityChanged) {
|
|
2837
|
+
setColumnVisibility(newVisibility);
|
|
2789
2838
|
}
|
|
2790
|
-
return 32;
|
|
2791
2839
|
};
|
|
2792
|
-
|
|
2793
|
-
|
|
2794
|
-
|
|
2795
|
-
|
|
2796
|
-
|
|
2797
|
-
|
|
2798
|
-
|
|
2799
|
-
|
|
2800
|
-
|
|
2840
|
+
// Initial calculation
|
|
2841
|
+
updateColumnVisibility();
|
|
2842
|
+
// Set up ResizeObserver
|
|
2843
|
+
const resizeObserver = new ResizeObserver(() => {
|
|
2844
|
+
updateColumnVisibility();
|
|
2845
|
+
});
|
|
2846
|
+
resizeObserver.observe(containerRef.current);
|
|
2847
|
+
return () => {
|
|
2848
|
+
resizeObserver.disconnect();
|
|
2849
|
+
};
|
|
2850
|
+
}, [enabled, containerRef, table, setColumnVisibility, showSelector]);
|
|
2801
2851
|
};
|
|
2802
|
-
//end of custom feature code
|
|
2803
2852
|
|
|
2804
|
-
|
|
2805
|
-
const
|
|
2806
|
-
|
|
2807
|
-
const
|
|
2808
|
-
//
|
|
2809
|
-
|
|
2810
|
-
|
|
2853
|
+
const EmptyResult = (jsx(EmptyState$1, { icon: jsx(HiColorSwatch, {}), title: "No results found", description: "Try adjusting your search", children: jsxs(List.Root, { variant: "marker", children: [jsx(List.Item, { children: "Try removing filters" }), jsx(List.Item, { children: "Try different keywords" })] }) }));
|
|
2854
|
+
const Table = ({ children, emptyComponent = EmptyResult, canResize = true, showLoading = false, showSelector = false, ...props }) => {
|
|
2855
|
+
const { table } = useDataTableContext();
|
|
2856
|
+
const containerRef = useRef(null);
|
|
2857
|
+
// Enable responsive column hiding when canResize is false
|
|
2858
|
+
useResponsiveColumnVisibility({
|
|
2859
|
+
containerRef,
|
|
2860
|
+
enabled: !canResize,
|
|
2861
|
+
showSelector,
|
|
2811
2862
|
});
|
|
2812
|
-
//
|
|
2813
|
-
|
|
2863
|
+
// Skip empty check when loading to allow skeleton to render
|
|
2864
|
+
if (!showLoading && table.getRowModel().rows.length <= 0) {
|
|
2865
|
+
return emptyComponent;
|
|
2866
|
+
}
|
|
2867
|
+
return (jsx(Box, { ref: containerRef, width: "100%", overflow: "auto", children: jsx(Table$1.Root, { stickyHeader: true, variant: 'outline', width: canResize ? table.getCenterTotalSize() : undefined, display: 'grid', alignContent: 'start', overflowY: 'auto', bg: { base: 'colorPalette.50', _dark: 'colorPalette.950' }, ...props, children: children }) }));
|
|
2868
|
+
};
|
|
2869
|
+
|
|
2870
|
+
const Checkbox = React.forwardRef(function Checkbox(props, ref) {
|
|
2871
|
+
const { icon, children, inputProps, rootRef, ...rest } = props;
|
|
2872
|
+
return (jsxs(Checkbox$1.Root, { ref: rootRef, ...rest, children: [jsx(Checkbox$1.HiddenInput, { ref: ref, ...inputProps }), jsx(Checkbox$1.Control, { children: icon || jsx(Checkbox$1.Indicator, {}) }), children != null && (jsx(Checkbox$1.Label, { children: children }))] }));
|
|
2873
|
+
});
|
|
2874
|
+
|
|
2875
|
+
const TableBody = ({ showSelector = false, canResize = true, }) => {
|
|
2876
|
+
"use no memo";
|
|
2877
|
+
const { table } = useDataTableContext();
|
|
2878
|
+
const SELECTION_BOX_WIDTH = 20;
|
|
2879
|
+
const [hoveredRow, setHoveredRow] = useState(-1);
|
|
2880
|
+
const handleRowHover = (index) => {
|
|
2881
|
+
setHoveredRow(index);
|
|
2882
|
+
};
|
|
2883
|
+
const getTdProps = (cell) => {
|
|
2884
|
+
const tdProps = cell.column.getIsPinned()
|
|
2885
|
+
? {
|
|
2886
|
+
left: showSelector
|
|
2887
|
+
? `${cell.column.getStart("left") + SELECTION_BOX_WIDTH + table.getDensityValue() * 2}px`
|
|
2888
|
+
: `${cell.column.getStart("left")}px`,
|
|
2889
|
+
position: "relative",
|
|
2890
|
+
}
|
|
2891
|
+
: {};
|
|
2892
|
+
return tdProps;
|
|
2893
|
+
};
|
|
2894
|
+
const getTrProps = ({ hoveredRow, index, }) => {
|
|
2895
|
+
if (hoveredRow === -1) {
|
|
2896
|
+
return {};
|
|
2897
|
+
}
|
|
2898
|
+
if (hoveredRow === index) {
|
|
2899
|
+
return {
|
|
2900
|
+
opacity: "1",
|
|
2901
|
+
};
|
|
2902
|
+
}
|
|
2903
|
+
return {
|
|
2904
|
+
opacity: "0.8",
|
|
2905
|
+
};
|
|
2906
|
+
};
|
|
2907
|
+
return (jsx(Table$1.Body, { children: table.getRowModel().rows.map((row, index) => {
|
|
2908
|
+
return (jsxs(Table$1.Row, { display: "flex", zIndex: 1, onMouseEnter: () => handleRowHover(index), onMouseLeave: () => handleRowHover(-1), ...getTrProps({ hoveredRow, index }), children: [showSelector && (jsx(TableRowSelector, { index: index, row: row, hoveredRow: hoveredRow })), row.getVisibleCells().map((cell, index) => {
|
|
2909
|
+
return (jsx(Table$1.Cell, { padding: `${table.getDensityValue()}px`,
|
|
2910
|
+
// styling resize and pinning start
|
|
2911
|
+
flex: `${canResize ? "0" : "1"} 0 ${cell.column.getSize()}px`,
|
|
2912
|
+
// this is to avoid the cell from being too wide
|
|
2913
|
+
minWidth: `0`, color: {
|
|
2914
|
+
base: "colorPalette.900",
|
|
2915
|
+
_dark: "colorPalette.100",
|
|
2916
|
+
},
|
|
2917
|
+
bg: { base: "colorPalette.50", _dark: "colorPalette.950" }, ...getTdProps(cell), children: flexRender(cell.column.columnDef.cell, cell.getContext()) }, `chakra-table-rowcell-${cell.id}-${index}`));
|
|
2918
|
+
})] }, `chakra-table-row-${row.id}`));
|
|
2919
|
+
}) }));
|
|
2920
|
+
};
|
|
2921
|
+
const TableRowSelector = ({ row, }) => {
|
|
2922
|
+
const { table } = useDataTableContext();
|
|
2923
|
+
const SELECTION_BOX_WIDTH = 20;
|
|
2924
|
+
return (jsx(Table$1.Cell, { padding: `${table.getDensityValue()}px`, display: "grid", color: {
|
|
2925
|
+
base: "colorPalette.900",
|
|
2926
|
+
_dark: "colorPalette.100",
|
|
2927
|
+
},
|
|
2928
|
+
bg: { base: "colorPalette.50", _dark: "colorPalette.950" }, justifyItems: "center", alignItems: "center", children: jsx(Checkbox, { width: `${SELECTION_BOX_WIDTH}px`, height: `${SELECTION_BOX_WIDTH}px`, checked: row.getIsSelected(),
|
|
2929
|
+
disabled: !row.getCanSelect(),
|
|
2930
|
+
onCheckedChange: row.getToggleSelectedHandler() }) }));
|
|
2931
|
+
};
|
|
2932
|
+
|
|
2933
|
+
const TableCardContainer = ({ children, variant = "", gap = "1rem", gridTemplateColumns = "repeat(auto-fit, minmax(20rem, 1fr))", direction = "row", ...props }) => {
|
|
2934
|
+
if (variant === "carousel") {
|
|
2935
|
+
return (jsx(Flex, { overflow: "auto", gap: gap, direction: direction, ...props, children: children }));
|
|
2936
|
+
}
|
|
2937
|
+
return (jsx(Grid, { gridTemplateColumns: gridTemplateColumns, gap: gap, ...props, children: children }));
|
|
2938
|
+
};
|
|
2939
|
+
|
|
2940
|
+
const DefaultCardTitle = () => {
|
|
2941
|
+
return jsx(Fragment, {});
|
|
2942
|
+
};
|
|
2943
|
+
const TableCards = ({ isSelectable = false, showDisplayNameOnly = false, renderTitle = DefaultCardTitle, cardBodyProps = {}, }) => {
|
|
2944
|
+
const { table } = useDataTableContext();
|
|
2945
|
+
return (jsx(Fragment, { children: table.getRowModel().rows.map((row) => {
|
|
2946
|
+
return (jsx(Card.Root, { flex: "1 0 20rem", children: jsxs(Card.Body, { display: "flex", flexFlow: "column", gap: "0.5rem", ...cardBodyProps, children: [isSelectable && (jsx(Checkbox, { isChecked: row.getIsSelected(),
|
|
2947
|
+
disabled: !row.getCanSelect(),
|
|
2948
|
+
// indeterminate: row.getIsSomeSelected(),
|
|
2949
|
+
onChange: row.getToggleSelectedHandler() })), renderTitle(row), jsx(Grid, { templateColumns: "auto 1fr", gap: "1rem", children: row.getVisibleCells().map((cell) => {
|
|
2950
|
+
return (jsxs(Fragment, { children: [jsxs(Box, { children: [showDisplayNameOnly && (jsx(Text, { fontWeight: "bold", children: cell.column.columnDef.meta?.displayName ??
|
|
2951
|
+
cell.column.id })), !showDisplayNameOnly && (jsx(Fragment, { children: flexRender(cell.column.columnDef.header,
|
|
2952
|
+
// @ts-expect-error Assuming the CellContext interface is the same as HeaderContext
|
|
2953
|
+
cell.getContext()) }))] }, `chakra-table-cardcolumnid-${row.id}`), jsx(Box, { justifySelf: "end", children: flexRender(cell.column.columnDef.cell, cell.getContext()) }, `chakra-table-cardcolumn-${row.id}`)] }));
|
|
2954
|
+
}) })] }) }, `chakra-table-card-${row.id}`));
|
|
2955
|
+
}) }));
|
|
2956
|
+
};
|
|
2957
|
+
|
|
2958
|
+
const TableComponent = ({ render = () => {
|
|
2959
|
+
throw Error("Not Implemented");
|
|
2960
|
+
}, }) => {
|
|
2961
|
+
const { table } = useDataTableContext();
|
|
2962
|
+
return render(table);
|
|
2963
|
+
};
|
|
2964
|
+
|
|
2965
|
+
const TableFooter = ({ showSelector = false, alwaysShowSelector = true, }) => {
|
|
2966
|
+
const table = useDataTableContext().table;
|
|
2967
|
+
const SELECTION_BOX_WIDTH = 20;
|
|
2968
|
+
const [hoveredCheckBox, setHoveredCheckBox] = useState(false);
|
|
2969
|
+
const handleRowHover = (isHovered) => {
|
|
2970
|
+
setHoveredCheckBox(isHovered);
|
|
2971
|
+
};
|
|
2972
|
+
const isCheckBoxVisible = () => {
|
|
2973
|
+
if (alwaysShowSelector) {
|
|
2974
|
+
return true;
|
|
2975
|
+
}
|
|
2976
|
+
if (table.getIsAllRowsSelected()) {
|
|
2977
|
+
return true;
|
|
2978
|
+
}
|
|
2979
|
+
if (hoveredCheckBox) {
|
|
2980
|
+
return true;
|
|
2981
|
+
}
|
|
2982
|
+
return false;
|
|
2983
|
+
};
|
|
2984
|
+
return (jsx(Table$1.Footer, { children: table.getFooterGroups().map((footerGroup) => (jsxs(Table$1.Row, { display: "flex", children: [showSelector && (jsxs(Table$1.Header, { padding: `${table.getDensityValue()}px`, onMouseEnter: () => handleRowHover(true), onMouseLeave: () => handleRowHover(false), display: "grid", children: [isCheckBoxVisible() && (jsx(Box, { margin: "0rem", display: "grid", justifyItems: "center", alignItems: "center", children: jsx(Checkbox, { width: `${SELECTION_BOX_WIDTH}px`, height: `${SELECTION_BOX_WIDTH}px`, isChecked: table.getIsAllRowsSelected(),
|
|
2985
|
+
// indeterminate: table.getIsSomeRowsSelected(),
|
|
2986
|
+
onChange: table.getToggleAllRowsSelectedHandler() }) })), !isCheckBoxVisible() && (jsx(Box, { as: "span", margin: "0rem", display: "grid", justifyItems: "center", alignItems: "center", width: `${SELECTION_BOX_WIDTH}px`, height: `${SELECTION_BOX_WIDTH}px` }))] })), footerGroup.headers.map((header) => (jsx(Table$1.Cell, { padding: "0", columnSpan: `${header.colSpan}`,
|
|
2987
|
+
// styling resize and pinning start
|
|
2988
|
+
maxWidth: `${header.getSize()}px`, width: `${header.getSize()}px`, display: "grid", children: jsx(MenuRoot$1, { children: jsx(MenuTrigger$1, { asChild: true, children: jsx(Box, { padding: `${table.getDensityValue()}px`, display: "flex", alignItems: "center", justifyContent: "start", borderRadius: "0rem", children: jsxs(Flex, { gap: "0.5rem", alignItems: "center", children: [header.isPlaceholder
|
|
2989
|
+
? null
|
|
2990
|
+
: flexRender(header.column.columnDef.footer, header.getContext()), jsx(Box, { children: header.column.getCanSort() && (jsxs(Fragment, { children: [header.column.getIsSorted() === false && jsx(Fragment, {}), header.column.getIsSorted() === "asc" && (jsx(BiUpArrow, {})), header.column.getIsSorted() === "desc" && (jsx(BiDownArrow, {}))] })) })] }) }) }) }) }, `chakra-table-footer-${header.column.id}-${footerGroup.id}`)))] }, `chakra-table-footergroup-${footerGroup.id}`))) }));
|
|
2991
|
+
};
|
|
2992
|
+
|
|
2993
|
+
// Default text values
|
|
2994
|
+
const DEFAULT_HEADER_TEXTS = {
|
|
2995
|
+
pinColumn: "Pin Column",
|
|
2996
|
+
cancelPin: "Cancel Pin",
|
|
2997
|
+
sortAscending: "Sort Ascending",
|
|
2998
|
+
sortDescending: "Sort Descending",
|
|
2999
|
+
clearSorting: "Clear Sorting",
|
|
2814
3000
|
};
|
|
2815
3001
|
/**
|
|
2816
|
-
*
|
|
2817
|
-
* help the render of the DataTable in serverside
|
|
3002
|
+
* TableHeader component with configurable text strings.
|
|
2818
3003
|
*
|
|
3004
|
+
* @example
|
|
3005
|
+
* // Using default texts
|
|
3006
|
+
* <TableHeader />
|
|
2819
3007
|
*
|
|
2820
|
-
*
|
|
2821
|
-
*
|
|
3008
|
+
* @example
|
|
3009
|
+
* // Customizing default texts for all columns
|
|
3010
|
+
* <TableHeader
|
|
3011
|
+
* defaultTexts={{
|
|
3012
|
+
* pinColumn: "Pin This Column",
|
|
3013
|
+
* sortAscending: "Sort A-Z"
|
|
3014
|
+
* }}
|
|
3015
|
+
* />
|
|
2822
3016
|
*
|
|
2823
|
-
* @
|
|
3017
|
+
* @example
|
|
3018
|
+
* // Customizing texts per column via meta
|
|
3019
|
+
* const columns = [
|
|
3020
|
+
* columnHelper.accessor("name", {
|
|
3021
|
+
* header: "Name",
|
|
3022
|
+
* meta: {
|
|
3023
|
+
* headerTexts: {
|
|
3024
|
+
* pinColumn: "Pin Name Column",
|
|
3025
|
+
* sortAscending: "Sort Names A-Z"
|
|
3026
|
+
* }
|
|
3027
|
+
* }
|
|
3028
|
+
* })
|
|
3029
|
+
* ];
|
|
2824
3030
|
*/
|
|
2825
|
-
|
|
2826
|
-
view: 'View',
|
|
2827
|
-
edit: 'Edit',
|
|
2828
|
-
filterButtonText: 'Filter',
|
|
2829
|
-
filterTitle: 'Filter',
|
|
2830
|
-
filterReset: 'Reset',
|
|
2831
|
-
filterClose: 'Close',
|
|
2832
|
-
reloadTooltip: 'Reload',
|
|
2833
|
-
reloadButtonText: 'Reload',
|
|
2834
|
-
resetSelection: 'Reset Selection',
|
|
2835
|
-
resetSorting: 'Reset Sorting',
|
|
2836
|
-
rowCountText: 'Row Count',
|
|
2837
|
-
hasErrorText: 'Has Error',
|
|
2838
|
-
globalFilterPlaceholder: 'Search',
|
|
2839
|
-
trueLabel: 'True',
|
|
2840
|
-
falseLabel: 'False',
|
|
2841
|
-
}, }) {
|
|
2842
|
-
const table = useReactTable({
|
|
2843
|
-
_features: [DensityFeature],
|
|
2844
|
-
data: data,
|
|
2845
|
-
rowCount: data.length,
|
|
2846
|
-
columns: columns,
|
|
2847
|
-
getCoreRowModel: getCoreRowModel(),
|
|
2848
|
-
getFilteredRowModel: getFilteredRowModel(),
|
|
2849
|
-
getSortedRowModel: getSortedRowModel(),
|
|
2850
|
-
getPaginationRowModel: getPaginationRowModel(),
|
|
2851
|
-
defaultColumn: {
|
|
2852
|
-
size: 150, //starting column size
|
|
2853
|
-
minSize: 10, //enforced during column resizing
|
|
2854
|
-
maxSize: 10000, //enforced during column resizing
|
|
2855
|
-
},
|
|
2856
|
-
enableRowSelection: enableRowSelection,
|
|
2857
|
-
enableMultiRowSelection: enableMultiRowSelection,
|
|
2858
|
-
enableSubRowSelection: enableSubRowSelection,
|
|
2859
|
-
columnResizeMode: 'onChange',
|
|
2860
|
-
// global filter start
|
|
2861
|
-
filterFns: {
|
|
2862
|
-
fuzzy: fuzzyFilter,
|
|
2863
|
-
},
|
|
2864
|
-
globalFilterFn: 'fuzzy',
|
|
2865
|
-
state: {
|
|
2866
|
-
pagination,
|
|
2867
|
-
sorting,
|
|
2868
|
-
columnFilters,
|
|
2869
|
-
rowSelection,
|
|
2870
|
-
columnOrder,
|
|
2871
|
-
globalFilter,
|
|
2872
|
-
density,
|
|
2873
|
-
columnVisibility,
|
|
2874
|
-
},
|
|
2875
|
-
onPaginationChange: setPagination,
|
|
2876
|
-
onSortingChange: setSorting,
|
|
2877
|
-
onColumnFiltersChange: setColumnFilters,
|
|
2878
|
-
onRowSelectionChange: setRowSelection,
|
|
2879
|
-
onColumnOrderChange: (state) => {
|
|
2880
|
-
setColumnOrder(state);
|
|
2881
|
-
},
|
|
2882
|
-
onGlobalFilterChange: (state) => {
|
|
2883
|
-
setGlobalFilter(state);
|
|
2884
|
-
},
|
|
2885
|
-
onDensityChange: setDensity,
|
|
2886
|
-
onColumnVisibilityChange: setColumnVisibility,
|
|
2887
|
-
});
|
|
2888
|
-
return (jsx(DataTableContext.Provider, { value: {
|
|
2889
|
-
table: table,
|
|
2890
|
-
globalFilter,
|
|
2891
|
-
setGlobalFilter,
|
|
2892
|
-
type: 'client',
|
|
2893
|
-
translate,
|
|
2894
|
-
columns: columns,
|
|
2895
|
-
sorting,
|
|
2896
|
-
setSorting,
|
|
2897
|
-
columnFilters,
|
|
2898
|
-
setColumnFilters,
|
|
2899
|
-
pagination,
|
|
2900
|
-
setPagination,
|
|
2901
|
-
rowSelection,
|
|
2902
|
-
setRowSelection,
|
|
2903
|
-
columnOrder,
|
|
2904
|
-
setColumnOrder,
|
|
2905
|
-
density,
|
|
2906
|
-
setDensity,
|
|
2907
|
-
columnVisibility,
|
|
2908
|
-
setColumnVisibility,
|
|
2909
|
-
data,
|
|
2910
|
-
tableLabel,
|
|
2911
|
-
}, children: children }));
|
|
2912
|
-
}
|
|
2913
|
-
|
|
2914
|
-
/**
|
|
2915
|
-
* DataTableServer will create a context to hold all values to
|
|
2916
|
-
* help the render of the DataTable in serverside
|
|
2917
|
-
*
|
|
2918
|
-
* The query is required to be a GET request that can receive
|
|
2919
|
-
* specified params and return a specified response
|
|
2920
|
-
*
|
|
2921
|
-
* The `useDataTableServer` can help to create the specified request and response
|
|
2922
|
-
*
|
|
2923
|
-
* @link https://tanstack.com/table/latest/docs/guide/column-defs
|
|
2924
|
-
*/
|
|
2925
|
-
function DataTableServer({ columns, enableRowSelection = true, enableMultiRowSelection = true, enableSubRowSelection = true, columnOrder, columnFilters, columnVisibility, density, globalFilter, pagination, sorting, rowSelection, setPagination, setSorting, setColumnFilters, setRowSelection, setGlobalFilter, setColumnOrder, setDensity, setColumnVisibility, query, url, translate, children, tableLabel = {
|
|
2926
|
-
view: "View",
|
|
2927
|
-
edit: "Edit",
|
|
2928
|
-
filterButtonText: "Filter",
|
|
2929
|
-
filterTitle: "Filter",
|
|
2930
|
-
filterReset: "Reset",
|
|
2931
|
-
filterClose: "Close",
|
|
2932
|
-
reloadTooltip: "Reload",
|
|
2933
|
-
reloadButtonText: "Reload",
|
|
2934
|
-
resetSelection: "Reset Selection",
|
|
2935
|
-
resetSorting: "Reset Sorting",
|
|
2936
|
-
rowCountText: "Row Count",
|
|
2937
|
-
hasErrorText: "Has Error",
|
|
2938
|
-
globalFilterPlaceholder: "Search",
|
|
2939
|
-
trueLabel: "True",
|
|
2940
|
-
falseLabel: "False",
|
|
2941
|
-
}, }) {
|
|
2942
|
-
const table = useReactTable({
|
|
2943
|
-
_features: [DensityFeature],
|
|
2944
|
-
data: (query.data?.data ?? []),
|
|
2945
|
-
rowCount: query.data?.count ?? 0,
|
|
2946
|
-
columns: columns,
|
|
2947
|
-
getCoreRowModel: getCoreRowModel(),
|
|
2948
|
-
manualPagination: true,
|
|
2949
|
-
manualSorting: true,
|
|
2950
|
-
columnResizeMode: "onChange",
|
|
2951
|
-
defaultColumn: {
|
|
2952
|
-
size: 150, //starting column size
|
|
2953
|
-
minSize: 10, //enforced during column resizing
|
|
2954
|
-
maxSize: 10000, //enforced during column resizing
|
|
2955
|
-
},
|
|
2956
|
-
enableRowSelection: enableRowSelection,
|
|
2957
|
-
enableMultiRowSelection: enableMultiRowSelection,
|
|
2958
|
-
enableSubRowSelection: enableSubRowSelection,
|
|
2959
|
-
state: {
|
|
2960
|
-
pagination,
|
|
2961
|
-
sorting,
|
|
2962
|
-
columnFilters,
|
|
2963
|
-
rowSelection,
|
|
2964
|
-
columnOrder,
|
|
2965
|
-
globalFilter,
|
|
2966
|
-
density,
|
|
2967
|
-
columnVisibility,
|
|
2968
|
-
},
|
|
2969
|
-
onPaginationChange: setPagination,
|
|
2970
|
-
onSortingChange: setSorting,
|
|
2971
|
-
onColumnFiltersChange: setColumnFilters,
|
|
2972
|
-
onRowSelectionChange: setRowSelection,
|
|
2973
|
-
onColumnOrderChange: (state) => {
|
|
2974
|
-
setColumnOrder(state);
|
|
2975
|
-
},
|
|
2976
|
-
onGlobalFilterChange: (state) => {
|
|
2977
|
-
setGlobalFilter(state);
|
|
2978
|
-
},
|
|
2979
|
-
onDensityChange: setDensity,
|
|
2980
|
-
onColumnVisibilityChange: setColumnVisibility,
|
|
2981
|
-
// for tanstack-table ts bug start
|
|
2982
|
-
filterFns: {
|
|
2983
|
-
fuzzy: () => {
|
|
2984
|
-
return false;
|
|
2985
|
-
},
|
|
2986
|
-
},
|
|
2987
|
-
// for tanstack-table ts bug end
|
|
2988
|
-
});
|
|
2989
|
-
return (jsx(DataTableContext.Provider, { value: {
|
|
2990
|
-
table: table,
|
|
2991
|
-
globalFilter,
|
|
2992
|
-
setGlobalFilter,
|
|
2993
|
-
type: "server",
|
|
2994
|
-
translate,
|
|
2995
|
-
columns: columns,
|
|
2996
|
-
sorting,
|
|
2997
|
-
setSorting,
|
|
2998
|
-
columnFilters,
|
|
2999
|
-
setColumnFilters,
|
|
3000
|
-
pagination,
|
|
3001
|
-
setPagination,
|
|
3002
|
-
rowSelection,
|
|
3003
|
-
setRowSelection,
|
|
3004
|
-
columnOrder,
|
|
3005
|
-
setColumnOrder,
|
|
3006
|
-
density,
|
|
3007
|
-
setDensity,
|
|
3008
|
-
columnVisibility,
|
|
3009
|
-
setColumnVisibility,
|
|
3010
|
-
data: query.data?.data ?? [],
|
|
3011
|
-
tableLabel,
|
|
3012
|
-
}, children: jsx(DataTableServerContext.Provider, { value: { url, query }, children: children }) }));
|
|
3013
|
-
}
|
|
3014
|
-
|
|
3015
|
-
const InputGroup = React.forwardRef(function InputGroup(props, ref) {
|
|
3016
|
-
const { startElement, startElementProps, endElement, endElementProps, children, startOffset = "6px", endOffset = "6px", ...rest } = props;
|
|
3017
|
-
return (jsxs(Group, { ref: ref, ...rest, children: [startElement && (jsx(InputElement, { pointerEvents: "none", ...startElementProps, children: startElement })), React.cloneElement(children, {
|
|
3018
|
-
...(startElement && {
|
|
3019
|
-
ps: `calc(var(--input-height) - ${startOffset})`,
|
|
3020
|
-
}),
|
|
3021
|
-
...(endElement && { pe: `calc(var(--input-height) - ${endOffset})` }),
|
|
3022
|
-
// @ts-expect-error chakra generated files
|
|
3023
|
-
...children.props,
|
|
3024
|
-
}), endElement && (jsx(InputElement, { placement: "end", ...endElementProps, children: endElement }))] }));
|
|
3025
|
-
});
|
|
3026
|
-
|
|
3027
|
-
const GlobalFilter = () => {
|
|
3028
|
-
const { table, tableLabel } = useDataTableContext();
|
|
3029
|
-
const { globalFilterPlaceholder } = tableLabel;
|
|
3030
|
-
const [searchTerm, setSearchTerm] = useState("");
|
|
3031
|
-
const debouncedSearchTerm = useDebounce(searchTerm, 500);
|
|
3032
|
-
useEffect(() => {
|
|
3033
|
-
const searchHN = async () => {
|
|
3034
|
-
table.setGlobalFilter(debouncedSearchTerm);
|
|
3035
|
-
};
|
|
3036
|
-
searchHN();
|
|
3037
|
-
}, [debouncedSearchTerm]);
|
|
3038
|
-
return (jsx(Fragment, { children: jsx(InputGroup, { flex: "1", startElement: jsx(MdSearch, {}), children: jsx(Input, { placeholder: globalFilterPlaceholder, variant: "outline", onChange: (e) => {
|
|
3039
|
-
setSearchTerm(e.target.value);
|
|
3040
|
-
} }) }) }));
|
|
3041
|
-
};
|
|
3042
|
-
|
|
3043
|
-
const Tooltip = React.forwardRef(function Tooltip(props, ref) {
|
|
3044
|
-
const { showArrow, children, disabled, portalled, content, contentProps, portalRef, ...rest } = props;
|
|
3045
|
-
if (disabled)
|
|
3046
|
-
return children;
|
|
3047
|
-
return (jsxs(Tooltip$1.Root, { ...rest, children: [jsx(Tooltip$1.Trigger, { asChild: true, children: children }), jsx(Portal, { disabled: !portalled, container: portalRef, children: jsx(Tooltip$1.Positioner, { children: jsxs(Tooltip$1.Content, { ref: ref, ...contentProps, children: [showArrow && (jsx(Tooltip$1.Arrow, { children: jsx(Tooltip$1.ArrowTip, {}) })), content] }) }) })] }));
|
|
3048
|
-
});
|
|
3049
|
-
|
|
3050
|
-
const ReloadButton = ({ variant = "icon", }) => {
|
|
3051
|
-
const { url } = useDataTableServerContext();
|
|
3052
|
-
const queryClient = useQueryClient();
|
|
3053
|
-
const { tableLabel } = useDataTableContext();
|
|
3054
|
-
const { reloadTooltip, reloadButtonText } = tableLabel;
|
|
3055
|
-
if (variant === "icon") {
|
|
3056
|
-
return (jsx(Tooltip, { showArrow: true, content: reloadTooltip, children: jsx(Button, { variant: "ghost", onClick: () => {
|
|
3057
|
-
queryClient.invalidateQueries({ queryKey: [url] });
|
|
3058
|
-
}, "aria-label": "refresh", children: jsx(IoReload, {}) }) }));
|
|
3059
|
-
}
|
|
3060
|
-
return (jsxs(Button, { variant: "ghost", onClick: () => {
|
|
3061
|
-
queryClient.invalidateQueries({ queryKey: [url] });
|
|
3062
|
-
}, children: [jsx(IoReload, {}), " ", reloadButtonText] }));
|
|
3063
|
-
};
|
|
3064
|
-
|
|
3065
|
-
const TableFilterTags = () => {
|
|
3066
|
-
const { table } = useDataTableContext();
|
|
3067
|
-
return (jsx(Flex, { gap: "0.5rem", flexFlow: "wrap", children: table.getState().columnFilters.map(({ id, value }) => {
|
|
3068
|
-
return (jsx(Tag, { gap: "0.5rem", closable: true, cursor: "pointer", onClick: () => {
|
|
3069
|
-
table.setColumnFilters(table.getState().columnFilters.filter((filter) => {
|
|
3070
|
-
return filter.value != value;
|
|
3071
|
-
}));
|
|
3072
|
-
}, children: `${id}: ${value}` }, `${id}-${value}`));
|
|
3073
|
-
}) }));
|
|
3074
|
-
};
|
|
3075
|
-
|
|
3076
|
-
const TableControls = ({ fitTableWidth = false, fitTableHeight = false, children = jsx(Fragment, {}), showGlobalFilter = false, showFilter = false, showFilterName = false, showFilterTags = false, showReload = false, showPagination = true, showPageSizeControl = true, showPageCountText = true, showView = true, filterTagsOptions = [], extraItems = jsx(Fragment, {}), loading = false, hasError = false, gridProps = {}, }) => {
|
|
3077
|
-
const { tableLabel, table } = useDataTableContext();
|
|
3078
|
-
const { rowCountText, hasErrorText } = tableLabel;
|
|
3079
|
-
return (jsxs(Grid, { templateRows: "auto 1fr", width: fitTableWidth ? "fit-content" : "100%", height: fitTableHeight ? "fit-content" : "100%", gap: "0.5rem", ...gridProps, children: [jsxs(Flex, { flexFlow: "column", gap: 2, children: [jsxs(Flex, { justifyContent: "space-between", children: [jsx(Box, { children: showView && jsx(ViewDialog, { icon: jsx(MdOutlineViewColumn, {}) }) }), jsxs(Flex, { gap: "0.5rem", alignItems: "center", justifySelf: "end", children: [loading && jsx(Spinner, { size: "sm" }), hasError && (jsx(Tooltip, { content: hasErrorText, children: jsx(Icon, { as: BsExclamationCircleFill, color: "red.400" }) })), showGlobalFilter && jsx(GlobalFilter, {}), showFilter && jsx(FilterDialog, {}), showReload && jsx(ReloadButton, {}), extraItems] })] }), filterTagsOptions.length > 0 && (jsx(Flex, { flexFlow: "column", gap: "0.5rem", children: filterTagsOptions.map((option) => {
|
|
3080
|
-
const { column, options } = option;
|
|
3081
|
-
const tableColumn = table.getColumn(column);
|
|
3082
|
-
return (jsxs(Flex, { alignItems: "center", flexFlow: "wrap", gap: "0.5rem", children: [tableColumn?.columnDef.meta?.displayName && (jsx(Text, { children: tableColumn?.columnDef.meta?.displayName })), jsx(TagFilter, { availableTags: options, selectedTags: tableColumn?.getFilterValue() ?? [], selectOne: true, onTagChange: (tags) => {
|
|
3083
|
-
if (tags.length === 0) {
|
|
3084
|
-
return tableColumn?.setFilterValue(undefined);
|
|
3085
|
-
}
|
|
3086
|
-
tableColumn?.setFilterValue(tags);
|
|
3087
|
-
} })] }, column));
|
|
3088
|
-
}) })), showFilterTags && (jsx(Flex, { children: jsx(TableFilterTags, {}) }))] }), jsx(Grid, { overflow: "auto", bg: { base: "colorPalette.50", _dark: "colorPalette.950" }, children: children }), (showPageSizeControl || showPageCountText || showPagination) && (jsxs(Flex, { justifyContent: "space-between", children: [jsxs(Flex, { gap: "1rem", alignItems: "center", children: [showPageSizeControl && jsx(PageSizeControl, {}), showPageCountText && (jsxs(Flex, { children: [jsx(Text, { paddingRight: "0.5rem", children: rowCountText }), jsx(RowCountText, {})] }))] }), jsx(Box, { justifySelf: "end", children: showPagination && jsx(Pagination, {}) })] }))] }));
|
|
3089
|
-
};
|
|
3090
|
-
|
|
3091
|
-
const EmptyState = React.forwardRef(function EmptyState(props, ref) {
|
|
3092
|
-
const { title, description, icon, children, ...rest } = props;
|
|
3093
|
-
return (jsx(EmptyState$2.Root, { ref: ref, ...rest, children: jsxs(EmptyState$2.Content, { children: [icon && (jsx(EmptyState$2.Indicator, { children: icon })), description ? (jsxs(VStack, { textAlign: "center", children: [jsx(EmptyState$2.Title, { children: title }), jsx(EmptyState$2.Description, { children: description })] })) : (jsx(EmptyState$2.Title, { children: title })), children] }) }));
|
|
3094
|
-
});
|
|
3095
|
-
|
|
3096
|
-
const EmptyResult = (jsx(EmptyState, { icon: jsx(HiColorSwatch, {}), title: "No results found", description: "Try adjusting your search", children: jsxs(List.Root, { variant: "marker", children: [jsx(List.Item, { children: "Try removing filters" }), jsx(List.Item, { children: "Try different keywords" })] }) }));
|
|
3097
|
-
const Table = ({ children, emptyComponent = EmptyResult, canResize = true, showLoading = false, ...props }) => {
|
|
3098
|
-
const { table } = useDataTableContext();
|
|
3099
|
-
// Skip empty check when loading to allow skeleton to render
|
|
3100
|
-
if (!showLoading && table.getRowModel().rows.length <= 0) {
|
|
3101
|
-
return emptyComponent;
|
|
3102
|
-
}
|
|
3103
|
-
return (jsx(Table$1.Root, { stickyHeader: true, variant: 'outline', width: canResize ? table.getCenterTotalSize() : undefined, display: 'grid', alignContent: 'start', overflowY: 'auto', bg: { base: 'colorPalette.50', _dark: 'colorPalette.950' }, ...props, children: children }));
|
|
3104
|
-
};
|
|
3105
|
-
|
|
3106
|
-
const Checkbox = React.forwardRef(function Checkbox(props, ref) {
|
|
3107
|
-
const { icon, children, inputProps, rootRef, ...rest } = props;
|
|
3108
|
-
return (jsxs(Checkbox$1.Root, { ref: rootRef, ...rest, children: [jsx(Checkbox$1.HiddenInput, { ref: ref, ...inputProps }), jsx(Checkbox$1.Control, { children: icon || jsx(Checkbox$1.Indicator, {}) }), children != null && (jsx(Checkbox$1.Label, { children: children }))] }));
|
|
3109
|
-
});
|
|
3110
|
-
|
|
3111
|
-
const TableBody = ({ showSelector = false, canResize = true, }) => {
|
|
3112
|
-
"use no memo";
|
|
3031
|
+
const TableHeader = ({ canResize = true, showSelector = false, isSticky = true, tableHeaderProps = {}, tableRowProps = {}, defaultTexts = {}, }) => {
|
|
3113
3032
|
const { table } = useDataTableContext();
|
|
3114
3033
|
const SELECTION_BOX_WIDTH = 20;
|
|
3115
|
-
|
|
3116
|
-
const
|
|
3117
|
-
|
|
3034
|
+
// Merge default texts with provided defaults
|
|
3035
|
+
const mergedDefaultTexts = { ...DEFAULT_HEADER_TEXTS, ...defaultTexts };
|
|
3036
|
+
// Helper function to get text for a specific header
|
|
3037
|
+
const getHeaderText = (header, key) => {
|
|
3038
|
+
const columnMeta = header.column.columnDef.meta;
|
|
3039
|
+
return columnMeta?.headerTexts?.[key] || mergedDefaultTexts[key];
|
|
3118
3040
|
};
|
|
3119
|
-
const
|
|
3120
|
-
const
|
|
3041
|
+
const getThProps = (header) => {
|
|
3042
|
+
const thProps = header.column.getIsPinned()
|
|
3121
3043
|
? {
|
|
3122
3044
|
left: showSelector
|
|
3123
|
-
? `${
|
|
3124
|
-
: `${
|
|
3125
|
-
position: "
|
|
3045
|
+
? `${header.getStart("left") + SELECTION_BOX_WIDTH + table.getDensityValue() * 2}px`
|
|
3046
|
+
: `${header.getStart("left")}px`,
|
|
3047
|
+
position: "sticky",
|
|
3048
|
+
zIndex: 100 + 1,
|
|
3126
3049
|
}
|
|
3127
3050
|
: {};
|
|
3128
|
-
return
|
|
3129
|
-
};
|
|
3130
|
-
const getTrProps = ({ hoveredRow, index, }) => {
|
|
3131
|
-
if (hoveredRow === -1) {
|
|
3132
|
-
return {};
|
|
3133
|
-
}
|
|
3134
|
-
if (hoveredRow === index) {
|
|
3135
|
-
return {
|
|
3136
|
-
opacity: "1",
|
|
3137
|
-
};
|
|
3138
|
-
}
|
|
3139
|
-
return {
|
|
3140
|
-
opacity: "0.8",
|
|
3141
|
-
};
|
|
3142
|
-
};
|
|
3143
|
-
return (jsx(Table$1.Body, { children: table.getRowModel().rows.map((row, index) => {
|
|
3144
|
-
return (jsxs(Table$1.Row, { display: "flex", zIndex: 1, onMouseEnter: () => handleRowHover(index), onMouseLeave: () => handleRowHover(-1), ...getTrProps({ hoveredRow, index }), children: [showSelector && (jsx(TableRowSelector, { index: index, row: row, hoveredRow: hoveredRow })), row.getVisibleCells().map((cell, index) => {
|
|
3145
|
-
return (jsx(Table$1.Cell, { padding: `${table.getDensityValue()}px`,
|
|
3146
|
-
// styling resize and pinning start
|
|
3147
|
-
flex: `${canResize ? "0" : "1"} 0 ${cell.column.getSize()}px`,
|
|
3148
|
-
// this is to avoid the cell from being too wide
|
|
3149
|
-
minWidth: `0`, color: {
|
|
3150
|
-
base: "colorPalette.900",
|
|
3151
|
-
_dark: "colorPalette.100",
|
|
3152
|
-
},
|
|
3153
|
-
bg: { base: "colorPalette.50", _dark: "colorPalette.950" }, ...getTdProps(cell), children: flexRender(cell.column.columnDef.cell, cell.getContext()) }, `chakra-table-rowcell-${cell.id}-${index}`));
|
|
3154
|
-
})] }, `chakra-table-row-${row.id}`));
|
|
3155
|
-
}) }));
|
|
3156
|
-
};
|
|
3157
|
-
const TableRowSelector = ({ row, }) => {
|
|
3158
|
-
const { table } = useDataTableContext();
|
|
3159
|
-
const SELECTION_BOX_WIDTH = 20;
|
|
3160
|
-
return (jsx(Table$1.Cell, { padding: `${table.getDensityValue()}px`, display: "grid", color: {
|
|
3161
|
-
base: "colorPalette.900",
|
|
3162
|
-
_dark: "colorPalette.100",
|
|
3163
|
-
},
|
|
3164
|
-
bg: { base: "colorPalette.50", _dark: "colorPalette.950" }, justifyItems: "center", alignItems: "center", children: jsx(Checkbox, { width: `${SELECTION_BOX_WIDTH}px`, height: `${SELECTION_BOX_WIDTH}px`, checked: row.getIsSelected(),
|
|
3165
|
-
disabled: !row.getCanSelect(),
|
|
3166
|
-
onCheckedChange: row.getToggleSelectedHandler() }) }));
|
|
3167
|
-
};
|
|
3168
|
-
|
|
3169
|
-
const TableBodySkeleton = ({ showSelector = false, canResize = true, }) => {
|
|
3170
|
-
'use no memo';
|
|
3171
|
-
const { table } = useDataTableContext();
|
|
3172
|
-
const SELECTION_BOX_WIDTH = 20;
|
|
3173
|
-
const [hoveredRow, setHoveredRow] = useState(-1);
|
|
3174
|
-
const handleRowHover = (index) => {
|
|
3175
|
-
setHoveredRow(index);
|
|
3176
|
-
};
|
|
3177
|
-
const getTdProps = (column) => {
|
|
3178
|
-
const tdProps = column.getIsPinned()
|
|
3179
|
-
? {
|
|
3180
|
-
left: showSelector
|
|
3181
|
-
? `${column.getStart('left') + SELECTION_BOX_WIDTH + table.getDensityValue() * 2}px`
|
|
3182
|
-
: `${column.getStart('left')}px`,
|
|
3183
|
-
position: 'relative',
|
|
3184
|
-
}
|
|
3185
|
-
: {};
|
|
3186
|
-
return tdProps;
|
|
3187
|
-
};
|
|
3188
|
-
const getTrProps = ({ hoveredRow, index, }) => {
|
|
3189
|
-
if (hoveredRow === -1) {
|
|
3190
|
-
return {};
|
|
3191
|
-
}
|
|
3192
|
-
if (hoveredRow === index) {
|
|
3193
|
-
return {
|
|
3194
|
-
opacity: '1',
|
|
3195
|
-
};
|
|
3196
|
-
}
|
|
3197
|
-
return {
|
|
3198
|
-
opacity: '0.8',
|
|
3199
|
-
};
|
|
3200
|
-
};
|
|
3201
|
-
// Get the number of skeleton rows based on current pageSize
|
|
3202
|
-
const pageSize = table.getState().pagination.pageSize;
|
|
3203
|
-
const visibleColumns = table.getVisibleLeafColumns();
|
|
3204
|
-
return (jsx(Table$1.Body, { children: Array.from({ length: pageSize }).map((_, rowIndex) => {
|
|
3205
|
-
return (jsxs(Table$1.Row, { display: 'flex', zIndex: 1, onMouseEnter: () => handleRowHover(rowIndex), onMouseLeave: () => handleRowHover(-1), ...getTrProps({ hoveredRow, index: rowIndex }), children: [showSelector && jsx(TableRowSelectorSkeleton, {}), visibleColumns.map((column, colIndex) => {
|
|
3206
|
-
return (jsx(Table$1.Cell, { padding: `${table.getDensityValue()}px`,
|
|
3207
|
-
// styling resize and pinning start
|
|
3208
|
-
flex: `${canResize ? '0' : '1'} 0 ${column.getSize()}px`,
|
|
3209
|
-
// this is to avoid the cell from being too wide
|
|
3210
|
-
minWidth: `0`, color: {
|
|
3211
|
-
base: 'colorPalette.900',
|
|
3212
|
-
_dark: 'colorPalette.100',
|
|
3213
|
-
},
|
|
3214
|
-
bg: { base: 'colorPalette.50', _dark: 'colorPalette.950' }, ...getTdProps(column), children: jsx(Skeleton, { height: "20px", width: "80%" }) }, `chakra-table-skeleton-cell-${rowIndex}-${colIndex}`));
|
|
3215
|
-
})] }, `chakra-table-skeleton-row-${rowIndex}`));
|
|
3216
|
-
}) }));
|
|
3217
|
-
};
|
|
3218
|
-
const TableRowSelectorSkeleton = () => {
|
|
3219
|
-
const { table } = useDataTableContext();
|
|
3220
|
-
const SELECTION_BOX_WIDTH = 20;
|
|
3221
|
-
return (jsx(Table$1.Cell, { padding: `${table.getDensityValue()}px`, display: 'grid', color: {
|
|
3222
|
-
base: 'colorPalette.900',
|
|
3223
|
-
_dark: 'colorPalette.100',
|
|
3224
|
-
},
|
|
3225
|
-
bg: { base: 'colorPalette.50', _dark: 'colorPalette.950' }, justifyItems: 'center', alignItems: 'center', children: jsx(Skeleton, { width: `${SELECTION_BOX_WIDTH}px`, height: `${SELECTION_BOX_WIDTH}px` }) }));
|
|
3226
|
-
};
|
|
3227
|
-
|
|
3228
|
-
const TableFooter = ({ showSelector = false, alwaysShowSelector = true, }) => {
|
|
3229
|
-
const table = useDataTableContext().table;
|
|
3230
|
-
const SELECTION_BOX_WIDTH = 20;
|
|
3231
|
-
const [hoveredCheckBox, setHoveredCheckBox] = useState(false);
|
|
3232
|
-
const handleRowHover = (isHovered) => {
|
|
3233
|
-
setHoveredCheckBox(isHovered);
|
|
3234
|
-
};
|
|
3235
|
-
const isCheckBoxVisible = () => {
|
|
3236
|
-
if (alwaysShowSelector) {
|
|
3237
|
-
return true;
|
|
3238
|
-
}
|
|
3239
|
-
if (table.getIsAllRowsSelected()) {
|
|
3240
|
-
return true;
|
|
3241
|
-
}
|
|
3242
|
-
if (hoveredCheckBox) {
|
|
3243
|
-
return true;
|
|
3244
|
-
}
|
|
3245
|
-
return false;
|
|
3246
|
-
};
|
|
3247
|
-
return (jsx(Table$1.Footer, { children: table.getFooterGroups().map((footerGroup) => (jsxs(Table$1.Row, { display: "flex", children: [showSelector && (jsxs(Table$1.Header, { padding: `${table.getDensityValue()}px`, onMouseEnter: () => handleRowHover(true), onMouseLeave: () => handleRowHover(false), display: "grid", children: [isCheckBoxVisible() && (jsx(Box, { margin: "0rem", display: "grid", justifyItems: "center", alignItems: "center", children: jsx(Checkbox, { width: `${SELECTION_BOX_WIDTH}px`, height: `${SELECTION_BOX_WIDTH}px`, isChecked: table.getIsAllRowsSelected(),
|
|
3248
|
-
// indeterminate: table.getIsSomeRowsSelected(),
|
|
3249
|
-
onChange: table.getToggleAllRowsSelectedHandler() }) })), !isCheckBoxVisible() && (jsx(Box, { as: "span", margin: "0rem", display: "grid", justifyItems: "center", alignItems: "center", width: `${SELECTION_BOX_WIDTH}px`, height: `${SELECTION_BOX_WIDTH}px` }))] })), footerGroup.headers.map((header) => (jsx(Table$1.Cell, { padding: "0", columnSpan: `${header.colSpan}`,
|
|
3250
|
-
// styling resize and pinning start
|
|
3251
|
-
maxWidth: `${header.getSize()}px`, width: `${header.getSize()}px`, display: "grid", children: jsx(MenuRoot$1, { children: jsx(MenuTrigger$1, { asChild: true, children: jsx(Box, { padding: `${table.getDensityValue()}px`, display: "flex", alignItems: "center", justifyContent: "start", borderRadius: "0rem", children: jsxs(Flex, { gap: "0.5rem", alignItems: "center", children: [header.isPlaceholder
|
|
3252
|
-
? null
|
|
3253
|
-
: flexRender(header.column.columnDef.footer, header.getContext()), jsx(Box, { children: header.column.getCanSort() && (jsxs(Fragment, { children: [header.column.getIsSorted() === false && jsx(Fragment, {}), header.column.getIsSorted() === "asc" && (jsx(BiUpArrow, {})), header.column.getIsSorted() === "desc" && (jsx(BiDownArrow, {}))] })) })] }) }) }) }) }, `chakra-table-footer-${header.column.id}-${footerGroup.id}`)))] }, `chakra-table-footergroup-${footerGroup.id}`))) }));
|
|
3254
|
-
};
|
|
3255
|
-
|
|
3256
|
-
// Default text values
|
|
3257
|
-
const DEFAULT_HEADER_TEXTS = {
|
|
3258
|
-
pinColumn: "Pin Column",
|
|
3259
|
-
cancelPin: "Cancel Pin",
|
|
3260
|
-
sortAscending: "Sort Ascending",
|
|
3261
|
-
sortDescending: "Sort Descending",
|
|
3262
|
-
clearSorting: "Clear Sorting",
|
|
3263
|
-
};
|
|
3264
|
-
/**
|
|
3265
|
-
* TableHeader component with configurable text strings.
|
|
3266
|
-
*
|
|
3267
|
-
* @example
|
|
3268
|
-
* // Using default texts
|
|
3269
|
-
* <TableHeader />
|
|
3270
|
-
*
|
|
3271
|
-
* @example
|
|
3272
|
-
* // Customizing default texts for all columns
|
|
3273
|
-
* <TableHeader
|
|
3274
|
-
* defaultTexts={{
|
|
3275
|
-
* pinColumn: "Pin This Column",
|
|
3276
|
-
* sortAscending: "Sort A-Z"
|
|
3277
|
-
* }}
|
|
3278
|
-
* />
|
|
3279
|
-
*
|
|
3280
|
-
* @example
|
|
3281
|
-
* // Customizing texts per column via meta
|
|
3282
|
-
* const columns = [
|
|
3283
|
-
* columnHelper.accessor("name", {
|
|
3284
|
-
* header: "Name",
|
|
3285
|
-
* meta: {
|
|
3286
|
-
* headerTexts: {
|
|
3287
|
-
* pinColumn: "Pin Name Column",
|
|
3288
|
-
* sortAscending: "Sort Names A-Z"
|
|
3289
|
-
* }
|
|
3290
|
-
* }
|
|
3291
|
-
* })
|
|
3292
|
-
* ];
|
|
3293
|
-
*/
|
|
3294
|
-
const TableHeader = ({ canResize = true, showSelector = false, isSticky = true, tableHeaderProps = {}, tableRowProps = {}, defaultTexts = {}, }) => {
|
|
3295
|
-
const { table } = useDataTableContext();
|
|
3296
|
-
const SELECTION_BOX_WIDTH = 20;
|
|
3297
|
-
// Merge default texts with provided defaults
|
|
3298
|
-
const mergedDefaultTexts = { ...DEFAULT_HEADER_TEXTS, ...defaultTexts };
|
|
3299
|
-
// Helper function to get text for a specific header
|
|
3300
|
-
const getHeaderText = (header, key) => {
|
|
3301
|
-
const columnMeta = header.column.columnDef.meta;
|
|
3302
|
-
return columnMeta?.headerTexts?.[key] || mergedDefaultTexts[key];
|
|
3303
|
-
};
|
|
3304
|
-
const getThProps = (header) => {
|
|
3305
|
-
const thProps = header.column.getIsPinned()
|
|
3306
|
-
? {
|
|
3307
|
-
left: showSelector
|
|
3308
|
-
? `${header.getStart("left") + SELECTION_BOX_WIDTH + table.getDensityValue() * 2}px`
|
|
3309
|
-
: `${header.getStart("left")}px`,
|
|
3310
|
-
position: "sticky",
|
|
3311
|
-
zIndex: 100 + 1,
|
|
3312
|
-
}
|
|
3313
|
-
: {};
|
|
3314
|
-
return thProps;
|
|
3051
|
+
return thProps;
|
|
3315
3052
|
};
|
|
3316
3053
|
const stickyProps = {
|
|
3317
3054
|
position: "sticky",
|
|
@@ -3386,89 +3123,11 @@ const TableHeader = ({ canResize = true, showSelector = false, isSticky = true,
|
|
|
3386
3123
|
})] }, `chakra-table-headergroup-${headerGroup.id}`))) }));
|
|
3387
3124
|
};
|
|
3388
3125
|
|
|
3389
|
-
const DefaultTable = ({ showFooter = false, tableProps = {}, tableHeaderProps = {}, tableBodyProps = {}, tableFooterProps = {}, controlProps = {}, variant = '', isLoading = false, }) => {
|
|
3390
|
-
if (variant === 'greedy') {
|
|
3391
|
-
const bodyComponent = isLoading ? (jsx(TableBodySkeleton, { showSelector: tableBodyProps.showSelector, canResize: false })) : (jsx(TableBody, { ...tableBodyProps, canResize: false, ...tableBodyProps }));
|
|
3392
|
-
return (jsx(TableControls, { ...controlProps, children: jsxs(Table, { canResize: false, showLoading: isLoading, ...tableProps, children: [jsx(TableHeader, { canResize: false, ...tableHeaderProps }), bodyComponent, showFooter && (jsx(TableFooter, { canResize: false, ...tableFooterProps }))] }) }));
|
|
3393
|
-
}
|
|
3394
|
-
const bodyComponent = isLoading ? (jsx(TableBodySkeleton, { showSelector: tableBodyProps.showSelector, canResize: tableBodyProps.canResize })) : (jsx(TableBody, { ...tableBodyProps }));
|
|
3395
|
-
return (jsx(TableControls, { ...controlProps, children: jsxs(Table, { showLoading: isLoading, ...tableProps, children: [jsx(TableHeader, { ...tableHeaderProps }), bodyComponent, showFooter && jsx(TableFooter, { ...tableFooterProps })] }) }));
|
|
3396
|
-
};
|
|
3397
|
-
|
|
3398
|
-
/**
|
|
3399
|
-
* DefaultTableServer is a wrapper around DefaultTable that automatically
|
|
3400
|
-
* detects server-side loading state from DataTableServerContext.
|
|
3401
|
-
*
|
|
3402
|
-
* Use this component when working with DataTableServer to automatically
|
|
3403
|
-
* show skeleton loading state during data fetching.
|
|
3404
|
-
*
|
|
3405
|
-
* @example
|
|
3406
|
-
* ```tsx
|
|
3407
|
-
* <DataTableServer columns={columns} {...datatableServer}>
|
|
3408
|
-
* <DefaultTableServer />
|
|
3409
|
-
* </DataTableServer>
|
|
3410
|
-
* ```
|
|
3411
|
-
*/
|
|
3412
|
-
const DefaultTableServer = ({ isLoading: isLoadingOverride, ...props }) => {
|
|
3413
|
-
// Automatically detect loading state from server context
|
|
3414
|
-
const serverContext = useDataTableServerContext();
|
|
3415
|
-
const isLoading = isLoadingOverride ?? serverContext?.query?.isLoading ?? false;
|
|
3416
|
-
return jsx(DefaultTable, { ...props, isLoading: isLoading });
|
|
3417
|
-
};
|
|
3418
|
-
|
|
3419
|
-
const TableCardContainer = ({ children, variant = "", gap = "1rem", gridTemplateColumns = "repeat(auto-fit, minmax(20rem, 1fr))", direction = "row", ...props }) => {
|
|
3420
|
-
if (variant === "carousel") {
|
|
3421
|
-
return (jsx(Flex, { overflow: "auto", gap: gap, direction: direction, ...props, children: children }));
|
|
3422
|
-
}
|
|
3423
|
-
return (jsx(Grid, { gridTemplateColumns: gridTemplateColumns, gap: gap, ...props, children: children }));
|
|
3424
|
-
};
|
|
3425
|
-
|
|
3426
|
-
const DefaultCardTitle = () => {
|
|
3427
|
-
return jsx(Fragment, {});
|
|
3428
|
-
};
|
|
3429
|
-
const TableCards = ({ isSelectable = false, showDisplayNameOnly = false, renderTitle = DefaultCardTitle, cardBodyProps = {}, }) => {
|
|
3430
|
-
const { table } = useDataTableContext();
|
|
3431
|
-
return (jsx(Fragment, { children: table.getRowModel().rows.map((row) => {
|
|
3432
|
-
return (jsx(Card.Root, { flex: "1 0 20rem", children: jsxs(Card.Body, { display: "flex", flexFlow: "column", gap: "0.5rem", ...cardBodyProps, children: [isSelectable && (jsx(Checkbox, { isChecked: row.getIsSelected(),
|
|
3433
|
-
disabled: !row.getCanSelect(),
|
|
3434
|
-
// indeterminate: row.getIsSomeSelected(),
|
|
3435
|
-
onChange: row.getToggleSelectedHandler() })), renderTitle(row), jsx(Grid, { templateColumns: "auto 1fr", gap: "1rem", children: row.getVisibleCells().map((cell) => {
|
|
3436
|
-
return (jsxs(Fragment, { children: [jsxs(Box, { children: [showDisplayNameOnly && (jsx(Text, { fontWeight: "bold", children: cell.column.columnDef.meta?.displayName ??
|
|
3437
|
-
cell.column.id })), !showDisplayNameOnly && (jsx(Fragment, { children: flexRender(cell.column.columnDef.header,
|
|
3438
|
-
// @ts-expect-error Assuming the CellContext interface is the same as HeaderContext
|
|
3439
|
-
cell.getContext()) }))] }, `chakra-table-cardcolumnid-${row.id}`), jsx(Box, { justifySelf: "end", children: flexRender(cell.column.columnDef.cell, cell.getContext()) }, `chakra-table-cardcolumn-${row.id}`)] }));
|
|
3440
|
-
}) })] }) }, `chakra-table-card-${row.id}`));
|
|
3441
|
-
}) }));
|
|
3442
|
-
};
|
|
3443
|
-
|
|
3444
|
-
const TableComponent = ({ render = () => {
|
|
3445
|
-
throw Error("Not Implemented");
|
|
3446
|
-
}, }) => {
|
|
3447
|
-
const { table } = useDataTableContext();
|
|
3448
|
-
return render(table);
|
|
3449
|
-
};
|
|
3450
|
-
|
|
3451
3126
|
const TableLoadingComponent = ({ render, }) => {
|
|
3452
3127
|
const { query } = useDataTableServerContext();
|
|
3453
3128
|
return jsx(Fragment, { children: render(query.isLoading) });
|
|
3454
3129
|
};
|
|
3455
3130
|
|
|
3456
|
-
const SelectAllRowsToggle = ({ selectAllIcon = jsx(MdOutlineChecklist, {}), clearAllIcon = jsx(MdClear, {}), selectAllText = "", clearAllText = "", }) => {
|
|
3457
|
-
const { table } = useDataTableContext();
|
|
3458
|
-
return (jsxs(Fragment, { children: [!!selectAllText === false && (jsx(IconButton, { variant: "ghost", "aria-label": table.getIsAllRowsSelected() ? clearAllText : selectAllText, onClick: (event) => {
|
|
3459
|
-
table.getToggleAllRowsSelectedHandler()(event);
|
|
3460
|
-
}, children: table.getIsAllRowsSelected() ? clearAllIcon : selectAllIcon })), !!selectAllText !== false && (jsxs(Button$1, { variant: "ghost", onClick: (event) => {
|
|
3461
|
-
table.getToggleAllRowsSelectedHandler()(event);
|
|
3462
|
-
}, children: [table.getIsAllRowsSelected() ? clearAllIcon : selectAllIcon, table.getIsAllRowsSelected() ? clearAllText : selectAllText] }))] }));
|
|
3463
|
-
};
|
|
3464
|
-
|
|
3465
|
-
const TableSelector = () => {
|
|
3466
|
-
const { table } = useDataTableContext();
|
|
3467
|
-
return (jsxs(Fragment, { children: [table.getSelectedRowModel().rows.length > 0 && (jsxs(Button$1, { onClick: () => { }, variant: "ghost", display: "flex", gap: "0.25rem", children: [jsx(Box, { fontSize: "sm", children: `${table.getSelectedRowModel().rows.length}` }), jsx(IoMdCheckbox, {})] })), !table.getIsAllPageRowsSelected() && jsx(SelectAllRowsToggle, {}), table.getSelectedRowModel().rows.length > 0 && (jsx(IconButton, { variant: "ghost", onClick: () => {
|
|
3468
|
-
table.resetRowSelection();
|
|
3469
|
-
}, "aria-label": "reset selection", children: jsx(MdClear, {}) }))] }));
|
|
3470
|
-
};
|
|
3471
|
-
|
|
3472
3131
|
const TextCell = ({ label, containerProps = {}, textProps = {}, children, }) => {
|
|
3473
3132
|
if (label) {
|
|
3474
3133
|
return (jsx(Flex, { alignItems: "center", height: "100%", ...containerProps, children: jsx(Tooltip, { content: jsx(Text, { as: "span", overflow: "hidden", textOverflow: "ellipsis", children: label }), children: jsx(Text, { as: "span", overflow: "hidden", textOverflow: "ellipsis", wordBreak: "break-all", ...textProps, children: children }) }) }));
|
|
@@ -3476,7 +3135,26 @@ const TextCell = ({ label, containerProps = {}, textProps = {}, children, }) =>
|
|
|
3476
3135
|
return (jsx(Flex, { alignItems: "center", height: "100%", ...containerProps, children: jsx(Text, { as: "span", overflow: "hidden", textOverflow: "ellipsis", wordBreak: "break-all", ...textProps, children: children }) }));
|
|
3477
3136
|
};
|
|
3478
3137
|
|
|
3479
|
-
const
|
|
3138
|
+
const CardHeader = ({ row, imageColumnId = undefined, titleColumnId = undefined, tagColumnId = undefined, tagIcon = undefined, showTag = true, imageProps = {}, }) => {
|
|
3139
|
+
if (!!row.original === false) {
|
|
3140
|
+
return jsx(Fragment, {});
|
|
3141
|
+
}
|
|
3142
|
+
const isShowFirstColumn = !!titleColumnId || showTag;
|
|
3143
|
+
return (jsxs(Grid, { templateRows: "auto auto", gap: "1rem", children: [!!imageColumnId && (jsx(Image, { width: "100%", src: row.original[imageColumnId], ...imageProps })), isShowFirstColumn && (jsxs(Flex, { gap: "0.5rem", flexFlow: "wrap", children: [!!titleColumnId && (jsx(Text, { fontWeight: "bold", fontSize: "large", children: row.original[titleColumnId] })), showTag && (jsx(Tag, { fontSize: "large", startElement: tagIcon && tagIcon({}), children: row.original[tagColumnId] }))] }))] }));
|
|
3144
|
+
};
|
|
3145
|
+
|
|
3146
|
+
const EmptyState = ({ title = "No records", description = "Add a new events to get started or refine your search", }) => {
|
|
3147
|
+
const { isEmpty } = useDataTableServerContext();
|
|
3148
|
+
return (jsx(Fragment, { children: isEmpty && (jsx(EmptyState$2.Root, { children: jsxs(EmptyState$2.Content, { children: [jsx(EmptyState$2.Indicator, { children: jsx(HiColorSwatch, {}) }), jsxs(VStack, { textAlign: "center", children: [jsx(EmptyState$2.Title, { children: title }), jsx(EmptyState$2.Description, { children: description })] })] }) })) }));
|
|
3149
|
+
};
|
|
3150
|
+
|
|
3151
|
+
const ErrorAlert = ({ showMessage = true }) => {
|
|
3152
|
+
const { query } = useDataTableServerContext();
|
|
3153
|
+
const { isError, error } = query;
|
|
3154
|
+
return (jsx(Fragment, { children: isError && (jsxs(Alert.Root, { status: "error", children: [jsx(Alert.Indicator, {}), jsxs(Alert.Content, { children: [jsx(Alert.Title, { children: error.name }), showMessage && (jsx(Alert.Description, { children: error.message }))] })] })) }));
|
|
3155
|
+
};
|
|
3156
|
+
|
|
3157
|
+
const useDataTable = ({ default: { sorting: defaultSorting = [], pagination: defaultPagination = {
|
|
3480
3158
|
pageIndex: 0, //initial page index
|
|
3481
3159
|
pageSize: 10, //default page size
|
|
3482
3160
|
}, rowSelection: defaultRowSelection = {}, columnFilters: defaultColumnFilters = [], columnOrder: defaultColumnOrder = [], columnVisibility: defaultColumnVisibility = {}, globalFilter: defaultGlobalFilter = "", density: defaultDensity = "sm", } = {
|
|
@@ -3605,6 +3283,28 @@ const idListSanityCheck = (param, idList, properties) => {
|
|
|
3605
3283
|
}
|
|
3606
3284
|
};
|
|
3607
3285
|
|
|
3286
|
+
const snakeToLabel = (str) => {
|
|
3287
|
+
return str
|
|
3288
|
+
.split("_") // Split by underscore
|
|
3289
|
+
.map((word) => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase()) // Capitalize each word
|
|
3290
|
+
.join(" "); // Join with space
|
|
3291
|
+
};
|
|
3292
|
+
|
|
3293
|
+
const RecordDisplay = ({ object, boxProps, translate, prefix = "", }) => {
|
|
3294
|
+
const getColumn = ({ field }) => {
|
|
3295
|
+
if (translate !== undefined) {
|
|
3296
|
+
return translate.t(`${prefix}${field}`);
|
|
3297
|
+
}
|
|
3298
|
+
return snakeToLabel(field);
|
|
3299
|
+
};
|
|
3300
|
+
if (object === null) {
|
|
3301
|
+
return jsx(Fragment, { children: "null" });
|
|
3302
|
+
}
|
|
3303
|
+
return (jsx(Grid, { rowGap: 1, padding: 1, overflow: "auto", ...boxProps, children: Object.entries(object).map(([field, value]) => {
|
|
3304
|
+
return (jsxs(Grid, { columnGap: 2, gridTemplateColumns: "auto 1fr", children: [jsx(Text, { color: "colorPalette.400", children: getColumn({ field }) }), typeof value === "object" ? (jsx(RecordDisplay, { object: value, prefix: `${prefix}${field}.`, translate: translate })) : (jsx(Text, { children: JSON.stringify(value) }))] }, field));
|
|
3305
|
+
}) }));
|
|
3306
|
+
};
|
|
3307
|
+
|
|
3608
3308
|
const widthSanityCheck = (widthList, ignoreList, properties) => {
|
|
3609
3309
|
const widthListToolong = widthList.length > Object.keys(properties).length;
|
|
3610
3310
|
if (widthListToolong) {
|
|
@@ -3662,70 +3362,6 @@ const getColumns = ({ schema, include = [], ignore = [], width = [], meta = {},
|
|
|
3662
3362
|
return columns;
|
|
3663
3363
|
};
|
|
3664
3364
|
|
|
3665
|
-
const TableDataDisplay = ({ colorPalette, emptyComponent, }) => {
|
|
3666
|
-
const { columns, translate, data } = useDataTableContext();
|
|
3667
|
-
const columnsMap = Object.fromEntries(columns.map((def) => {
|
|
3668
|
-
const { accessorKey, id } = def;
|
|
3669
|
-
if (accessorKey) {
|
|
3670
|
-
return [accessorKey, def];
|
|
3671
|
-
}
|
|
3672
|
-
return [id, def];
|
|
3673
|
-
}));
|
|
3674
|
-
const columnHeaders = Object.keys(columnsMap);
|
|
3675
|
-
const totalWidths = columns
|
|
3676
|
-
.map(({ size }) => {
|
|
3677
|
-
if (!!size === false) {
|
|
3678
|
-
return 0;
|
|
3679
|
-
}
|
|
3680
|
-
if (typeof size === "number") {
|
|
3681
|
-
return size;
|
|
3682
|
-
}
|
|
3683
|
-
return 0;
|
|
3684
|
-
})
|
|
3685
|
-
.reduce((previous, current) => previous + current, 0);
|
|
3686
|
-
const columnWidths = columns
|
|
3687
|
-
.map(({ size }) => {
|
|
3688
|
-
if (!!size === false) {
|
|
3689
|
-
return "1fr";
|
|
3690
|
-
}
|
|
3691
|
-
return `minmax(${size}px, ${(size / totalWidths) * 100}%)`;
|
|
3692
|
-
})
|
|
3693
|
-
.join(" ");
|
|
3694
|
-
console.log({ columnWidths }, "hadfg");
|
|
3695
|
-
const cellProps = {
|
|
3696
|
-
flex: "1 0 0%",
|
|
3697
|
-
overflow: "auto",
|
|
3698
|
-
paddingX: "2",
|
|
3699
|
-
py: "1",
|
|
3700
|
-
color: { base: "colorPalette.900", _dark: "colorPalette.100" },
|
|
3701
|
-
bgColor: { base: "colorPalette.50", _dark: "colorPalette.950" },
|
|
3702
|
-
borderBottomColor: { base: "colorPalette.200", _dark: "colorPalette.800" },
|
|
3703
|
-
borderBottomWidth: "1px",
|
|
3704
|
-
...{ colorPalette },
|
|
3705
|
-
};
|
|
3706
|
-
if (data.length <= 0) {
|
|
3707
|
-
return jsx(Fragment, { children: emptyComponent });
|
|
3708
|
-
}
|
|
3709
|
-
return (jsxs(Grid, { templateColumns: `${columnWidths}`, overflow: "auto", borderWidth: "1px", color: { base: "colorPalette.900", _dark: "colorPalette.100" }, borderColor: { base: "colorPalette.200", _dark: "colorPalette.800" }, colorPalette, children: [jsx(Grid, { templateColumns: `${columnWidths}`, column: `1/span ${columns.length}`, bg: { base: "colorPalette.200", _dark: "colorPalette.800" }, colorPalette, children: columnHeaders.map((header) => {
|
|
3710
|
-
return (jsx(Box, { flex: "1 0 0%", paddingX: "2", py: "1", overflow: "auto", textOverflow: "ellipsis", children: translate.t(`column_header.${header}`) }));
|
|
3711
|
-
}) }), data.map((record) => {
|
|
3712
|
-
return (jsx(Fragment, { children: columnHeaders.map((header) => {
|
|
3713
|
-
const { cell } = columnsMap[header];
|
|
3714
|
-
const value = record[header];
|
|
3715
|
-
if (!!record === false) {
|
|
3716
|
-
return (jsx(Box, { ...cellProps, children: translate.t(`column_cell.placeholder`) }));
|
|
3717
|
-
}
|
|
3718
|
-
if (cell) {
|
|
3719
|
-
return (jsx(Box, { ...cellProps, children: cell({ row: { original: record } }) }));
|
|
3720
|
-
}
|
|
3721
|
-
if (typeof value === "object") {
|
|
3722
|
-
return (jsx(Box, { ...cellProps, children: jsx(RecordDisplay, { object: value }) }));
|
|
3723
|
-
}
|
|
3724
|
-
return jsx(Box, { ...cellProps, children: value });
|
|
3725
|
-
}) }));
|
|
3726
|
-
})] }));
|
|
3727
|
-
};
|
|
3728
|
-
|
|
3729
3365
|
//@ts-expect-error TODO: find appropriate type
|
|
3730
3366
|
const SchemaFormContext = createContext({
|
|
3731
3367
|
schema: {},
|
|
@@ -5217,7 +4853,7 @@ const getTableData = async ({ serverUrl, in_table, searching = "", where = [], l
|
|
|
5217
4853
|
};
|
|
5218
4854
|
|
|
5219
4855
|
const IdPicker = ({ column, schema, prefix, isMultiple = false, }) => {
|
|
5220
|
-
const { watch, formState: { errors }, setValue, } = useFormContext();
|
|
4856
|
+
const { watch, getValues, formState: { errors }, setValue, } = useFormContext();
|
|
5221
4857
|
const { serverUrl, idMap, setIdMap, schema: parentSchema, idPickerLabels, } = useSchemaContext();
|
|
5222
4858
|
const formI18n = useFormI18n(column, prefix);
|
|
5223
4859
|
const { required, gridColumn = 'span 12', gridRow = 'span 1', renderDisplay, foreign_key, } = schema;
|
|
@@ -5229,8 +4865,26 @@ const IdPicker = ({ column, schema, prefix, isMultiple = false, }) => {
|
|
|
5229
4865
|
const [page, setPage] = useState(0);
|
|
5230
4866
|
const ref = useRef(null);
|
|
5231
4867
|
const colLabel = formI18n.colLabel;
|
|
5232
|
-
const
|
|
5233
|
-
const
|
|
4868
|
+
const watchedValue = watch(colLabel);
|
|
4869
|
+
const watchId = !isMultiple ? watchedValue : undefined;
|
|
4870
|
+
const watchIds = isMultiple
|
|
4871
|
+
? (Array.isArray(watchedValue) ? watchedValue : [])
|
|
4872
|
+
: [];
|
|
4873
|
+
// Get initial values immediately to ensure query can trigger on mount
|
|
4874
|
+
const initialValue = getValues(colLabel);
|
|
4875
|
+
const initialId = !isMultiple ? initialValue : undefined;
|
|
4876
|
+
const initialIds = isMultiple
|
|
4877
|
+
? (Array.isArray(initialValue) ? initialValue : [])
|
|
4878
|
+
: [];
|
|
4879
|
+
// Use watched values if they exist (including empty string for single select),
|
|
4880
|
+
// otherwise fall back to initial values from getValues()
|
|
4881
|
+
// This ensures the query can trigger on mount with initial values
|
|
4882
|
+
// For single: use watchId if it's not undefined/null, otherwise use initialId
|
|
4883
|
+
// For multiple: use watchIds if watchedValue is defined, otherwise use initialIds
|
|
4884
|
+
const currentId = watchId !== undefined && watchId !== null ? watchId : initialId;
|
|
4885
|
+
const currentIds = watchedValue !== undefined && watchedValue !== null && isMultiple
|
|
4886
|
+
? watchIds
|
|
4887
|
+
: initialIds;
|
|
5234
4888
|
// Query for search results
|
|
5235
4889
|
const query = useQuery({
|
|
5236
4890
|
queryKey: [`idpicker`, { column, searchText, limit, page }],
|
|
@@ -5270,33 +4924,43 @@ const IdPicker = ({ column, schema, prefix, isMultiple = false, }) => {
|
|
|
5270
4924
|
staleTime: 300000,
|
|
5271
4925
|
});
|
|
5272
4926
|
// Query for currently selected items (to display them properly)
|
|
4927
|
+
// Use currentId/currentIds in queryKey so it includes initial values and updates when watched values change
|
|
5273
4928
|
const queryDefault = useQuery({
|
|
5274
4929
|
queryKey: [
|
|
5275
4930
|
`idpicker-default`,
|
|
5276
|
-
{
|
|
4931
|
+
{
|
|
4932
|
+
form: parentSchema.title,
|
|
4933
|
+
column,
|
|
4934
|
+
id: isMultiple ? currentIds : currentId,
|
|
4935
|
+
},
|
|
5277
4936
|
],
|
|
5278
4937
|
queryFn: async () => {
|
|
4938
|
+
// Use current values (which include initial) for the query
|
|
4939
|
+
const queryId = currentId;
|
|
4940
|
+
const queryIds = currentIds;
|
|
5279
4941
|
if (customQueryFn) {
|
|
4942
|
+
// For customQueryFn, pass where clause to fetch specific IDs
|
|
5280
4943
|
const { data, idMap } = await customQueryFn({
|
|
5281
|
-
searching:
|
|
5282
|
-
limit: isMultiple ?
|
|
4944
|
+
searching: '',
|
|
4945
|
+
limit: isMultiple ? queryIds.length : 1,
|
|
5283
4946
|
offset: 0,
|
|
4947
|
+
where: [{ id: column_ref, value: isMultiple ? queryIds : queryId }],
|
|
5284
4948
|
});
|
|
5285
4949
|
setIdMap((state) => {
|
|
5286
4950
|
return { ...state, ...idMap };
|
|
5287
4951
|
});
|
|
5288
4952
|
return data;
|
|
5289
4953
|
}
|
|
5290
|
-
if (!
|
|
4954
|
+
if (!queryId && (!queryIds || queryIds.length === 0)) {
|
|
5291
4955
|
return { data: [] };
|
|
5292
4956
|
}
|
|
5293
|
-
const searchValue = isMultiple ?
|
|
4957
|
+
const searchValue = isMultiple ? queryIds.join(',') : queryId;
|
|
5294
4958
|
const data = await getTableData({
|
|
5295
4959
|
serverUrl,
|
|
5296
4960
|
searching: searchValue,
|
|
5297
4961
|
in_table: table,
|
|
5298
|
-
where: [{ id: column_ref, value: isMultiple ?
|
|
5299
|
-
limit: isMultiple ?
|
|
4962
|
+
where: [{ id: column_ref, value: isMultiple ? queryIds : queryId }],
|
|
4963
|
+
limit: isMultiple ? queryIds.length : 1,
|
|
5300
4964
|
offset: 0,
|
|
5301
4965
|
});
|
|
5302
4966
|
const newMap = Object.fromEntries((data ?? { data: [] }).data.map((item) => {
|
|
@@ -5313,16 +4977,9 @@ const IdPicker = ({ column, schema, prefix, isMultiple = false, }) => {
|
|
|
5313
4977
|
return data;
|
|
5314
4978
|
},
|
|
5315
4979
|
enabled: isMultiple
|
|
5316
|
-
? Array.isArray(
|
|
5317
|
-
: !!
|
|
4980
|
+
? Array.isArray(currentIds) && currentIds.length > 0
|
|
4981
|
+
: !!currentId,
|
|
5318
4982
|
});
|
|
5319
|
-
// Effect to load selected values when component mounts
|
|
5320
|
-
useEffect(() => {
|
|
5321
|
-
if (isMultiple ? watchIds.length > 0 : !!watchId) {
|
|
5322
|
-
queryDefault.refetch();
|
|
5323
|
-
}
|
|
5324
|
-
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
5325
|
-
}, []);
|
|
5326
4983
|
// Effect to trigger initial data fetch when popover opens
|
|
5327
4984
|
useEffect(() => {
|
|
5328
4985
|
if (openSearchResult) {
|
|
@@ -5355,7 +5012,8 @@ const IdPicker = ({ column, schema, prefix, isMultiple = false, }) => {
|
|
|
5355
5012
|
if (Object.keys(idMap).length <= 0) {
|
|
5356
5013
|
return '';
|
|
5357
5014
|
}
|
|
5358
|
-
|
|
5015
|
+
// Use currentId which includes initial values
|
|
5016
|
+
const record = idMap[currentId];
|
|
5359
5017
|
if (record === undefined) {
|
|
5360
5018
|
return '';
|
|
5361
5019
|
}
|
|
@@ -7194,4 +6852,524 @@ const getMultiDates = ({ selected, selectedDate, selectedDates, selectable, }) =
|
|
|
7194
6852
|
}
|
|
7195
6853
|
};
|
|
7196
6854
|
|
|
7197
|
-
|
|
6855
|
+
const TableDataDisplay = ({ colorPalette, emptyComponent, }) => {
|
|
6856
|
+
const { columns, translate, data } = useDataTableContext();
|
|
6857
|
+
const columnsMap = Object.fromEntries(columns.map((def) => {
|
|
6858
|
+
const { accessorKey, id } = def;
|
|
6859
|
+
if (accessorKey) {
|
|
6860
|
+
return [accessorKey, def];
|
|
6861
|
+
}
|
|
6862
|
+
return [id, def];
|
|
6863
|
+
}));
|
|
6864
|
+
const columnHeaders = Object.keys(columnsMap);
|
|
6865
|
+
const totalWidths = columns
|
|
6866
|
+
.map(({ size }) => {
|
|
6867
|
+
if (!!size === false) {
|
|
6868
|
+
return 0;
|
|
6869
|
+
}
|
|
6870
|
+
if (typeof size === "number") {
|
|
6871
|
+
return size;
|
|
6872
|
+
}
|
|
6873
|
+
return 0;
|
|
6874
|
+
})
|
|
6875
|
+
.reduce((previous, current) => previous + current, 0);
|
|
6876
|
+
const columnWidths = columns
|
|
6877
|
+
.map(({ size }) => {
|
|
6878
|
+
if (!!size === false) {
|
|
6879
|
+
return "1fr";
|
|
6880
|
+
}
|
|
6881
|
+
return `minmax(${size}px, ${(size / totalWidths) * 100}%)`;
|
|
6882
|
+
})
|
|
6883
|
+
.join(" ");
|
|
6884
|
+
console.log({ columnWidths }, "hadfg");
|
|
6885
|
+
const cellProps = {
|
|
6886
|
+
flex: "1 0 0%",
|
|
6887
|
+
overflow: "auto",
|
|
6888
|
+
paddingX: "2",
|
|
6889
|
+
py: "1",
|
|
6890
|
+
color: { base: "colorPalette.900", _dark: "colorPalette.100" },
|
|
6891
|
+
bgColor: { base: "colorPalette.50", _dark: "colorPalette.950" },
|
|
6892
|
+
borderBottomColor: { base: "colorPalette.200", _dark: "colorPalette.800" },
|
|
6893
|
+
borderBottomWidth: "1px",
|
|
6894
|
+
...{ colorPalette },
|
|
6895
|
+
};
|
|
6896
|
+
if (data.length <= 0) {
|
|
6897
|
+
return jsx(Fragment, { children: emptyComponent });
|
|
6898
|
+
}
|
|
6899
|
+
return (jsxs(Grid, { templateColumns: `${columnWidths}`, overflow: "auto", borderWidth: "1px", color: { base: "colorPalette.900", _dark: "colorPalette.100" }, borderColor: { base: "colorPalette.200", _dark: "colorPalette.800" }, colorPalette, children: [jsx(Grid, { templateColumns: `${columnWidths}`, column: `1/span ${columns.length}`, bg: { base: "colorPalette.200", _dark: "colorPalette.800" }, colorPalette, children: columnHeaders.map((header) => {
|
|
6900
|
+
return (jsx(Box, { flex: "1 0 0%", paddingX: "2", py: "1", overflow: "auto", textOverflow: "ellipsis", children: translate.t(`column_header.${header}`) }));
|
|
6901
|
+
}) }), data.map((record) => {
|
|
6902
|
+
return (jsx(Fragment, { children: columnHeaders.map((header) => {
|
|
6903
|
+
const { cell } = columnsMap[header];
|
|
6904
|
+
const value = record[header];
|
|
6905
|
+
if (!!record === false) {
|
|
6906
|
+
return (jsx(Box, { ...cellProps, children: translate.t(`column_cell.placeholder`) }));
|
|
6907
|
+
}
|
|
6908
|
+
if (cell) {
|
|
6909
|
+
return (jsx(Box, { ...cellProps, children: cell({ row: { original: record } }) }));
|
|
6910
|
+
}
|
|
6911
|
+
if (typeof value === "object") {
|
|
6912
|
+
return (jsx(Box, { ...cellProps, children: jsx(RecordDisplay, { object: value }) }));
|
|
6913
|
+
}
|
|
6914
|
+
return jsx(Box, { ...cellProps, children: value });
|
|
6915
|
+
}) }));
|
|
6916
|
+
})] }));
|
|
6917
|
+
};
|
|
6918
|
+
|
|
6919
|
+
const TableBodySkeleton = ({ showSelector = false, canResize = true, }) => {
|
|
6920
|
+
'use no memo';
|
|
6921
|
+
const { table } = useDataTableContext();
|
|
6922
|
+
const SELECTION_BOX_WIDTH = 20;
|
|
6923
|
+
const [hoveredRow, setHoveredRow] = useState(-1);
|
|
6924
|
+
const handleRowHover = (index) => {
|
|
6925
|
+
setHoveredRow(index);
|
|
6926
|
+
};
|
|
6927
|
+
const getTdProps = (column) => {
|
|
6928
|
+
const tdProps = column.getIsPinned()
|
|
6929
|
+
? {
|
|
6930
|
+
left: showSelector
|
|
6931
|
+
? `${column.getStart('left') + SELECTION_BOX_WIDTH + table.getDensityValue() * 2}px`
|
|
6932
|
+
: `${column.getStart('left')}px`,
|
|
6933
|
+
position: 'relative',
|
|
6934
|
+
}
|
|
6935
|
+
: {};
|
|
6936
|
+
return tdProps;
|
|
6937
|
+
};
|
|
6938
|
+
const getTrProps = ({ hoveredRow, index, }) => {
|
|
6939
|
+
if (hoveredRow === -1) {
|
|
6940
|
+
return {};
|
|
6941
|
+
}
|
|
6942
|
+
if (hoveredRow === index) {
|
|
6943
|
+
return {
|
|
6944
|
+
opacity: '1',
|
|
6945
|
+
};
|
|
6946
|
+
}
|
|
6947
|
+
return {
|
|
6948
|
+
opacity: '0.8',
|
|
6949
|
+
};
|
|
6950
|
+
};
|
|
6951
|
+
// Get the number of skeleton rows based on current pageSize
|
|
6952
|
+
const pageSize = table.getState().pagination.pageSize;
|
|
6953
|
+
const visibleColumns = table.getVisibleLeafColumns();
|
|
6954
|
+
return (jsx(Table$1.Body, { children: Array.from({ length: pageSize }).map((_, rowIndex) => {
|
|
6955
|
+
return (jsxs(Table$1.Row, { display: 'flex', zIndex: 1, onMouseEnter: () => handleRowHover(rowIndex), onMouseLeave: () => handleRowHover(-1), ...getTrProps({ hoveredRow, index: rowIndex }), children: [showSelector && jsx(TableRowSelectorSkeleton, {}), visibleColumns.map((column, colIndex) => {
|
|
6956
|
+
return (jsx(Table$1.Cell, { padding: `${table.getDensityValue()}px`,
|
|
6957
|
+
// styling resize and pinning start
|
|
6958
|
+
flex: `${canResize ? '0' : '1'} 0 ${column.getSize()}px`,
|
|
6959
|
+
// this is to avoid the cell from being too wide
|
|
6960
|
+
minWidth: `0`, color: {
|
|
6961
|
+
base: 'colorPalette.900',
|
|
6962
|
+
_dark: 'colorPalette.100',
|
|
6963
|
+
},
|
|
6964
|
+
bg: { base: 'colorPalette.50', _dark: 'colorPalette.950' }, ...getTdProps(column), children: jsx(Skeleton, { height: "20px", width: "80%" }) }, `chakra-table-skeleton-cell-${rowIndex}-${colIndex}`));
|
|
6965
|
+
})] }, `chakra-table-skeleton-row-${rowIndex}`));
|
|
6966
|
+
}) }));
|
|
6967
|
+
};
|
|
6968
|
+
const TableRowSelectorSkeleton = () => {
|
|
6969
|
+
const { table } = useDataTableContext();
|
|
6970
|
+
const SELECTION_BOX_WIDTH = 20;
|
|
6971
|
+
return (jsx(Table$1.Cell, { padding: `${table.getDensityValue()}px`, display: 'grid', color: {
|
|
6972
|
+
base: 'colorPalette.900',
|
|
6973
|
+
_dark: 'colorPalette.100',
|
|
6974
|
+
},
|
|
6975
|
+
bg: { base: 'colorPalette.50', _dark: 'colorPalette.950' }, justifyItems: 'center', alignItems: 'center', children: jsx(Skeleton, { width: `${SELECTION_BOX_WIDTH}px`, height: `${SELECTION_BOX_WIDTH}px` }) }));
|
|
6976
|
+
};
|
|
6977
|
+
|
|
6978
|
+
const DefaultTable = ({ showFooter = false, tableProps = {}, tableHeaderProps = {}, tableBodyProps = {}, tableFooterProps = {}, controlProps = {}, variant = '', isLoading = false, }) => {
|
|
6979
|
+
if (variant === 'greedy') {
|
|
6980
|
+
const bodyComponent = isLoading ? (jsx(TableBodySkeleton, { showSelector: tableBodyProps.showSelector, canResize: false })) : (jsx(TableBody, { ...tableBodyProps, canResize: false, ...tableBodyProps }));
|
|
6981
|
+
return (jsx(TableControls, { ...controlProps, children: jsxs(Table, { canResize: false,
|
|
6982
|
+
showLoading: isLoading,
|
|
6983
|
+
showSelector: tableHeaderProps.showSelector ??
|
|
6984
|
+
tableBodyProps.showSelector ??
|
|
6985
|
+
false,
|
|
6986
|
+
...tableProps, children: [jsx(TableHeader, { canResize: false, ...tableHeaderProps }), bodyComponent, showFooter && (jsx(TableFooter, { canResize: false, ...tableFooterProps }))] }) }));
|
|
6987
|
+
}
|
|
6988
|
+
const bodyComponent = isLoading ? (jsx(TableBodySkeleton, { showSelector: tableBodyProps.showSelector, canResize: tableBodyProps.canResize })) : (jsx(TableBody, { ...tableBodyProps }));
|
|
6989
|
+
return (jsx(TableControls, { ...controlProps, children: jsxs(Table, { showLoading: isLoading,
|
|
6990
|
+
showSelector: tableHeaderProps.showSelector ??
|
|
6991
|
+
tableBodyProps.showSelector ??
|
|
6992
|
+
false,
|
|
6993
|
+
...tableProps, children: [jsx(TableHeader, { ...tableHeaderProps }), bodyComponent, showFooter && jsx(TableFooter, { ...tableFooterProps })] }) }));
|
|
6994
|
+
};
|
|
6995
|
+
|
|
6996
|
+
/**
|
|
6997
|
+
* DefaultTableServer is a wrapper around DefaultTable that automatically
|
|
6998
|
+
* detects server-side loading state from DataTableServerContext.
|
|
6999
|
+
*
|
|
7000
|
+
* Use this component when working with DataTableServer to automatically
|
|
7001
|
+
* show skeleton loading state during data fetching.
|
|
7002
|
+
*
|
|
7003
|
+
* @example
|
|
7004
|
+
* ```tsx
|
|
7005
|
+
* <DataTableServer columns={columns} {...datatableServer}>
|
|
7006
|
+
* <DefaultTableServer />
|
|
7007
|
+
* </DataTableServer>
|
|
7008
|
+
* ```
|
|
7009
|
+
*/
|
|
7010
|
+
const DefaultTableServer = ({ isLoading: isLoadingOverride, ...props }) => {
|
|
7011
|
+
// Automatically detect loading state from server context
|
|
7012
|
+
const serverContext = useDataTableServerContext();
|
|
7013
|
+
const isLoading = isLoadingOverride ?? serverContext?.query?.isLoading ?? false;
|
|
7014
|
+
return jsx(DefaultTable, { ...props, isLoading: isLoading });
|
|
7015
|
+
};
|
|
7016
|
+
|
|
7017
|
+
const CellRenderer = ({ cell }) => {
|
|
7018
|
+
const { translate } = useDataTableContext();
|
|
7019
|
+
const getLabel = ({ columnId }) => {
|
|
7020
|
+
if (translate !== undefined) {
|
|
7021
|
+
return translate.t(`${columnId}`);
|
|
7022
|
+
}
|
|
7023
|
+
return snakeToLabel(columnId);
|
|
7024
|
+
};
|
|
7025
|
+
const formatValue = (value) => {
|
|
7026
|
+
if (typeof value === "object") {
|
|
7027
|
+
return JSON.stringify(value);
|
|
7028
|
+
}
|
|
7029
|
+
if (typeof value === "string") {
|
|
7030
|
+
return value;
|
|
7031
|
+
}
|
|
7032
|
+
if (typeof value === "number" || typeof value === "boolean") {
|
|
7033
|
+
return `${value}`;
|
|
7034
|
+
}
|
|
7035
|
+
if (value === undefined) {
|
|
7036
|
+
if (translate !== undefined) {
|
|
7037
|
+
return translate.t(`undefined`);
|
|
7038
|
+
}
|
|
7039
|
+
return `undefined`;
|
|
7040
|
+
}
|
|
7041
|
+
throw new Error(`value is unknown, ${typeof value}`);
|
|
7042
|
+
};
|
|
7043
|
+
const showCustomDataDisplay = cell.column.columnDef.meta?.showCustomDisplay ?? false;
|
|
7044
|
+
const gridColumn = cell.column.columnDef.meta?.gridColumn ?? [
|
|
7045
|
+
"span 12",
|
|
7046
|
+
"span 6",
|
|
7047
|
+
"span 3",
|
|
7048
|
+
];
|
|
7049
|
+
const gridRow = cell.column.columnDef.meta?.gridRow ?? {};
|
|
7050
|
+
if (showCustomDataDisplay) {
|
|
7051
|
+
return (jsx(Flex, { gridColumn, gridRow, children: flexRender(cell.column.columnDef.cell, cell.getContext()) }, cell.id));
|
|
7052
|
+
}
|
|
7053
|
+
const value = cell.getValue();
|
|
7054
|
+
if (typeof value === "object") {
|
|
7055
|
+
return (jsxs(Box, { gridColumn, gridRow, children: [jsx(Box, { children: getLabel({ columnId: cell.column.id }) }), jsx(RecordDisplay, { boxProps: {
|
|
7056
|
+
borderWidth: 1,
|
|
7057
|
+
borderRadius: 4,
|
|
7058
|
+
borderColor: "gray.400",
|
|
7059
|
+
paddingX: 4,
|
|
7060
|
+
paddingY: 2,
|
|
7061
|
+
}, object: value })] }, cell.id));
|
|
7062
|
+
}
|
|
7063
|
+
return (jsxs(Box, { gridColumn, gridRow, children: [jsx(Box, { color: "colorPalette.400", children: getLabel({ columnId: cell.column.id }) }), jsx(Box, { wordBreak: "break-word", textOverflow: "ellipsis", overflow: "hidden", children: `${formatValue(cell.getValue())}` })] }, cell.id));
|
|
7064
|
+
};
|
|
7065
|
+
const DataDisplay = ({ variant = "" }) => {
|
|
7066
|
+
const { table, translate } = useDataTableContext();
|
|
7067
|
+
return (jsx(Flex, { flexFlow: "column", gap: "1", children: table.getRowModel().rows.map((row) => {
|
|
7068
|
+
const rowId = row.id;
|
|
7069
|
+
return (jsx(Card.Root, { children: jsx(Card.Body, { display: "grid", gap: 4, padding: 4, gridTemplateColumns: "repeat(12, 1fr)", children: table.getAllColumns().map((column) => {
|
|
7070
|
+
const childCell = row.getAllCells().find((cell) => {
|
|
7071
|
+
return cell.id === `${rowId}_${column.id}`;
|
|
7072
|
+
});
|
|
7073
|
+
if (column.columns.length > 0) {
|
|
7074
|
+
return (jsxs(Card.Root, { margin: "1", gridColumn: "span 12", children: [jsx(Card.Header, { color: "gray.400", children: translate.t(column.id) }), jsx(Card.Body, { display: "grid", gap: "4", gridTemplateColumns: "repeat(12, 1fr)", children: column.columns.map((column) => {
|
|
7075
|
+
if (!column.getIsVisible()) {
|
|
7076
|
+
return jsx(Fragment, {});
|
|
7077
|
+
}
|
|
7078
|
+
const foundCell = row
|
|
7079
|
+
.getVisibleCells()
|
|
7080
|
+
.find((cell) => {
|
|
7081
|
+
return cell.id === `${rowId}_${column.id}`;
|
|
7082
|
+
});
|
|
7083
|
+
return jsx(CellRenderer, { cell: foundCell });
|
|
7084
|
+
}) })] }, `chakra-table-card-${childCell?.id}`));
|
|
7085
|
+
}
|
|
7086
|
+
return jsx(CellRenderer, { cell: childCell });
|
|
7087
|
+
}) }) }, `chakra-table-card-${rowId}`));
|
|
7088
|
+
}) }));
|
|
7089
|
+
};
|
|
7090
|
+
|
|
7091
|
+
// Reference: https://tanstack.com/table/latest/docs/framework/react/examples/custom-features
|
|
7092
|
+
// TypeScript setup for our new feature with all of the same type-safety as stock TanStack Table features
|
|
7093
|
+
// end of TS setup!
|
|
7094
|
+
// Here is all of the actual javascript code for our new feature
|
|
7095
|
+
const DensityFeature = {
|
|
7096
|
+
// define the new feature's initial state
|
|
7097
|
+
getInitialState: (state) => {
|
|
7098
|
+
return {
|
|
7099
|
+
density: "sm",
|
|
7100
|
+
...state,
|
|
7101
|
+
};
|
|
7102
|
+
},
|
|
7103
|
+
// define the new feature's default options
|
|
7104
|
+
getDefaultOptions: (table) => {
|
|
7105
|
+
return {
|
|
7106
|
+
enableDensity: true,
|
|
7107
|
+
onDensityChange: makeStateUpdater("density", table),
|
|
7108
|
+
};
|
|
7109
|
+
},
|
|
7110
|
+
// if you need to add a default column definition...
|
|
7111
|
+
// getDefaultColumnDef: <TData extends RowData>(): Partial<ColumnDef<TData>> => {
|
|
7112
|
+
// return { meta: {} } //use meta instead of directly adding to the columnDef to avoid typescript stuff that's hard to workaround
|
|
7113
|
+
// },
|
|
7114
|
+
// define the new feature's table instance methods
|
|
7115
|
+
createTable: (table) => {
|
|
7116
|
+
table.setDensity = (updater) => {
|
|
7117
|
+
const safeUpdater = (old) => {
|
|
7118
|
+
let newState = functionalUpdate(updater, old);
|
|
7119
|
+
return newState;
|
|
7120
|
+
};
|
|
7121
|
+
return table.options.onDensityChange?.(safeUpdater);
|
|
7122
|
+
};
|
|
7123
|
+
table.toggleDensity = (value) => {
|
|
7124
|
+
table.setDensity((old) => {
|
|
7125
|
+
if (value)
|
|
7126
|
+
return value;
|
|
7127
|
+
if (old === "sm") {
|
|
7128
|
+
return "md";
|
|
7129
|
+
}
|
|
7130
|
+
if (old === "md") {
|
|
7131
|
+
return "lg";
|
|
7132
|
+
}
|
|
7133
|
+
return "sm";
|
|
7134
|
+
});
|
|
7135
|
+
};
|
|
7136
|
+
table.getDensityValue = (value) => {
|
|
7137
|
+
let density;
|
|
7138
|
+
if (value) {
|
|
7139
|
+
density = value;
|
|
7140
|
+
}
|
|
7141
|
+
else {
|
|
7142
|
+
density = table.getState().density;
|
|
7143
|
+
}
|
|
7144
|
+
if (density === "sm") {
|
|
7145
|
+
return 8;
|
|
7146
|
+
}
|
|
7147
|
+
if (density === "md") {
|
|
7148
|
+
return 16;
|
|
7149
|
+
}
|
|
7150
|
+
return 32;
|
|
7151
|
+
};
|
|
7152
|
+
},
|
|
7153
|
+
// if you need to add row instance APIs...
|
|
7154
|
+
// createRow: <TData extends RowData>(row, table): void => {},
|
|
7155
|
+
// if you need to add cell instance APIs...
|
|
7156
|
+
// createCell: <TData extends RowData>(cell, column, row, table): void => {},
|
|
7157
|
+
// if you need to add column instance APIs...
|
|
7158
|
+
// createColumn: <TData extends RowData>(column, table): void => {},
|
|
7159
|
+
// if you need to add header instance APIs...
|
|
7160
|
+
// createHeader: <TData extends RowData>(header, table): void => {},
|
|
7161
|
+
};
|
|
7162
|
+
//end of custom feature code
|
|
7163
|
+
|
|
7164
|
+
// Define a custom fuzzy filter function that will apply ranking info to rows (using match-sorter utils)
|
|
7165
|
+
const fuzzyFilter = (row, columnId, value, addMeta) => {
|
|
7166
|
+
// Rank the item
|
|
7167
|
+
const itemRank = rankItem(row.getValue(columnId), value);
|
|
7168
|
+
// Store the itemRank info
|
|
7169
|
+
addMeta({
|
|
7170
|
+
itemRank,
|
|
7171
|
+
});
|
|
7172
|
+
// Return if the item should be filtered in/out
|
|
7173
|
+
return itemRank.passed;
|
|
7174
|
+
};
|
|
7175
|
+
/**
|
|
7176
|
+
* DataTable will create a context to hold all values to
|
|
7177
|
+
* help the render of the DataTable in serverside
|
|
7178
|
+
*
|
|
7179
|
+
*
|
|
7180
|
+
* The query is required to be a GET request that can receive
|
|
7181
|
+
* specified params and return a specified response
|
|
7182
|
+
*
|
|
7183
|
+
* @link https://tanstack.com/table/latest/docs/guide/column-defs
|
|
7184
|
+
*/
|
|
7185
|
+
function DataTable({ columns, data, enableRowSelection = true, enableMultiRowSelection = true, enableSubRowSelection = true, columnOrder, columnFilters, columnVisibility, density, globalFilter, pagination, sorting, rowSelection, setPagination, setSorting, setColumnFilters, setRowSelection, setGlobalFilter, setColumnOrder, setDensity, setColumnVisibility, translate, children, tableLabel = {
|
|
7186
|
+
view: 'View',
|
|
7187
|
+
edit: 'Edit',
|
|
7188
|
+
filterButtonText: 'Filter',
|
|
7189
|
+
filterTitle: 'Filter',
|
|
7190
|
+
filterReset: 'Reset',
|
|
7191
|
+
filterClose: 'Close',
|
|
7192
|
+
reloadTooltip: 'Reload',
|
|
7193
|
+
reloadButtonText: 'Reload',
|
|
7194
|
+
resetSelection: 'Reset Selection',
|
|
7195
|
+
resetSorting: 'Reset Sorting',
|
|
7196
|
+
rowCountText: 'Row Count',
|
|
7197
|
+
hasErrorText: 'Has Error',
|
|
7198
|
+
globalFilterPlaceholder: 'Search',
|
|
7199
|
+
trueLabel: 'True',
|
|
7200
|
+
falseLabel: 'False',
|
|
7201
|
+
}, }) {
|
|
7202
|
+
const table = useReactTable({
|
|
7203
|
+
_features: [DensityFeature],
|
|
7204
|
+
data: data,
|
|
7205
|
+
rowCount: data.length,
|
|
7206
|
+
columns: columns,
|
|
7207
|
+
getCoreRowModel: getCoreRowModel(),
|
|
7208
|
+
getFilteredRowModel: getFilteredRowModel(),
|
|
7209
|
+
getSortedRowModel: getSortedRowModel(),
|
|
7210
|
+
getPaginationRowModel: getPaginationRowModel(),
|
|
7211
|
+
defaultColumn: {
|
|
7212
|
+
size: 150, //starting column size
|
|
7213
|
+
minSize: 10, //enforced during column resizing
|
|
7214
|
+
maxSize: 10000, //enforced during column resizing
|
|
7215
|
+
},
|
|
7216
|
+
enableRowSelection: enableRowSelection,
|
|
7217
|
+
enableMultiRowSelection: enableMultiRowSelection,
|
|
7218
|
+
enableSubRowSelection: enableSubRowSelection,
|
|
7219
|
+
columnResizeMode: 'onChange',
|
|
7220
|
+
// global filter start
|
|
7221
|
+
filterFns: {
|
|
7222
|
+
fuzzy: fuzzyFilter,
|
|
7223
|
+
},
|
|
7224
|
+
globalFilterFn: 'fuzzy',
|
|
7225
|
+
state: {
|
|
7226
|
+
pagination,
|
|
7227
|
+
sorting,
|
|
7228
|
+
columnFilters,
|
|
7229
|
+
rowSelection,
|
|
7230
|
+
columnOrder,
|
|
7231
|
+
globalFilter,
|
|
7232
|
+
density,
|
|
7233
|
+
columnVisibility,
|
|
7234
|
+
},
|
|
7235
|
+
onPaginationChange: setPagination,
|
|
7236
|
+
onSortingChange: setSorting,
|
|
7237
|
+
onColumnFiltersChange: setColumnFilters,
|
|
7238
|
+
onRowSelectionChange: setRowSelection,
|
|
7239
|
+
onColumnOrderChange: (state) => {
|
|
7240
|
+
setColumnOrder(state);
|
|
7241
|
+
},
|
|
7242
|
+
onGlobalFilterChange: (state) => {
|
|
7243
|
+
setGlobalFilter(state);
|
|
7244
|
+
},
|
|
7245
|
+
onDensityChange: setDensity,
|
|
7246
|
+
onColumnVisibilityChange: setColumnVisibility,
|
|
7247
|
+
});
|
|
7248
|
+
return (jsx(DataTableContext.Provider, { value: {
|
|
7249
|
+
table: table,
|
|
7250
|
+
globalFilter,
|
|
7251
|
+
setGlobalFilter,
|
|
7252
|
+
type: 'client',
|
|
7253
|
+
translate,
|
|
7254
|
+
columns: columns,
|
|
7255
|
+
sorting,
|
|
7256
|
+
setSorting,
|
|
7257
|
+
columnFilters,
|
|
7258
|
+
setColumnFilters,
|
|
7259
|
+
pagination,
|
|
7260
|
+
setPagination,
|
|
7261
|
+
rowSelection,
|
|
7262
|
+
setRowSelection,
|
|
7263
|
+
columnOrder,
|
|
7264
|
+
setColumnOrder,
|
|
7265
|
+
density,
|
|
7266
|
+
setDensity,
|
|
7267
|
+
columnVisibility,
|
|
7268
|
+
setColumnVisibility,
|
|
7269
|
+
data,
|
|
7270
|
+
tableLabel,
|
|
7271
|
+
}, children: children }));
|
|
7272
|
+
}
|
|
7273
|
+
|
|
7274
|
+
/**
|
|
7275
|
+
* DataTableServer will create a context to hold all values to
|
|
7276
|
+
* help the render of the DataTable in serverside
|
|
7277
|
+
*
|
|
7278
|
+
* The query is required to be a GET request that can receive
|
|
7279
|
+
* specified params and return a specified response
|
|
7280
|
+
*
|
|
7281
|
+
* The `useDataTableServer` can help to create the specified request and response
|
|
7282
|
+
*
|
|
7283
|
+
* @link https://tanstack.com/table/latest/docs/guide/column-defs
|
|
7284
|
+
*/
|
|
7285
|
+
function DataTableServer({ columns, enableRowSelection = true, enableMultiRowSelection = true, enableSubRowSelection = true, columnOrder, columnFilters, columnVisibility, density, globalFilter, pagination, sorting, rowSelection, setPagination, setSorting, setColumnFilters, setRowSelection, setGlobalFilter, setColumnOrder, setDensity, setColumnVisibility, query, url, translate, children, tableLabel = {
|
|
7286
|
+
view: "View",
|
|
7287
|
+
edit: "Edit",
|
|
7288
|
+
filterButtonText: "Filter",
|
|
7289
|
+
filterTitle: "Filter",
|
|
7290
|
+
filterReset: "Reset",
|
|
7291
|
+
filterClose: "Close",
|
|
7292
|
+
reloadTooltip: "Reload",
|
|
7293
|
+
reloadButtonText: "Reload",
|
|
7294
|
+
resetSelection: "Reset Selection",
|
|
7295
|
+
resetSorting: "Reset Sorting",
|
|
7296
|
+
rowCountText: "Row Count",
|
|
7297
|
+
hasErrorText: "Has Error",
|
|
7298
|
+
globalFilterPlaceholder: "Search",
|
|
7299
|
+
trueLabel: "True",
|
|
7300
|
+
falseLabel: "False",
|
|
7301
|
+
}, }) {
|
|
7302
|
+
const table = useReactTable({
|
|
7303
|
+
_features: [DensityFeature],
|
|
7304
|
+
data: (query.data?.data ?? []),
|
|
7305
|
+
rowCount: query.data?.count ?? 0,
|
|
7306
|
+
columns: columns,
|
|
7307
|
+
getCoreRowModel: getCoreRowModel(),
|
|
7308
|
+
manualPagination: true,
|
|
7309
|
+
manualSorting: true,
|
|
7310
|
+
columnResizeMode: "onChange",
|
|
7311
|
+
defaultColumn: {
|
|
7312
|
+
size: 150, //starting column size
|
|
7313
|
+
minSize: 10, //enforced during column resizing
|
|
7314
|
+
maxSize: 10000, //enforced during column resizing
|
|
7315
|
+
},
|
|
7316
|
+
enableRowSelection: enableRowSelection,
|
|
7317
|
+
enableMultiRowSelection: enableMultiRowSelection,
|
|
7318
|
+
enableSubRowSelection: enableSubRowSelection,
|
|
7319
|
+
state: {
|
|
7320
|
+
pagination,
|
|
7321
|
+
sorting,
|
|
7322
|
+
columnFilters,
|
|
7323
|
+
rowSelection,
|
|
7324
|
+
columnOrder,
|
|
7325
|
+
globalFilter,
|
|
7326
|
+
density,
|
|
7327
|
+
columnVisibility,
|
|
7328
|
+
},
|
|
7329
|
+
onPaginationChange: setPagination,
|
|
7330
|
+
onSortingChange: setSorting,
|
|
7331
|
+
onColumnFiltersChange: setColumnFilters,
|
|
7332
|
+
onRowSelectionChange: setRowSelection,
|
|
7333
|
+
onColumnOrderChange: (state) => {
|
|
7334
|
+
setColumnOrder(state);
|
|
7335
|
+
},
|
|
7336
|
+
onGlobalFilterChange: (state) => {
|
|
7337
|
+
setGlobalFilter(state);
|
|
7338
|
+
},
|
|
7339
|
+
onDensityChange: setDensity,
|
|
7340
|
+
onColumnVisibilityChange: setColumnVisibility,
|
|
7341
|
+
// for tanstack-table ts bug start
|
|
7342
|
+
filterFns: {
|
|
7343
|
+
fuzzy: () => {
|
|
7344
|
+
return false;
|
|
7345
|
+
},
|
|
7346
|
+
},
|
|
7347
|
+
// for tanstack-table ts bug end
|
|
7348
|
+
});
|
|
7349
|
+
return (jsx(DataTableContext.Provider, { value: {
|
|
7350
|
+
table: table,
|
|
7351
|
+
globalFilter,
|
|
7352
|
+
setGlobalFilter,
|
|
7353
|
+
type: "server",
|
|
7354
|
+
translate,
|
|
7355
|
+
columns: columns,
|
|
7356
|
+
sorting,
|
|
7357
|
+
setSorting,
|
|
7358
|
+
columnFilters,
|
|
7359
|
+
setColumnFilters,
|
|
7360
|
+
pagination,
|
|
7361
|
+
setPagination,
|
|
7362
|
+
rowSelection,
|
|
7363
|
+
setRowSelection,
|
|
7364
|
+
columnOrder,
|
|
7365
|
+
setColumnOrder,
|
|
7366
|
+
density,
|
|
7367
|
+
setDensity,
|
|
7368
|
+
columnVisibility,
|
|
7369
|
+
setColumnVisibility,
|
|
7370
|
+
data: query.data?.data ?? [],
|
|
7371
|
+
tableLabel,
|
|
7372
|
+
}, children: jsx(DataTableServerContext.Provider, { value: { url, query }, children: children }) }));
|
|
7373
|
+
}
|
|
7374
|
+
|
|
7375
|
+
export { CardHeader, DataDisplay, DataTable, DataTableServer, DefaultCardTitle, DefaultForm, DefaultTable, DefaultTableServer, DensityToggleButton, EditSortingButton, EmptyState, ErrorAlert, FilterDialog, FormBody, FormRoot, FormTitle, GlobalFilter, PageSizeControl, Pagination, RecordDisplay, ReloadButton, ResetFilteringButton, ResetSelectionButton, ResetSortingButton, RowCountText, Table, TableBody, TableCardContainer, TableCards, TableComponent, TableControls, TableDataDisplay, TableFilter, TableFilterTags, TableFooter, TableHeader, TableLoadingComponent, TableSelector, TableSorter, TableViewer, TextCell, ViewDialog, buildErrorMessages, buildFieldErrors, buildRequiredErrors, convertToAjvErrorsFormat, createErrorMessage, getColumns, getMultiDates, getRangeDates, idPickerSanityCheck, useDataTable, useDataTableContext, useDataTableServer, useForm, widthSanityCheck };
|