@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.
@@ -1,5 +1,5 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
- import { memo, useCallback, useMemo } from 'react';
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, stableFilters } = usePerformanceOptimizations(columns);
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 = Object.assign(Object.assign({}, memoizedHeaderProps), { tableTitle,
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 ? (
@@ -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 {};
@@ -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
- // Create stable filter references to prevent unnecessary header re-renders
6
- const stableFiltersRef = useRef({});
34
+ const isFirstRenderRef = useRef(true);
35
+ const filterChangeTrackingRef = useRef(new Map());
7
36
  const stableColumns = useMemo(() => {
8
- // Only update if columns have actually changed (deep comparison of essential properties)
9
- const hasChanged = columns.length !== stableColumnsRef.current.length ||
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
- return !prevCol || col.id !== prevCol.id || col.filter !== prevCol.filter;
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
- if (hasChanged) {
15
- stableColumnsRef.current = [...columns];
16
- }
17
- return stableColumnsRef.current;
18
- }, [columns]);
19
- const stableFilters = useMemo(() => {
20
- // Extract filter-related data from columns for header rendering optimization
21
- const currentFilters = {};
22
- columns.forEach((col) => {
23
- if (col.filter && col.id) {
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
- // Safe comparison helper that avoids circular references
38
- const safeCompare = (obj1, obj2) => {
39
- // Handle primitive types
40
- if (obj1 === obj2)
41
- return true;
42
- if (obj1 == null || obj2 == null)
43
- return obj1 === obj2;
44
- if (typeof obj1 !== 'object' || typeof obj2 !== 'object')
45
- return obj1 === obj2;
46
- // Handle arrays
47
- if (Array.isArray(obj1) && Array.isArray(obj2)) {
48
- if (obj1.length !== obj2.length)
49
- return false;
50
- return obj1.every((item, index) => safeCompare(item, obj2[index]));
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 stableFiltersRef.current;
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.reduce((sum, col) => sum + +((col === null || col === void 0 ? void 0 : col.width) || 100), 0);
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[0]) === null || _a === void 0 ? void 0 : _a.id,
108
- lastColumnId: (_b = visibleColumns[columnCount - 1]) === null || _b === void 0 ? void 0 : _b.id,
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.135-test.5",
5
- "testVersion": 5,
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",