@tap-payments/os-micro-frontend-shared 0.1.372-test.2-test.3-test.4-test.5-test.6 → 0.1.372-test.2-test.3-test.4-test.5-test.6-test.7

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,3 +1,3 @@
1
1
  import type { CreateCustomViewDialogProps } from './types';
2
- declare function CreateViewDialog({ open, onClose, onCreate, availableColumns, isLoading, defaultColumns, editingView, onDelete, tableViews, mode, }: Readonly<CreateCustomViewDialogProps>): import("react/jsx-runtime").JSX.Element | null;
2
+ declare function CreateViewDialog({ open, onClose, onCreate, availableColumns, defaultColumns, editingView, onDelete, tableViews, mode, }: Readonly<CreateCustomViewDialogProps>): import("react/jsx-runtime").JSX.Element | null;
3
3
  export default CreateViewDialog;
@@ -8,10 +8,12 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
8
8
  });
9
9
  };
10
10
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
11
+ import React, { useState } from 'react';
11
12
  import { Box, Typography, CircularProgress, Dialog } from '@mui/material';
12
13
  import { useTranslation } from 'react-i18next';
13
14
  import Draggable from 'react-draggable';
14
15
  import { InputBase } from '../../index.js';
16
+ import { useToast } from '../../../hooks/index.js';
15
17
  import Toolbar, { StyledHeaderWrapperStyled } from '../../Toolbar';
16
18
  import { CloseIcon } from '../../ToolbarIcon';
17
19
  import { TEMPLATE_NAME_MAX_LENGTH } from './constants';
@@ -20,8 +22,18 @@ import { DIALOG_WIDTH, DIALOG_HEIGHT } from './constants';
20
22
  import { useCreateViewDialog } from './hooks';
21
23
  import { ColumnList } from './components/ColumnList';
22
24
  import { convertColumnsToLayoutSection } from './utils';
23
- function CreateViewDialog({ open, onClose, onCreate, availableColumns = [], isLoading = false, defaultColumns = [], editingView, onDelete, tableViews = [], mode = 'sheet', }) {
25
+ function CreateViewDialog({ open, onClose, onCreate, availableColumns = [], defaultColumns = [], editingView, onDelete, tableViews = [], mode = 'sheet', }) {
24
26
  const { t } = useTranslation();
27
+ const toast = useToast();
28
+ const [isDeleting, setIsDeleting] = useState(false);
29
+ const [isLoading, setIsLoading] = useState(false);
30
+ // Reset loading state when dialog closes
31
+ React.useEffect(() => {
32
+ if (!open) {
33
+ setIsDeleting(false);
34
+ setIsLoading(false);
35
+ }
36
+ }, [open]);
25
37
  const { templateName, setTemplateName, selectedColumns, columnNames, allSelected, someSelected, isNameValid, hoveredColumn, anchorEl, openSubmenu, closeSubmenu, cancelClose, handleReorder, handleColumnToggle, handleSubItemToggle, handleSelectAll, handleResetToDefault, } = useCreateViewDialog({
26
38
  open,
27
39
  availableColumns,
@@ -30,20 +42,40 @@ function CreateViewDialog({ open, onClose, onCreate, availableColumns = [], isLo
30
42
  tableViews,
31
43
  });
32
44
  const handleCreate = () => __awaiter(this, void 0, void 0, function* () {
33
- if (!isNameValid)
45
+ if (!isNameValid || isLoading || isDeleting)
34
46
  return;
35
- const columnsToCreate = selectedColumns.filter((col) => col.selected);
36
- const layout = convertColumnsToLayoutSection(columnsToCreate, mode);
37
- yield (onCreate === null || onCreate === void 0 ? void 0 : onCreate({ name: templateName, selectedColumns: columnsToCreate, layout }));
38
- onClose();
47
+ setIsLoading(true);
48
+ try {
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 }));
52
+ onClose();
53
+ }
54
+ catch (error) {
55
+ const errorMessage = error instanceof Error ? error.message : 'Failed to save view. Please try again.';
56
+ toast.error(errorMessage);
57
+ }
58
+ finally {
59
+ setIsLoading(false);
60
+ }
39
61
  });
40
62
  const handleDelete = () => __awaiter(this, void 0, void 0, function* () {
41
- if (!editingView)
63
+ if (!editingView || isDeleting || isLoading)
42
64
  return;
43
65
  const templateId = editingView.templateId || editingView.id;
44
66
  console.log({ templateId });
45
- yield (onDelete === null || onDelete === void 0 ? void 0 : onDelete(templateId));
46
- onClose();
67
+ setIsDeleting(true);
68
+ try {
69
+ yield (onDelete === null || onDelete === void 0 ? void 0 : onDelete(templateId));
70
+ onClose();
71
+ }
72
+ catch (error) {
73
+ const errorMessage = error instanceof Error ? error.message : 'Failed to delete view. Please try again.';
74
+ toast.error(errorMessage);
75
+ }
76
+ finally {
77
+ setIsDeleting(false);
78
+ }
47
79
  });
48
80
  if (!open)
49
81
  return null;
@@ -55,6 +87,6 @@ function CreateViewDialog({ open, onClose, onCreate, availableColumns = [], isLo
55
87
  transition: 'none',
56
88
  },
57
89
  },
58
- } }, { children: [_jsx(StyledHeaderWrapperStyled, Object.assign({ id: "draggable-dialog-title", style: { cursor: 'move' } }, { children: _jsx(Toolbar, { isHovered: true, title: editingView ? 'Edit Custom View' : t('createCustomView') || 'Create Custom View', leftActions: _jsx(CloseIcon, { onClick: onClose }) }) })), _jsxs(DialogContentWrapper, { children: [_jsxs(ScrollableContent, { children: [_jsxs(TitleSection, { children: [_jsxs(Box, { children: [_jsx(Typography, Object.assign({ sx: { fontSize: 24, fontWeight: 700, color: '#9F9F9F', lineHeight: '0.7' } }, { children: "Custom" })), _jsx(Typography, Object.assign({ sx: { fontSize: 24, fontWeight: 700, color: '#20232B', lineHeight: 1.2 } }, { children: "View" }))] }), editingView && _jsx(DeleteButton, Object.assign({ onClick: handleDelete }, { children: "Delete View" }))] }), _jsx(Box, Object.assign({ sx: { mb: 3 } }, { children: _jsx(InputBase, { name: "templateName", label: "Name", value: templateName, onChange: (value) => setTemplateName(value), hasError: false, inputProps: { maxLength: TEMPLATE_NAME_MAX_LENGTH }, required: true }) })), _jsx(ColumnList, { selectedColumns: selectedColumns, columnNames: columnNames, allSelected: allSelected, someSelected: someSelected, hoveredColumn: hoveredColumn, anchorEl: anchorEl, onReorder: handleReorder, onColumnToggle: handleColumnToggle, onSubItemToggle: handleSubItemToggle, onSelectAll: handleSelectAll, onResetToDefault: handleResetToDefault, onSubmenuEnter: openSubmenu, onSubmenuLeave: closeSubmenu, onCancelClose: cancelClose })] }), _jsx(FooterBar, {}), _jsx(CreateButtonWrapper, { children: _jsx(CreateButton, Object.assign({ variant: "contained", onClick: handleCreate, disabled: !isNameValid || isLoading }, { children: isLoading ? (_jsxs(Box, Object.assign({ sx: { display: 'flex', alignItems: 'center', gap: 1 } }, { children: [_jsx(CircularProgress, { size: 14, color: "inherit" }), _jsx("span", { children: editingView ? 'Saving...' : 'Creating...' })] }))) : editingView ? ('Update View') : ('Create View') })) })] })] })) })));
90
+ } }, { children: [_jsx(StyledHeaderWrapperStyled, Object.assign({ id: "draggable-dialog-title", style: { cursor: 'move' } }, { children: _jsx(Toolbar, { isHovered: true, title: editingView ? 'Edit Custom View' : t('createCustomView') || 'Create Custom View', leftActions: _jsx(CloseIcon, { onClick: onClose }) }) })), _jsxs(DialogContentWrapper, { children: [_jsxs(ScrollableContent, { children: [_jsxs(TitleSection, { children: [_jsxs(Box, { children: [_jsx(Typography, Object.assign({ sx: { fontSize: 24, fontWeight: 700, color: '#9F9F9F', lineHeight: '0.7' } }, { children: "Custom" })), _jsx(Typography, Object.assign({ sx: { fontSize: 24, fontWeight: 700, color: '#20232B', lineHeight: 1.2 } }, { children: "View" }))] }), editingView && (_jsx(DeleteButton, Object.assign({ onClick: handleDelete, disabled: isDeleting }, { children: isDeleting ? (_jsxs(Box, Object.assign({ sx: { display: 'flex', alignItems: 'center', gap: 1 } }, { children: [_jsx(CircularProgress, { size: 14, color: "inherit" }), _jsx("span", { children: "Deleting..." })] }))) : ('Delete View') })))] }), _jsx(Box, Object.assign({ sx: { mb: 3 } }, { children: _jsx(InputBase, { name: "templateName", label: "Name", value: templateName, onChange: (value) => setTemplateName(value), hasError: false, inputProps: { maxLength: TEMPLATE_NAME_MAX_LENGTH }, required: true }) })), _jsx(ColumnList, { selectedColumns: selectedColumns, columnNames: columnNames, allSelected: allSelected, someSelected: someSelected, hoveredColumn: hoveredColumn, anchorEl: anchorEl, onReorder: handleReorder, onColumnToggle: handleColumnToggle, onSubItemToggle: handleSubItemToggle, onSelectAll: handleSelectAll, onResetToDefault: handleResetToDefault, onSubmenuEnter: openSubmenu, onSubmenuLeave: closeSubmenu, onCancelClose: cancelClose })] }), _jsx(FooterBar, {}), _jsx(CreateButtonWrapper, { children: _jsx(CreateButton, Object.assign({ variant: "contained", onClick: handleCreate, disabled: !isNameValid || isLoading || isDeleting, title: !isNameValid ? `Name is required. Current: "${templateName}"` : undefined }, { children: isLoading ? (_jsxs(Box, Object.assign({ sx: { display: 'flex', alignItems: 'center', gap: 1 } }, { children: [_jsx(CircularProgress, { size: 14, color: "inherit" }), _jsx("span", { children: editingView ? 'Saving...' : 'Creating...' })] }))) : editingView ? ('Update View') : ('Create View') })) })] })] })) })));
59
91
  }
60
92
  export default CreateViewDialog;
@@ -186,6 +186,21 @@ function ViewsDropdown({ open, selectedViewInfo, setSelectedViewInfo, onSelect,
186
186
  handleSubmenuLeave();
187
187
  onSelect(e);
188
188
  onCreateCustomView === null || onCreateCustomView === void 0 ? void 0 : onCreateCustomView(false); // Don't use current state for "New Custom View"
189
- } }, { children: [_jsx(Space, {}), _jsxs(Box, Object.assign({ sx: { display: 'flex', alignItems: 'center', gap: 0.5 } }, { children: [_jsx("img", { src: bluePlusIcon, alt: "icon", style: { opacity: shouldDimNewCustomView ? 0.5 : 1, width: 10, height: 10 } }), _jsx("span", Object.assign({ style: { color: shouldDimNewCustomView ? '#999' : '#1F88D0', fontSize: 11, fontWeight: 500 } }, { children: t('New Custom View') }))] })), _jsx(SpaceAfter, {})] })) }))] }) })), hoveredItem && submenuAnchorEl && getHoveredSubmenu().length > 0 && (_jsx(Menu, Object.assign({ open: Boolean(hoveredItem), anchorEl: submenuAnchorEl, placement: "right-start", onMouseEnter: handleSubmenuEnter, onMouseLeave: handleSubmenuLeave }, { children: _jsxs(SubmenuContainer, { children: [_jsx(ViewsSubmenu, { columns: getHoveredSubmenu(), allCurrentSelected: allCurrentSelected, someCurrentSelected: someCurrentSelected, onSelectAll: handleSelectAll, onReset: handleReset, onColumnToggle: toggleColumnSelection, onNestedItemToggle: toggleNestedItem, anchorEl: submenuAnchorEl, isModified: isSubmenuModified }), _jsx(SaveCustomViewBox, { children: _jsx(Tooltip, Object.assign({ title: "Limit reached. Delete a view to create a new one.", placement: "left", disableHoverListener: !shouldDimNewCustomView }, { children: _jsxs(SaveCustomViewInnerBox, Object.assign({ disabled: shouldDimNewCustomView, onClick: shouldDimNewCustomView ? undefined : handleSaveAsCustomView }, { children: [_jsx(Typography, Object.assign({ sx: { fontSize: 11, color: 'text.secondary' } }, { children: "Save as a custom view" })), _jsxs(Box, Object.assign({ sx: { display: 'flex', alignItems: 'center', gap: 0.5 } }, { children: [_jsx("img", { src: bluePlusIcon, alt: "add", style: { width: 10, height: 10, opacity: shouldDimNewCustomView ? 0.5 : 1 } }), _jsx(Typography, Object.assign({ sx: { fontSize: 10, fontWeight: 600, color: shouldDimNewCustomView ? '#999' : '#1F88D0' } }, { children: "Custom View" }))] }))] })) })) }), _jsxs(ButtonsContainer, { children: [_jsx(Button, Object.assign({ variant: "text", onClick: handleCancel, sx: CancelButtonSx }, { children: "Cancel" })), _jsx(Button, Object.assign({ variant: "contained", onClick: handleOkay, sx: OkayButtonSx }, { children: "Okay" }))] })] }) })))] })));
189
+ } }, { children: [_jsx(Space, {}), _jsxs(Box, Object.assign({ sx: { display: 'flex', alignItems: 'center', gap: 0.5 } }, { children: [_jsx("img", { src: bluePlusIcon, alt: "icon", style: { opacity: shouldDimNewCustomView ? 0.5 : 1, width: 10, height: 10 } }), _jsx("span", Object.assign({ style: { color: shouldDimNewCustomView ? '#999' : '#1F88D0', fontSize: 11, fontWeight: 500 } }, { children: t('New Custom View') }))] })), _jsx(SpaceAfter, {})] })) }))] }) })), hoveredItem && submenuAnchorEl && getHoveredSubmenu().length > 0 && (_jsx(Menu, Object.assign({ open: Boolean(hoveredItem), anchorEl: submenuAnchorEl, placement: "auto-end", onMouseEnter: handleSubmenuEnter, onMouseLeave: handleSubmenuLeave, modifiers: [
190
+ {
191
+ name: 'offset',
192
+ options: {
193
+ offset: [-4, 0],
194
+ },
195
+ },
196
+ {
197
+ name: 'preventOverflow',
198
+ enabled: true,
199
+ },
200
+ {
201
+ name: 'flip',
202
+ enabled: true,
203
+ },
204
+ ] }, { children: _jsxs(SubmenuContainer, { children: [_jsx(ViewsSubmenu, { columns: getHoveredSubmenu(), allCurrentSelected: allCurrentSelected, someCurrentSelected: someCurrentSelected, onSelectAll: handleSelectAll, onReset: handleReset, onColumnToggle: toggleColumnSelection, onNestedItemToggle: toggleNestedItem, anchorEl: submenuAnchorEl, isModified: isSubmenuModified }), _jsx(SaveCustomViewBox, { children: _jsx(Tooltip, Object.assign({ title: "Limit reached. Delete a view to create a new one.", placement: "left", disableHoverListener: !shouldDimNewCustomView }, { children: _jsxs(SaveCustomViewInnerBox, Object.assign({ disabled: shouldDimNewCustomView, onClick: shouldDimNewCustomView ? undefined : handleSaveAsCustomView }, { children: [_jsx(Typography, Object.assign({ sx: { fontSize: 11, color: 'text.secondary' } }, { children: "Save as a custom view" })), _jsxs(Box, Object.assign({ sx: { display: 'flex', alignItems: 'center', gap: 0.5 } }, { children: [_jsx("img", { src: bluePlusIcon, alt: "add", style: { width: 10, height: 10, opacity: shouldDimNewCustomView ? 0.5 : 1 } }), _jsx(Typography, Object.assign({ sx: { fontSize: 10, fontWeight: 600, color: shouldDimNewCustomView ? '#999' : '#1F88D0' } }, { children: "Custom View" }))] }))] })) })) }), _jsxs(ButtonsContainer, { children: [_jsx(Button, Object.assign({ variant: "text", onClick: handleCancel, sx: CancelButtonSx }, { children: "Cancel" })), _jsx(Button, Object.assign({ variant: "contained", onClick: handleOkay, sx: OkayButtonSx }, { children: "Okay" }))] })] }) })))] })));
190
205
  }
191
206
  export default React.memo(ViewsDropdown);
@@ -5,6 +5,6 @@ export declare const MAX_CUSTOM_VIEWS = 3;
5
5
  export declare const TEMPLATE_NAME_MAX_LENGTH = 20;
6
6
  export declare const DATE_COLUMN_CONFIG: {
7
7
  readonly name: "date";
8
- readonly label: "Date & Time";
8
+ readonly label: "Date";
9
9
  readonly selected: true;
10
10
  };
@@ -5,6 +5,6 @@ export const MAX_CUSTOM_VIEWS = 3;
5
5
  export const TEMPLATE_NAME_MAX_LENGTH = 20;
6
6
  export const DATE_COLUMN_CONFIG = {
7
7
  name: 'date',
8
- label: 'Date & Time',
8
+ label: 'Date',
9
9
  selected: true,
10
10
  };
@@ -3,12 +3,13 @@ import { DATE_COLUMN_CONFIG, TEMPLATE_NAME_MAX_LENGTH } from '../constants';
3
3
  import { initializeEditingColumns, initializeCreateColumns, initializeCreateColumnsWithCurrentState, resetColumnsToDefault, toggleColumn, toggleSubItem, toggleAllColumns, areAllColumnsSelected, areSomeColumnsSelected, isValidTemplateName, } from '../utils';
4
4
  import { useSubmenuHover } from './useSubmenuHover';
5
5
  export const useCreateViewDialog = ({ open, availableColumns, defaultColumns, editingView, tableViews = [] }) => {
6
- const [templateName, setTemplateName] = useState('');
6
+ const [templateName, setTemplateName] = useState(() => (editingView === null || editingView === void 0 ? void 0 : editingView.label) || '');
7
7
  const [selectedColumns, setSelectedColumns] = useState([]);
8
8
  const previousOpenRef = useRef(false);
9
9
  const { hoveredColumn, anchorEl, openSubmenu, closeSubmenu, cancelClose } = useSubmenuHover();
10
10
  const dateColumn = DATE_COLUMN_CONFIG;
11
11
  useEffect(() => {
12
+ var _a, _b;
12
13
  if (!open) {
13
14
  previousOpenRef.current = false;
14
15
  return;
@@ -16,9 +17,15 @@ export const useCreateViewDialog = ({ open, availableColumns, defaultColumns, ed
16
17
  const wasClosed = !previousOpenRef.current;
17
18
  if (wasClosed && open) {
18
19
  if (editingView) {
19
- const otherColumns = initializeEditingColumns(defaultColumns, availableColumns);
20
+ // Use the saved submenu from editingView if available, otherwise fall back to defaultColumns
21
+ const savedColumns = editingView.submenu && editingView.submenu.length > 0
22
+ ? editingView.submenu
23
+ : defaultColumns;
24
+ const otherColumns = initializeEditingColumns(savedColumns, availableColumns);
20
25
  setSelectedColumns([dateColumn, ...otherColumns]);
21
- setTemplateName(editingView.label);
26
+ // Ensure templateName is set to editingView.label (fallback to empty string if undefined)
27
+ const nameToSet = ((_a = editingView.label) === null || _a === void 0 ? void 0 : _a.trim()) || '';
28
+ setTemplateName(nameToSet);
22
29
  }
23
30
  else {
24
31
  const otherColumns = tableViews && tableViews.length > 0
@@ -28,12 +35,17 @@ export const useCreateViewDialog = ({ open, availableColumns, defaultColumns, ed
28
35
  setTemplateName('');
29
36
  }
30
37
  }
38
+ else if (open && editingView) {
39
+ // Update templateName when editingView changes while dialog is open
40
+ const nameToSet = ((_b = editingView.label) === null || _b === void 0 ? void 0 : _b.trim()) || '';
41
+ setTemplateName(nameToSet);
42
+ }
31
43
  previousOpenRef.current = open;
32
- }, [open, editingView, availableColumns, defaultColumns, tableViews, dateColumn]);
44
+ }, [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]);
33
45
  const columnNames = useMemo(() => selectedColumns.map((col) => col.name), [selectedColumns]);
34
46
  const allSelected = useMemo(() => areAllColumnsSelected(selectedColumns), [selectedColumns]);
35
47
  const someSelected = useMemo(() => areSomeColumnsSelected(selectedColumns, allSelected), [selectedColumns, allSelected]);
36
- const isNameValid = isValidTemplateName(templateName, TEMPLATE_NAME_MAX_LENGTH);
48
+ const isNameValid = useMemo(() => isValidTemplateName(templateName, TEMPLATE_NAME_MAX_LENGTH), [templateName]);
37
49
  const handleReorder = (reorderedNames) => {
38
50
  const reorderedColumns = reorderedNames
39
51
  .map((name) => selectedColumns.find((col) => col.name === name))
@@ -17,10 +17,37 @@ export const useViewSelector = ({ mode, onViewChange, onTableViewsChange, onCust
17
17
  const [selectedViewInfo, setSelectedViewInfo] = useState({ id: 'default', label: 'Default' });
18
18
  const [shouldUseCurrentState, setShouldUseCurrentState] = useState(false);
19
19
  const [selectedView, setSelectedView] = useState(undefined);
20
+ // Update editingView when customViews changes to ensure it reflects the latest saved state
21
+ useEffect(() => {
22
+ if (editingView && customViews.length > 0) {
23
+ const updatedView = customViews.find((view) => view.id === editingView.id);
24
+ if (updatedView && updatedView !== editingView) {
25
+ setEditingView(updatedView);
26
+ }
27
+ }
28
+ }, [customViews, editingView]);
29
+ // Update selectedView when customViews changes to ensure it reflects the latest saved state
30
+ useEffect(() => {
31
+ if (selectedView && selectedView.isCustom && customViews.length > 0) {
32
+ const updatedView = customViews.find((view) => view.id === selectedView.id);
33
+ if (updatedView) {
34
+ // Compare submenu to detect changes (deep comparison would be better, but this works for now)
35
+ const submenuChanged = JSON.stringify(updatedView.submenu) !== JSON.stringify(selectedView.submenu);
36
+ const labelChanged = updatedView.label !== selectedView.label;
37
+ if (submenuChanged || labelChanged) {
38
+ // Create a new object reference to ensure React detects the change
39
+ const newSelectedView = Object.assign(Object.assign({}, updatedView), { submenu: updatedView.submenu ? [...updatedView.submenu] : undefined });
40
+ setSelectedView(newSelectedView);
41
+ onViewChange === null || onViewChange === void 0 ? void 0 : onViewChange(newSelectedView);
42
+ }
43
+ }
44
+ }
45
+ }, [customViews, selectedView, onViewChange]);
20
46
  // Notify parent of initial view on mount
21
47
  useEffect(() => {
22
48
  // Use defaultTemplate if available, otherwise undefined (built-in default view)
23
49
  const initialView = defaultTemplate || undefined;
50
+ console.log('initialView', initialView);
24
51
  setSelectedView(initialView);
25
52
  onViewChange === null || onViewChange === void 0 ? void 0 : onViewChange(initialView);
26
53
  }, [onViewChange, defaultTemplate]);
@@ -49,6 +76,7 @@ export const useViewSelector = ({ mode, onViewChange, onTableViewsChange, onCust
49
76
  setSelectedViewInfo(selected);
50
77
  // Update selected view and notify parent
51
78
  const newSelectedView = viewMenuItem || undefined;
79
+ console.log('newSelectedView', newSelectedView);
52
80
  setSelectedView(newSelectedView);
53
81
  onViewChange === null || onViewChange === void 0 ? void 0 : onViewChange(newSelectedView);
54
82
  handleCloseViewDropdown();
@@ -70,24 +98,51 @@ export const useViewSelector = ({ mode, onViewChange, onTableViewsChange, onCust
70
98
  setShouldUseCurrentState(false);
71
99
  }, []);
72
100
  const handleSaveView = useCallback((data) => __awaiter(void 0, void 0, void 0, function* () {
73
- if (editingView) {
74
- const updatedViews = customViews.map((view) => view.id === editingView.id
75
- ? Object.assign(Object.assign({}, view), { label: data.name, columns: data.selectedColumns.map((col) => col.name), submenu: data.selectedColumns }) : view);
76
- handleCustomViewsChange(updatedViews);
77
- yield (onEditCustomView === null || onEditCustomView === void 0 ? void 0 : onEditCustomView(editingView.id, data));
101
+ try {
102
+ if (editingView) {
103
+ yield (onEditCustomView === null || onEditCustomView === void 0 ? void 0 : onEditCustomView(editingView.id, data));
104
+ // Update state after promise resolves successfully
105
+ const updatedView = Object.assign(Object.assign({}, editingView), { label: data.name, columns: data.selectedColumns.map((col) => col.name), submenu: data.selectedColumns });
106
+ const updatedViews = customViews.map((view) => (view.id === editingView.id ? updatedView : view));
107
+ handleCustomViewsChange(updatedViews);
108
+ // If the updated view is currently selected, update selectedView to reflect changes
109
+ // Create a new object reference to ensure React detects the change
110
+ if ((selectedView === null || selectedView === void 0 ? void 0 : selectedView.id) === editingView.id) {
111
+ const newSelectedView = Object.assign(Object.assign({}, updatedView), { submenu: [...updatedView.submenu] });
112
+ setSelectedView(newSelectedView);
113
+ onViewChange === null || onViewChange === void 0 ? void 0 : onViewChange(newSelectedView);
114
+ }
115
+ }
116
+ else {
117
+ yield (onCreateCustomView === null || onCreateCustomView === void 0 ? void 0 : onCreateCustomView(data));
118
+ // Update state after promise resolves successfully
119
+ const newView = createCustomViewMenuItem(data.name, data.selectedColumns);
120
+ const updatedViews = [...customViews, newView];
121
+ handleCustomViewsChange(updatedViews);
122
+ }
78
123
  }
79
- else {
80
- const newView = createCustomViewMenuItem(data.name, data.selectedColumns);
81
- const updatedViews = [...customViews, newView];
82
- handleCustomViewsChange(updatedViews);
83
- yield (onCreateCustomView === null || onCreateCustomView === void 0 ? void 0 : onCreateCustomView(data));
124
+ catch (error) {
125
+ // Error will be handled by the toast in CreateViewDialog
126
+ throw error;
84
127
  }
85
- }), [editingView, customViews, handleCustomViewsChange, onEditCustomView, onCreateCustomView]);
128
+ }), [editingView, customViews, handleCustomViewsChange, onEditCustomView, onCreateCustomView, selectedView, onViewChange]);
86
129
  const handleDeleteView = useCallback((viewId) => __awaiter(void 0, void 0, void 0, function* () {
87
- const updatedViews = customViews.filter((view) => view.id !== viewId);
88
- handleCustomViewsChange(updatedViews);
89
- yield (onDeleteCustomView === null || onDeleteCustomView === void 0 ? void 0 : onDeleteCustomView(viewId));
90
- }), [customViews, handleCustomViewsChange, onDeleteCustomView]);
130
+ try {
131
+ yield (onDeleteCustomView === null || onDeleteCustomView === void 0 ? void 0 : onDeleteCustomView(viewId));
132
+ // Update state after promise resolves successfully
133
+ const updatedViews = customViews.filter((view) => view.id !== viewId);
134
+ handleCustomViewsChange(updatedViews);
135
+ // If the deleted view was selected, reset to default
136
+ if ((selectedView === null || selectedView === void 0 ? void 0 : selectedView.id) === viewId) {
137
+ setSelectedView(undefined);
138
+ onViewChange === null || onViewChange === void 0 ? void 0 : onViewChange(undefined);
139
+ }
140
+ }
141
+ catch (error) {
142
+ // Error will be handled by the toast in CreateViewDialog
143
+ throw error;
144
+ }
145
+ }), [customViews, handleCustomViewsChange, onDeleteCustomView, selectedView, onViewChange]);
91
146
  const handleResetViews = useCallback((views) => {
92
147
  if (resetTableViews) {
93
148
  resetTableViews({ id: views[0], label: views[0] });
@@ -76,7 +76,6 @@ export interface CreateCustomViewDialogProps {
76
76
  layout: LayoutSection;
77
77
  }) => Promise<void>;
78
78
  availableColumns?: ColumnViewProps[];
79
- isLoading?: boolean;
80
79
  defaultColumns?: ColumnViewProps[];
81
80
  editingView?: {
82
81
  id: string;
@@ -92,6 +92,7 @@ export declare const deepCloneColumns: (columns: ColumnViewProps[]) => ColumnVie
92
92
  export declare const toggleSingleColumn: (columns: ColumnViewProps[], columnName: string) => ColumnViewProps[];
93
93
  /**
94
94
  * Get submenu items for a view menu item
95
+ * Always includes the date column at the beginning
95
96
  */
96
97
  export declare const getSubmenuItems: (item: ViewMenuItem, defaultColumns: ColumnViewProps[]) => ColumnViewProps[];
97
98
  /**
@@ -1,3 +1,4 @@
1
+ import { DATE_COLUMN_CONFIG } from './constants';
1
2
  // Note: advancedColumns and sheetColumns are only used in demo - not imported here to avoid default data
2
3
  /**
3
4
  * Transform API layout response to internal ColumnViewProps format
@@ -107,9 +108,17 @@ export const transformTemplatesToViewMenuItems = (templates, mode = 'sheet', lan
107
108
  // Handle id as either string or object
108
109
  const templateIdString = typeof template.id === 'string' ? template.id : template.templateId;
109
110
  const viewId = typeof template.id === 'string' ? template.id : template.templateId;
111
+ // Always include date column at the beginning
112
+ const dateColumn = DATE_COLUMN_CONFIG;
113
+ const columnsWithDate = columns.some((col) => col.name.toLowerCase() === 'date') ? columns : [dateColumn, ...columns];
114
+ // Ensure date column is first
115
+ const dateColumnIndex = columnsWithDate.findIndex((col) => col.name.toLowerCase() === 'date');
116
+ const finalColumns = dateColumnIndex > 0
117
+ ? [columnsWithDate[dateColumnIndex], ...columnsWithDate.filter((col) => col.name.toLowerCase() !== 'date')]
118
+ : columnsWithDate;
110
119
  if (template.default) {
111
120
  // Store default template columns to merge into built-in Default view
112
- defaultTemplateColumns = columns;
121
+ defaultTemplateColumns = finalColumns;
113
122
  // Also create a ViewMenuItem for the default template
114
123
  defaultTemplate = {
115
124
  id: 'default',
@@ -117,8 +126,8 @@ export const transformTemplatesToViewMenuItems = (templates, mode = 'sheet', lan
117
126
  label: template.name,
118
127
  isCustom: false,
119
128
  default: true,
120
- columns: columns.map((col) => col.name),
121
- submenu: columns,
129
+ columns: finalColumns.map((col) => col.name),
130
+ submenu: finalColumns,
122
131
  };
123
132
  }
124
133
  else {
@@ -129,8 +138,8 @@ export const transformTemplatesToViewMenuItems = (templates, mode = 'sheet', lan
129
138
  label: template.name,
130
139
  isCustom: true,
131
140
  default: false,
132
- columns: columns.map((col) => col.name),
133
- submenu: columns,
141
+ columns: finalColumns.map((col) => col.name),
142
+ submenu: finalColumns,
134
143
  });
135
144
  }
136
145
  });
@@ -321,16 +330,38 @@ export const toggleSingleColumn = (columns, columnName) => {
321
330
  };
322
331
  /**
323
332
  * Get submenu items for a view menu item
333
+ * Always includes the date column at the beginning
324
334
  */
325
335
  export const getSubmenuItems = (item, defaultColumns) => {
326
336
  var _a;
337
+ let columns = [];
327
338
  if (item.isCustom && ((_a = item.submenu) === null || _a === void 0 ? void 0 : _a.length)) {
328
- return item.submenu;
339
+ columns = item.submenu;
329
340
  }
330
- if (item.id === 'default') {
331
- return defaultColumns;
341
+ else if (item.id === 'default') {
342
+ columns = defaultColumns;
332
343
  }
333
- return item.submenu || [];
344
+ else {
345
+ columns = item.submenu || [];
346
+ }
347
+ // Always include date column at the beginning if it's not already present
348
+ const hasDateColumn = columns.some((col) => col.name.toLowerCase() === 'date');
349
+ if (!hasDateColumn) {
350
+ const dateColumn = {
351
+ name: 'date',
352
+ label: 'Date',
353
+ selected: true,
354
+ };
355
+ return [dateColumn, ...columns];
356
+ }
357
+ // Ensure date column is first
358
+ const dateColumnIndex = columns.findIndex((col) => col.name.toLowerCase() === 'date');
359
+ if (dateColumnIndex > 0) {
360
+ const dateColumn = columns[dateColumnIndex];
361
+ const otherColumns = columns.filter((col) => col.name.toLowerCase() !== 'date');
362
+ return [dateColumn, ...otherColumns];
363
+ }
364
+ return columns;
334
365
  };
335
366
  /**
336
367
  * Check if a view menu item has submenu
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.372-test.2-test.3-test.4-test.5-test.6",
5
- "testVersion": 6,
4
+ "version": "0.1.372-test.2-test.3-test.4-test.5-test.6-test.7",
5
+ "testVersion": 7,
6
6
  "type": "module",
7
7
  "main": "build/index.js",
8
8
  "module": "build/index.js",