@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.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, Image, EmptyState as EmptyState$2, VStack, Alert, Card, Group, InputElement, Tooltip as Tooltip$1, Icon, List, Table as Table$1, Checkbox as Checkbox$1, Skeleton, MenuRoot as MenuRoot$1, MenuTrigger as MenuTrigger$1, Field as Field$1, Popover, NumberInput, Show, RadioCard, CheckboxGroup, Center, Heading } from '@chakra-ui/react';
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, MdClear, MdOutlineChecklist, MdDateRange } from 'react-icons/md';
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 CardHeader = ({ row, imageColumnId = undefined, titleColumnId = undefined, tagColumnId = undefined, tagIcon = undefined, showTag = true, imageProps = {}, }) => {
2606
- if (!!row.original === false) {
2607
- return jsx(Fragment, {});
2608
- }
2609
- const isShowFirstColumn = !!titleColumnId || showTag;
2610
- 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] }))] }))] }));
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 EmptyState$1 = ({ title = "No records", description = "Add a new events to get started or refine your search", }) => {
2625
- const { isEmpty } = useDataTableServerContext();
2626
- 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 })] })] }) })) }));
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 ErrorAlert = ({ showMessage = true }) => {
2630
- const { query } = useDataTableServerContext();
2631
- const { isError, error } = query;
2632
- 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 }))] })] })) }));
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 snakeToLabel = (str) => {
2636
- return str
2637
- .split("_") // Split by underscore
2638
- .map((word) => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase()) // Capitalize each word
2639
- .join(" "); // Join with space
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 RecordDisplay = ({ object, boxProps, translate, prefix = "", }) => {
2643
- const getColumn = ({ field }) => {
2644
- if (translate !== undefined) {
2645
- return translate.t(`${prefix}${field}`);
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 CellRenderer = ({ cell }) => {
2658
- const { translate } = useDataTableContext();
2659
- const getLabel = ({ columnId }) => {
2660
- if (translate !== undefined) {
2661
- return translate.t(`${columnId}`);
2662
- }
2663
- return snakeToLabel(columnId);
2664
- };
2665
- const formatValue = (value) => {
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
- const DataDisplay = ({ variant = "" }) => {
2706
- const { table, translate } = useDataTableContext();
2707
- return (jsx(Flex, { flexFlow: "column", gap: "1", children: table.getRowModel().rows.map((row) => {
2708
- const rowId = row.id;
2709
- return (jsx(Card.Root, { children: jsx(Card.Body, { display: "grid", gap: 4, padding: 4, gridTemplateColumns: "repeat(12, 1fr)", children: table.getAllColumns().map((column) => {
2710
- const childCell = row.getAllCells().find((cell) => {
2711
- return cell.id === `${rowId}_${column.id}`;
2712
- });
2713
- if (column.columns.length > 0) {
2714
- 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) => {
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
- const foundCell = row
2719
- .getVisibleCells()
2720
- .find((cell) => {
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
- // Reference: https://tanstack.com/table/latest/docs/framework/react/examples/custom-features
2732
- // TypeScript setup for our new feature with all of the same type-safety as stock TanStack Table features
2733
- // end of TS setup!
2734
- // Here is all of the actual javascript code for our new feature
2735
- const DensityFeature = {
2736
- // define the new feature's initial state
2737
- getInitialState: (state) => {
2738
- return {
2739
- density: "sm",
2740
- ...state,
2741
- };
2742
- },
2743
- // define the new feature's default options
2744
- getDefaultOptions: (table) => {
2745
- return {
2746
- enableDensity: true,
2747
- onDensityChange: makeStateUpdater("density", table),
2748
- };
2749
- },
2750
- // if you need to add a default column definition...
2751
- // getDefaultColumnDef: <TData extends RowData>(): Partial<ColumnDef<TData>> => {
2752
- // return { meta: {} } //use meta instead of directly adding to the columnDef to avoid typescript stuff that's hard to workaround
2753
- // },
2754
- // define the new feature's table instance methods
2755
- createTable: (table) => {
2756
- table.setDensity = (updater) => {
2757
- const safeUpdater = (old) => {
2758
- let newState = functionalUpdate(updater, old);
2759
- return newState;
2760
- };
2761
- return table.options.onDensityChange?.(safeUpdater);
2762
- };
2763
- table.toggleDensity = (value) => {
2764
- table.setDensity((old) => {
2765
- if (value)
2766
- return value;
2767
- if (old === "sm") {
2768
- return "md";
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
- if (old === "md") {
2771
- return "lg";
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 "sm";
2775
+ return a.index - b.index;
2774
2776
  });
2775
- };
2776
- table.getDensityValue = (value) => {
2777
- let density;
2778
- if (value) {
2779
- density = value;
2780
- }
2781
- else {
2782
- density = table.getState().density;
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
- if (density === "sm") {
2785
- return 8;
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
- if (density === "md") {
2788
- return 16;
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
- // if you need to add row instance APIs...
2794
- // createRow: <TData extends RowData>(row, table): void => {},
2795
- // if you need to add cell instance APIs...
2796
- // createCell: <TData extends RowData>(cell, column, row, table): void => {},
2797
- // if you need to add column instance APIs...
2798
- // createColumn: <TData extends RowData>(column, table): void => {},
2799
- // if you need to add header instance APIs...
2800
- // createHeader: <TData extends RowData>(header, table): void => {},
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
- // Define a custom fuzzy filter function that will apply ranking info to rows (using match-sorter utils)
2805
- const fuzzyFilter = (row, columnId, value, addMeta) => {
2806
- // Rank the item
2807
- const itemRank = rankItem(row.getValue(columnId), value);
2808
- // Store the itemRank info
2809
- addMeta({
2810
- itemRank,
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
- // Return if the item should be filtered in/out
2813
- return itemRank.passed;
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
- * DataTable will create a context to hold all values to
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
- * The query is required to be a GET request that can receive
2821
- * specified params and return a specified response
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
- * @link https://tanstack.com/table/latest/docs/guide/column-defs
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
- 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 = {
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
- const [hoveredRow, setHoveredRow] = useState(-1);
3116
- const handleRowHover = (index) => {
3117
- setHoveredRow(index);
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 getTdProps = (cell) => {
3120
- const tdProps = cell.column.getIsPinned()
3041
+ const getThProps = (header) => {
3042
+ const thProps = header.column.getIsPinned()
3121
3043
  ? {
3122
3044
  left: showSelector
3123
- ? `${cell.column.getStart("left") + SELECTION_BOX_WIDTH + table.getDensityValue() * 2}px`
3124
- : `${cell.column.getStart("left")}px`,
3125
- position: "relative",
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 tdProps;
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 useDataTable = ({ default: { sorting: defaultSorting = [], pagination: defaultPagination = {
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 watchId = watch(colLabel);
5233
- const watchIds = isMultiple ? (watch(colLabel) ?? []) : [];
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
- { form: parentSchema.title, column, id: isMultiple ? watchIds : watchId },
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: watchIds.join(','),
5282
- limit: isMultiple ? watchIds.length : 1,
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 (!watchId && (!watchIds || watchIds.length === 0)) {
4954
+ if (!queryId && (!queryIds || queryIds.length === 0)) {
5291
4955
  return { data: [] };
5292
4956
  }
5293
- const searchValue = isMultiple ? watchIds.join(',') : watchId;
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 ? watchIds : watchId }],
5299
- limit: isMultiple ? watchIds.length : 1,
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(watchIds) && watchIds.length > 0
5317
- : !!watchId,
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
- const record = idMap[watchId];
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
- export { CardHeader, DataDisplay, DataTable, DataTableServer, DefaultCardTitle, DefaultForm, DefaultTable, DefaultTableServer, DensityToggleButton, EditSortingButton, EmptyState$1 as 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 };
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 };