playbook_ui 14.15.0.pre.alpha.play1917lodashremoval2of36615 → 14.15.0.pre.rc.0

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.
Files changed (156) hide show
  1. checksums.yaml +4 -4
  2. data/app/pb_kits/playbook/pb_advanced_table/Context/AdvancedTableContext.tsx +3 -143
  3. data/app/pb_kits/playbook/pb_advanced_table/SubKits/TableBody.tsx +99 -45
  4. data/app/pb_kits/playbook/pb_advanced_table/_advanced_table.scss +7 -123
  5. data/app/pb_kits/playbook/pb_advanced_table/_advanced_table.tsx +299 -153
  6. data/app/pb_kits/playbook/pb_bar_graph/_bar_graph.tsx +1 -1
  7. data/app/pb_kits/playbook/pb_card/_card.tsx +1 -2
  8. data/app/pb_kits/playbook/pb_circle_chart/_circle_chart.tsx +1 -1
  9. data/app/pb_kits/playbook/pb_date_picker/date_picker.html.erb +1 -4
  10. data/app/pb_kits/playbook/pb_date_picker/date_picker.rb +0 -2
  11. data/app/pb_kits/playbook/pb_dialog/dialog.html.erb +6 -5
  12. data/app/pb_kits/playbook/pb_dialog/dialogHelper.js +0 -2
  13. data/app/pb_kits/playbook/pb_drawer/_drawer.scss +3 -43
  14. data/app/pb_kits/playbook/pb_drawer/docs/_drawer_borders.jsx +3 -3
  15. data/app/pb_kits/playbook/pb_drawer/docs/_drawer_breakpoints.jsx +37 -20
  16. data/app/pb_kits/playbook/pb_drawer/docs/_drawer_default.html.erb +1 -20
  17. data/app/pb_kits/playbook/pb_drawer/docs/_drawer_menu.jsx +6 -6
  18. data/app/pb_kits/playbook/pb_drawer/docs/_drawer_overlay.jsx +0 -1
  19. data/app/pb_kits/playbook/pb_drawer/docs/example.yml +0 -6
  20. data/app/pb_kits/playbook/pb_drawer/drawer.html.erb +12 -20
  21. data/app/pb_kits/playbook/pb_drawer/drawer.rb +1 -49
  22. data/app/pb_kits/playbook/pb_filter/Filter/CurrentFilters.tsx +4 -5
  23. data/app/pb_kits/playbook/pb_filter/Filter/FilterSingle.tsx +2 -2
  24. data/app/pb_kits/playbook/pb_filter/Filter/SortMenu.tsx +1 -2
  25. data/app/pb_kits/playbook/pb_form/docs/_form_form_with_validate.html.erb +2 -2
  26. data/app/pb_kits/playbook/pb_form_pill/_form_pill.scss +2 -9
  27. data/app/pb_kits/playbook/pb_form_pill/_form_pill.tsx +0 -4
  28. data/app/pb_kits/playbook/pb_form_pill/docs/example.yml +0 -2
  29. data/app/pb_kits/playbook/pb_form_pill/docs/index.js +0 -1
  30. data/app/pb_kits/playbook/pb_form_pill/form_pill.rb +1 -7
  31. data/app/pb_kits/playbook/pb_gauge/_gauge.tsx +1 -1
  32. data/app/pb_kits/playbook/pb_lightbox/Carousel/Slide.tsx +1 -1
  33. data/app/pb_kits/playbook/pb_lightbox/Carousel/Slides.tsx +1 -1
  34. data/app/pb_kits/playbook/pb_lightbox/Carousel/Thumbnails.tsx +1 -1
  35. data/app/pb_kits/playbook/pb_line_graph/_line_graph.tsx +1 -1
  36. data/app/pb_kits/playbook/pb_multi_level_select/_multi_level_select.scss +0 -7
  37. data/app/pb_kits/playbook/pb_multi_level_select/_multi_level_select.tsx +3 -13
  38. data/app/pb_kits/playbook/pb_multi_level_select/docs/example.yml +1 -2
  39. data/app/pb_kits/playbook/pb_multi_level_select/docs/index.js +0 -1
  40. data/app/pb_kits/playbook/pb_multi_level_select/multi_level_select.rb +0 -6
  41. data/app/pb_kits/playbook/pb_overlay/_overlay.scss +0 -13
  42. data/app/pb_kits/playbook/pb_overlay/_overlay.tsx +1 -7
  43. data/app/pb_kits/playbook/pb_overlay/docs/example.yml +0 -3
  44. data/app/pb_kits/playbook/pb_overlay/docs/index.js +0 -1
  45. data/app/pb_kits/playbook/pb_overlay/overlay.html.erb +3 -5
  46. data/app/pb_kits/playbook/pb_overlay/overlay.rb +1 -16
  47. data/app/pb_kits/playbook/pb_overlay/overlay.test.jsx +0 -12
  48. data/app/pb_kits/playbook/pb_popover/_popover.tsx +2 -2
  49. data/app/pb_kits/playbook/pb_popover/popover.test.js +1 -1
  50. data/app/pb_kits/playbook/pb_radio/_radio.tsx +74 -85
  51. data/app/pb_kits/playbook/pb_radio/docs/example.yml +1 -2
  52. data/app/pb_kits/playbook/pb_radio/docs/index.js +0 -1
  53. data/app/pb_kits/playbook/pb_radio/radio.test.js +0 -16
  54. data/app/pb_kits/playbook/pb_select/docs/example.yml +0 -1
  55. data/app/pb_kits/playbook/pb_select/docs/index.js +0 -1
  56. data/app/pb_kits/playbook/pb_select/select.html.erb +5 -3
  57. data/app/pb_kits/playbook/pb_select/select.rb +0 -8
  58. data/app/pb_kits/playbook/pb_selectable_card/selectable_card.html.erb +5 -1
  59. data/app/pb_kits/playbook/pb_selectable_card_icon/selectable_card_icon.html.erb +4 -1
  60. data/app/pb_kits/playbook/pb_selectable_icon/selectable_icon.html.erb +5 -1
  61. data/app/pb_kits/playbook/pb_text_input/inputMask.ts +3 -2
  62. data/app/pb_kits/playbook/pb_timeline/_timeline.scss +2 -2
  63. data/app/pb_kits/playbook/pb_title/_title.scss +0 -32
  64. data/app/pb_kits/playbook/pb_title/_title.tsx +1 -10
  65. data/app/pb_kits/playbook/pb_title/docs/_title_default.html.erb +2 -1
  66. data/app/pb_kits/playbook/pb_title/docs/_title_default.jsx +1 -1
  67. data/app/pb_kits/playbook/pb_title/docs/example.yml +0 -2
  68. data/app/pb_kits/playbook/pb_title/docs/index.js +0 -1
  69. data/app/pb_kits/playbook/pb_title/title.rb +1 -10
  70. data/app/pb_kits/playbook/pb_tooltip/_tooltip.scss +3 -0
  71. data/app/pb_kits/playbook/pb_tooltip/_tooltip.tsx +0 -25
  72. data/app/pb_kits/playbook/pb_tooltip/docs/_tooltip_icon.erb +10 -0
  73. data/app/pb_kits/playbook/pb_tooltip/docs/example.yml +1 -4
  74. data/app/pb_kits/playbook/pb_tooltip/docs/index.js +0 -1
  75. data/app/pb_kits/playbook/pb_tooltip/index.js +1 -1
  76. data/app/pb_kits/playbook/pb_tooltip/tooltip.rb +2 -10
  77. data/app/pb_kits/playbook/pb_treemap_chart/_treemap_chart.tsx +1 -1
  78. data/app/pb_kits/playbook/pb_typeahead/_typeahead.tsx +5 -51
  79. data/app/pb_kits/playbook/pb_typeahead/components/MultiValue.tsx +1 -5
  80. data/app/pb_kits/playbook/pb_typeahead/docs/_typeahead_with_pills_async_custom_options.jsx +1 -1
  81. data/app/pb_kits/playbook/pb_typeahead/docs/_typeahead_with_pills_async_users.jsx +1 -1
  82. data/app/pb_kits/playbook/pb_typeahead/docs/example.yml +0 -3
  83. data/app/pb_kits/playbook/pb_typeahead/docs/index.js +0 -1
  84. data/app/pb_kits/playbook/pb_typeahead/index.ts +8 -61
  85. data/app/pb_kits/playbook/pb_typeahead/typeahead.rb +2 -17
  86. data/app/pb_kits/playbook/utilities/object.ts +1 -103
  87. data/app/pb_kits/playbook/utilities/text.ts +1 -1
  88. data/dist/chunks/_typeahead-PqkcDf1H.js +36 -0
  89. data/dist/chunks/_weekday_stacked-BrSrpj7J.js +45 -0
  90. data/dist/chunks/{lib-e7oBFFDo.js → lib-D3us1bGD.js} +2 -2
  91. data/dist/chunks/{pb_form_validation-CMXevI1t.js → pb_form_validation-BpihMSOQ.js} +1 -1
  92. data/dist/chunks/vendor.js +1 -1
  93. data/dist/menu.yml +2 -2
  94. data/dist/playbook-doc.js +1 -1
  95. data/dist/playbook-rails-react-bindings.js +1 -1
  96. data/dist/playbook-rails.js +1 -1
  97. data/dist/playbook.css +1 -1
  98. data/lib/playbook/version.rb +2 -2
  99. metadata +7 -61
  100. data/app/pb_kits/playbook/pb_advanced_table/Components/RegularTableView.tsx +0 -127
  101. data/app/pb_kits/playbook/pb_advanced_table/Components/TableActionBar.tsx +0 -55
  102. data/app/pb_kits/playbook/pb_advanced_table/Components/TablePagination.tsx +0 -33
  103. data/app/pb_kits/playbook/pb_advanced_table/Components/VirtualizedTableView.tsx +0 -275
  104. data/app/pb_kits/playbook/pb_advanced_table/Hooks/useTableActions.ts +0 -66
  105. data/app/pb_kits/playbook/pb_advanced_table/Hooks/useTableState.ts +0 -195
  106. data/app/pb_kits/playbook/pb_advanced_table/Utilities/CellRendererUtils.tsx +0 -73
  107. data/app/pb_kits/playbook/pb_advanced_table/Utilities/RowUtils.ts +0 -52
  108. data/app/pb_kits/playbook/pb_advanced_table/Utilities/TableContainerStyles.ts +0 -80
  109. data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_infinite_scroll.jsx +0 -50
  110. data/app/pb_kits/playbook/pb_advanced_table/docs/advanced_table_mock_data_infinite_scroll.json +0 -152002
  111. data/app/pb_kits/playbook/pb_date_picker/index.ts +0 -38
  112. data/app/pb_kits/playbook/pb_dialog/index.js +0 -75
  113. data/app/pb_kits/playbook/pb_drawer/docs/_drawer_behavior.html.erb +0 -8
  114. data/app/pb_kits/playbook/pb_drawer/docs/_drawer_borders.html.erb +0 -33
  115. data/app/pb_kits/playbook/pb_drawer/docs/_drawer_breakpoints.html.erb +0 -0
  116. data/app/pb_kits/playbook/pb_drawer/docs/_drawer_menu.html.erb +0 -24
  117. data/app/pb_kits/playbook/pb_drawer/docs/_drawer_overlay.html.erb +0 -21
  118. data/app/pb_kits/playbook/pb_drawer/docs/_drawer_overlay.md +0 -1
  119. data/app/pb_kits/playbook/pb_drawer/docs/_drawer_sizes.html.erb +0 -49
  120. data/app/pb_kits/playbook/pb_drawer/index.js +0 -257
  121. data/app/pb_kits/playbook/pb_form_pill/docs/_form_pill_wrapped.html.erb +0 -40
  122. data/app/pb_kits/playbook/pb_form_pill/docs/_form_pill_wrapped.jsx +0 -50
  123. data/app/pb_kits/playbook/pb_form_pill/docs/_form_pill_wrapped.md +0 -3
  124. data/app/pb_kits/playbook/pb_multi_level_select/docs/_multi_level_select_disabled.html.erb +0 -72
  125. data/app/pb_kits/playbook/pb_multi_level_select/docs/_multi_level_select_disabled.jsx +0 -91
  126. data/app/pb_kits/playbook/pb_overlay/docs/_overlay_hide_scroll_bar.html.erb +0 -11
  127. data/app/pb_kits/playbook/pb_overlay/docs/_overlay_hide_scroll_bar.jsx +0 -37
  128. data/app/pb_kits/playbook/pb_overlay/docs/_overlay_hide_scroll_bar_rails.md +0 -1
  129. data/app/pb_kits/playbook/pb_overlay/docs/_overlay_hide_scroll_bar_react.md +0 -1
  130. data/app/pb_kits/playbook/pb_overlay/docs/_overlay_vertical_dynamic_multi_directional.html.erb +0 -11
  131. data/app/pb_kits/playbook/pb_overlay/docs/_overlay_vertical_dynamic_multi_directional.md +0 -1
  132. data/app/pb_kits/playbook/pb_overlay/index.js +0 -61
  133. data/app/pb_kits/playbook/pb_radio/docs/_radio_react_hook.jsx +0 -60
  134. data/app/pb_kits/playbook/pb_radio/docs/_radio_react_hook.md +0 -1
  135. data/app/pb_kits/playbook/pb_select/docs/_select_react_hook.jsx +0 -58
  136. data/app/pb_kits/playbook/pb_select/docs/_select_react_hook.md +0 -1
  137. data/app/pb_kits/playbook/pb_select/index.js +0 -38
  138. data/app/pb_kits/playbook/pb_title/docs/_title_display_size.html.erb +0 -7
  139. data/app/pb_kits/playbook/pb_title/docs/_title_display_size.jsx +0 -54
  140. data/app/pb_kits/playbook/pb_title/docs/_title_display_size.md +0 -1
  141. data/app/pb_kits/playbook/pb_tooltip/docs/_tooltip_delay_rails.html.erb +0 -39
  142. data/app/pb_kits/playbook/pb_tooltip/docs/_tooltip_delay_rails.md +0 -3
  143. data/app/pb_kits/playbook/pb_tooltip/docs/_tooltip_icon_rails.html.erb +0 -22
  144. data/app/pb_kits/playbook/pb_tooltip/docs/_tooltip_interaction.html.erb +0 -26
  145. data/app/pb_kits/playbook/pb_tooltip/docs/_tooltip_sizing.jsx +0 -69
  146. data/app/pb_kits/playbook/pb_tooltip/docs/_tooltip_sizing.md +0 -3
  147. data/app/pb_kits/playbook/pb_tooltip/floating_ui.js +0 -282
  148. data/app/pb_kits/playbook/pb_typeahead/docs/_typeahead_dynamic_options.html.erb +0 -45
  149. data/app/pb_kits/playbook/pb_typeahead/docs/_typeahead_dynamic_options.md +0 -5
  150. data/app/pb_kits/playbook/pb_typeahead/docs/_typeahead_dynamic_options_pure_rails.html.erb +0 -33
  151. data/app/pb_kits/playbook/pb_typeahead/docs/_typeahead_dynamic_options_pure_rails.md +0 -3
  152. data/app/pb_kits/playbook/pb_typeahead/docs/_typeahead_react_hook.jsx +0 -66
  153. data/app/pb_kits/playbook/pb_typeahead/docs/_typeahead_react_hook.md +0 -1
  154. data/app/pb_kits/playbook/utilities/object.test.js +0 -237
  155. data/dist/chunks/_typeahead-CdVbIURO.js +0 -36
  156. data/dist/chunks/_weekday_stacked-BSTKfYPJ.js +0 -45
@@ -1,275 +0,0 @@
1
- import React, { useContext, useLayoutEffect, useState, useEffect } from "react"
2
- import classnames from "classnames"
3
- import { flexRender, Cell } from "@tanstack/react-table"
4
- import { VirtualItem } from "@tanstack/react-virtual"
5
-
6
- import { GenericObject } from "../../types"
7
-
8
- import { isChrome } from "../Utilities/BrowserCheck"
9
- import { getVirtualizedRowStyle } from "../Utilities/TableContainerStyles"
10
-
11
- import LoadingInline from "../../pb_loading_inline/_loading_inline"
12
- import Checkbox from "../../pb_checkbox/_checkbox"
13
-
14
- import { SubRowHeaderRow } from "../Components/SubRowHeaderRow"
15
- import { LoadingCell } from "../Components/LoadingCell"
16
- import { renderCollapsibleTrail } from "../Components/CollapsibleTrail"
17
-
18
- import AdvancedTableContext from "../Context/AdvancedTableContext"
19
-
20
- type VirtualizedTableViewProps = {
21
- collapsibleTrail?: boolean
22
- subRowHeaders?: string[]
23
- }
24
-
25
- export const VirtualizedTableView = ({
26
- collapsibleTrail = true,
27
- subRowHeaders,
28
- }: VirtualizedTableViewProps) => {
29
- const {
30
- enableToggleExpansion,
31
- handleExpandOrCollapse,
32
- inlineRowLoading,
33
- loading,
34
- table,
35
- selectableRows,
36
- hasAnySubRows,
37
- virtualizer,
38
- flattenedItems,
39
- } = useContext(AdvancedTableContext)
40
-
41
- const columnPinning = table.getState().columnPinning || { left: [] };
42
- const sortingState = JSON.stringify(table.getState().sorting || []);
43
-
44
- // Store column widths extracted from header
45
- const [columnWidths, setColumnWidths] = useState<{[key: string]: string}>({});
46
-
47
- // Function to get header cell widths
48
- const getHeaderCellWidths = () => {
49
- const widths: {[key: string]: string} = {};
50
-
51
- // Get all header cells
52
- const headerCells = document.querySelectorAll('.table-header-cells, .table-header-cells-custom');
53
-
54
- // If checkbox is present in header
55
- if (selectableRows && !hasAnySubRows && headerCells.length > 0) {
56
- widths['checkbox'] = `${headerCells[0].getBoundingClientRect().width}px`;
57
- }
58
-
59
- // Process regular header cells
60
- table.getFlatHeaders().forEach((header: any, index: number) => {
61
- // Adjust index if checkbox column exists
62
- const headerIndex = (selectableRows && !hasAnySubRows) ? index + 1 : index;
63
-
64
- if (headerCells[headerIndex]) {
65
- const width = headerCells[headerIndex].getBoundingClientRect().width;
66
- widths[header.id] = `${width}px`;
67
- }
68
- });
69
-
70
- return widths;
71
- };
72
-
73
- // Debounce function to prevent too many updates during resize
74
- const debounce = <T extends (...args: any[]) => any>(func: T, wait: number): ((...args: Parameters<T>) => void) => {
75
- let timeout: ReturnType<typeof setTimeout>;
76
- return function executedFunction(...args: Parameters<T>) {
77
- const later = () => {
78
- clearTimeout(timeout);
79
- func(...args);
80
- };
81
- clearTimeout(timeout);
82
- timeout = setTimeout(later, wait);
83
- };
84
- };
85
-
86
- // Update column widths when component mounts and when sorting changes
87
- useLayoutEffect(() => {
88
- // Apply widths after a small delay to ensure header is rendered
89
- const timer = setTimeout(() => {
90
- setColumnWidths(getHeaderCellWidths());
91
- }, 0);
92
-
93
- return () => clearTimeout(timer);
94
- }, [table, selectableRows, hasAnySubRows, sortingState]);
95
-
96
- // Add window resize listener to update widths on window resize
97
- useEffect(() => {
98
- // Create debounced version of the width measurement function
99
- const handleResize = debounce(() => {
100
- setColumnWidths(getHeaderCellWidths());
101
- }, 0);
102
-
103
- // Add the event listener
104
- window.addEventListener('resize', handleResize);
105
-
106
- // Cleanup
107
- return () => {
108
- window.removeEventListener('resize', handleResize);
109
- };
110
- }, [table, selectableRows, hasAnySubRows]);
111
-
112
- // Safety check
113
- if (!virtualizer || !flattenedItems) {
114
- return (
115
- <tr>
116
- <td colSpan={table.getAllFlatColumns().length || 1}>
117
- No data to display.
118
- </td>
119
- </tr>
120
- );
121
- }
122
-
123
- // Get virtual items
124
- let virtualItems: VirtualItem[] = [];
125
- try {
126
- virtualItems = virtualizer.getVirtualItems();
127
- } catch (err) {
128
- return (
129
- <tr>
130
- <td colSpan={table.getAllFlatColumns().length || 1}>
131
- Error loading virtualized data.
132
- </td>
133
- </tr>
134
- );
135
- }
136
-
137
- if (!virtualItems.length) {
138
- return (
139
- <tr>
140
- <td colSpan={table.getAllFlatColumns().length || 1}>
141
- No items to display.
142
- </td>
143
- </tr>
144
- );
145
- }
146
-
147
- return (
148
- <>
149
- {virtualItems.map((virtualRow: VirtualItem) => {
150
- const item = flattenedItems[virtualRow.index];
151
- if (!item) return null;
152
-
153
- // Use consistent row styling
154
- const virtualItemStyle = getVirtualizedRowStyle(virtualRow.start);
155
-
156
- if (item.type === 'header') {
157
- return (
158
- <tr
159
- className="virtualized-table-row virtualized-header-row"
160
- key={`header-${item.id}-sort-${sortingState}`}
161
- style={virtualItemStyle}
162
- >
163
- <td colSpan={table.getAllFlatColumns().length}>
164
- <SubRowHeaderRow
165
- collapsibleTrail={collapsibleTrail}
166
- enableToggleExpansion={enableToggleExpansion}
167
- onClick={handleExpandOrCollapse}
168
- row={item.row}
169
- subRowHeaders={subRowHeaders}
170
- table={table}
171
- />
172
- </td>
173
- </tr>
174
- );
175
- }
176
-
177
- if (item.type === 'row') {
178
- const row = item.row;
179
- const isExpandable = row.getIsExpanded();
180
- const rowHasNoChildren = row.original?.children && !row.original.children.length ? true : false;
181
- const rowBackground = isExpandable && ((!inlineRowLoading && row.getCanExpand()) || (inlineRowLoading && rowHasNoChildren));
182
- const rowColor = row.getIsSelected() ? "bg-row-selection" : rowBackground ? "bg-silver" : "bg-white";
183
-
184
- return (
185
- <tr
186
- className={`virtualized-table-row ${rowColor} ${row.depth > 0 ? `depth-sub-row-${row.depth}` : ""}`}
187
- data-index={virtualRow.index}
188
- key={`row-${item.id}-sort-${sortingState}`}
189
- ref={(node) => {
190
- if (node) {
191
- try {
192
- virtualizer.measureElement(node);
193
- } catch (err) {
194
- // Silent error handling
195
- }
196
- }
197
- }}
198
- style={virtualItemStyle}
199
- >
200
- {/* Render custom checkbox column when we want selectableRows for non-expanding tables */}
201
- {selectableRows && !hasAnySubRows && (
202
- <td
203
- className="checkbox-cell"
204
- style={{ width: columnWidths['checkbox'] || 'auto' }}
205
- >
206
- <Checkbox
207
- checked={row.getIsSelected()}
208
- disabled={!row.getCanSelect()}
209
- indeterminate={row.getIsSomeSelected()}
210
- name={row.id}
211
- onChange={row.getToggleSelectedHandler()}
212
- />
213
- </td>
214
- )}
215
-
216
- {row.getVisibleCells().map((cell: Cell<GenericObject, unknown>, i: number) => {
217
- const isPinnedLeft = columnPinning.left.includes(cell.column.id);
218
- const isLastCell = cell.column.parent?.columns?.at(-1)?.id === cell.column.id;
219
- const cellWidth = columnWidths[cell.column.id] || 'auto';
220
-
221
- return (
222
- <td
223
- align="right"
224
- className={classnames(
225
- `${cell.id}-cell position_relative`,
226
- isChrome() ? "chrome-styles" : "",
227
- isPinnedLeft && 'pinned-left',
228
- isLastCell && 'last-cell',
229
- )}
230
- key={`${cell.id}-data`}
231
- style={{ width: cellWidth }}
232
- >
233
- {collapsibleTrail && i === 0 && row.depth > 0 && renderCollapsibleTrail(row.depth)}
234
- <span id={`${cell.id}-span`}>
235
- {loading ? (
236
- <LoadingCell />
237
- ) : (
238
- flexRender(cell.column.columnDef.cell, cell.getContext())
239
- )}
240
- </span>
241
- </td>
242
- );
243
- })}
244
- </tr>
245
- );
246
- }
247
-
248
- if (item.type === 'loading') {
249
- // Render loading indicator
250
- const row = item.row;
251
- const numberOfColumns = table.getAllFlatColumns().length;
252
-
253
- return (
254
- <tr
255
- className="virtualized-table-row virtualized-loading-row"
256
- key={`loading-${item.id}-sort-${sortingState}`}
257
- style={virtualItemStyle}
258
- >
259
- <td
260
- colSpan={numberOfColumns}
261
- style={{ paddingLeft: `${row.depth === 0 ? 0.5 : (row.depth * 2)}em` }}
262
- >
263
- <LoadingInline />
264
- </td>
265
- </tr>
266
- );
267
- }
268
-
269
- return null;
270
- })}
271
- </>
272
- );
273
- }
274
-
275
- export default VirtualizedTableView;
@@ -1,66 +0,0 @@
1
- import { useCallback, useEffect } from 'react';
2
- import { Row } from "@tanstack/react-table";
3
- import { GenericObject } from "../../types";
4
- import { updateExpandAndCollapseState } from "../Utilities/ExpansionControlHelpers";
5
-
6
- interface UseTableActionsProps {
7
- table: any;
8
- expanded: GenericObject;
9
- setExpanded: (expanded: GenericObject) => void;
10
- onToggleExpansionClick?: (arg: Row<GenericObject>) => void;
11
- onRowSelectionChange?: (rowSelection: any) => void;
12
- }
13
-
14
- export function useTableActions({
15
- table,
16
- expanded,
17
- setExpanded,
18
- onToggleExpansionClick,
19
- onRowSelectionChange
20
- }: UseTableActionsProps) {
21
-
22
- // Handle expand/collapse
23
- const handleExpandOrCollapse = useCallback(async (row: Row<GenericObject>) => {
24
- onToggleExpansionClick && onToggleExpansionClick(row);
25
-
26
- const expandedState = expanded;
27
- const targetParent = row?.parentId;
28
- const updatedRows = await updateExpandAndCollapseState(table.getRowModel(), expandedState, targetParent);
29
- setExpanded(updatedRows);
30
- }, [expanded, setExpanded, onToggleExpansionClick, table]);
31
-
32
- // Handle pagination
33
- const onPageChange = useCallback((page: number) => {
34
- table.setPageIndex(page - 1);
35
- }, [table]);
36
-
37
- // Handle scroll detection for infinite scroll/virtualization
38
- const fetchMoreOnBottomReached = useCallback((
39
- containerRefElement: HTMLDivElement | null,
40
- fetchNextPage: () => void,
41
- isFetching: boolean,
42
- totalFetched: number,
43
- totalDBRowCount: number
44
- ) => {
45
- if (containerRefElement) {
46
- const { scrollHeight, scrollTop, clientHeight } = containerRefElement;
47
- // If user scrolls near bottom, fetch more data
48
- if (scrollHeight - scrollTop - clientHeight < 500 && !isFetching && totalFetched < totalDBRowCount) {
49
- fetchNextPage();
50
- }
51
- }
52
- }, []);
53
-
54
- // Update selection state
55
- useEffect(() => {
56
- if (onRowSelectionChange) {
57
- onRowSelectionChange(table.getState().rowSelection);
58
- }
59
- }, [table.getState().rowSelection, onRowSelectionChange]);
60
-
61
- return {
62
- handleExpandOrCollapse,
63
- onPageChange,
64
- fetchMoreOnBottomReached
65
- };
66
- }
@@ -1,195 +0,0 @@
1
- import { useState, useCallback, useMemo } from 'react';
2
- import {
3
- useReactTable,
4
- getCoreRowModel,
5
- getExpandedRowModel,
6
- getPaginationRowModel,
7
- getSortedRowModel,
8
- RowSelectionState,
9
- Row
10
- } from "@tanstack/react-table";
11
- import { GenericObject } from "../../types";
12
- import { createColumnHelper } from "@tanstack/react-table";
13
- import { createCellFunction } from "../Utilities/CellRendererUtils";
14
-
15
- interface UseTableStateProps {
16
- tableData: GenericObject[];
17
- columnDefinitions: GenericObject[];
18
- expandedControl?: GenericObject;
19
- sortControl?: GenericObject;
20
- onRowToggleClick?: (arg: Row<GenericObject>) => void;
21
- selectableRows?: boolean;
22
- initialLoadingRowsCount?: number;
23
- loading?: boolean | string;
24
- pagination?: boolean;
25
- paginationProps?: GenericObject;
26
- virtualizedRows?: boolean;
27
- tableOptions?: GenericObject;
28
- onRowSelectionChange?: (arg: RowSelectionState) => void;
29
- }
30
-
31
- export function useTableState({
32
- tableData,
33
- columnDefinitions,
34
- expandedControl,
35
- sortControl,
36
- onRowToggleClick,
37
- selectableRows,
38
- initialLoadingRowsCount = 10,
39
- loading,
40
- pagination = false,
41
- paginationProps,
42
- virtualizedRows = false,
43
- tableOptions
44
- }: UseTableStateProps) {
45
- // Create a local state for expanded and setExpanded if expandedControl not used
46
- const [localExpanded, setLocalExpanded] = useState({});
47
- const [loadingStateRowCount, setLoadingStateRowCount] = useState(initialLoadingRowsCount);
48
- const [rowSelection, setRowSelection] = useState<RowSelectionState>({});
49
-
50
- // Determine whether to use the prop or the local state
51
- const expanded = expandedControl ? expandedControl.value : localExpanded;
52
- const setExpanded = expandedControl ? expandedControl.onChange : setLocalExpanded;
53
-
54
- // Virtualized data handling (chunked loading)
55
- const fetchSize = 20; // Number of rows per "page"
56
- const [fullData] = useState(tableData); // All data from the JSON file
57
- const [dataChunk, setDataChunk] = useState(fullData.slice(0, fetchSize)); // Initial chunk
58
- const [totalFetched, setTotalFetched] = useState(fetchSize); // Track loaded rows
59
- const [isFetching, setIsFetching] = useState(false);
60
-
61
- // Create column structure
62
- const columnHelper = createColumnHelper();
63
-
64
- // Build columns with proper cell renderers
65
- const buildColumns = useCallback((columnDefinitions: GenericObject[], isRoot = true): any[] => {
66
- return columnDefinitions?.map((column, index) => {
67
- const isFirstColumn = isRoot && index === 0;
68
-
69
- // Handle grouped columns
70
- if (column.columns && column.columns.length > 0) {
71
- return {
72
- header: column.label || "",
73
- columns: buildColumns(column.columns, false),
74
- };
75
- }
76
-
77
- // Define the base column structure
78
- const columnStructure = {
79
- ...columnHelper.accessor(column.accessor, {
80
- header: column.label || "",
81
- }),
82
- };
83
-
84
- if (column.cellAccessors || column.customRenderer) {
85
- columnStructure.cell = createCellFunction(
86
- column.cellAccessors || [],
87
- column.customRenderer,
88
- isFirstColumn,
89
- onRowToggleClick,
90
- selectableRows
91
- );
92
- }
93
-
94
- return columnStructure;
95
- }) || [];
96
- }, [columnHelper, onRowToggleClick, selectableRows]);
97
-
98
- const columns = useMemo(() => buildColumns(columnDefinitions), [buildColumns, columnDefinitions]);
99
-
100
- // Sorting configuration
101
- const sorting = useMemo(() => ([{
102
- id: columnDefinitions[0].accessor,
103
- desc: sortControl && sortControl.value !== null ? !sortControl.value.desc : false,
104
- }]), [columnDefinitions, sortControl]);
105
-
106
- // Custom state based on features enabled
107
- const customState = useCallback(() => {
108
- if (sortControl && selectableRows) {
109
- return { state: { expanded, sorting, rowSelection } };
110
- } else if (sortControl) {
111
- return { state: { expanded, sorting } };
112
- } else if (selectableRows) {
113
- return { state: { expanded, rowSelection } };
114
- } else {
115
- return { state: { expanded } };
116
- }
117
- }, [expanded, rowSelection, sortControl, selectableRows, sorting]);
118
-
119
- // Pagination configuration
120
- const paginationInitializer = useMemo(() => {
121
- if (!pagination) return {};
122
-
123
- return {
124
- getPaginationRowModel: getPaginationRowModel(),
125
- paginateExpandedRows: false,
126
- initialState: {
127
- pagination: {
128
- pageIndex: paginationProps?.pageIndex ?? 0,
129
- pageSize: paginationProps?.pageSize ?? 20,
130
- },
131
- },
132
- };
133
- }, [pagination, paginationProps]);
134
-
135
- // Initialize the table
136
- const table = useReactTable({
137
- data: loading ? Array(loadingStateRowCount).fill({}) : (virtualizedRows ? dataChunk : tableData),
138
- columns,
139
- onExpandedChange: setExpanded,
140
- getSubRows: (row: GenericObject) => row.children,
141
- getCoreRowModel: getCoreRowModel(),
142
- getExpandedRowModel: getExpandedRowModel(),
143
- getSortedRowModel: getSortedRowModel(),
144
- enableSortingRemoval: false,
145
- sortDescFirst: true,
146
- onRowSelectionChange: setRowSelection,
147
- getRowId: selectableRows ? row => row.id : undefined,
148
- meta: {
149
- columnDefinitions
150
- },
151
- ...customState(),
152
- ...paginationInitializer,
153
- ...tableOptions,
154
- });
155
-
156
- // Check if table has any sub-rows
157
- const hasAnySubRows = table.getRowModel().rows.some(row => row.subRows && row.subRows.length > 0);
158
- const selectedRowsLength = Object.keys(table.getState().rowSelection).length;
159
-
160
- // Data fetching for virtualized view
161
- const fetchNextPage = useCallback(() => {
162
- if (isFetching || totalFetched >= fullData.length) return;
163
-
164
- setIsFetching(true);
165
- // Simulate API call delay
166
- setTimeout(() => {
167
- const nextChunk = fullData.slice(totalFetched, totalFetched + fetchSize);
168
- setDataChunk(prev => [...prev, ...nextChunk]);
169
- setTotalFetched(prev => prev + nextChunk.length);
170
- setIsFetching(false);
171
- }, 500);
172
- }, [isFetching, totalFetched, fullData, fetchSize]);
173
-
174
- // Update row count for loading state
175
- const updateLoadingStateRowCount = useCallback(() => {
176
- const rowsCount = table.getRowModel().rows.length;
177
- if (rowsCount !== loadingStateRowCount && rowsCount !== 0) {
178
- setLoadingStateRowCount(rowsCount);
179
- }
180
- }, [loadingStateRowCount, table]);
181
-
182
- return {
183
- table,
184
- expanded,
185
- setExpanded,
186
- hasAnySubRows,
187
- selectedRowsLength,
188
- fetchNextPage,
189
- updateLoadingStateRowCount,
190
- rowSelection,
191
- fullData,
192
- totalFetched,
193
- isFetching
194
- };
195
- }
@@ -1,73 +0,0 @@
1
- import React from "react";
2
- import { Row, Getter } from "@tanstack/react-table";
3
- import { GenericObject } from "../../types";
4
- import { CustomCell } from "../Components/CustomCell";
5
-
6
- /**
7
- * Creates a cell render function for table columns
8
- *
9
- * @param cellAccessors Array of accessors to use based on row depth
10
- * @param customRenderer Optional custom renderer function
11
- * @param isFirstColumn Whether this is the first column (special handling)
12
- * @param onRowToggleClick Optional callback for row toggle
13
- * @param selectableRows Whether rows are selectable
14
- */
15
- export const createCellFunction = (
16
- cellAccessors: string[],
17
- customRenderer?: (row: Row<GenericObject>, value: any) => JSX.Element,
18
- isFirstColumn?: boolean,
19
- onRowToggleClick?: (row: Row<GenericObject>) => void,
20
- selectableRows?: boolean
21
- ) => {
22
- // Add display name to the returned function
23
- const cellRenderer = ({
24
- row,
25
- getValue,
26
- }: {
27
- row: Row<GenericObject>
28
- getValue: Getter<string>
29
- }) => {
30
- const rowData = row.original;
31
-
32
- if (isFirstColumn) {
33
- switch (row.depth) {
34
- case 0: {
35
- return (
36
- <CustomCell
37
- customRenderer={customRenderer}
38
- getValue={getValue}
39
- onRowToggleClick={onRowToggleClick}
40
- row={row}
41
- selectableRows={selectableRows}
42
- />
43
- );
44
- }
45
- default: {
46
- // Handle other depths based on cellAccessors
47
- const depthAccessor = cellAccessors[row.depth - 1]; // Adjust index for depth
48
- const accessorValue = rowData[depthAccessor];
49
- return accessorValue ? (
50
- <CustomCell
51
- customRenderer={customRenderer}
52
- onRowToggleClick={onRowToggleClick}
53
- row={row}
54
- selectableRows={selectableRows}
55
- value={accessorValue}
56
- />
57
- ) : (
58
- "N/A"
59
- );
60
- }
61
- }
62
- }
63
-
64
- return customRenderer
65
- ? customRenderer(row, getValue())
66
- : getValue();
67
- };
68
-
69
- // Add a display name to the function to fix the react/display-name warning
70
- cellRenderer.displayName = 'CellRenderer';
71
-
72
- return cellRenderer;
73
- };
@@ -1,52 +0,0 @@
1
- import { Row } from "@tanstack/react-table"
2
- import { GenericObject } from "../../types"
3
-
4
- /**
5
- * Determines the background color class for a row
6
- */
7
- export const getRowColorClass = (
8
- row: Row<GenericObject>,
9
- inlineRowLoading: boolean
10
- ): string => {
11
- const isExpandable = row.getIsExpanded();
12
- const rowHasNoChildren = row.original?.children && !row.original.children.length ? true : false;
13
- const rowBackground = isExpandable && ((!inlineRowLoading && row.getCanExpand()) || (inlineRowLoading && rowHasNoChildren));
14
-
15
- return row.getIsSelected() ? "bg-row-selection" : rowBackground ? "bg-silver" : "bg-white";
16
- }
17
-
18
- /**
19
- * Determines if loading indicator should be shown for a row
20
- */
21
- export const shouldShowLoadingIndicator = (
22
- row: Row<GenericObject>,
23
- inlineRowLoading: boolean,
24
- cellAccessorsLength: number
25
- ): boolean => {
26
- const isExpandable = row.getIsExpanded();
27
- const rowHasNoChildren = row.original?.children && !row.original.children.length ? true : false;
28
-
29
- return isExpandable &&
30
- (inlineRowLoading && rowHasNoChildren) &&
31
- (row.depth < cellAccessorsLength);
32
- }
33
-
34
- /**
35
- * Creates a virtual item style object for virtualized rows
36
- */
37
- export const createVirtualItemStyle = (startPosition: number): React.CSSProperties => {
38
- return {
39
- position: 'absolute',
40
- top: 0,
41
- left: 0,
42
- width: '100%',
43
- transform: `translateY(${startPosition}px)`,
44
- };
45
- }
46
-
47
- /**
48
- * Calculates padding left based on row depth
49
- */
50
- export const getDepthPaddingLeft = (depth: number): string => {
51
- return `${depth === 0 ? 0.5 : (depth * 2)}em`;
52
- }