@teselagen/ui 0.9.6 → 0.9.8

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 (61) hide show
  1. package/DataTable/EditabelCell.d.ts +7 -0
  2. package/DataTable/ReactTable.d.ts +78 -0
  3. package/DataTable/defaultProps.d.ts +43 -0
  4. package/DataTable/index.d.ts +3 -3
  5. package/DataTable/utils/computePresets.d.ts +1 -0
  6. package/DataTable/utils/types/Entity.d.ts +9 -0
  7. package/DataTable/utils/types/Field.d.ts +4 -0
  8. package/DataTable/utils/types/OrderBy.d.ts +11 -0
  9. package/DataTable/utils/types/Schema.d.ts +4 -0
  10. package/DataTable/utils/useDeepEqualMemo.d.ts +1 -0
  11. package/DataTable/utils/useHotKeysWrapper.d.ts +29 -0
  12. package/DataTable/utils/useTableParams.d.ts +49 -0
  13. package/index.cjs.js +22409 -22286
  14. package/index.es.js +22421 -22298
  15. package/package.json +1 -2
  16. package/src/DataTable/Columns.jsx +945 -0
  17. package/src/DataTable/EditabelCell.js +44 -0
  18. package/src/DataTable/EditabelCell.jsx +44 -0
  19. package/src/DataTable/PagingTool.js +2 -2
  20. package/src/DataTable/ReactTable.js +738 -0
  21. package/src/DataTable/RenderCell.jsx +191 -0
  22. package/src/DataTable/defaultProps.js +45 -0
  23. package/src/DataTable/index.js +217 -1203
  24. package/src/DataTable/utils/computePresets.js +42 -0
  25. package/src/DataTable/utils/convertSchema.ts +79 -0
  26. package/src/DataTable/utils/formatPasteData.ts +34 -0
  27. package/src/DataTable/utils/getAllRows.ts +11 -0
  28. package/src/DataTable/utils/getCellCopyText.ts +7 -0
  29. package/src/DataTable/utils/getCellInfo.ts +46 -0
  30. package/src/DataTable/utils/getFieldPathToField.ts +10 -0
  31. package/src/DataTable/utils/getIdOrCodeOrIndex.ts +14 -0
  32. package/src/DataTable/utils/getLastSelectedEntity.ts +15 -0
  33. package/src/DataTable/utils/getNewEntToSelect.ts +32 -0
  34. package/src/DataTable/utils/initializeHasuraWhereAndFilter.ts +35 -0
  35. package/src/DataTable/utils/isBottomRightCornerOfRectangle.ts +27 -0
  36. package/src/DataTable/utils/isEntityClean.ts +15 -0
  37. package/src/DataTable/utils/primarySelectedValue.ts +1 -0
  38. package/src/DataTable/utils/removeCleanRows.ts +26 -0
  39. package/src/DataTable/utils/selection.ts +11 -0
  40. package/src/DataTable/utils/types/Entity.ts +13 -0
  41. package/src/DataTable/utils/types/Field.ts +4 -0
  42. package/src/DataTable/utils/types/OrderBy.ts +15 -0
  43. package/src/DataTable/utils/types/Schema.ts +5 -0
  44. package/src/DataTable/utils/useDeepEqualMemo.js +10 -0
  45. package/src/DataTable/utils/useHotKeysWrapper.js +395 -0
  46. package/src/DataTable/utils/useTableEntities.ts +60 -0
  47. package/src/DataTable/utils/useTableParams.js +361 -0
  48. package/src/DataTable/utils/utils.ts +39 -0
  49. package/src/DataTable/utils/withTableParams.js +1 -1
  50. package/src/Timeline/TimelineEvent.tsx +36 -0
  51. package/src/Timeline/index.tsx +21 -0
  52. package/src/utils/browserUtils.ts +3 -0
  53. package/src/utils/determineBlackOrWhiteTextColor.ts +11 -0
  54. package/src/utils/getTextFromEl.ts +45 -0
  55. package/src/utils/handlerHelpers.ts +32 -0
  56. package/src/utils/hooks/index.ts +1 -0
  57. package/src/utils/hooks/useDeepEqualMemo.ts +10 -0
  58. package/src/utils/hooks/useStableReference.ts +9 -0
  59. package/src/utils/hotkeyUtils.tsx +155 -0
  60. package/src/utils/isBeingCalledExcessively.ts +37 -0
  61. package/style.css +10537 -0
@@ -0,0 +1,738 @@
1
+ import React, { useCallback, useMemo } from "react";
2
+ import Table from "@teselagen/react-table";
3
+ import { cloneDeep, keyBy, forEach, omitBy } from "lodash-es";
4
+ import classNames from "classnames";
5
+ import { useColumns } from "./Columns";
6
+ import { arrayMove } from "@dnd-kit/sortable";
7
+ import SortableColumns from "./SortableColumns";
8
+ import {
9
+ getCellCopyText,
10
+ getCellInfo,
11
+ getIdOrCodeOrIndex,
12
+ getRecordsFromIdMap,
13
+ handleCopyColumn,
14
+ handleCopyHelper,
15
+ handleCopyRows,
16
+ handleCopyTable,
17
+ isEntityClean,
18
+ PRIMARY_SELECTED_VAL
19
+ } from "./utils";
20
+ import { Menu, MenuItem, ContextMenu } from "@blueprintjs/core";
21
+ import rowClick, { finalizeSelection } from "./utils/rowClick";
22
+ import { ThComponent } from "./ThComponent";
23
+ import DisabledLoadingComponent from "./DisabledLoadingComponent";
24
+ import "./style.css";
25
+
26
+ const itemSizeEstimators = {
27
+ compact: () => 25.34,
28
+ normal: () => 33.34,
29
+ comfortable: () => 41.34
30
+ };
31
+
32
+ export const ReactTable = ({
33
+ addFilters,
34
+ cellRenderer,
35
+ change,
36
+ columns,
37
+ compact,
38
+ contextMenu,
39
+ currentParams,
40
+ disabled,
41
+ doNotShowEmptyRows,
42
+ doNotValidateUntouchedRows,
43
+ editingCellSelectAll,
44
+ entities,
45
+ expandedEntityIdMap,
46
+ extraCompact,
47
+ filters,
48
+ formName,
49
+ getCellHoverText,
50
+ getRowClassName,
51
+ handleCellClick,
52
+ handleCopySelectedRows,
53
+ history,
54
+ insertRows,
55
+ isCellEditable,
56
+ isCopyable,
57
+ isEntityDisabled,
58
+ isLoading,
59
+ isLocalCall,
60
+ isSelectionARectangle,
61
+ isSimple,
62
+ isSingleSelect,
63
+ maxHeight,
64
+ moveColumnPersist,
65
+ mustClickCheckboxToSelect,
66
+ noDeselectAll,
67
+ noRowsFoundMessage,
68
+ noSelect,
69
+ noUserSelect,
70
+ noVirtual,
71
+ numRows,
72
+ onDeselect,
73
+ onDoubleClick,
74
+ onlyShowRowsWErrors,
75
+ onMultiRowSelect,
76
+ onRowClick,
77
+ onRowSelect,
78
+ onSingleRowSelect,
79
+ order,
80
+ primarySelectedCellId,
81
+ ReactTableProps,
82
+ recordIdToIsVisibleMap,
83
+ reduxFormCellValidation,
84
+ reduxFormEditingCell,
85
+ reduxFormSelectedEntityIdMap,
86
+ refocusTable,
87
+ removeSingleFilter,
88
+ resizePersist,
89
+ schema,
90
+ selectedCells,
91
+ setColumns,
92
+ setExpandedEntityIdMap,
93
+ setNewParams,
94
+ setOrder,
95
+ setRecordIdToIsVisibleMap,
96
+ setSelectedCells,
97
+ shouldShowSubComponent,
98
+ startCellEdit,
99
+ style,
100
+ SubComponent,
101
+ tableConfig,
102
+ tableRef,
103
+ updateEntitiesHelper,
104
+ updateValidation,
105
+ withCheckboxes,
106
+ withExpandAndCollapseAllButton,
107
+ withFilter,
108
+ withSort
109
+ }) => {
110
+ let rowsToShow = doNotShowEmptyRows
111
+ ? Math.min(numRows, entities.length)
112
+ : numRows;
113
+ // if there are no entities then provide enough space to show
114
+ // no rows found message
115
+ if (entities.length === 0 && rowsToShow < 3) rowsToShow = 3;
116
+
117
+ const showContextMenu = useCallback(
118
+ (e, { idMap, selectedCells } = {}) => {
119
+ let selectedRecords;
120
+ if (isCellEditable) {
121
+ const rowIds = {};
122
+ Object.keys(selectedCells).forEach(cellKey => {
123
+ const [rowId] = cellKey.split(":");
124
+ rowIds[rowId] = true;
125
+ });
126
+ selectedRecords = entities.filter(
127
+ ent => rowIds[getIdOrCodeOrIndex(ent)]
128
+ );
129
+ } else {
130
+ selectedRecords = getRecordsFromIdMap(idMap);
131
+ }
132
+
133
+ const itemsToRender = contextMenu({
134
+ selectedRecords,
135
+ history
136
+ });
137
+ if (!itemsToRender && !isCopyable) return null;
138
+ const copyMenuItems = [];
139
+
140
+ e.persist();
141
+ if (isCopyable) {
142
+ //compute the cellWrapper here so we don't lose access to it
143
+ const cellWrapper =
144
+ e.target.querySelector(".tg-cell-wrapper") ||
145
+ e.target.closest(".tg-cell-wrapper");
146
+ if (cellWrapper) {
147
+ copyMenuItems.push(
148
+ <MenuItem
149
+ key="copyCell"
150
+ onClick={() => {
151
+ //TODOCOPY: we need to make sure that the cell copy is being used by the row copy.. right now we have 2 different things going on
152
+ //do we need to be able to copy hidden cells? It seems like it should just copy what's on the page..?
153
+ const specificColumn = cellWrapper.getAttribute("data-test");
154
+ handleCopyRows([cellWrapper.closest(".rt-tr")], {
155
+ specificColumn,
156
+ onFinishMsg: "Cell copied"
157
+ });
158
+ const [text, jsonText] = getCellCopyText(cellWrapper);
159
+ handleCopyHelper(text, jsonText);
160
+ }}
161
+ text="Cell"
162
+ />
163
+ );
164
+
165
+ copyMenuItems.push(
166
+ <MenuItem
167
+ key="copyColumn"
168
+ onClick={() => {
169
+ handleCopyColumn(tableRef, cellWrapper);
170
+ }}
171
+ text="Column"
172
+ />
173
+ );
174
+ if (selectedRecords.length > 1) {
175
+ copyMenuItems.push(
176
+ <MenuItem
177
+ key="copyColumnSelected"
178
+ onClick={() => {
179
+ handleCopyColumn(tableRef, cellWrapper, selectedRecords);
180
+ }}
181
+ text="Column (Selected)"
182
+ />
183
+ );
184
+ }
185
+ }
186
+ if (selectedRecords.length === 0 || selectedRecords.length === 1) {
187
+ //compute the row here so we don't lose access to it
188
+ const cell =
189
+ e.target.querySelector(".tg-cell-wrapper") ||
190
+ e.target.closest(".tg-cell-wrapper") ||
191
+ e.target.closest(".rt-td");
192
+ const row = cell.closest(".rt-tr");
193
+ copyMenuItems.push(
194
+ <MenuItem
195
+ key="copySelectedRows"
196
+ onClick={() => {
197
+ handleCopyRows([row]);
198
+ // loop through each cell in the row
199
+ }}
200
+ text="Row"
201
+ />
202
+ );
203
+ } else if (selectedRecords.length > 1) {
204
+ copyMenuItems.push(
205
+ <MenuItem
206
+ key="copySelectedRows"
207
+ onClick={() => {
208
+ handleCopySelectedRows(selectedRecords, e);
209
+ // loop through each cell in the row
210
+ }}
211
+ text="Rows"
212
+ />
213
+ );
214
+ }
215
+ copyMenuItems.push(
216
+ <MenuItem
217
+ key="copyFullTableRows"
218
+ onClick={() => {
219
+ handleCopyTable(tableRef);
220
+ // loop through each cell in the row
221
+ }}
222
+ text="Table"
223
+ />
224
+ );
225
+ }
226
+ const selectedRowIds = Object.keys(selectedCells).map(cellId => {
227
+ const [rowId] = cellId.split(":");
228
+ return rowId;
229
+ });
230
+
231
+ const menu = (
232
+ <Menu>
233
+ {itemsToRender}
234
+ {copyMenuItems.length && (
235
+ <MenuItem icon="clipboard" key="copyOpts" text="Copy">
236
+ {copyMenuItems}
237
+ </MenuItem>
238
+ )}
239
+ {isCellEditable && (
240
+ <>
241
+ <MenuItem
242
+ icon="add-row-top"
243
+ text="Add Row Above"
244
+ key="addRowAbove"
245
+ onClick={() => {
246
+ insertRows({ above: true });
247
+ }}
248
+ />
249
+ <MenuItem
250
+ icon="add-row-top"
251
+ text="Add Row Below"
252
+ key="addRowBelow"
253
+ onClick={() => {
254
+ insertRows({});
255
+ }}
256
+ />
257
+ <MenuItem
258
+ icon="remove"
259
+ text={`Remove Row${selectedRowIds.length > 1 ? "s" : ""}`}
260
+ key="removeRow"
261
+ onClick={() => {
262
+ const selectedRowIds = Object.keys(selectedCells).map(
263
+ cellId => {
264
+ const [rowId] = cellId.split(":");
265
+ return rowId;
266
+ }
267
+ );
268
+ updateEntitiesHelper(entities, entities => {
269
+ const ents = entities.filter(
270
+ (e, i) =>
271
+ !selectedRowIds.includes(getIdOrCodeOrIndex(e, i))
272
+ );
273
+ updateValidation(
274
+ ents,
275
+ omitBy(reduxFormCellValidation, (v, cellId) =>
276
+ selectedRowIds.includes(cellId.split(":")[0])
277
+ )
278
+ );
279
+ return ents;
280
+ });
281
+ refocusTable();
282
+ }}
283
+ />
284
+ </>
285
+ )}
286
+ </Menu>
287
+ );
288
+ ContextMenu.show(menu, { left: e.clientX, top: e.clientY });
289
+ },
290
+ [
291
+ contextMenu,
292
+ entities,
293
+ handleCopySelectedRows,
294
+ history,
295
+ insertRows,
296
+ isCellEditable,
297
+ isCopyable,
298
+ reduxFormCellValidation,
299
+ refocusTable,
300
+ tableRef,
301
+ updateEntitiesHelper,
302
+ updateValidation
303
+ ]
304
+ );
305
+
306
+ const getTableCellProps = useCallback(
307
+ (state, rowInfo, column) => {
308
+ if (!isCellEditable) return {}; //only allow cell selection to do stuff here
309
+ if (!rowInfo) return {};
310
+ if (!reduxFormCellValidation) return {};
311
+ const entity = rowInfo.original;
312
+ const rowIndex = rowInfo.index;
313
+ const rowId = getIdOrCodeOrIndex(entity, rowIndex);
314
+ const {
315
+ cellId,
316
+ cellIdAbove,
317
+ cellIdToRight,
318
+ cellIdBelow,
319
+ cellIdToLeft,
320
+ rowDisabled,
321
+ columnIndex
322
+ } = getCellInfo({
323
+ columnIndex: column.index,
324
+ columnPath: column.path,
325
+ rowId,
326
+ schema,
327
+ entities,
328
+ rowIndex,
329
+ isEntityDisabled,
330
+ entity
331
+ });
332
+
333
+ const _isClean =
334
+ (entity._isClean && doNotValidateUntouchedRows) ||
335
+ isEntityClean(entity);
336
+
337
+ const err = !_isClean && reduxFormCellValidation[cellId];
338
+ let selectedTopBorder,
339
+ selectedRightBorder,
340
+ selectedBottomBorder,
341
+ selectedLeftBorder;
342
+ if (selectedCells[cellId]) {
343
+ selectedTopBorder = !selectedCells[cellIdAbove];
344
+ selectedRightBorder = !selectedCells[cellIdToRight];
345
+ selectedBottomBorder = !selectedCells[cellIdBelow];
346
+ selectedLeftBorder = !selectedCells[cellIdToLeft];
347
+ }
348
+ const isPrimarySelected = selectedCells[cellId] === PRIMARY_SELECTED_VAL;
349
+ const className = classNames({
350
+ isSelectedCell: selectedCells[cellId],
351
+ isPrimarySelected,
352
+ isSecondarySelected: selectedCells[cellId] === true,
353
+ noSelectedTopBorder: !selectedTopBorder,
354
+ isCleanRow: _isClean,
355
+ noSelectedRightBorder: !selectedRightBorder,
356
+ noSelectedBottomBorder: !selectedBottomBorder,
357
+ noSelectedLeftBorder: !selectedLeftBorder,
358
+ isDropdownCell: column.type === "dropdown",
359
+ isEditingCell: reduxFormEditingCell === cellId,
360
+ hasCellError: !!err,
361
+ "no-data-tip": selectedCells[cellId]
362
+ });
363
+ return {
364
+ onDoubleClick: () => {
365
+ // cell double click
366
+ if (rowDisabled) return;
367
+ startCellEdit(cellId);
368
+ },
369
+ ...(err && {
370
+ "data-tip": err?.message || err,
371
+ "data-no-child-data-tip": true
372
+ }),
373
+ onContextMenu: e => {
374
+ const newSelectedCells = { ...selectedCells };
375
+ if (!isPrimarySelected) {
376
+ if (primarySelectedCellId) {
377
+ newSelectedCells[primarySelectedCellId] = true;
378
+ }
379
+ newSelectedCells[cellId] = PRIMARY_SELECTED_VAL;
380
+ setSelectedCells(newSelectedCells);
381
+ }
382
+ showContextMenu(e, { selectedCells: newSelectedCells });
383
+ },
384
+ onClick: event => {
385
+ handleCellClick({
386
+ event,
387
+ cellId,
388
+ rowDisabled,
389
+ rowIndex,
390
+ columnIndex
391
+ });
392
+ },
393
+ className
394
+ };
395
+ },
396
+ [
397
+ doNotValidateUntouchedRows,
398
+ entities,
399
+ handleCellClick,
400
+ isCellEditable,
401
+ isEntityDisabled,
402
+ primarySelectedCellId,
403
+ reduxFormCellValidation,
404
+ reduxFormEditingCell,
405
+ schema,
406
+ selectedCells,
407
+ setSelectedCells,
408
+ showContextMenu,
409
+ startCellEdit
410
+ ]
411
+ );
412
+
413
+ const getTableRowProps = useCallback(
414
+ (state, rowInfo) => {
415
+ if (!rowInfo) {
416
+ return {
417
+ className: "no-row-data"
418
+ };
419
+ }
420
+ const entity = rowInfo.original;
421
+ const rowId = getIdOrCodeOrIndex(entity, rowInfo.index);
422
+ const rowSelected = reduxFormSelectedEntityIdMap[rowId];
423
+ const isExpanded = expandedEntityIdMap[rowId];
424
+ const rowDisabled = isEntityDisabled(entity);
425
+ const dataId = entity.id || entity.code;
426
+ return {
427
+ onClick: e => {
428
+ if (isCellEditable) return;
429
+ // if checkboxes are activated or row expander is clicked don't select row
430
+ if (e.target.matches(".tg-expander, .tg-expander *")) {
431
+ setExpandedEntityIdMap(prev => ({ ...prev, [rowId]: !isExpanded }));
432
+ return;
433
+ } else if (
434
+ e.target.closest(".tg-react-table-checkbox-cell-container")
435
+ ) {
436
+ return;
437
+ } else if (mustClickCheckboxToSelect) {
438
+ return;
439
+ }
440
+ if (e.detail > 1) {
441
+ return; //cancel multiple quick clicks
442
+ }
443
+ rowClick(e, rowInfo, entities, {
444
+ reduxFormSelectedEntityIdMap,
445
+ isSingleSelect,
446
+ noSelect,
447
+ onRowClick,
448
+ isEntityDisabled,
449
+ withCheckboxes,
450
+ onDeselect,
451
+ onSingleRowSelect,
452
+ onMultiRowSelect,
453
+ noDeselectAll,
454
+ onRowSelect,
455
+ change
456
+ });
457
+ },
458
+ //row right click
459
+ onContextMenu: e => {
460
+ e.preventDefault();
461
+ if (rowId === undefined || rowDisabled || isCellEditable) return;
462
+ const oldIdMap = cloneDeep(reduxFormSelectedEntityIdMap) || {};
463
+ let newIdMap;
464
+ if (withCheckboxes) {
465
+ newIdMap = oldIdMap;
466
+ } else {
467
+ // if we are not using checkboxes we need to make sure
468
+ // that the id of the record gets added to the id map
469
+ newIdMap = oldIdMap[rowId] ? oldIdMap : { [rowId]: { entity } };
470
+
471
+ // tgreen: this will refresh the selection with fresh data. The entities in redux might not be up to date
472
+ const keyedEntities = keyBy(entities, getIdOrCodeOrIndex);
473
+ forEach(newIdMap, (val, key) => {
474
+ const freshEntity = keyedEntities[key];
475
+ if (freshEntity) {
476
+ newIdMap[key] = { ...newIdMap[key], entity: freshEntity };
477
+ }
478
+ });
479
+ finalizeSelection({
480
+ idMap: newIdMap,
481
+ entities,
482
+ props: {
483
+ onDeselect,
484
+ onSingleRowSelect,
485
+ onMultiRowSelect,
486
+ noDeselectAll,
487
+ onRowSelect,
488
+ noSelect,
489
+ change
490
+ }
491
+ });
492
+ }
493
+ showContextMenu(e, { idMap: newIdMap, selectedCells });
494
+ },
495
+ className: classNames(
496
+ "with-row-data",
497
+ getRowClassName && getRowClassName(rowInfo, state),
498
+ {
499
+ disabled: rowDisabled,
500
+ selected: rowSelected && !withCheckboxes,
501
+ "rt-tr-last-row": rowInfo.index === entities.length - 1
502
+ }
503
+ ),
504
+ "data-test-id": dataId === undefined ? rowInfo.index : dataId,
505
+ "data-index": rowInfo.index,
506
+ "data-tip": typeof rowDisabled === "string" ? rowDisabled : undefined,
507
+ onDoubleClick: e => {
508
+ if (rowDisabled) return;
509
+ onDoubleClick &&
510
+ onDoubleClick(rowInfo.original, rowInfo.index, history, e);
511
+ }
512
+ };
513
+ },
514
+ [
515
+ change,
516
+ entities,
517
+ expandedEntityIdMap,
518
+ getRowClassName,
519
+ history,
520
+ isCellEditable,
521
+ isEntityDisabled,
522
+ isSingleSelect,
523
+ mustClickCheckboxToSelect,
524
+ noDeselectAll,
525
+ noSelect,
526
+ onDeselect,
527
+ onDoubleClick,
528
+ onMultiRowSelect,
529
+ onRowClick,
530
+ onRowSelect,
531
+ onSingleRowSelect,
532
+ reduxFormSelectedEntityIdMap,
533
+ selectedCells,
534
+ setExpandedEntityIdMap,
535
+ showContextMenu,
536
+ withCheckboxes
537
+ ]
538
+ );
539
+
540
+ const TheadComponent = useCallback(
541
+ ({ className, style, children }) => {
542
+ const moveColumn = ({ oldIndex, newIndex }) => {
543
+ let oldStateColumnIndex, newStateColumnIndex;
544
+ columns.forEach((column, i) => {
545
+ if (oldIndex === column.columnIndex) oldStateColumnIndex = i;
546
+ if (newIndex === column.columnIndex) newStateColumnIndex = i;
547
+ });
548
+ // because it is all handled in state we need
549
+ // to perform the move and update the columnIndices
550
+ // because they are used for the sortable columns
551
+ const newColumns = arrayMove(
552
+ columns,
553
+ oldStateColumnIndex,
554
+ newStateColumnIndex
555
+ ).map((column, i) => {
556
+ return {
557
+ ...column,
558
+ columnIndex: i
559
+ };
560
+ });
561
+ setColumns(newColumns);
562
+ };
563
+ return (
564
+ <SortableColumns
565
+ className={className}
566
+ style={style}
567
+ moveColumn={moveColumnPersist || moveColumn}
568
+ >
569
+ {children}
570
+ </SortableColumns>
571
+ );
572
+ },
573
+ [columns, moveColumnPersist, setColumns]
574
+ );
575
+
576
+ const expandedRows = entities.reduce((acc, row, index) => {
577
+ const rowId = getIdOrCodeOrIndex(row, index);
578
+ acc[index] = expandedEntityIdMap[rowId];
579
+ return acc;
580
+ }, {});
581
+
582
+ const renderColumns = useColumns({
583
+ addFilters,
584
+ cellRenderer,
585
+ columns,
586
+ currentParams,
587
+ compact,
588
+ editingCellSelectAll,
589
+ entities,
590
+ expandedEntityIdMap,
591
+ extraCompact,
592
+ filters,
593
+ formName,
594
+ getCellHoverText,
595
+ isCellEditable,
596
+ isEntityDisabled,
597
+ isLocalCall,
598
+ isSimple,
599
+ isSingleSelect,
600
+ isSelectionARectangle,
601
+ noDeselectAll,
602
+ noSelect,
603
+ noUserSelect,
604
+ onDeselect,
605
+ onMultiRowSelect,
606
+ onRowClick,
607
+ onRowSelect,
608
+ onSingleRowSelect,
609
+ order,
610
+ primarySelectedCellId,
611
+ reduxFormCellValidation,
612
+ reduxFormSelectedEntityIdMap,
613
+ refocusTable,
614
+ removeSingleFilter,
615
+ schema,
616
+ selectedCells,
617
+ setExpandedEntityIdMap,
618
+ setNewParams,
619
+ setOrder,
620
+ setSelectedCells,
621
+ shouldShowSubComponent,
622
+ startCellEdit,
623
+ SubComponent,
624
+ tableRef,
625
+ updateEntitiesHelper,
626
+ updateValidation,
627
+ withCheckboxes,
628
+ withExpandAndCollapseAllButton,
629
+ withFilter,
630
+ withSort,
631
+ recordIdToIsVisibleMap,
632
+ setRecordIdToIsVisibleMap
633
+ });
634
+
635
+ const filteredEnts = useMemo(() => {
636
+ if (onlyShowRowsWErrors) {
637
+ const rowToErrorMap = {};
638
+ forEach(reduxFormCellValidation, (err, cellId) => {
639
+ if (err) {
640
+ const [rowId] = cellId.split(":");
641
+ rowToErrorMap[rowId] = true;
642
+ }
643
+ });
644
+ return entities.filter(e => {
645
+ return rowToErrorMap[e.id];
646
+ });
647
+ }
648
+ return entities;
649
+ }, [entities, onlyShowRowsWErrors, reduxFormCellValidation]);
650
+
651
+ const SubComponentToUse = useMemo(() => {
652
+ if (SubComponent) {
653
+ return row => {
654
+ let shouldShow = true;
655
+ if (shouldShowSubComponent) {
656
+ shouldShow = shouldShowSubComponent(row.original);
657
+ }
658
+ if (shouldShow) {
659
+ return SubComponent(row);
660
+ }
661
+ };
662
+ }
663
+ return;
664
+ }, [SubComponent, shouldShowSubComponent]);
665
+
666
+ const resized = useMemo(
667
+ () => tableConfig.resized || [],
668
+ [tableConfig?.resized]
669
+ );
670
+
671
+ return (
672
+ <Table
673
+ data={filteredEnts}
674
+ ref={tableRef}
675
+ noVirtual={noVirtual}
676
+ className={classNames({
677
+ isCellEditable,
678
+ "tg-table-loading": isLoading,
679
+ "tg-table-disabled": disabled
680
+ })}
681
+ itemSizeEstimator={
682
+ extraCompact
683
+ ? itemSizeEstimators.compact
684
+ : compact
685
+ ? itemSizeEstimators.normal
686
+ : itemSizeEstimators.comfortable
687
+ }
688
+ TfootComponent={() => {
689
+ return <button>hasdfasdf</button>;
690
+ }}
691
+ // We should try to not give all the props to the render column
692
+ columns={renderColumns}
693
+ pageSize={rowsToShow}
694
+ expanded={expandedRows}
695
+ showPagination={false}
696
+ sortable={false}
697
+ loading={isLoading || disabled}
698
+ defaultResized={resized}
699
+ onResizedChange={(newResized = []) => {
700
+ const resizedToUse = newResized.map(column => {
701
+ // have a min width of 50 so that columns don't disappear
702
+ if (column.value < 50) {
703
+ return {
704
+ ...column,
705
+ value: 50
706
+ };
707
+ } else {
708
+ return column;
709
+ }
710
+ });
711
+ resizePersist(resizedToUse);
712
+ }}
713
+ TheadComponent={TheadComponent}
714
+ ThComponent={ThComponent}
715
+ getTrGroupProps={getTableRowProps}
716
+ getTdProps={getTableCellProps}
717
+ NoDataComponent={({ children }) =>
718
+ isLoading ? null : (
719
+ <div className="rt-noData">{noRowsFoundMessage || children}</div>
720
+ )
721
+ }
722
+ LoadingComponent={({ loadingText, loading }) => (
723
+ <DisabledLoadingComponent
724
+ loading={loading}
725
+ loadingText={loadingText}
726
+ disabled={disabled}
727
+ />
728
+ )}
729
+ style={{
730
+ maxHeight,
731
+ minHeight: 150,
732
+ ...style
733
+ }}
734
+ SubComponent={SubComponentToUse}
735
+ {...ReactTableProps}
736
+ />
737
+ );
738
+ };