@tap-payments/os-micro-frontend-shared 0.1.135-test.5 → 0.1.136-test.1
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/build/components/VirtualTables/SheetViewVirtualTable/SheetViewVirtualTable.js +16 -29
- package/build/components/VirtualTables/SheetViewVirtualTable/hooks/usePerformanceOptimizations.d.ts +2 -10
- package/build/components/VirtualTables/SheetViewVirtualTable/hooks/usePerformanceOptimizations.js +84 -88
- package/package.json +2 -2
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
-
import { memo, useCallback
|
|
2
|
+
import { memo, useCallback } from 'react';
|
|
3
3
|
import { SHEET_VIEW_TABLE_THRESHOLD } from '../../../constants/index.js';
|
|
4
4
|
import TableFooter from '../components/TableFooter/TableFooter';
|
|
5
5
|
import { SheetViewTableContainer } from '../components/style';
|
|
@@ -8,7 +8,7 @@ import { usePinnedColumns, useSynchronizedScroll, useTableState, useTableData, u
|
|
|
8
8
|
import { PinnedColumn, MainTable, LoadingMainTable, NoDataView, VirtualTable } from './components';
|
|
9
9
|
function SheetViewVirtualTable({ columns, rows, threshold = SHEET_VIEW_TABLE_THRESHOLD, showHeader, headerProps, rowProps, footerProps, rowHeight = 28, isLoading, error, columnsSorting, onColumnSort, loadMoreItems, isFetchingNextPage, triggerDataRefetch, scrollToIndex, areAllRowsLoaded = false, tableBodyStyles, tableTitle, dragControls, onColumnPin, clearBackdropVisibilityTimeout = 100, isPinnable = false, tableMode, overscanCount, }) {
|
|
10
10
|
// Performance optimizations
|
|
11
|
-
const { stableColumns
|
|
11
|
+
const { stableColumns } = usePerformanceOptimizations(columns);
|
|
12
12
|
// Custom hooks for state management
|
|
13
13
|
const { selectedCell, selectedColumn, selectedRow, showBackDrop, setShowBackdrop, handleCellClick, handleColumnClick, handleChipClick, selectedChip, } = useTableState();
|
|
14
14
|
// Table data processing
|
|
@@ -42,31 +42,6 @@ function SheetViewVirtualTable({ columns, rows, threshold = SHEET_VIEW_TABLE_THR
|
|
|
42
42
|
handleCellClick,
|
|
43
43
|
handleChipClick,
|
|
44
44
|
});
|
|
45
|
-
// Memoized header props to prevent unnecessary re-renders when filters change
|
|
46
|
-
const memoizedHeaderProps = useMemo(() => ({
|
|
47
|
-
showHeader,
|
|
48
|
-
columnsSorting,
|
|
49
|
-
onColumnSort,
|
|
50
|
-
headerProps,
|
|
51
|
-
showBackDrop,
|
|
52
|
-
onColumnPin: handleColumnPin,
|
|
53
|
-
isPinnable,
|
|
54
|
-
lastColumnId,
|
|
55
|
-
selectedColumn,
|
|
56
|
-
onColumnClick: handleColumnClick,
|
|
57
|
-
}), [
|
|
58
|
-
showHeader,
|
|
59
|
-
columnsSorting,
|
|
60
|
-
onColumnSort,
|
|
61
|
-
headerProps,
|
|
62
|
-
showBackDrop,
|
|
63
|
-
handleColumnPin,
|
|
64
|
-
isPinnable,
|
|
65
|
-
lastColumnId,
|
|
66
|
-
selectedColumn,
|
|
67
|
-
handleColumnClick,
|
|
68
|
-
stableFilters, // This dependency ensures re-render when filters change
|
|
69
|
-
]);
|
|
70
45
|
const onPointerDown = (e) => {
|
|
71
46
|
dragControls === null || dragControls === void 0 ? void 0 : dragControls.start(e);
|
|
72
47
|
};
|
|
@@ -95,7 +70,18 @@ function SheetViewVirtualTable({ columns, rows, threshold = SHEET_VIEW_TABLE_THR
|
|
|
95
70
|
pinnedEndVirtualListRef,
|
|
96
71
|
scrollableVirtualListRef,
|
|
97
72
|
]);
|
|
98
|
-
const baseCommonProps =
|
|
73
|
+
const baseCommonProps = {
|
|
74
|
+
showHeader,
|
|
75
|
+
columnsSorting,
|
|
76
|
+
onColumnSort,
|
|
77
|
+
headerProps,
|
|
78
|
+
showBackDrop,
|
|
79
|
+
onColumnPin: handleColumnPin,
|
|
80
|
+
isPinnable,
|
|
81
|
+
lastColumnId,
|
|
82
|
+
selectedColumn,
|
|
83
|
+
onColumnClick: handleColumnClick,
|
|
84
|
+
tableTitle,
|
|
99
85
|
areAllRowsLoaded,
|
|
100
86
|
isFetchingNextPage,
|
|
101
87
|
scrollToIndex,
|
|
@@ -103,7 +89,8 @@ function SheetViewVirtualTable({ columns, rows, threshold = SHEET_VIEW_TABLE_THR
|
|
|
103
89
|
isError,
|
|
104
90
|
tableMode,
|
|
105
91
|
showNoDataView,
|
|
106
|
-
tableBodyStyles
|
|
92
|
+
tableBodyStyles,
|
|
93
|
+
};
|
|
107
94
|
const commonPropsWithTableStates = Object.assign(Object.assign({}, baseCommonProps), { hasTimeoutError,
|
|
108
95
|
tableLoading });
|
|
109
96
|
return (_jsxs(_Fragment, { children: [_jsx(SheetViewTableContainer, { children: showNoDataView ? (tableLoading ? (
|
package/build/components/VirtualTables/SheetViewVirtualTable/hooks/usePerformanceOptimizations.d.ts
CHANGED
|
@@ -1,19 +1,11 @@
|
|
|
1
1
|
import type { IColumnProps } from '../../../../types/index.js';
|
|
2
|
-
interface StableFilterData {
|
|
3
|
-
type: string;
|
|
4
|
-
data?: unknown;
|
|
5
|
-
options?: unknown;
|
|
6
|
-
apiKey?: string;
|
|
7
|
-
}
|
|
8
2
|
export declare const usePerformanceOptimizations: (columns: readonly IColumnProps[]) => {
|
|
9
3
|
stableColumns: IColumnProps<any>[];
|
|
10
|
-
stableFilters: Record<string, StableFilterData>;
|
|
11
4
|
columnMetrics: {
|
|
12
5
|
visibleColumns: IColumnProps<any>[];
|
|
13
6
|
totalWidth: number;
|
|
14
7
|
columnCount: number;
|
|
15
|
-
firstColumnId: string | number | symbol;
|
|
16
|
-
lastColumnId: string | number | symbol;
|
|
8
|
+
firstColumnId: string | number | symbol | undefined;
|
|
9
|
+
lastColumnId: string | number | symbol | undefined;
|
|
17
10
|
};
|
|
18
11
|
};
|
|
19
|
-
export {};
|
package/build/components/VirtualTables/SheetViewVirtualTable/hooks/usePerformanceOptimizations.js
CHANGED
|
@@ -1,116 +1,112 @@
|
|
|
1
1
|
import { useMemo, useRef } from 'react';
|
|
2
|
+
import { isEqual, pick, has, sumBy, first, last, forEach } from 'lodash';
|
|
3
|
+
// Deep comparison helper for filter data
|
|
4
|
+
const areFilterDataEqual = (filter1, filter2) => {
|
|
5
|
+
if (filter1 === filter2)
|
|
6
|
+
return true;
|
|
7
|
+
if (!filter1 || !filter2 || filter1.type === 'custom' || filter2.type === 'custom')
|
|
8
|
+
return false;
|
|
9
|
+
console.log({ filter1, filter2 });
|
|
10
|
+
// Extract comparable properties (excluding functions) using lodash
|
|
11
|
+
const getComparableProps = (filter) => {
|
|
12
|
+
if (!filter)
|
|
13
|
+
return null;
|
|
14
|
+
// Pick only the data properties we want to compare, excluding functions
|
|
15
|
+
const baseProps = pick(filter, ['type', 'data', 'options', 'isOnlyOneFilter']);
|
|
16
|
+
// Conditionally add properties that might not exist
|
|
17
|
+
const conditionalProps = {};
|
|
18
|
+
if (has(filter, 'apiKey'))
|
|
19
|
+
conditionalProps.apiKey = filter.apiKey;
|
|
20
|
+
if (has(filter, 'countries'))
|
|
21
|
+
conditionalProps.countries = filter.countries;
|
|
22
|
+
if (has(filter, 'isCountriesLoading'))
|
|
23
|
+
conditionalProps.isCountriesLoading = filter.isCountriesLoading;
|
|
24
|
+
return Object.assign(Object.assign({}, baseProps), conditionalProps);
|
|
25
|
+
};
|
|
26
|
+
const props1 = getComparableProps(filter1);
|
|
27
|
+
const props2 = getComparableProps(filter2);
|
|
28
|
+
// Use lodash's deep equality check instead of manual comparison
|
|
29
|
+
return isEqual(props1, props2);
|
|
30
|
+
};
|
|
2
31
|
export const usePerformanceOptimizations = (columns) => {
|
|
3
32
|
// Create stable column references to prevent unnecessary re-renders
|
|
4
33
|
const stableColumnsRef = useRef([]);
|
|
5
|
-
|
|
6
|
-
const
|
|
34
|
+
const isFirstRenderRef = useRef(true);
|
|
35
|
+
const filterChangeTrackingRef = useRef(new Map());
|
|
7
36
|
const stableColumns = useMemo(() => {
|
|
8
|
-
//
|
|
9
|
-
|
|
37
|
+
// On first render, just initialize and return columns
|
|
38
|
+
if (isFirstRenderRef.current) {
|
|
39
|
+
isFirstRenderRef.current = false;
|
|
40
|
+
stableColumnsRef.current = [...columns];
|
|
41
|
+
// Initialize filter tracking using lodash forEach
|
|
42
|
+
forEach(columns, (col) => {
|
|
43
|
+
filterChangeTrackingRef.current.set(col.id, col === null || col === void 0 ? void 0 : col.filter);
|
|
44
|
+
});
|
|
45
|
+
return stableColumnsRef.current;
|
|
46
|
+
}
|
|
47
|
+
// After first render, only update if structural changes or filter changes occurred
|
|
48
|
+
const structurallyChanged = columns.length !== stableColumnsRef.current.length ||
|
|
10
49
|
columns.some((col, index) => {
|
|
11
50
|
const prevCol = stableColumnsRef.current[index];
|
|
12
|
-
|
|
51
|
+
if (!prevCol)
|
|
52
|
+
return true;
|
|
53
|
+
// Extract structural properties and compare using lodash
|
|
54
|
+
const currentStructure = pick(col, ['id', 'width', 'pinned', 'hidden', 'order']);
|
|
55
|
+
const prevStructure = pick(prevCol, ['id', 'width', 'pinned', 'hidden', 'order']);
|
|
56
|
+
return !isEqual(currentStructure, prevStructure);
|
|
13
57
|
});
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
const columnId = col.id;
|
|
25
|
-
const filterData = {
|
|
26
|
-
type: col.filter.type,
|
|
27
|
-
data: col.filter.data,
|
|
28
|
-
options: col.filter.options,
|
|
29
|
-
};
|
|
30
|
-
// Only add apiKey if it exists (for 'list' type filters)
|
|
31
|
-
if (col.filter.type === 'list') {
|
|
32
|
-
filterData.apiKey = col.filter.apiKey;
|
|
33
|
-
}
|
|
34
|
-
currentFilters[columnId] = filterData;
|
|
58
|
+
// Check for filter-only changes using lodash forEach
|
|
59
|
+
const columnsWithFilterChanges = new Set();
|
|
60
|
+
forEach(columns, (col) => {
|
|
61
|
+
const colId = col.id;
|
|
62
|
+
const prevFilter = filterChangeTrackingRef.current.get(colId);
|
|
63
|
+
const currentFilter = col === null || col === void 0 ? void 0 : col.filter;
|
|
64
|
+
console.log({ col });
|
|
65
|
+
if (!areFilterDataEqual(prevFilter, currentFilter)) {
|
|
66
|
+
columnsWithFilterChanges.add(colId);
|
|
67
|
+
filterChangeTrackingRef.current.set(colId, currentFilter);
|
|
35
68
|
}
|
|
36
69
|
});
|
|
37
|
-
//
|
|
38
|
-
|
|
39
|
-
//
|
|
40
|
-
if (
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
70
|
+
// Only update if there are structural changes or filter changes
|
|
71
|
+
if (structurallyChanged || columnsWithFilterChanges.size > 0) {
|
|
72
|
+
// For filter-only changes, update only the affected columns
|
|
73
|
+
if (!structurallyChanged && columnsWithFilterChanges.size > 0) {
|
|
74
|
+
// Create a new array but preserve references for unchanged columns
|
|
75
|
+
const updatedColumns = stableColumnsRef.current.map((stableCol, index) => {
|
|
76
|
+
const newCol = columns[index];
|
|
77
|
+
const colId = newCol === null || newCol === void 0 ? void 0 : newCol.id;
|
|
78
|
+
// Only replace if this column's filter changed
|
|
79
|
+
if (columnsWithFilterChanges.has(colId)) {
|
|
80
|
+
return newCol;
|
|
81
|
+
}
|
|
82
|
+
// Keep the stable reference for unchanged columns
|
|
83
|
+
return stableCol;
|
|
84
|
+
});
|
|
85
|
+
stableColumnsRef.current = updatedColumns;
|
|
86
|
+
}
|
|
87
|
+
else {
|
|
88
|
+
// Full update for structural changes
|
|
89
|
+
stableColumnsRef.current = [...columns];
|
|
51
90
|
}
|
|
52
|
-
if (Array.isArray(obj1) || Array.isArray(obj2))
|
|
53
|
-
return false;
|
|
54
|
-
// Handle objects - only compare basic properties, avoid complex nested objects
|
|
55
|
-
const keys1 = Object.keys(obj1);
|
|
56
|
-
const keys2 = Object.keys(obj2);
|
|
57
|
-
if (keys1.length !== keys2.length)
|
|
58
|
-
return false;
|
|
59
|
-
return keys1.every((key) => {
|
|
60
|
-
const val1 = obj1[key];
|
|
61
|
-
const val2 = obj2[key];
|
|
62
|
-
// Skip complex objects that might have circular references
|
|
63
|
-
if (typeof val1 === 'object' && val1 != null && (val1.constructor === Object || Array.isArray(val1))) {
|
|
64
|
-
return safeCompare(val1, val2);
|
|
65
|
-
}
|
|
66
|
-
// For other object types (like React contexts), just compare references
|
|
67
|
-
return val1 === val2;
|
|
68
|
-
});
|
|
69
|
-
};
|
|
70
|
-
// Deep comparison of filter state
|
|
71
|
-
const hasFilterChanged = () => {
|
|
72
|
-
const currentKeys = Object.keys(currentFilters);
|
|
73
|
-
const prevKeys = Object.keys(stableFiltersRef.current);
|
|
74
|
-
if (currentKeys.length !== prevKeys.length)
|
|
75
|
-
return true;
|
|
76
|
-
return currentKeys.some((key) => {
|
|
77
|
-
const current = currentFilters[key];
|
|
78
|
-
const prev = stableFiltersRef.current[key];
|
|
79
|
-
if (!prev)
|
|
80
|
-
return true;
|
|
81
|
-
// Compare filter properties that affect rendering
|
|
82
|
-
if (current.type !== prev.type || current.apiKey !== prev.apiKey)
|
|
83
|
-
return true;
|
|
84
|
-
// Safe comparison for options and data
|
|
85
|
-
if (!safeCompare(current.options, prev.options))
|
|
86
|
-
return true;
|
|
87
|
-
if (!safeCompare(current.data, prev.data))
|
|
88
|
-
return true;
|
|
89
|
-
return false;
|
|
90
|
-
});
|
|
91
|
-
};
|
|
92
|
-
if (hasFilterChanged()) {
|
|
93
|
-
stableFiltersRef.current = Object.assign({}, currentFilters);
|
|
94
91
|
}
|
|
95
|
-
return
|
|
92
|
+
return stableColumnsRef.current;
|
|
96
93
|
}, [columns]);
|
|
97
|
-
// Memoize frequently used column calculations
|
|
94
|
+
// Memoize frequently used column calculations using lodash utilities
|
|
98
95
|
const columnMetrics = useMemo(() => {
|
|
99
96
|
var _a, _b;
|
|
100
97
|
const visibleColumns = stableColumns.filter((col) => !col.hidden);
|
|
101
|
-
const totalWidth = visibleColumns
|
|
98
|
+
const totalWidth = sumBy(visibleColumns, (col) => +((col === null || col === void 0 ? void 0 : col.width) || 100));
|
|
102
99
|
const columnCount = visibleColumns.length;
|
|
103
100
|
return {
|
|
104
101
|
visibleColumns,
|
|
105
102
|
totalWidth,
|
|
106
103
|
columnCount,
|
|
107
|
-
firstColumnId: (_a = visibleColumns
|
|
108
|
-
lastColumnId: (_b = visibleColumns
|
|
104
|
+
firstColumnId: (_a = first(visibleColumns)) === null || _a === void 0 ? void 0 : _a.id,
|
|
105
|
+
lastColumnId: (_b = last(visibleColumns)) === null || _b === void 0 ? void 0 : _b.id,
|
|
109
106
|
};
|
|
110
107
|
}, [stableColumns]);
|
|
111
108
|
return {
|
|
112
109
|
stableColumns,
|
|
113
|
-
stableFilters,
|
|
114
110
|
columnMetrics,
|
|
115
111
|
};
|
|
116
112
|
};
|
package/package.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tap-payments/os-micro-frontend-shared",
|
|
3
3
|
"description": "Shared components and utilities for Tap Payments micro frontends",
|
|
4
|
-
"version": "0.1.
|
|
5
|
-
"testVersion":
|
|
4
|
+
"version": "0.1.136-test.1",
|
|
5
|
+
"testVersion": 1,
|
|
6
6
|
"type": "module",
|
|
7
7
|
"main": "build/index.js",
|
|
8
8
|
"module": "build/index.js",
|