@gobolt/genesis 0.4.7 → 0.4.9

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.
@@ -3,7 +3,7 @@ import { OverflowMenuItemProps } from '../OverflowMenuItem';
3
3
  export interface OverflowMenuProps {
4
4
  items?: OverflowMenuItemProps[];
5
5
  children?: React.ReactNode;
6
- trigger: React.ReactNode;
6
+ trigger?: React.ReactNode;
7
7
  isOpen?: boolean;
8
8
  onOpenChange?: (open: boolean) => void;
9
9
  placement?: "bottom" | "top" | "left" | "right";
@@ -28,6 +28,7 @@ export interface TableProps<T extends Record<string, any>> {
28
28
  name?: string;
29
29
  };
30
30
  };
31
+ onRowClick?: (record: T, index: number, event: React.MouseEvent) => void;
31
32
  onChange?: (pagination: TablePaginationConfig, filters: Record<string, any>, sorter: SorterResult<T> | SorterResult<T>[], extra: any) => void;
32
33
  loading?: boolean;
33
34
  pagination?: (TablePaginationConfig & {
@@ -58,5 +59,5 @@ export type SorterResult<T> = {
58
59
  field?: keyof T | string | React.Key | readonly React.Key[];
59
60
  columnKey?: React.Key;
60
61
  };
61
- declare function Table<T extends Record<string, any>>({ columns, dataSource, rowKey, size, onChange, rowSelection, pagination, isMainContentCell, isMaterializedView, materializedViewConfig, ...rest }: TableProps<T>): import("react/jsx-runtime").JSX.Element;
62
+ declare function Table<T extends Record<string, any>>({ columns, dataSource, rowKey, size, onChange, rowSelection, onRowClick, pagination, isMainContentCell, isMaterializedView, materializedViewConfig, ...rest }: TableProps<T>): import("react/jsx-runtime").JSX.Element;
62
63
  export default Table;
@@ -15,15 +15,19 @@ export type UseTableConfig = {
15
15
  };
16
16
  export declare const useTable: <T extends Record<string, any>>(useTableConfig: any) => {
17
17
  isLoading: boolean;
18
+ hasErrored: boolean;
18
19
  rowSelection: {
19
20
  type: SelectionType;
20
- onChange: (selectedRowKeys: React.Key[], selectedRows: T[]) => void;
21
+ selectedRowKeys: import('react').Key[];
22
+ onChange: (newSelectedRowKeys: React.Key[], newSelectedRows: T[]) => void;
21
23
  getCheckboxProps: (record: any) => unknown;
22
24
  };
23
25
  selectedRows: T[];
26
+ selectedRowKeys: import('react').Key[];
24
27
  hasSettings: boolean;
25
28
  hasFilter: boolean;
26
29
  updateDataSource: (newDataSource: T[]) => void;
30
+ retry: () => void;
27
31
  dataSource: T[];
28
32
  columns: ColumnsType<T>;
29
33
  error: Error | null;
@@ -1,3 +1,4 @@
1
+ import { default as React } from 'react';
1
2
  import { TableProps } from '../Table';
2
3
  import { TableControlsData } from '../Table/TableControls/TableControls';
3
4
  import { ActionEvent, TableEventPayload } from '../../types/events';
@@ -5,6 +6,7 @@ export interface TableWithControlsProps {
5
6
  tableControlsData: TableControlsData;
6
7
  tableData: TableProps<Record<string, any>>;
7
8
  onChange: (event: ActionEvent<TableEventPayload>) => void;
9
+ onRowClick?: (record: Record<string, any>, index: number, event: React.MouseEvent) => void;
8
10
  }
9
- declare const TableWithControls: ({ tableData, tableControlsData, onChange, }: TableWithControlsProps) => import("react/jsx-runtime").JSX.Element;
11
+ declare const TableWithControls: ({ tableData, tableControlsData, onChange, onRowClick, }: TableWithControlsProps) => import("react/jsx-runtime").JSX.Element;
10
12
  export default TableWithControls;
@@ -20,12 +20,15 @@ export declare const useTableWithControls: (tableConfig: UseTableConfig) => {
20
20
  };
21
21
  totalRecords: number;
22
22
  };
23
- dataSource: Record<string, any>[];
23
+ dataSource: any[];
24
24
  columns: import('antd').TableColumnsType<Record<string, any>>;
25
25
  rowSelection: {
26
26
  type: import('../Table/Table').SelectionType;
27
- onChange: (selectedRowKeys: React.Key[], selectedRows: Record<string, any>[]) => void;
27
+ selectedRowKeys: import('react').Key[];
28
+ onChange: (newSelectedRowKeys: React.Key[], newSelectedRows: Record<string, any>[]) => void;
28
29
  getCheckboxProps: (record: any) => unknown;
29
30
  };
31
+ selectedRows: Record<string, any>[];
32
+ selectedRowKeys: import('react').Key[];
30
33
  updateDataSource: (newDataSource: Record<string, any>[]) => void;
31
- } | null;
34
+ };
package/dist/index.cjs CHANGED
@@ -60250,6 +60250,9 @@ function FaCircleCheck(props) {
60250
60250
  function HiClock(props) {
60251
60251
  return GenIcon({ "attr": { "viewBox": "0 0 20 20", "fill": "currentColor", "aria-hidden": "true" }, "child": [{ "tag": "path", "attr": { "fillRule": "evenodd", "d": "M10 18a8 8 0 100-16 8 8 0 000 16zm1-12a1 1 0 10-2 0v4a1 1 0 00.293.707l2.828 2.829a1 1 0 101.415-1.415L11 9.586V6z", "clipRule": "evenodd" }, "child": [] }] })(props);
60252
60252
  }
60253
+ function HiDotsHorizontal(props) {
60254
+ return GenIcon({ "attr": { "viewBox": "0 0 20 20", "fill": "currentColor", "aria-hidden": "true" }, "child": [{ "tag": "path", "attr": { "d": "M6 10a2 2 0 11-4 0 2 2 0 014 0zM12 10a2 2 0 11-4 0 2 2 0 014 0zM16 12a2 2 0 100-4 2 2 0 000 4z" }, "child": [] }] })(props);
60255
+ }
60253
60256
  function HiExclamationCircle(props) {
60254
60257
  return GenIcon({ "attr": { "viewBox": "0 0 20 20", "fill": "currentColor", "aria-hidden": "true" }, "child": [{ "tag": "path", "attr": { "fillRule": "evenodd", "d": "M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-7 4a1 1 0 11-2 0 1 1 0 012 0zm-1-9a1 1 0 00-1 1v4a1 1 0 102 0V6a1 1 0 00-1-1z", "clipRule": "evenodd" }, "child": [] }] })(props);
60255
60258
  }
@@ -80515,10 +80518,13 @@ const OverflowMenuItem$1 = styled.div`
80515
80518
  const OverflowMenuItem = ({ children: children2, onClick }) => {
80516
80519
  return /* @__PURE__ */ jsxRuntime.jsx(OverflowMenuItem$1, { onClick, children: children2 });
80517
80520
  };
80521
+ const DefaultTrigger = () => {
80522
+ return /* @__PURE__ */ jsxRuntime.jsx(Button$1, { isIconButton: true, themeType: "secondary", size: "small", children: /* @__PURE__ */ jsxRuntime.jsx(HiDotsHorizontal, {}) });
80523
+ };
80518
80524
  const OverflowMenu = ({
80519
80525
  items,
80520
80526
  children: children2,
80521
- trigger,
80527
+ trigger = /* @__PURE__ */ jsxRuntime.jsx(DefaultTrigger, {}),
80522
80528
  isOpen: controlledIsOpen,
80523
80529
  onOpenChange,
80524
80530
  placement = "bottom",
@@ -80795,7 +80801,7 @@ const getCombinedPercent = (firstBarData, secondBarData) => {
80795
80801
  if (firstBarData?.value !== void 0 && secondBarData?.value !== void 0) {
80796
80802
  const total = firstBarData.value + secondBarData.value;
80797
80803
  const dividedBy = total / 2;
80798
- return Math.round(dividedBy * 10) / 10;
80804
+ return Math.round(dividedBy);
80799
80805
  }
80800
80806
  return firstBarData?.value || 0;
80801
80807
  };
@@ -83969,6 +83975,7 @@ function Table({
83969
83975
  size = "small",
83970
83976
  onChange,
83971
83977
  rowSelection,
83978
+ onRowClick,
83972
83979
  pagination,
83973
83980
  isMainContentCell = false,
83974
83981
  isMaterializedView = false,
@@ -83981,6 +83988,7 @@ function Table({
83981
83988
  const [dynamicHeight, setDynamicHeight] = React__namespace.useState(
83982
83989
  400
83983
83990
  );
83991
+ const [selectedRowKeys, setSelectedRowKeys] = React__namespace.useState([]);
83984
83992
  const tableRef = React__namespace.useRef(null);
83985
83993
  const containerRef = React__namespace.useRef(null);
83986
83994
  React__namespace.useEffect(() => {
@@ -84083,6 +84091,61 @@ function Table({
84083
84091
  return rest.scroll;
84084
84092
  }, [isMaterializedView, materializedViewConfig, dynamicHeight, rest.scroll]);
84085
84093
  const tableDataSource = isMaterializedView ? materializedData : dataSource;
84094
+ const handleRowClick = React__namespace.useCallback(
84095
+ (record, index2, event) => {
84096
+ console.log("Row clicked:", record, "index:", index2);
84097
+ const target = event.target;
84098
+ const isInteractiveElement = target.closest(
84099
+ 'button, a, input, select, textarea, [role="button"], [onclick]'
84100
+ );
84101
+ console.log("Is interactive element:", isInteractiveElement);
84102
+ if (isInteractiveElement) {
84103
+ console.log("Skipping row selection due to interactive element");
84104
+ return;
84105
+ }
84106
+ if (!rowSelection || !rowSelection.onChange) {
84107
+ console.log("No row selection or onChange handler");
84108
+ return;
84109
+ }
84110
+ if (rowSelection.getCheckboxProps) {
84111
+ const checkboxProps = rowSelection.getCheckboxProps(record);
84112
+ if (checkboxProps.disabled) {
84113
+ console.log("Row is disabled for selection:", record);
84114
+ return;
84115
+ }
84116
+ }
84117
+ const currentSelectedKeys = selectedRowKeys;
84118
+ const recordKey = typeof rowKey === "function" ? rowKey(record) : record[rowKey];
84119
+ console.log("Current selected keys:", currentSelectedKeys);
84120
+ console.log("Record key:", recordKey);
84121
+ const newSelectedKeys = currentSelectedKeys.includes(recordKey) ? currentSelectedKeys.filter((key) => key !== recordKey) : [...currentSelectedKeys, recordKey];
84122
+ console.log("New selected keys:", newSelectedKeys);
84123
+ setSelectedRowKeys(newSelectedKeys);
84124
+ const selectedRows = tableDataSource.filter((record2) => {
84125
+ const key = typeof rowKey === "function" ? rowKey(record2) : record2[rowKey];
84126
+ return newSelectedKeys.includes(key);
84127
+ });
84128
+ console.log("Selected rows:", selectedRows);
84129
+ rowSelection.onChange(newSelectedKeys, selectedRows);
84130
+ },
84131
+ [rowSelection, rowKey, tableDataSource, selectedRowKeys]
84132
+ );
84133
+ const enhancedRowSelection = React__namespace.useMemo(() => {
84134
+ if (!rowSelection) return;
84135
+ return {
84136
+ ...rowSelection,
84137
+ selectedRowKeys,
84138
+ // Use internal state
84139
+ // Override the onChange to ensure we get the latest data
84140
+ onChange: (selectedRowKeys2, selectedRows) => {
84141
+ console.log("Row selection changed:", selectedRowKeys2, selectedRows);
84142
+ setSelectedRowKeys(selectedRowKeys2);
84143
+ if (rowSelection.onChange) {
84144
+ rowSelection.onChange(selectedRowKeys2, selectedRows);
84145
+ }
84146
+ }
84147
+ };
84148
+ }, [rowSelection, selectedRowKeys]);
84086
84149
  return /* @__PURE__ */ jsxRuntime.jsx("div", { ref: containerRef, children: /* @__PURE__ */ jsxRuntime.jsx(
84087
84150
  Table$1,
84088
84151
  {
@@ -84094,7 +84157,17 @@ function Table({
84094
84157
  locale: { emptyText: "No Data" },
84095
84158
  size,
84096
84159
  onChange,
84097
- rowSelection,
84160
+ rowSelection: enhancedRowSelection,
84161
+ onRow: (record, index2) => {
84162
+ const isDisabled = rowSelection?.getCheckboxProps?.(record)?.disabled ?? false;
84163
+ return {
84164
+ onClick: (event) => handleRowClick(record, index2 ?? 0, event),
84165
+ style: {
84166
+ cursor: rowSelection && !isDisabled ? "pointer" : "default",
84167
+ opacity: isDisabled ? 0.6 : 1
84168
+ }
84169
+ };
84170
+ },
84098
84171
  pagination: paginationConfig,
84099
84172
  scroll: scrollConfig,
84100
84173
  onScroll: isMaterializedView ? handleScroll : void 0,
@@ -84155,6 +84228,9 @@ const defaultRowSelection = (record) => ({
84155
84228
  });
84156
84229
  const useTable = (useTableConfig) => {
84157
84230
  const [isLoading, setLoading] = React.useState(true);
84231
+ const [hasErrored, setHasErrored] = React.useState(false);
84232
+ const hasFetchedRef = React.useRef(false);
84233
+ const isDisabledRef = React.useRef(false);
84158
84234
  const {
84159
84235
  columns,
84160
84236
  filters = null,
@@ -84181,14 +84257,39 @@ const useTable = (useTableConfig) => {
84181
84257
  error: null
84182
84258
  });
84183
84259
  const [selectedRows, setSelectedRows] = React.useState([]);
84260
+ const [selectedRowKeys, setSelectedRowKeys] = React.useState([]);
84261
+ const memoizedFetchOptions = React.useMemo(
84262
+ () => fetchOptions,
84263
+ [fetchOptions.method, fetchOptions.headers, fetchOptions.body]
84264
+ );
84184
84265
  React.useEffect(() => {
84185
- if (disableAutoFetch && initialDataSource.length > 0) {
84266
+ if (disableAutoFetch) {
84267
+ isDisabledRef.current = true;
84268
+ setLoading(false);
84269
+ return;
84270
+ }
84271
+ if (hasFetchedRef.current || hasErrored || isDisabledRef.current) {
84186
84272
  setLoading(false);
84187
84273
  return;
84188
84274
  }
84189
84275
  const fetchData = async () => {
84190
84276
  try {
84191
- const response = await fetch(fetchUrl, fetchOptions);
84277
+ hasFetchedRef.current = true;
84278
+ const response = await fetch(fetchUrl, memoizedFetchOptions);
84279
+ if (response.status === 404) {
84280
+ console.warn(`Table data not found at ${fetchUrl}, stopping retries`);
84281
+ setHasErrored(true);
84282
+ setData({
84283
+ dataSource: initialDataSource,
84284
+ columns,
84285
+ error: new Error(`Data not found at ${fetchUrl}`)
84286
+ });
84287
+ setLoading(false);
84288
+ return;
84289
+ }
84290
+ if (!response.ok) {
84291
+ throw new Error(`HTTP ${response.status}: ${response.statusText}`);
84292
+ }
84192
84293
  const result = await response.json();
84193
84294
  const sourceData = result.data || [];
84194
84295
  setOriginalData(sourceData);
@@ -84197,10 +84298,12 @@ const useTable = (useTableConfig) => {
84197
84298
  columns,
84198
84299
  error: null
84199
84300
  });
84301
+ setHasErrored(false);
84200
84302
  } catch (error2) {
84201
84303
  console.error("Error fetching table data:", error2);
84304
+ setHasErrored(true);
84202
84305
  setData({
84203
- dataSource: [],
84306
+ dataSource: initialDataSource,
84204
84307
  columns,
84205
84308
  error: error2 instanceof Error ? error2 : new Error(String(error2))
84206
84309
  });
@@ -84213,11 +84316,19 @@ const useTable = (useTableConfig) => {
84213
84316
  } else {
84214
84317
  fetchData();
84215
84318
  }
84216
- }, [fetchOptions, disableAutoFetch, initialDataSource]);
84319
+ }, [
84320
+ memoizedFetchOptions,
84321
+ disableAutoFetch,
84322
+ hasErrored,
84323
+ fetchUrl,
84324
+ columns,
84325
+ initialDataSource
84326
+ ]);
84217
84327
  const handleRowSelection = React.useCallback(
84218
- (selectedRowKeys, selectedRows2) => {
84219
- console.log("Row Selected:", selectedRowKeys, selectedRows2);
84220
- setSelectedRows(selectedRows2);
84328
+ (newSelectedRowKeys, newSelectedRows) => {
84329
+ console.log("Row Selected:", newSelectedRowKeys, newSelectedRows);
84330
+ setSelectedRowKeys(newSelectedRowKeys);
84331
+ setSelectedRows(newSelectedRows);
84221
84332
  },
84222
84333
  []
84223
84334
  );
@@ -84228,19 +84339,29 @@ const useTable = (useTableConfig) => {
84228
84339
  dataSource: newDataSource
84229
84340
  }));
84230
84341
  }, []);
84342
+ const retry = React.useCallback(() => {
84343
+ setHasErrored(false);
84344
+ hasFetchedRef.current = false;
84345
+ isDisabledRef.current = false;
84346
+ setLoading(true);
84347
+ }, []);
84231
84348
  const rowSelection = {
84232
84349
  type: selectionType,
84350
+ selectedRowKeys,
84233
84351
  onChange: handleRowSelection,
84234
84352
  getCheckboxProps: disableRowSelection
84235
84353
  };
84236
84354
  return {
84237
84355
  ...data,
84238
84356
  isLoading,
84357
+ hasErrored,
84239
84358
  rowSelection,
84240
84359
  selectedRows,
84360
+ selectedRowKeys,
84241
84361
  hasSettings,
84242
84362
  hasFilter,
84243
- updateDataSource
84363
+ updateDataSource,
84364
+ retry
84244
84365
  };
84245
84366
  };
84246
84367
  function HiMiniAdjustmentsVertical(props) {
@@ -84514,7 +84635,8 @@ const TableControls = ({
84514
84635
  const TableWithControls = ({
84515
84636
  tableData,
84516
84637
  tableControlsData: tableControlsData2,
84517
- onChange
84638
+ onChange,
84639
+ onRowClick
84518
84640
  }) => {
84519
84641
  const { primaryTableRowData, secondaryTableRowData } = tableControlsData2;
84520
84642
  const {
@@ -84551,6 +84673,7 @@ const TableWithControls = ({
84551
84673
  columns,
84552
84674
  rowSelection,
84553
84675
  onChange: onTableChange,
84676
+ onRowClick,
84554
84677
  isMaterializedView,
84555
84678
  materializedViewConfig
84556
84679
  }
@@ -84628,6 +84751,36 @@ const mockColumns = [
84628
84751
  isProgressCombined: true
84629
84752
  });
84630
84753
  }
84754
+ },
84755
+ {
84756
+ title: "Actions",
84757
+ key: "actions",
84758
+ render: (record) => {
84759
+ const menuItems = [
84760
+ {
84761
+ id: "edit",
84762
+ children: "Edit",
84763
+ onClick: () => {
84764
+ console.log("Edit clicked for record:", record.id);
84765
+ }
84766
+ },
84767
+ {
84768
+ id: "delete",
84769
+ children: "Delete",
84770
+ onClick: () => {
84771
+ console.log("Delete clicked for record:", record.id);
84772
+ }
84773
+ }
84774
+ ];
84775
+ return React.createElement(OverflowMenu, {
84776
+ items: menuItems,
84777
+ onItemClick: (item) => {
84778
+ if (item.onClick) {
84779
+ item.onClick();
84780
+ }
84781
+ }
84782
+ });
84783
+ }
84631
84784
  }
84632
84785
  ];
84633
84786
  mockColumns.map((column2) => ({
@@ -85037,9 +85190,10 @@ const startingUseTableConfig = {
85037
85190
  dataSource: []
85038
85191
  };
85039
85192
  const useTableWithControls = (tableConfig) => {
85040
- const [useTableConfig, setUseTableConfig] = React.useState(
85041
- startingUseTableConfig
85042
- );
85193
+ const [useTableConfig, setUseTableConfig] = React.useState(() => ({
85194
+ ...startingUseTableConfig,
85195
+ ...tableConfig
85196
+ }));
85043
85197
  const [groups, setGroups] = React.useState(
85044
85198
  tableControlsData.secondaryTableRowData.groups
85045
85199
  );
@@ -85050,20 +85204,22 @@ const useTableWithControls = (tableConfig) => {
85050
85204
  });
85051
85205
  const { secondaryTableRowData } = tableControlsData;
85052
85206
  const {
85053
- dataSource,
85207
+ dataSource: hookDataSource,
85054
85208
  columns,
85055
85209
  rowSelection,
85210
+ selectedRows,
85211
+ selectedRowKeys,
85056
85212
  hasSettings,
85057
85213
  hasFilter,
85058
85214
  updateDataSource
85059
85215
  } = useTable(useTableConfig);
85216
+ const dataSource = tableConfig.dataSource || hookDataSource;
85060
85217
  const safeDataSource = dataSource || [];
85061
85218
  const newSecondaryTableRowData = {
85062
85219
  ...secondaryTableRowData,
85063
85220
  groups,
85064
85221
  totalRecords: safeDataSource.length
85065
85222
  };
85066
- if (!dataSource) return null;
85067
85223
  const onGroupItemClick = (title, item) => {
85068
85224
  const newGroups = { ...groups };
85069
85225
  newGroups[title] = newGroups[title].filter((group) => group !== item);
@@ -85153,6 +85309,8 @@ const useTableWithControls = (tableConfig) => {
85153
85309
  dataSource: safeDataSource,
85154
85310
  columns,
85155
85311
  rowSelection,
85312
+ selectedRows,
85313
+ selectedRowKeys,
85156
85314
  updateDataSource
85157
85315
  };
85158
85316
  };
package/dist/index.js CHANGED
@@ -60232,6 +60232,9 @@ function FaCircleCheck(props) {
60232
60232
  function HiClock(props) {
60233
60233
  return GenIcon({ "attr": { "viewBox": "0 0 20 20", "fill": "currentColor", "aria-hidden": "true" }, "child": [{ "tag": "path", "attr": { "fillRule": "evenodd", "d": "M10 18a8 8 0 100-16 8 8 0 000 16zm1-12a1 1 0 10-2 0v4a1 1 0 00.293.707l2.828 2.829a1 1 0 101.415-1.415L11 9.586V6z", "clipRule": "evenodd" }, "child": [] }] })(props);
60234
60234
  }
60235
+ function HiDotsHorizontal(props) {
60236
+ return GenIcon({ "attr": { "viewBox": "0 0 20 20", "fill": "currentColor", "aria-hidden": "true" }, "child": [{ "tag": "path", "attr": { "d": "M6 10a2 2 0 11-4 0 2 2 0 014 0zM12 10a2 2 0 11-4 0 2 2 0 014 0zM16 12a2 2 0 100-4 2 2 0 000 4z" }, "child": [] }] })(props);
60237
+ }
60235
60238
  function HiExclamationCircle(props) {
60236
60239
  return GenIcon({ "attr": { "viewBox": "0 0 20 20", "fill": "currentColor", "aria-hidden": "true" }, "child": [{ "tag": "path", "attr": { "fillRule": "evenodd", "d": "M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-7 4a1 1 0 11-2 0 1 1 0 012 0zm-1-9a1 1 0 00-1 1v4a1 1 0 102 0V6a1 1 0 00-1-1z", "clipRule": "evenodd" }, "child": [] }] })(props);
60237
60240
  }
@@ -80497,10 +80500,13 @@ const OverflowMenuItem$1 = styled.div`
80497
80500
  const OverflowMenuItem = ({ children: children2, onClick }) => {
80498
80501
  return /* @__PURE__ */ jsx(OverflowMenuItem$1, { onClick, children: children2 });
80499
80502
  };
80503
+ const DefaultTrigger = () => {
80504
+ return /* @__PURE__ */ jsx(Button$1, { isIconButton: true, themeType: "secondary", size: "small", children: /* @__PURE__ */ jsx(HiDotsHorizontal, {}) });
80505
+ };
80500
80506
  const OverflowMenu = ({
80501
80507
  items,
80502
80508
  children: children2,
80503
- trigger,
80509
+ trigger = /* @__PURE__ */ jsx(DefaultTrigger, {}),
80504
80510
  isOpen: controlledIsOpen,
80505
80511
  onOpenChange,
80506
80512
  placement = "bottom",
@@ -80777,7 +80783,7 @@ const getCombinedPercent = (firstBarData, secondBarData) => {
80777
80783
  if (firstBarData?.value !== void 0 && secondBarData?.value !== void 0) {
80778
80784
  const total = firstBarData.value + secondBarData.value;
80779
80785
  const dividedBy = total / 2;
80780
- return Math.round(dividedBy * 10) / 10;
80786
+ return Math.round(dividedBy);
80781
80787
  }
80782
80788
  return firstBarData?.value || 0;
80783
80789
  };
@@ -83951,6 +83957,7 @@ function Table({
83951
83957
  size = "small",
83952
83958
  onChange,
83953
83959
  rowSelection,
83960
+ onRowClick,
83954
83961
  pagination,
83955
83962
  isMainContentCell = false,
83956
83963
  isMaterializedView = false,
@@ -83963,6 +83970,7 @@ function Table({
83963
83970
  const [dynamicHeight, setDynamicHeight] = React.useState(
83964
83971
  400
83965
83972
  );
83973
+ const [selectedRowKeys, setSelectedRowKeys] = React.useState([]);
83966
83974
  const tableRef = React.useRef(null);
83967
83975
  const containerRef = React.useRef(null);
83968
83976
  React.useEffect(() => {
@@ -84065,6 +84073,61 @@ function Table({
84065
84073
  return rest.scroll;
84066
84074
  }, [isMaterializedView, materializedViewConfig, dynamicHeight, rest.scroll]);
84067
84075
  const tableDataSource = isMaterializedView ? materializedData : dataSource;
84076
+ const handleRowClick = React.useCallback(
84077
+ (record, index2, event) => {
84078
+ console.log("Row clicked:", record, "index:", index2);
84079
+ const target = event.target;
84080
+ const isInteractiveElement = target.closest(
84081
+ 'button, a, input, select, textarea, [role="button"], [onclick]'
84082
+ );
84083
+ console.log("Is interactive element:", isInteractiveElement);
84084
+ if (isInteractiveElement) {
84085
+ console.log("Skipping row selection due to interactive element");
84086
+ return;
84087
+ }
84088
+ if (!rowSelection || !rowSelection.onChange) {
84089
+ console.log("No row selection or onChange handler");
84090
+ return;
84091
+ }
84092
+ if (rowSelection.getCheckboxProps) {
84093
+ const checkboxProps = rowSelection.getCheckboxProps(record);
84094
+ if (checkboxProps.disabled) {
84095
+ console.log("Row is disabled for selection:", record);
84096
+ return;
84097
+ }
84098
+ }
84099
+ const currentSelectedKeys = selectedRowKeys;
84100
+ const recordKey = typeof rowKey === "function" ? rowKey(record) : record[rowKey];
84101
+ console.log("Current selected keys:", currentSelectedKeys);
84102
+ console.log("Record key:", recordKey);
84103
+ const newSelectedKeys = currentSelectedKeys.includes(recordKey) ? currentSelectedKeys.filter((key) => key !== recordKey) : [...currentSelectedKeys, recordKey];
84104
+ console.log("New selected keys:", newSelectedKeys);
84105
+ setSelectedRowKeys(newSelectedKeys);
84106
+ const selectedRows = tableDataSource.filter((record2) => {
84107
+ const key = typeof rowKey === "function" ? rowKey(record2) : record2[rowKey];
84108
+ return newSelectedKeys.includes(key);
84109
+ });
84110
+ console.log("Selected rows:", selectedRows);
84111
+ rowSelection.onChange(newSelectedKeys, selectedRows);
84112
+ },
84113
+ [rowSelection, rowKey, tableDataSource, selectedRowKeys]
84114
+ );
84115
+ const enhancedRowSelection = React.useMemo(() => {
84116
+ if (!rowSelection) return;
84117
+ return {
84118
+ ...rowSelection,
84119
+ selectedRowKeys,
84120
+ // Use internal state
84121
+ // Override the onChange to ensure we get the latest data
84122
+ onChange: (selectedRowKeys2, selectedRows) => {
84123
+ console.log("Row selection changed:", selectedRowKeys2, selectedRows);
84124
+ setSelectedRowKeys(selectedRowKeys2);
84125
+ if (rowSelection.onChange) {
84126
+ rowSelection.onChange(selectedRowKeys2, selectedRows);
84127
+ }
84128
+ }
84129
+ };
84130
+ }, [rowSelection, selectedRowKeys]);
84068
84131
  return /* @__PURE__ */ jsx("div", { ref: containerRef, children: /* @__PURE__ */ jsx(
84069
84132
  Table$1,
84070
84133
  {
@@ -84076,7 +84139,17 @@ function Table({
84076
84139
  locale: { emptyText: "No Data" },
84077
84140
  size,
84078
84141
  onChange,
84079
- rowSelection,
84142
+ rowSelection: enhancedRowSelection,
84143
+ onRow: (record, index2) => {
84144
+ const isDisabled = rowSelection?.getCheckboxProps?.(record)?.disabled ?? false;
84145
+ return {
84146
+ onClick: (event) => handleRowClick(record, index2 ?? 0, event),
84147
+ style: {
84148
+ cursor: rowSelection && !isDisabled ? "pointer" : "default",
84149
+ opacity: isDisabled ? 0.6 : 1
84150
+ }
84151
+ };
84152
+ },
84080
84153
  pagination: paginationConfig,
84081
84154
  scroll: scrollConfig,
84082
84155
  onScroll: isMaterializedView ? handleScroll : void 0,
@@ -84137,6 +84210,9 @@ const defaultRowSelection = (record) => ({
84137
84210
  });
84138
84211
  const useTable = (useTableConfig) => {
84139
84212
  const [isLoading, setLoading] = useState(true);
84213
+ const [hasErrored, setHasErrored] = useState(false);
84214
+ const hasFetchedRef = useRef(false);
84215
+ const isDisabledRef = useRef(false);
84140
84216
  const {
84141
84217
  columns,
84142
84218
  filters = null,
@@ -84163,14 +84239,39 @@ const useTable = (useTableConfig) => {
84163
84239
  error: null
84164
84240
  });
84165
84241
  const [selectedRows, setSelectedRows] = useState([]);
84242
+ const [selectedRowKeys, setSelectedRowKeys] = useState([]);
84243
+ const memoizedFetchOptions = useMemo$1(
84244
+ () => fetchOptions,
84245
+ [fetchOptions.method, fetchOptions.headers, fetchOptions.body]
84246
+ );
84166
84247
  useEffect(() => {
84167
- if (disableAutoFetch && initialDataSource.length > 0) {
84248
+ if (disableAutoFetch) {
84249
+ isDisabledRef.current = true;
84250
+ setLoading(false);
84251
+ return;
84252
+ }
84253
+ if (hasFetchedRef.current || hasErrored || isDisabledRef.current) {
84168
84254
  setLoading(false);
84169
84255
  return;
84170
84256
  }
84171
84257
  const fetchData = async () => {
84172
84258
  try {
84173
- const response = await fetch(fetchUrl, fetchOptions);
84259
+ hasFetchedRef.current = true;
84260
+ const response = await fetch(fetchUrl, memoizedFetchOptions);
84261
+ if (response.status === 404) {
84262
+ console.warn(`Table data not found at ${fetchUrl}, stopping retries`);
84263
+ setHasErrored(true);
84264
+ setData({
84265
+ dataSource: initialDataSource,
84266
+ columns,
84267
+ error: new Error(`Data not found at ${fetchUrl}`)
84268
+ });
84269
+ setLoading(false);
84270
+ return;
84271
+ }
84272
+ if (!response.ok) {
84273
+ throw new Error(`HTTP ${response.status}: ${response.statusText}`);
84274
+ }
84174
84275
  const result = await response.json();
84175
84276
  const sourceData = result.data || [];
84176
84277
  setOriginalData(sourceData);
@@ -84179,10 +84280,12 @@ const useTable = (useTableConfig) => {
84179
84280
  columns,
84180
84281
  error: null
84181
84282
  });
84283
+ setHasErrored(false);
84182
84284
  } catch (error2) {
84183
84285
  console.error("Error fetching table data:", error2);
84286
+ setHasErrored(true);
84184
84287
  setData({
84185
- dataSource: [],
84288
+ dataSource: initialDataSource,
84186
84289
  columns,
84187
84290
  error: error2 instanceof Error ? error2 : new Error(String(error2))
84188
84291
  });
@@ -84195,11 +84298,19 @@ const useTable = (useTableConfig) => {
84195
84298
  } else {
84196
84299
  fetchData();
84197
84300
  }
84198
- }, [fetchOptions, disableAutoFetch, initialDataSource]);
84301
+ }, [
84302
+ memoizedFetchOptions,
84303
+ disableAutoFetch,
84304
+ hasErrored,
84305
+ fetchUrl,
84306
+ columns,
84307
+ initialDataSource
84308
+ ]);
84199
84309
  const handleRowSelection = useCallback(
84200
- (selectedRowKeys, selectedRows2) => {
84201
- console.log("Row Selected:", selectedRowKeys, selectedRows2);
84202
- setSelectedRows(selectedRows2);
84310
+ (newSelectedRowKeys, newSelectedRows) => {
84311
+ console.log("Row Selected:", newSelectedRowKeys, newSelectedRows);
84312
+ setSelectedRowKeys(newSelectedRowKeys);
84313
+ setSelectedRows(newSelectedRows);
84203
84314
  },
84204
84315
  []
84205
84316
  );
@@ -84210,19 +84321,29 @@ const useTable = (useTableConfig) => {
84210
84321
  dataSource: newDataSource
84211
84322
  }));
84212
84323
  }, []);
84324
+ const retry = useCallback(() => {
84325
+ setHasErrored(false);
84326
+ hasFetchedRef.current = false;
84327
+ isDisabledRef.current = false;
84328
+ setLoading(true);
84329
+ }, []);
84213
84330
  const rowSelection = {
84214
84331
  type: selectionType,
84332
+ selectedRowKeys,
84215
84333
  onChange: handleRowSelection,
84216
84334
  getCheckboxProps: disableRowSelection
84217
84335
  };
84218
84336
  return {
84219
84337
  ...data,
84220
84338
  isLoading,
84339
+ hasErrored,
84221
84340
  rowSelection,
84222
84341
  selectedRows,
84342
+ selectedRowKeys,
84223
84343
  hasSettings,
84224
84344
  hasFilter,
84225
- updateDataSource
84345
+ updateDataSource,
84346
+ retry
84226
84347
  };
84227
84348
  };
84228
84349
  function HiMiniAdjustmentsVertical(props) {
@@ -84496,7 +84617,8 @@ const TableControls = ({
84496
84617
  const TableWithControls = ({
84497
84618
  tableData,
84498
84619
  tableControlsData: tableControlsData2,
84499
- onChange
84620
+ onChange,
84621
+ onRowClick
84500
84622
  }) => {
84501
84623
  const { primaryTableRowData, secondaryTableRowData } = tableControlsData2;
84502
84624
  const {
@@ -84533,6 +84655,7 @@ const TableWithControls = ({
84533
84655
  columns,
84534
84656
  rowSelection,
84535
84657
  onChange: onTableChange,
84658
+ onRowClick,
84536
84659
  isMaterializedView,
84537
84660
  materializedViewConfig
84538
84661
  }
@@ -84610,6 +84733,36 @@ const mockColumns = [
84610
84733
  isProgressCombined: true
84611
84734
  });
84612
84735
  }
84736
+ },
84737
+ {
84738
+ title: "Actions",
84739
+ key: "actions",
84740
+ render: (record) => {
84741
+ const menuItems = [
84742
+ {
84743
+ id: "edit",
84744
+ children: "Edit",
84745
+ onClick: () => {
84746
+ console.log("Edit clicked for record:", record.id);
84747
+ }
84748
+ },
84749
+ {
84750
+ id: "delete",
84751
+ children: "Delete",
84752
+ onClick: () => {
84753
+ console.log("Delete clicked for record:", record.id);
84754
+ }
84755
+ }
84756
+ ];
84757
+ return React__default.createElement(OverflowMenu, {
84758
+ items: menuItems,
84759
+ onItemClick: (item) => {
84760
+ if (item.onClick) {
84761
+ item.onClick();
84762
+ }
84763
+ }
84764
+ });
84765
+ }
84613
84766
  }
84614
84767
  ];
84615
84768
  mockColumns.map((column2) => ({
@@ -85019,9 +85172,10 @@ const startingUseTableConfig = {
85019
85172
  dataSource: []
85020
85173
  };
85021
85174
  const useTableWithControls = (tableConfig) => {
85022
- const [useTableConfig, setUseTableConfig] = useState(
85023
- startingUseTableConfig
85024
- );
85175
+ const [useTableConfig, setUseTableConfig] = useState(() => ({
85176
+ ...startingUseTableConfig,
85177
+ ...tableConfig
85178
+ }));
85025
85179
  const [groups, setGroups] = useState(
85026
85180
  tableControlsData.secondaryTableRowData.groups
85027
85181
  );
@@ -85032,20 +85186,22 @@ const useTableWithControls = (tableConfig) => {
85032
85186
  });
85033
85187
  const { secondaryTableRowData } = tableControlsData;
85034
85188
  const {
85035
- dataSource,
85189
+ dataSource: hookDataSource,
85036
85190
  columns,
85037
85191
  rowSelection,
85192
+ selectedRows,
85193
+ selectedRowKeys,
85038
85194
  hasSettings,
85039
85195
  hasFilter,
85040
85196
  updateDataSource
85041
85197
  } = useTable(useTableConfig);
85198
+ const dataSource = tableConfig.dataSource || hookDataSource;
85042
85199
  const safeDataSource = dataSource || [];
85043
85200
  const newSecondaryTableRowData = {
85044
85201
  ...secondaryTableRowData,
85045
85202
  groups,
85046
85203
  totalRecords: safeDataSource.length
85047
85204
  };
85048
- if (!dataSource) return null;
85049
85205
  const onGroupItemClick = (title, item) => {
85050
85206
  const newGroups = { ...groups };
85051
85207
  newGroups[title] = newGroups[title].filter((group) => group !== item);
@@ -85135,6 +85291,8 @@ const useTableWithControls = (tableConfig) => {
85135
85291
  dataSource: safeDataSource,
85136
85292
  columns,
85137
85293
  rowSelection,
85294
+ selectedRows,
85295
+ selectedRowKeys,
85138
85296
  updateDataSource
85139
85297
  };
85140
85298
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gobolt/genesis",
3
- "version": "0.4.7",
3
+ "version": "0.4.9",
4
4
  "description": "genesis design system",
5
5
  "author": "gobolt",
6
6
  "license": "MIT",