@tap-payments/os-micro-frontend-shared 0.1.373-test.3-test.4-test.5-test.6 → 0.1.373-test.3-test.4-test.5-test.6-test.7-test.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 (25) hide show
  1. package/build/components/TableHeader/TableView/CreateViewDialog.js +3 -10
  2. package/build/components/TableHeader/TableView/ViewsMenu.js +1 -1
  3. package/build/components/TableHeader/TableView/components/ColumnList.js +4 -4
  4. package/build/components/TableHeader/TableView/components/ViewsSubmenu.js +8 -6
  5. package/build/components/TableHeader/TableView/constants.d.ts +0 -5
  6. package/build/components/TableHeader/TableView/constants.js +0 -5
  7. package/build/components/TableHeader/TableView/hooks/useCreateViewDialog.js +11 -19
  8. package/build/components/TableHeader/TableView/hooks/useViewsManager.js +30 -24
  9. package/build/components/TableHeader/TableView/hooks/useViewsMenu.d.ts +4 -1
  10. package/build/components/TableHeader/TableView/hooks/useViewsMenu.js +35 -17
  11. package/build/components/TableHeader/TableView/index.d.ts +1 -1
  12. package/build/components/TableHeader/TableView/styles.js +1 -1
  13. package/build/components/TableHeader/TableView/types.d.ts +16 -5
  14. package/build/components/TableHeader/TableView/utils.d.ts +4 -2
  15. package/build/components/TableHeader/TableView/utils.js +54 -27
  16. package/build/components/TableHeader/index.d.ts +1 -1
  17. package/build/components/TableHeader/type.d.ts +4 -1
  18. package/build/components/VirtualTables/SheetViewVirtualTable/SheetViewVirtualTable.d.ts +1 -1
  19. package/build/components/VirtualTables/SheetViewVirtualTable/SheetViewVirtualTable.js +1 -4
  20. package/build/components/VirtualTables/VirtualTable/VirtualTable.d.ts +1 -1
  21. package/build/components/VirtualTables/VirtualTable/VirtualTable.js +3 -3
  22. package/build/types/column.d.ts +0 -8
  23. package/build/utils/skeletonColumns.d.ts +0 -4
  24. package/build/utils/skeletonColumns.js +1 -18
  25. package/package.json +2 -2
@@ -46,16 +46,9 @@ function CreateViewDialog({ open, onClose, onCreate, availableColumns = [], defa
46
46
  return;
47
47
  setIsLoading(true);
48
48
  try {
49
- if (editingView) {
50
- // On update: send whole layout with current selected/default (true/false) for every column and field
51
- const layout = convertColumnsToLayoutSection(selectedColumns, mode);
52
- yield (onCreate === null || onCreate === void 0 ? void 0 : onCreate({ name: templateName, selectedColumns, layout }));
53
- }
54
- else {
55
- const columnsToCreate = selectedColumns.filter((col) => col.selected);
56
- const layout = convertColumnsToLayoutSection(columnsToCreate, mode);
57
- yield (onCreate === null || onCreate === void 0 ? void 0 : onCreate({ name: templateName, selectedColumns: columnsToCreate, layout }));
58
- }
49
+ const columnsToCreate = selectedColumns.filter((col) => col.selected);
50
+ const layout = convertColumnsToLayoutSection(columnsToCreate, mode);
51
+ yield (onCreate === null || onCreate === void 0 ? void 0 : onCreate({ name: templateName, selectedColumns: columnsToCreate, layout }));
59
52
  onClose();
60
53
  }
61
54
  catch (error) {
@@ -71,6 +71,6 @@ function ViewsMenu({ onViewChange, onCreateCustomView, onEditCustomView, onDelet
71
71
  });
72
72
  return (_jsxs(_Fragment, { children: [_jsx(ClickAwayListener, Object.assign({ onClickAway: handleCloseViewDropdown }, { children: _jsxs(ViewWrapper, Object.assign({ sx: { width: '32px' }, "data-testid": "ViewsMenu" }, { children: [_jsx(StyledButton, Object.assign({ title: t('tableView'), "data-testid": "ViewsMenu_button", onClick: handleViewButtonClick }, { children: _jsx(Icon, { src: viewIcon, alt: "view", sx: { width: 14, height: 14 } }) })), _jsx(ViewsDropdown, { open: Boolean(anchorEl), anchorEl: anchorEl, onClose: handleCloseViewDropdown, defaultModified: (_a = modifiedModes[tableMode]) !== null && _a !== void 0 ? _a : false, onMarkDefaultModified: () => {
73
73
  setModifiedModes((current) => (Object.assign(Object.assign({}, current), { [tableMode]: true })));
74
- }, setSelectedViewInfo: handleSelectedViewInfo, selectedViewInfo: selectedViewInfo, onCreateCustomView: handleOpenCreateDialog, customViews: customViews, onEditCustomView: handleOpenEditDialog, onSaveDefaultColumns: handleSaveDefaultColumns, defaultColumns: defaultColumns, setDefaultColumns: updateDefaultColumns, updateSelectedView: updateSelectedView, baseDefaultColumns: baseDefaultColumns, mode: tableMode, defaultTemplate: defaultTemplate })] })) })), _jsx(CreateViewDialog, { open: isCreateDialogOpen, onClose: handleCloseCreateDialog, availableColumns: editingView && baseDefaultColumns.length > 0 ? baseDefaultColumns : defaultColumns, defaultColumns: defaultColumns, onCreate: handleSaveView, editingView: editingView, onDelete: handleDeleteView, tableViews: shouldUseCurrentState ? currentViewColumns : undefined, mode: tableMode })] }));
74
+ }, setSelectedViewInfo: handleSelectedViewInfo, selectedViewInfo: selectedViewInfo, onCreateCustomView: handleOpenCreateDialog, customViews: customViews, onEditCustomView: handleOpenEditDialog, onSaveDefaultColumns: handleSaveDefaultColumns, defaultColumns: defaultColumns, setDefaultColumns: updateDefaultColumns, updateSelectedView: updateSelectedView, baseDefaultColumns: baseDefaultColumns, mode: tableMode, defaultTemplate: defaultTemplate })] })) })), _jsx(CreateViewDialog, { open: isCreateDialogOpen, onClose: handleCloseCreateDialog, availableColumns: defaultColumns, defaultColumns: defaultColumns, onCreate: handleSaveView, editingView: editingView, onDelete: handleDeleteView, tableViews: shouldUseCurrentState ? currentViewColumns : undefined, mode: tableMode })] }));
75
75
  }
76
76
  export default memo(ViewsMenu);
@@ -22,9 +22,9 @@ export const ColumnList = ({ selectedColumns, columnNames, allSelected, someSele
22
22
  e.stopPropagation();
23
23
  onResetToDefault();
24
24
  }, underline: "none", sx: { fontSize: 13, fontWeight: 500, cursor: 'pointer', color: 'common.blue' } }, { children: "Reset to default" }))] }), _jsx(Box, Object.assign({ sx: { flex: 1, overflowY: 'auto', minHeight: 0 } }, { children: _jsx(Reorder.Group, Object.assign({ axis: "y", onReorder: onReorder, values: columnNames, style: { listStyle: 'none', padding: 0, margin: 0 } }, { children: selectedColumns.map((column) => {
25
- var _a, _b;
25
+ var _a;
26
26
  const isDate = isDateColumn(column.name);
27
- const hasSubmenu = !isDate && Boolean((_a = column.menuItems) === null || _a === void 0 ? void 0 : _a.length);
27
+ const hasSubmenu = column.menuItems && column.menuItems.length > 0;
28
28
  const { checked, indeterminate } = getColumnCheckState(column);
29
29
  return (_jsxs(Reorder.Item, Object.assign({ value: column.name, drag: !isDate, dragListener: !isDate, transition: { duration: 0 }, whileDrag: { zIndex: 9999, boxShadow: '0 4px 12px rgba(0,0,0,0.15)', scale: 1 }, style: {
30
30
  listStyle: 'none',
@@ -62,9 +62,9 @@ export const ColumnList = ({ selectedColumns, columnNames, allSelected, someSele
62
62
  offset: [0, 0],
63
63
  },
64
64
  },
65
- ] }, { children: _jsxs(Box, Object.assign({ onMouseEnter: onCancelClose, onMouseLeave: onSubmenuLeave, sx: { display: 'flex', pl: 0.5 } }, { children: [_jsx(Box, { sx: { width: 8, height: '100%', position: 'absolute', left: -8, top: 0, bottom: 0 } }), _jsx(SubmenuPaper, { children: (_b = column.menuItems) === null || _b === void 0 ? void 0 : _b.map((subItem, subItemIndex) => {
65
+ ] }, { children: _jsxs(Box, Object.assign({ onMouseEnter: onCancelClose, onMouseLeave: onSubmenuLeave, sx: { display: 'flex', pl: 0.5 } }, { children: [_jsx(Box, { sx: { width: 8, height: '100%', position: 'absolute', left: -8, top: 0, bottom: 0 } }), _jsx(SubmenuPaper, { children: (_a = column.menuItems) === null || _a === void 0 ? void 0 : _a.map((subItem, subItemIndex) => {
66
66
  var _a, _b;
67
- return (_jsxs(React.Fragment, { children: [_jsx(MenuItem, Object.assign({ isSelected: subItem.selected, isDisabled: isDateColumn(subItem.name), onClick: () => !isDateColumn(subItem.name) && onSubItemToggle(column.name, subItem.name) }, { children: subItem.label || subItem.name })), subItemIndex < ((_b = (_a = column.menuItems) === null || _a === void 0 ? void 0 : _a.length) !== null && _b !== void 0 ? _b : 0) - 1 && _jsx(Divider, {})] }, subItem.name));
67
+ return (_jsxs(React.Fragment, { children: [_jsx(MenuItem, Object.assign({ isSelected: subItem.selected, onClick: () => onSubItemToggle(column.name, subItem.name) }, { children: subItem.label || subItem.name })), subItemIndex < ((_b = (_a = column.menuItems) === null || _a === void 0 ? void 0 : _a.length) !== null && _b !== void 0 ? _b : 0) - 1 && _jsx(Divider, {})] }, subItem.name));
68
68
  }) })] })) })))] }), column.name));
69
69
  }) })) }))] }));
70
70
  };
@@ -7,7 +7,9 @@ import { blackRightArrowIcon } from '../../../../constants/index.js';
7
7
  import { getColumnCheckState, isDateColumn } from '../utils';
8
8
  import { ResetHeaderBox, ResetCheckboxSx, ColumnItemsContainer, SubmenuPaper } from '../styles';
9
9
  import { useNestedSubmenu } from '../hooks/useNestedSubmenu';
10
- export const ViewsSubmenu = ({ columns, allCurrentSelected, someCurrentSelected, onSelectAll, onReset, onColumnToggle, onNestedItemToggle, onReorder, anchorEl, isModified = false, }) => {
10
+ export const ViewsSubmenu = ({ columns, allCurrentSelected, someCurrentSelected, onSelectAll, onReset, onColumnToggle, onNestedItemToggle, onReorder,
11
+ // anchorEl required by interface but unused in this component
12
+ isModified = false, }) => {
11
13
  const { hoveredNestedColumn, nestedSubmenuAnchorEl, openNestedSubmenu, closeNestedSubmenu, cancelNestedClose } = useNestedSubmenu();
12
14
  const columnNames = useMemo(() => columns.map((col) => col.name), [columns]);
13
15
  return (_jsxs(_Fragment, { children: [_jsxs(ResetHeaderBox, { children: [_jsx(Box, Object.assign({ sx: { display: 'flex', alignItems: 'center', gap: 1 } }, { children: _jsx(Checkbox, { checked: allCurrentSelected, indeterminate: someCurrentSelected, onChange: (e) => {
@@ -31,10 +33,10 @@ export const ViewsSubmenu = ({ columns, allCurrentSelected, someCurrentSelected,
31
33
  pointerEvents: isModified ? 'auto' : 'none',
32
34
  '&:hover': isModified ? { textDecoration: 'underline' } : undefined,
33
35
  } }, { children: "Reset" }))] }), _jsx(Divider, {}), _jsx(ColumnItemsContainer, { children: _jsx(Reorder.Group, Object.assign({ axis: "y", onReorder: onReorder, values: columnNames, style: { listStyle: 'none', padding: 0, margin: 0 } }, { children: columns.map((column, columnIndex) => {
34
- var _a, _b;
35
- const isDate = isDateColumn(column.name);
36
- const hasNestedSubmenu = !isDate && Boolean((_a = column.menuItems) === null || _a === void 0 ? void 0 : _a.length);
36
+ var _a;
37
+ const hasNestedSubmenu = column.menuItems && column.menuItems.length > 0;
37
38
  const { checked, indeterminate } = getColumnCheckState(column);
39
+ const isDate = isDateColumn(column.name);
38
40
  return (_jsxs(Reorder.Item, Object.assign({ value: column.name, drag: !isDate, dragListener: !isDate, transition: { duration: 0 }, whileDrag: { zIndex: 9999, boxShadow: '0 4px 12px rgba(0,0,0,0.15)', scale: 1.02 }, style: {
39
41
  listStyle: 'none',
40
42
  margin: 0,
@@ -60,9 +62,9 @@ export const ViewsSubmenu = ({ columns, allCurrentSelected, someCurrentSelected,
60
62
  if (!isDate) {
61
63
  onColumnToggle(column.name);
62
64
  }
63
- }, sx: { flex: 1, display: 'flex', alignItems: 'center' } }, { children: _jsx("span", { children: column.label || column.name }) })), hasNestedSubmenu && (_jsx(Box, Object.assign({ sx: { display: 'flex', alignItems: 'center', pr: 1, pointerEvents: 'none' } }, { children: _jsx("img", { src: blackRightArrowIcon, alt: "arrow", style: { height: 12 } }) })))] })), hasNestedSubmenu && (_jsx(Popper, Object.assign({ open: hoveredNestedColumn === column.name, anchorEl: nestedSubmenuAnchorEl, placement: "right-start", sx: { zIndex: 10000 } }, { children: _jsxs(Box, Object.assign({ onMouseEnter: cancelNestedClose, onMouseLeave: closeNestedSubmenu, sx: { display: 'flex', pl: 0.5 } }, { children: [_jsx(Box, { sx: { width: 8, height: '100%', position: 'absolute', left: -8, top: 0, bottom: 0 } }), _jsx(SubmenuPaper, { children: (_b = column.menuItems) === null || _b === void 0 ? void 0 : _b.map((subItem, subItemIndex) => {
65
+ }, sx: { flex: 1, display: 'flex', alignItems: 'center' } }, { children: _jsx("span", { children: column.label || column.name }) })), hasNestedSubmenu && (_jsx(Box, Object.assign({ sx: { display: 'flex', alignItems: 'center', pr: 1, pointerEvents: 'none' } }, { children: _jsx("img", { src: blackRightArrowIcon, alt: "arrow", style: { height: 12 } }) })))] })), hasNestedSubmenu && (_jsx(Popper, Object.assign({ open: hoveredNestedColumn === column.name, anchorEl: nestedSubmenuAnchorEl, placement: "right-start", sx: { zIndex: 10000 } }, { children: _jsxs(Box, Object.assign({ onMouseEnter: cancelNestedClose, onMouseLeave: closeNestedSubmenu, sx: { display: 'flex', pl: 0.5 } }, { children: [_jsx(Box, { sx: { width: 8, height: '100%', position: 'absolute', left: -8, top: 0, bottom: 0 } }), _jsx(SubmenuPaper, { children: (_a = column.menuItems) === null || _a === void 0 ? void 0 : _a.map((subItem, subItemIndex) => {
64
66
  var _a, _b;
65
- return (_jsxs(React.Fragment, { children: [_jsx(MenuItem, Object.assign({ isSelected: subItem.selected, isDisabled: isDateColumn(subItem.name), onClick: () => !isDateColumn(subItem.name) && onNestedItemToggle(column.name, subItem.name) }, { children: subItem.label || subItem.name })), subItemIndex < ((_b = (_a = column.menuItems) === null || _a === void 0 ? void 0 : _a.length) !== null && _b !== void 0 ? _b : 0) - 1 && _jsx(Divider, {})] }, subItem.name));
67
+ return (_jsxs(React.Fragment, { children: [_jsx(MenuItem, Object.assign({ isSelected: subItem.selected, onClick: () => onNestedItemToggle(column.name, subItem.name) }, { children: subItem.label || subItem.name })), subItemIndex < ((_b = (_a = column.menuItems) === null || _a === void 0 ? void 0 : _a.length) !== null && _b !== void 0 ? _b : 0) - 1 && _jsx(Divider, {})] }, subItem.name));
66
68
  }) })] })) })))] })), columnIndex < columns.length - 1 && _jsx(Divider, {})] }), column.name));
67
69
  }) })) })] }));
68
70
  };
@@ -7,9 +7,4 @@ export declare const DATE_COLUMN_CONFIG: {
7
7
  readonly name: "date";
8
8
  readonly label: "Date";
9
9
  readonly selected: true;
10
- readonly menuItems: undefined;
11
- readonly order: 1;
12
- readonly pinned: "start";
13
- readonly isDefaultPinned: true;
14
- readonly pinnable: true;
15
10
  };
@@ -7,9 +7,4 @@ export const DATE_COLUMN_CONFIG = {
7
7
  name: 'date',
8
8
  label: 'Date',
9
9
  selected: true,
10
- menuItems: undefined,
11
- order: 1,
12
- pinned: 'start',
13
- isDefaultPinned: true,
14
- pinnable: true,
15
10
  };
@@ -1,6 +1,6 @@
1
1
  import { useState, useEffect, useMemo, useRef } from 'react';
2
2
  import { DATE_COLUMN_CONFIG, TEMPLATE_NAME_MAX_LENGTH } from '../constants';
3
- import { isDateColumn, initializeCreateColumns, initializeCreateColumnsWithCurrentState, toggleColumn, toggleSubItem, toggleAllColumns, areAllColumnsSelected, areSomeColumnsSelected, isValidTemplateName, deepCloneColumns as copyColumns, } from '../utils';
3
+ import { initializeEditingColumns, initializeCreateColumns, initializeCreateColumnsWithCurrentState, toggleColumn, toggleSubItem, toggleAllColumns, areAllColumnsSelected, areSomeColumnsSelected, isValidTemplateName, deepCloneColumns, } from '../utils';
4
4
  import { useSubmenuHover } from './useSubmenuHover';
5
5
  export const useCreateViewDialog = ({ open, availableColumns, defaultColumns, editingView, tableViews = [] }) => {
6
6
  const [templateName, setTemplateName] = useState(() => (editingView === null || editingView === void 0 ? void 0 : editingView.label) || '');
@@ -10,7 +10,7 @@ export const useCreateViewDialog = ({ open, availableColumns, defaultColumns, ed
10
10
  const { hoveredColumn, anchorEl, openSubmenu, closeSubmenu, cancelClose } = useSubmenuHover();
11
11
  const dateColumn = DATE_COLUMN_CONFIG;
12
12
  useEffect(() => {
13
- var _a, _b, _c;
13
+ var _a, _b;
14
14
  if (!open) {
15
15
  previousOpenRef.current = false;
16
16
  return;
@@ -18,21 +18,12 @@ export const useCreateViewDialog = ({ open, availableColumns, defaultColumns, ed
18
18
  const wasClosed = !previousOpenRef.current;
19
19
  if (wasClosed && open) {
20
20
  if (editingView) {
21
- // Use template's submenu as source of truth so selection state is preserved (don't rely on name matching vs availableColumns)
22
- const submenu = ((_a = editingView.submenu) === null || _a === void 0 ? void 0 : _a.length) ? copyColumns(editingView.submenu) : [];
23
- const templateNonDate = submenu.filter((c) => !isDateColumn(c.name));
24
- const templateWithDateFirst = [dateColumn, ...templateNonDate];
25
- const templateNames = new Set(templateWithDateFirst.map((c) => c.name));
26
- const missingFromAvailable = availableColumns
27
- .filter((col) => !isDateColumn(col.name) && !templateNames.has(col.name))
28
- .map((col) => {
29
- var _a;
30
- return (Object.assign(Object.assign({}, col), { selected: false, menuItems: (_a = col.menuItems) === null || _a === void 0 ? void 0 : _a.map((item) => (Object.assign(Object.assign({}, item), { selected: false }))) }));
31
- });
32
- const columnsToSet = [...templateWithDateFirst, ...missingFromAvailable];
21
+ const savedColumns = editingView.submenu && editingView.submenu.length > 0 ? editingView.submenu : defaultColumns;
22
+ const otherColumns = initializeEditingColumns(savedColumns, availableColumns);
23
+ const columnsToSet = [dateColumn, ...otherColumns];
33
24
  setSelectedColumns(columnsToSet);
34
- initialColumnsRef.current = copyColumns(columnsToSet);
35
- const nameToSet = ((_b = editingView.label) === null || _b === void 0 ? void 0 : _b.trim()) || '';
25
+ initialColumnsRef.current = deepCloneColumns(columnsToSet);
26
+ const nameToSet = ((_a = editingView.label) === null || _a === void 0 ? void 0 : _a.trim()) || '';
36
27
  setTemplateName(nameToSet);
37
28
  }
38
29
  else {
@@ -41,15 +32,16 @@ export const useCreateViewDialog = ({ open, availableColumns, defaultColumns, ed
41
32
  : initializeCreateColumns(availableColumns);
42
33
  const columnsToSet = [dateColumn, ...otherColumns];
43
34
  setSelectedColumns(columnsToSet);
44
- initialColumnsRef.current = copyColumns(columnsToSet);
35
+ initialColumnsRef.current = deepCloneColumns(columnsToSet);
45
36
  setTemplateName('');
46
37
  }
47
38
  }
48
39
  else if (open && editingView) {
49
- const nameToSet = ((_c = editingView.label) === null || _c === void 0 ? void 0 : _c.trim()) || '';
40
+ const nameToSet = ((_b = editingView.label) === null || _b === void 0 ? void 0 : _b.trim()) || '';
50
41
  setTemplateName(nameToSet);
51
42
  }
52
43
  previousOpenRef.current = open;
44
+ // eslint-disable-next-line react-hooks/exhaustive-deps -- intentionally depend on editingView fields only to avoid unnecessary resets when object reference changes
53
45
  }, [open, editingView === null || editingView === void 0 ? void 0 : editingView.id, editingView === null || editingView === void 0 ? void 0 : editingView.label, editingView === null || editingView === void 0 ? void 0 : editingView.submenu, availableColumns, defaultColumns, tableViews, dateColumn]);
54
46
  const columnNames = useMemo(() => selectedColumns.map((col) => col.name), [selectedColumns]);
55
47
  const allSelected = useMemo(() => areAllColumnsSelected(selectedColumns), [selectedColumns]);
@@ -72,7 +64,7 @@ export const useCreateViewDialog = ({ open, availableColumns, defaultColumns, ed
72
64
  };
73
65
  const handleResetToDefault = () => {
74
66
  if (initialColumnsRef.current.length > 0) {
75
- setSelectedColumns(copyColumns(initialColumnsRef.current));
67
+ setSelectedColumns(deepCloneColumns(initialColumnsRef.current));
76
68
  }
77
69
  };
78
70
  return {
@@ -1,57 +1,63 @@
1
1
  import { useState, useEffect, useMemo, useCallback } from 'react';
2
2
  import { transformTemplatesToViewMenuItems, deepCloneColumns } from '../utils';
3
3
  export const useViewsManager = ({ tableMode, templates, lang = 'en' }) => {
4
- const viewMenuFromTemplates = useMemo(() => {
5
- var _a, _b;
6
- const { customViews, defaultTemplate, defaultTemplateColumns } = transformTemplatesToViewMenuItems(templates !== null && templates !== void 0 ? templates : [], tableMode, lang);
7
- const templateColumns = (_b = (_a = defaultTemplate === null || defaultTemplate === void 0 ? void 0 : defaultTemplate.submenu) !== null && _a !== void 0 ? _a : defaultTemplateColumns) !== null && _b !== void 0 ? _b : [];
4
+ const parsedTemplates = useMemo(() => {
5
+ if (!templates || templates.length === 0) {
6
+ return {
7
+ customViews: [],
8
+ defaultTemplate: undefined,
9
+ templateDefaultColumns: [],
10
+ allTemplates: [],
11
+ };
12
+ }
13
+ const { customViews, defaultTemplate } = transformTemplatesToViewMenuItems(templates, tableMode, lang);
8
14
  const allTemplates = defaultTemplate ? [defaultTemplate, ...customViews] : customViews;
9
15
  return {
10
16
  customViews,
11
17
  defaultTemplate,
12
- templateDefaultColumns: templateColumns,
18
+ templateDefaultColumns: (defaultTemplate === null || defaultTemplate === void 0 ? void 0 : defaultTemplate.submenu) || [],
13
19
  allTemplates,
14
20
  };
15
21
  }, [templates, tableMode, lang]);
16
22
  const [defaultColumns, setDefaultColumns] = useState([]);
17
23
  const [initializedMode, setInitializedMode] = useState(null);
18
24
  useEffect(() => {
19
- if (initializedMode !== tableMode && viewMenuFromTemplates.templateDefaultColumns.length > 0) {
20
- setDefaultColumns(deepCloneColumns(viewMenuFromTemplates.templateDefaultColumns));
25
+ if (initializedMode !== tableMode && parsedTemplates.templateDefaultColumns.length > 0) {
26
+ setDefaultColumns(deepCloneColumns(parsedTemplates.templateDefaultColumns));
21
27
  setInitializedMode(tableMode);
22
28
  }
23
- }, [tableMode, viewMenuFromTemplates.templateDefaultColumns, initializedMode]);
29
+ }, [tableMode, parsedTemplates.templateDefaultColumns, initializedMode]);
24
30
  const updateDefaultColumns = useCallback((columns) => {
25
31
  setDefaultColumns(deepCloneColumns(columns));
26
32
  }, []);
27
33
  const updatedDefaultTemplate = useMemo(() => {
28
- if (!viewMenuFromTemplates.defaultTemplate) {
29
- return viewMenuFromTemplates.defaultTemplate;
34
+ if (!parsedTemplates.defaultTemplate) {
35
+ return parsedTemplates.defaultTemplate;
30
36
  }
31
- const columnsToUse = initializedMode !== tableMode ? viewMenuFromTemplates.templateDefaultColumns : defaultColumns;
37
+ const columnsToUse = initializedMode !== tableMode ? parsedTemplates.templateDefaultColumns : defaultColumns;
32
38
  if (columnsToUse.length === 0) {
33
- return viewMenuFromTemplates.defaultTemplate;
39
+ return parsedTemplates.defaultTemplate;
34
40
  }
35
- return Object.assign(Object.assign({}, viewMenuFromTemplates.defaultTemplate), { submenu: columnsToUse, columns: columnsToUse.map((col) => col.name) });
36
- }, [viewMenuFromTemplates.defaultTemplate, viewMenuFromTemplates.templateDefaultColumns, defaultColumns, initializedMode, tableMode]);
41
+ return Object.assign(Object.assign({}, parsedTemplates.defaultTemplate), { submenu: columnsToUse, columns: columnsToUse.map((col) => col.name) });
42
+ }, [parsedTemplates.defaultTemplate, parsedTemplates.templateDefaultColumns, defaultColumns, initializedMode, tableMode]);
37
43
  const updatedAllTemplates = useMemo(() => {
38
44
  if (!updatedDefaultTemplate) {
39
- return viewMenuFromTemplates.customViews;
45
+ return parsedTemplates.customViews;
40
46
  }
41
- return [updatedDefaultTemplate, ...viewMenuFromTemplates.customViews];
42
- }, [updatedDefaultTemplate, viewMenuFromTemplates.customViews]);
43
- const currentDefaultColumns = useMemo(() => {
47
+ return [updatedDefaultTemplate, ...parsedTemplates.customViews];
48
+ }, [updatedDefaultTemplate, parsedTemplates.customViews]);
49
+ const effectiveDefaultColumns = useMemo(() => {
44
50
  if (initializedMode !== tableMode && defaultColumns.length === 0) {
45
- return viewMenuFromTemplates.templateDefaultColumns;
51
+ return parsedTemplates.templateDefaultColumns;
46
52
  }
47
- return defaultColumns.length > 0 ? defaultColumns : viewMenuFromTemplates.templateDefaultColumns;
48
- }, [initializedMode, tableMode, defaultColumns, viewMenuFromTemplates.templateDefaultColumns]);
53
+ return defaultColumns.length > 0 ? defaultColumns : parsedTemplates.templateDefaultColumns;
54
+ }, [initializedMode, tableMode, defaultColumns, parsedTemplates.templateDefaultColumns]);
49
55
  return {
50
56
  defaultTemplate: updatedDefaultTemplate,
51
- customViews: viewMenuFromTemplates.customViews,
57
+ customViews: parsedTemplates.customViews,
52
58
  allTemplates: updatedAllTemplates,
53
- defaultColumns: currentDefaultColumns,
54
- baseDefaultColumns: viewMenuFromTemplates.templateDefaultColumns,
59
+ defaultColumns: effectiveDefaultColumns,
60
+ baseDefaultColumns: parsedTemplates.templateDefaultColumns,
55
61
  updateDefaultColumns,
56
62
  };
57
63
  };
@@ -9,7 +9,10 @@ export interface UseViewsMenuProps {
9
9
  name: string;
10
10
  selectedColumns: ColumnViewProps[];
11
11
  layout: LayoutSection;
12
- }) => Promise<void>;
12
+ }) => Promise<{
13
+ templateId: string;
14
+ name: string;
15
+ } | void>;
13
16
  onEditCustomView?: (viewId: string, data: {
14
17
  name: string;
15
18
  selectedColumns: ColumnViewProps[];
@@ -16,10 +16,12 @@ export const useViewsMenu = ({ mode, onViewChange, onCreateCustomView, onEditCus
16
16
  const [selectedViewInfo, setSelectedViewInfo] = useState({ id: 'default', label: 'Default' });
17
17
  const [shouldUseCurrentState, setShouldUseCurrentState] = useState(false);
18
18
  const [selectedView, setSelectedView] = useState(undefined);
19
+ /** Template id of the currently selected view (custom view). Used to re-select after templates refetch. */
20
+ const [selectedTemplateId, setSelectedTemplateId] = useState(null);
21
+ /** After create, we may receive templateId from parent; once allTemplates includes it, select that view. */
22
+ const [pendingSelectedTemplateId, setPendingSelectedTemplateId] = useState(null);
19
23
  const [currentViewColumns, setCurrentViewColumns] = useState([]);
20
24
  const hasInitializedRef = useRef(false);
21
- const pendingSelectAfterCreateRef = useRef(false);
22
- const allTemplatesLengthRef = useRef(allTemplates.length);
23
25
  const getViewForParent = useCallback((view) => {
24
26
  var _a;
25
27
  const selectedColumns = ((_a = view.submenu) === null || _a === void 0 ? void 0 : _a.filter((col) => col.selected)) || [];
@@ -70,6 +72,7 @@ export const useViewsMenu = ({ mode, onViewChange, onCreateCustomView, onEditCus
70
72
  onViewChange === null || onViewChange === void 0 ? void 0 : onViewChange(getViewForParent(newView));
71
73
  }
72
74
  }
75
+ // eslint-disable-next-line react-hooks/exhaustive-deps -- getViewForParent is stable from parent
73
76
  }, [mode, defaultColumns, selectedView, allTemplates, onViewChange]);
74
77
  useEffect(() => {
75
78
  if (!hasInitializedRef.current)
@@ -96,25 +99,28 @@ export const useViewsMenu = ({ mode, onViewChange, onCreateCustomView, onEditCus
96
99
  const fullView = Object.assign(Object.assign({}, updatedTemplate), { submenu: deepCloneColumns(updatedTemplate.submenu || []) });
97
100
  setSelectedView(fullView);
98
101
  setCurrentViewColumns(deepCloneColumns(updatedTemplate.submenu || []));
102
+ setSelectedTemplateId(updatedTemplate.templateId || updatedTemplate.id);
99
103
  const viewForParent = getViewForParent(fullView);
100
104
  onViewChange === null || onViewChange === void 0 ? void 0 : onViewChange(viewForParent);
101
105
  }
106
+ // eslint-disable-next-line react-hooks/exhaustive-deps -- getViewForParent is stable from parent
102
107
  }, [allTemplates, selectedView, onViewChange]);
108
+ // After create: when allTemplates includes the new template (parent refetched), select it
103
109
  useEffect(() => {
104
- const prevLength = allTemplatesLengthRef.current;
105
- allTemplatesLengthRef.current = allTemplates.length;
106
- if (!pendingSelectAfterCreateRef.current || allTemplates.length === 0 || allTemplates.length <= prevLength)
110
+ var _a;
111
+ if (!pendingSelectedTemplateId || allTemplates.length === 0)
107
112
  return;
108
- const customViews = allTemplates.filter((t) => t.isCustom);
109
- if (customViews.length === 0)
113
+ const newTemplate = allTemplates.find((t) => (t.templateId || t.id) === pendingSelectedTemplateId);
114
+ if (!((_a = newTemplate === null || newTemplate === void 0 ? void 0 : newTemplate.submenu) === null || _a === void 0 ? void 0 : _a.length))
110
115
  return;
111
- const newView = customViews[customViews.length - 1];
112
- setSelectedView(newView);
113
- setCurrentViewColumns(deepCloneColumns(newView.submenu || []));
114
- setSelectedViewInfo({ id: newView.id, label: newView.label });
115
- onViewChange === null || onViewChange === void 0 ? void 0 : onViewChange(getViewForParent(newView));
116
- pendingSelectAfterCreateRef.current = false;
117
- }, [allTemplates, onViewChange, getViewForParent]);
116
+ const fullView = Object.assign(Object.assign({}, newTemplate), { submenu: deepCloneColumns(newTemplate.submenu) });
117
+ setSelectedView(fullView);
118
+ setSelectedViewInfo({ id: fullView.id, label: fullView.label });
119
+ setCurrentViewColumns(deepCloneColumns(newTemplate.submenu));
120
+ setSelectedTemplateId(pendingSelectedTemplateId);
121
+ setPendingSelectedTemplateId(null);
122
+ onViewChange === null || onViewChange === void 0 ? void 0 : onViewChange(getViewForParent(fullView));
123
+ }, [allTemplates, pendingSelectedTemplateId, onViewChange, getViewForParent]);
118
124
  const handleViewButtonClick = useCallback((event) => {
119
125
  setAnchorEl((current) => (current ? null : event.currentTarget));
120
126
  }, []);
@@ -126,6 +132,11 @@ export const useViewsMenu = ({ mode, onViewChange, onCreateCustomView, onEditCus
126
132
  const newSelectedView = viewMenuItem || undefined;
127
133
  setSelectedView(newSelectedView);
128
134
  setCurrentViewColumns(deepCloneColumns((newSelectedView === null || newSelectedView === void 0 ? void 0 : newSelectedView.submenu) || []));
135
+ const templateId = (newSelectedView === null || newSelectedView === void 0 ? void 0 : newSelectedView.isCustom)
136
+ ? newSelectedView.templateId || newSelectedView.id
137
+ : null;
138
+ setSelectedTemplateId(templateId);
139
+ setPendingSelectedTemplateId(null);
129
140
  onViewChange === null || onViewChange === void 0 ? void 0 : onViewChange(newSelectedView ? getViewForParent(newSelectedView) : undefined);
130
141
  handleCloseViewDropdown();
131
142
  }, [handleCloseViewDropdown, onViewChange, getViewForParent]);
@@ -158,13 +169,17 @@ export const useViewsMenu = ({ mode, onViewChange, onCreateCustomView, onEditCus
158
169
  yield (onEditCustomView === null || onEditCustomView === void 0 ? void 0 : onEditCustomView(templateId, data));
159
170
  const updatedView = Object.assign(Object.assign({}, editingView), { label: data.name, submenu: deepCloneColumns(data.selectedColumns), columns: data.selectedColumns.map((c) => c.name) });
160
171
  setSelectedView(updatedView);
161
- setCurrentViewColumns(deepCloneColumns(data.selectedColumns));
162
172
  setSelectedViewInfo({ id: updatedView.id, label: updatedView.label });
173
+ setCurrentViewColumns(deepCloneColumns(data.selectedColumns));
174
+ setSelectedTemplateId(templateId);
175
+ setPendingSelectedTemplateId(null);
163
176
  onViewChange === null || onViewChange === void 0 ? void 0 : onViewChange(getViewForParent(updatedView));
164
177
  }
165
178
  else {
166
- yield (onCreateCustomView === null || onCreateCustomView === void 0 ? void 0 : onCreateCustomView(data));
167
- pendingSelectAfterCreateRef.current = true;
179
+ const created = yield (onCreateCustomView === null || onCreateCustomView === void 0 ? void 0 : onCreateCustomView(data));
180
+ if (created === null || created === void 0 ? void 0 : created.templateId) {
181
+ setPendingSelectedTemplateId(created.templateId);
182
+ }
168
183
  }
169
184
  }), [editingView, onEditCustomView, onCreateCustomView, onViewChange, getViewForParent]);
170
185
  const handleDeleteView = useCallback((viewId) => __awaiter(void 0, void 0, void 0, function* () {
@@ -173,7 +188,10 @@ export const useViewsMenu = ({ mode, onViewChange, onCreateCustomView, onEditCus
173
188
  yield (onDeleteCustomView === null || onDeleteCustomView === void 0 ? void 0 : onDeleteCustomView(templateId));
174
189
  if ((selectedView === null || selectedView === void 0 ? void 0 : selectedView.id) === viewId || (selectedView === null || selectedView === void 0 ? void 0 : selectedView.templateId) === viewId) {
175
190
  setSelectedView(defaultTemplate);
191
+ setSelectedViewInfo(defaultTemplate ? { id: defaultTemplate.id, label: defaultTemplate.label } : { id: 'default', label: 'Default' });
176
192
  setCurrentViewColumns(deepCloneColumns(defaultColumns));
193
+ setSelectedTemplateId(null);
194
+ setPendingSelectedTemplateId(null);
177
195
  if (defaultTemplate) {
178
196
  onViewChange === null || onViewChange === void 0 ? void 0 : onViewChange(getViewForParent(defaultTemplate));
179
197
  }
@@ -5,7 +5,7 @@ export { default as CustomViews } from './CustomViews';
5
5
  export { default as ViewsMenu } from './ViewsMenu';
6
6
  export { default as ViewsDropdown } from './ViewsDropdown';
7
7
  export { default as CreateViewDialog } from './CreateViewDialog';
8
- export type { ViewMenuItem, CreateCustomViewDialogProps, LayoutSection, ColumnItem, FieldItem, Template, CreateTemplatePayload, UpdateTemplatePayload, } from './types';
8
+ export type { ViewMenuItem, CreateCustomViewDialogProps, CreateOrEditViewPayload, ColumnChange, LayoutSection, ColumnItem, FieldItem, Template, CreateTemplatePayload, UpdateTemplatePayload, } from './types';
9
9
  export { transformLayoutToColumns, getColumnsByMode, createCustomViewMenuItem, setViewAsDefault, transformTemplatesToViewMenuItems, convertColumnsToLayoutSection, isDateColumn, getColumnCheckState, } from './utils';
10
10
  export { useSubmenuHover, useViewsManager, useViewsMenu } from './hooks';
11
11
  export { DIALOG_WIDTH, DIALOG_HEIGHT, MAX_CUSTOM_VIEWS, TEMPLATE_NAME_MAX_LENGTH } from './constants';
@@ -211,7 +211,7 @@ export const SubmenuPaper = styled(Paper)(() => ({
211
211
  boxShadow: '0 4px 12px rgba(0,0,0,0.15)',
212
212
  borderRadius: '8px',
213
213
  }));
214
- export const SubmenuItem = styled(Box)(({ theme }) => ({
214
+ export const SubmenuItem = styled(Box)(() => ({
215
215
  display: 'flex',
216
216
  alignItems: 'center',
217
217
  padding: '8px 12px',
@@ -77,6 +77,18 @@ export interface TemplatesList {
77
77
  has_more: boolean;
78
78
  templates: Template[];
79
79
  }
80
+ /** Payload for create or edit view (name, selected columns, and layout section) */
81
+ export interface CreateOrEditViewPayload {
82
+ name: string;
83
+ selectedColumns: ColumnViewProps[];
84
+ layout: LayoutSection;
85
+ }
86
+ /** Represents a column or sub-item selection change (e.g. for diffing) */
87
+ export interface ColumnChange {
88
+ columnName: string;
89
+ selected: boolean;
90
+ subItemName?: string;
91
+ }
80
92
  export interface CreateCustomViewDialogProps {
81
93
  open: boolean;
82
94
  onClose: () => void;
@@ -107,12 +119,11 @@ export interface ViewsMenuProps {
107
119
  name: string;
108
120
  selectedColumns: ColumnViewProps[];
109
121
  layout: LayoutSection;
110
- }) => Promise<void>;
111
- onEditCustomView?: (viewId: string, data: {
122
+ }) => Promise<{
123
+ templateId: string;
112
124
  name: string;
113
- selectedColumns: ColumnViewProps[];
114
- layout: LayoutSection;
115
- }) => Promise<void>;
125
+ } | void>;
126
+ onEditCustomView?: (viewId: string, data: CreateOrEditViewPayload) => Promise<void>;
116
127
  onDeleteCustomView?: (viewId: string) => Promise<void>;
117
128
  tableMode?: TableMode;
118
129
  templates: Template[];
@@ -43,7 +43,8 @@ export declare const transformTemplatesToViewMenuItems: (templates: Array<{
43
43
  */
44
44
  export declare const convertColumnsToLayoutSection: (columns: ColumnViewProps[], mode: TableMode, lang?: string) => LayoutSection;
45
45
  /**
46
- * Initialize columns for editing mode
46
+ * Initialize columns for editing mode.
47
+ * Preserves the order from editingColumns (saved view), then appends any columns from availableColumns not in the saved view.
47
48
  */
48
49
  export declare const initializeEditingColumns: (editingColumns: ColumnViewProps[], availableColumns: ColumnViewProps[]) => ColumnViewProps[];
49
50
  /**
@@ -51,7 +52,8 @@ export declare const initializeEditingColumns: (editingColumns: ColumnViewProps[
51
52
  */
52
53
  export declare const initializeCreateColumns: (availableColumns: ColumnViewProps[]) => ColumnViewProps[];
53
54
  /**
54
- * Initialize columns for create mode with current tableViews state (preserves checked/unchecked values)
55
+ * Initialize columns for create mode with current tableViews state (preserves checked/unchecked values).
56
+ * Preserves the order from currentTableViews (current table columns), then appends any columns from availableColumns not in the table.
55
57
  */
56
58
  export declare const initializeCreateColumnsWithCurrentState: (availableColumns: ColumnViewProps[], currentTableViews: ColumnViewProps[]) => ColumnViewProps[];
57
59
  /**
@@ -110,7 +110,6 @@ export const transformTemplatesToViewMenuItems = (templates, mode = 'sheet', lan
110
110
  const section = template.layout.find((s) => s.code.toLowerCase() === sectionCode);
111
111
  const columns = section ? transformLayoutToColumns([section], lang) : [];
112
112
  // Handle id as either string or object
113
- const templateIdString = typeof template.id === 'string' ? template.id : template.templateId;
114
113
  const viewId = typeof template.id === 'string' ? template.id : template.templateId;
115
114
  // Always include date column at the beginning
116
115
  const dateColumn = DATE_COLUMN_CONFIG;
@@ -184,16 +183,31 @@ export const convertColumnsToLayoutSection = (columns, mode, lang = 'en') => {
184
183
  };
185
184
  };
186
185
  /**
187
- * Initialize columns for editing mode
186
+ * Initialize columns for editing mode.
187
+ * Preserves the order from editingColumns (saved view), then appends any columns from availableColumns not in the saved view.
188
188
  */
189
189
  export const initializeEditingColumns = (editingColumns, availableColumns) => {
190
- return availableColumns
191
- .filter((col) => !isDateColumn(col.name))
192
- .map((col) => {
193
- var _a;
194
- const savedCol = editingColumns.find((ec) => ec.name === col.name);
195
- return (savedCol || Object.assign(Object.assign({}, col), { selected: false, menuItems: (_a = col.menuItems) === null || _a === void 0 ? void 0 : _a.map((item) => (Object.assign(Object.assign({}, item), { selected: false }))) }));
196
- });
190
+ var _a, _b;
191
+ const editingOrder = editingColumns.filter((col) => !isDateColumn(col.name)).map((col) => col.name);
192
+ const availableByName = new Map(availableColumns.filter((c) => !isDateColumn(c.name)).map((c) => [c.name, c]));
193
+ const result = [];
194
+ for (const name of editingOrder) {
195
+ const savedCol = editingColumns.find((ec) => ec.name === name);
196
+ const availCol = availableByName.get(name);
197
+ if (availCol) {
198
+ result.push(savedCol !== null && savedCol !== void 0 ? savedCol : Object.assign(Object.assign({}, availCol), { selected: false, menuItems: (_a = availCol.menuItems) === null || _a === void 0 ? void 0 : _a.map((item) => (Object.assign(Object.assign({}, item), { selected: false }))) }));
199
+ }
200
+ else if (savedCol) {
201
+ result.push(savedCol);
202
+ }
203
+ }
204
+ for (const [, availCol] of availableByName) {
205
+ if (!editingOrder.includes(availCol.name)) {
206
+ const savedCol = editingColumns.find((ec) => ec.name === availCol.name);
207
+ result.push(savedCol !== null && savedCol !== void 0 ? savedCol : Object.assign(Object.assign({}, availCol), { selected: false, menuItems: (_b = availCol.menuItems) === null || _b === void 0 ? void 0 : _b.map((item) => (Object.assign(Object.assign({}, item), { selected: false }))) }));
208
+ }
209
+ }
210
+ return result;
197
211
  };
198
212
  /**
199
213
  * Initialize columns for create mode (all unchecked except date)
@@ -207,23 +221,34 @@ export const initializeCreateColumns = (availableColumns) => {
207
221
  });
208
222
  };
209
223
  /**
210
- * Initialize columns for create mode with current tableViews state (preserves checked/unchecked values)
224
+ * Initialize columns for create mode with current tableViews state (preserves checked/unchecked values).
225
+ * Preserves the order from currentTableViews (current table columns), then appends any columns from availableColumns not in the table.
211
226
  */
212
227
  export const initializeCreateColumnsWithCurrentState = (availableColumns, currentTableViews) => {
213
- return availableColumns
214
- .filter((col) => !isDateColumn(col.name))
215
- .map((col) => {
216
- var _a, _b, _c;
217
- const currentCol = currentTableViews.find((tc) => tc.name === col.name);
218
- if (currentCol) {
219
- return Object.assign(Object.assign({}, col), { selected: (_a = currentCol.selected) !== null && _a !== void 0 ? _a : false, menuItems: (_b = col.menuItems) === null || _b === void 0 ? void 0 : _b.map((item) => {
228
+ var _a, _b, _c, _d;
229
+ const availableByName = new Map(availableColumns.filter((c) => !isDateColumn(c.name)).map((c) => [c.name, c]));
230
+ const currentOrder = currentTableViews.filter((c) => !isDateColumn(c.name)).map((c) => c.name);
231
+ const result = [];
232
+ for (const name of currentOrder) {
233
+ const currentCol = currentTableViews.find((tc) => tc.name === name);
234
+ const availCol = availableByName.get(name);
235
+ if (availCol && currentCol) {
236
+ result.push(Object.assign(Object.assign({}, availCol), { selected: (_a = currentCol.selected) !== null && _a !== void 0 ? _a : false, menuItems: (_b = availCol.menuItems) === null || _b === void 0 ? void 0 : _b.map((item) => {
220
237
  var _a, _b;
221
238
  const currentMenuItem = (_a = currentCol.menuItems) === null || _a === void 0 ? void 0 : _a.find((mi) => mi.name === item.name);
222
239
  return Object.assign(Object.assign({}, item), { selected: (_b = currentMenuItem === null || currentMenuItem === void 0 ? void 0 : currentMenuItem.selected) !== null && _b !== void 0 ? _b : false });
223
- }) });
240
+ }) }));
224
241
  }
225
- return Object.assign(Object.assign({}, col), { selected: false, menuItems: (_c = col.menuItems) === null || _c === void 0 ? void 0 : _c.map((item) => (Object.assign(Object.assign({}, item), { selected: false }))) });
226
- });
242
+ else if (availCol) {
243
+ result.push(Object.assign(Object.assign({}, availCol), { selected: false, menuItems: (_c = availCol.menuItems) === null || _c === void 0 ? void 0 : _c.map((item) => (Object.assign(Object.assign({}, item), { selected: false }))) }));
244
+ }
245
+ }
246
+ for (const [, availCol] of availableByName) {
247
+ if (!currentOrder.includes(availCol.name)) {
248
+ result.push(Object.assign(Object.assign({}, availCol), { selected: false, menuItems: (_d = availCol.menuItems) === null || _d === void 0 ? void 0 : _d.map((item) => (Object.assign(Object.assign({}, item), { selected: false }))) }));
249
+ }
250
+ }
251
+ return result;
227
252
  };
228
253
  /**
229
254
  * Reset columns to their default selection state
@@ -353,22 +378,24 @@ export const getSubmenuItems = (item, defaultColumns) => {
353
378
  else {
354
379
  columns = item.submenu || [];
355
380
  }
356
- // Always include date column at the beginning if it's not already present (date column submenu disabled)
381
+ // Always include date column at the beginning if it's not already present
357
382
  const hasDateColumn = columns.some((col) => col.name.toLowerCase() === 'date');
358
383
  if (!hasDateColumn) {
359
- const dateColumn = Object.assign({}, DATE_COLUMN_CONFIG);
384
+ const dateColumn = {
385
+ name: 'date',
386
+ label: 'Date',
387
+ selected: true,
388
+ };
360
389
  return [dateColumn, ...columns];
361
390
  }
362
- // Ensure date column is first and strip submenu from date (date column submenu disabled); always apply date pin/order config
391
+ // Ensure date column is first
363
392
  const dateColumnIndex = columns.findIndex((col) => col.name.toLowerCase() === 'date');
364
393
  if (dateColumnIndex > 0) {
365
- const dateCol = columns[dateColumnIndex];
366
- const dateColumn = Object.assign(Object.assign(Object.assign({}, DATE_COLUMN_CONFIG), dateCol), { menuItems: undefined });
394
+ const dateColumn = columns[dateColumnIndex];
367
395
  const otherColumns = columns.filter((col) => col.name.toLowerCase() !== 'date');
368
396
  return [dateColumn, ...otherColumns];
369
397
  }
370
- return columns.map((col) => col.name.toLowerCase() === 'date'
371
- ? Object.assign(Object.assign(Object.assign({}, DATE_COLUMN_CONFIG), col), { menuItems: undefined }) : col);
398
+ return columns;
372
399
  };
373
400
  /**
374
401
  * Check if a view menu item has submenu
@@ -6,4 +6,4 @@ export { default as FiltersRowWrapper } from './FiltersRowWrapper';
6
6
  export { default as FiltersRow } from './FiltersRow';
7
7
  export * from './style';
8
8
  export * from './type';
9
- export type { Template, LayoutSection, ViewMenuItem } from './TableView/types';
9
+ export type { Template, LayoutSection, ViewMenuItem, ColumnChange, CreateOrEditViewPayload } from './TableView/types';
@@ -49,7 +49,10 @@ export interface TableHeaderProps<IStatus extends TableHeaderStatus | TableHeade
49
49
  name: string;
50
50
  selectedColumns: ColumnViewProps[];
51
51
  layout: LayoutSection;
52
- }) => Promise<void>;
52
+ }) => Promise<{
53
+ templateId: string;
54
+ name: string;
55
+ } | void>;
53
56
  onEditCustomView?: (viewId: string, data: {
54
57
  name: string;
55
58
  selectedColumns: ColumnViewProps[];
@@ -1,5 +1,5 @@
1
1
  /// <reference types="react" />
2
2
  import { ISheetViewVirtualTable } from './types';
3
- declare function SheetViewVirtualTable({ columns: inputColumns, rows, threshold, showHeader, headerProps, rowProps, footerProps, rowHeight, isLoading, error, columnsSorting, onColumnSort, loadMoreItems, isFetchingNextPage, triggerDataRefetch, scrollToIndex, areAllRowsLoaded, tableBodyStyles, tableTitle, onStartDrag, onColumnPin, clearBackdropVisibilityTimeout, isPinnable, tableMode, overscanCount, windowId, serviceCode, customNoDataComponent, defaultSkeleton, }: Readonly<ISheetViewVirtualTable>): import("react/jsx-runtime").JSX.Element;
3
+ declare function SheetViewVirtualTable({ columns, rows, threshold, showHeader, headerProps, rowProps, footerProps, rowHeight, isLoading, error, columnsSorting, onColumnSort, loadMoreItems, isFetchingNextPage, triggerDataRefetch, scrollToIndex, areAllRowsLoaded, tableBodyStyles, tableTitle, onStartDrag, onColumnPin, clearBackdropVisibilityTimeout, isPinnable, tableMode, overscanCount, windowId, serviceCode, customNoDataComponent, }: Readonly<ISheetViewVirtualTable>): import("react/jsx-runtime").JSX.Element;
4
4
  declare const _default: import("react").MemoExoticComponent<typeof SheetViewVirtualTable>;
5
5
  export default _default;
@@ -1,7 +1,6 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
2
  import { memo, useCallback, useMemo, useRef, useEffect } from 'react';
3
3
  import { SHEET_VIEW_TABLE_THRESHOLD } from '../../../constants/index.js';
4
- import { getProcessedColumns } from '../../../utils/index.js';
5
4
  import TableFooter from '../components/TableFooter/TableFooter';
6
5
  import { SheetViewTableContainer } from '../components/style';
7
6
  import { SheetViewVirtualTableWrapper } from './style';
@@ -9,9 +8,7 @@ import { usePinnedColumns, useSynchronizedScroll, useTableState, useTableData, u
9
8
  import { useColumnResize, useColumnResizeWithPinned, applyColumnWidths } from './features/resize';
10
9
  import { ResizeOverlay } from './features/resize/components';
11
10
  import { PinnedColumn, MainTable, LoadingMainTable, NoDataView, VirtualTable } from './components';
12
- function SheetViewVirtualTable({ columns: inputColumns, rows, threshold = SHEET_VIEW_TABLE_THRESHOLD, showHeader, headerProps, rowProps, footerProps, rowHeight = 28, isLoading, error, columnsSorting, onColumnSort, loadMoreItems, isFetchingNextPage, triggerDataRefetch, scrollToIndex, areAllRowsLoaded = false, tableBodyStyles, tableTitle, onStartDrag, onColumnPin, clearBackdropVisibilityTimeout = 100, isPinnable = false, tableMode, overscanCount, windowId, serviceCode, customNoDataComponent, defaultSkeleton = false, }) {
13
- // Use skeleton columns when loading and defaultSkeleton is true (same behavior as VirtualTable)
14
- const columns = useMemo(() => getProcessedColumns(inputColumns, isLoading !== null && isLoading !== void 0 ? isLoading : false, defaultSkeleton), [inputColumns, isLoading, defaultSkeleton]);
11
+ 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, onStartDrag, onColumnPin, clearBackdropVisibilityTimeout = 100, isPinnable = false, tableMode, overscanCount, windowId, serviceCode, customNoDataComponent, }) {
15
12
  // Custom hooks for state management
16
13
  const { selectedCell, selectedColumn, selectedRow, showBackDrop, setShowBackdrop, handleCellClick, handleColumnClick, handleChipClick, selectedChip, } = useTableState();
17
14
  // Refs and state for resize indicator positioning
@@ -1,5 +1,5 @@
1
1
  /// <reference types="react" />
2
2
  import type { IVirtualTable } from '../../../types/index.js';
3
- declare function VirtualTable({ columns: inputColumns, rows, threshold, showHeader, headerProps, rowProps, footerProps, isLoading, error, columnsSorting, onColumnSort, loadMoreItems, isFetchingNextPage, triggerDataRefetch, scrollToIndex, areAllRowsLoaded, tableBodyStyles, tableMode, tableTitle, onStartDrag, isSheetView, isMinimized, footerComponent, customNoDataComponent, defaultSkeleton, }: Readonly<IVirtualTable>): import("react/jsx-runtime").JSX.Element;
3
+ declare function VirtualTable({ columns, rows, threshold, showHeader, headerProps, rowProps, footerProps, isLoading, error, columnsSorting, onColumnSort, loadMoreItems, isFetchingNextPage, triggerDataRefetch, scrollToIndex, areAllRowsLoaded, tableBodyStyles, tableMode, tableTitle, onStartDrag, isSheetView, isMinimized, footerComponent, customNoDataComponent, defaultSkeleton, }: Readonly<IVirtualTable>): import("react/jsx-runtime").JSX.Element;
4
4
  declare const _default: import("react").MemoExoticComponent<typeof VirtualTable>;
5
5
  export default _default;
@@ -34,7 +34,7 @@ const createItemData = memoize((columns, isLoading, rows, rowProps, scrollToInde
34
34
  areAllRowsLoaded,
35
35
  isSheetView,
36
36
  }));
37
- function VirtualTable({ columns: inputColumns, rows, threshold = TABLE_THRESHOLD, showHeader, headerProps, rowProps, footerProps, isLoading, error, columnsSorting, onColumnSort, loadMoreItems, isFetchingNextPage, triggerDataRefetch, scrollToIndex, areAllRowsLoaded = false, tableBodyStyles, tableMode, tableTitle, onStartDrag, isSheetView = false, isMinimized, footerComponent, customNoDataComponent, defaultSkeleton = false, }) {
37
+ function VirtualTable({ columns, rows, threshold = TABLE_THRESHOLD, showHeader, headerProps, rowProps, footerProps, isLoading, error, columnsSorting, onColumnSort, loadMoreItems, isFetchingNextPage, triggerDataRefetch, scrollToIndex, areAllRowsLoaded = false, tableBodyStyles, tableMode, tableTitle, onStartDrag, isSheetView = false, isMinimized, footerComponent, customNoDataComponent, defaultSkeleton = false, }) {
38
38
  var _a;
39
39
  const theme = useTheme();
40
40
  const onPointerDown = (e) => {
@@ -58,8 +58,8 @@ function VirtualTable({ columns: inputColumns, rows, threshold = TABLE_THRESHOLD
58
58
  const tableEmpty = !isLoading && rows.length === 0;
59
59
  const hasTimeoutError = isTimeoutError(error);
60
60
  const lastItemIndex = rows.length - 1;
61
- const columns = useMemo(() => getProcessedColumns(inputColumns, isLoading !== null && isLoading !== void 0 ? isLoading : false, defaultSkeleton), [inputColumns, isLoading, defaultSkeleton]);
62
- const shownColumns = useMemo(() => columns.filter((column) => !column.hidden), [columns]);
61
+ const processedColumns = useMemo(() => getProcessedColumns(columns, isLoading !== null && isLoading !== void 0 ? isLoading : false, defaultSkeleton), [columns, isLoading, defaultSkeleton]);
62
+ const shownColumns = useMemo(() => processedColumns.filter((column) => !column.hidden), [processedColumns]);
63
63
  const orderedColumns = useMemo(() => shownColumns.sort((a, b) => { var _a, _b; return ((_a = a === null || a === void 0 ? void 0 : a.order) !== null && _a !== void 0 ? _a : 1000000) - ((_b = b === null || b === void 0 ? void 0 : b.order) !== null && _b !== void 0 ? _b : 1000000); }), [shownColumns]);
64
64
  const areTotalRowsNotFillingHeight = isHeightNotFullyFilledByRows(rows.length) && !tableLoading;
65
65
  const itemsCount = isDelayedFetchingNextPage || (areAllRowsLoaded && !areTotalRowsNotFillingHeight) ? rows.length + 1 : rows.length;
@@ -40,12 +40,4 @@ export interface ColumnViewProps {
40
40
  disabled?: boolean;
41
41
  sx?: SxProps<Theme>;
42
42
  menuSx?: SxProps<Theme>;
43
- /** Table column order (date column should always be 1) */
44
- order?: number;
45
- /** Pinned position (date column should always be 'start') */
46
- pinned?: 'start' | 'end';
47
- /** Whether column is pinned by default (date column should always be true) */
48
- isDefaultPinned?: boolean;
49
- /** Whether column can be pinned (date column should always be true) */
50
- pinnable?: boolean;
51
43
  }
@@ -1,8 +1,4 @@
1
1
  import type { IColumnProps } from '../types/index.js';
2
2
  export declare const DEFAULT_SKELETON_WIDTHS: string[];
3
3
  export declare const generateSkeletonColumns: (staticWidths?: string[]) => IColumnProps[];
4
- /**
5
- * Returns columns to display: when loading and defaultSkeleton is true, returns skeleton columns
6
- * (with date column first so it shows skeleton); otherwise returns the given columns.
7
- */
8
4
  export declare const getProcessedColumns: <T = unknown>(columns: readonly IColumnProps<T>[], isLoading: boolean, defaultSkeleton: boolean) => IColumnProps<T>[];
@@ -1,16 +1,4 @@
1
1
  export const DEFAULT_SKELETON_WIDTHS = ['120px', '180px', '100px', '150px', '200px', '140px', '160px', '110px', '190px', '130px'];
2
- /** Date column config for skeleton so the date column shows skeleton like other columns */
3
- const SKELETON_DATE_COLUMN = {
4
- id: 'date',
5
- header: '',
6
- width: DEFAULT_SKELETON_WIDTHS[0],
7
- order: 1,
8
- pinned: 'start',
9
- isDefaultPinned: true,
10
- pinnable: true,
11
- hidden: false,
12
- sortable: false,
13
- };
14
2
  export const generateSkeletonColumns = (staticWidths = DEFAULT_SKELETON_WIDTHS) => {
15
3
  return staticWidths.map((width, index) => ({
16
4
  id: `skeleton-col-${index}`,
@@ -21,14 +9,9 @@ export const generateSkeletonColumns = (staticWidths = DEFAULT_SKELETON_WIDTHS)
21
9
  sortable: false,
22
10
  }));
23
11
  };
24
- /**
25
- * Returns columns to display: when loading and defaultSkeleton is true, returns skeleton columns
26
- * (with date column first so it shows skeleton); otherwise returns the given columns.
27
- */
28
12
  export const getProcessedColumns = (columns, isLoading, defaultSkeleton) => {
29
13
  if (defaultSkeleton && isLoading) {
30
- const restSkeleton = generateSkeletonColumns(DEFAULT_SKELETON_WIDTHS.slice(1)).map((col, i) => (Object.assign(Object.assign({}, col), { order: i + 2 })));
31
- return [SKELETON_DATE_COLUMN, ...restSkeleton];
14
+ return generateSkeletonColumns();
32
15
  }
33
16
  return [...columns];
34
17
  };
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.373-test.3-test.4-test.5-test.6",
5
- "testVersion": 6,
4
+ "version": "0.1.373-test.3-test.4-test.5-test.6-test.7-test.8",
5
+ "testVersion": 8,
6
6
  "type": "module",
7
7
  "main": "build/index.js",
8
8
  "module": "build/index.js",