@tap-payments/os-micro-frontend-shared 0.1.372-test.2-test.3-test.4-test.5 → 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;
@@ -13,7 +13,7 @@ function ViewSelector({ onViewChange, setIsViewVisible, setTableViews, tableView
13
13
  const { t } = useTranslation();
14
14
  // Map tableMode to viewMode: 'sheet' → 'sheet', 'default' → 'advanced'
15
15
  const mode = tableMode === 'sheet' ? 'sheet' : 'advanced';
16
- const { defaultColumns, setDefaultColumns, internalTableViews, setInternalTableViews, internalCustomViews, setInternalCustomViews } = useViewsManager({
16
+ const { defaultColumns, setDefaultColumns, internalTableViews, setInternalTableViews, internalCustomViews, setInternalCustomViews, defaultTemplate, } = useViewsManager({
17
17
  mode,
18
18
  templates,
19
19
  lang,
@@ -22,6 +22,7 @@ function ViewSelector({ onViewChange, setIsViewVisible, setTableViews, tableView
22
22
  const customViews = externalCustomViews !== null && externalCustomViews !== void 0 ? externalCustomViews : internalCustomViews;
23
23
  const { anchorViewEl, defaultViewEl, setDefaultViewElement, isCreateDialogOpen, editingView, selectedViewInfo, shouldUseCurrentState, handleViewButtonClick, handleCloseViewDropdown, handleSelectedViewInfo, handleOpenCreateDialog, handleOpenEditDialog, handleCloseCreateDialog, handleSaveView, handleDeleteView, handleResetViews, handleTableViewsChange, } = useViewSelector({
24
24
  mode,
25
+ onViewChange,
25
26
  onTableViewsChange,
26
27
  onCustomViewsChange,
27
28
  onCreateCustomView,
@@ -32,11 +33,11 @@ function ViewSelector({ onViewChange, setIsViewVisible, setTableViews, tableView
32
33
  tableViews,
33
34
  customViews,
34
35
  defaultColumns,
36
+ defaultTemplate,
35
37
  setInternalCustomViews,
36
38
  setInternalTableViews,
37
39
  });
38
- return (_jsxs(_Fragment, { children: [_jsx(ClickAwayListener, Object.assign({ onClickAway: handleCloseViewDropdown }, { children: _jsxs(ViewWrapper, Object.assign({ sx: { width: '32px' }, "data-testid": "ViewSelector" }, { children: [_jsx(StyledButton, Object.assign({ title: t('tableView'), "data-testid": "ViewSelector_button", onClick: handleViewButtonClick }, { children: _jsx(Icon, { src: viewIcon, alt: "view", sx: { width: 14, height: 14 } }) })), _jsx(ViewsDropdown, { open: Boolean(defaultViewEl), anchorEl: anchorViewEl, setSelectedViewInfo: handleSelectedViewInfo, selectedViewInfo: selectedViewInfo, onSelect: (e, templateId) => {
39
- onViewChange === null || onViewChange === void 0 ? void 0 : onViewChange(templateId);
40
+ return (_jsxs(_Fragment, { children: [_jsx(ClickAwayListener, Object.assign({ onClickAway: handleCloseViewDropdown }, { children: _jsxs(ViewWrapper, Object.assign({ sx: { width: '32px' }, "data-testid": "ViewSelector" }, { children: [_jsx(StyledButton, Object.assign({ title: t('tableView'), "data-testid": "ViewSelector_button", onClick: handleViewButtonClick }, { children: _jsx(Icon, { src: viewIcon, alt: "view", sx: { width: 14, height: 14 } }) })), _jsx(ViewsDropdown, { open: Boolean(defaultViewEl), anchorEl: anchorViewEl, setSelectedViewInfo: handleSelectedViewInfo, selectedViewInfo: selectedViewInfo, onSelect: (e, selectedView) => {
40
41
  setDefaultViewElement(defaultViewEl ? null : e.currentTarget);
41
42
  }, setViews: handleResetViews, tableViews: tableViews, setTableViews: handleTableViewsChange, onCreateCustomView: handleOpenCreateDialog, customViews: customViews, onEditCustomView: handleOpenEditDialog, defaultColumns: defaultColumns, setDefaultColumns: setDefaultColumns })] })) })), _jsx(CreateViewDialog, { open: isCreateDialogOpen, onClose: handleCloseCreateDialog, availableColumns: defaultColumns, defaultColumns: defaultColumns, onCreate: handleSaveView, editingView: editingView, onDelete: handleDeleteView, tableViews: shouldUseCurrentState ? defaultColumns : undefined, mode: mode })] }));
42
43
  }
@@ -39,24 +39,17 @@ function ViewsDropdown({ open, selectedViewInfo, setSelectedViewInfo, onSelect,
39
39
  // Default templates are merged into built-in Default view, so no need to sort
40
40
  const viewList = [...defaultViewList, ...customViews];
41
41
  const handleViewClick = (item) => {
42
- setSelectedViewInfo(item);
43
42
  if (item.columns)
44
43
  setViews === null || setViews === void 0 ? void 0 : setViews(item.columns);
45
- // Call onSelect with templateId for custom views
46
- if (item.isCustom && item.templateId) {
47
- // Create a synthetic event-like object for onSelect
48
- const syntheticEvent = {
49
- currentTarget: anchorEl || document.createElement('div'),
50
- };
51
- onSelect(syntheticEvent, item.templateId);
52
- }
53
- else {
54
- // For default view, call onSelect without templateId
55
- const syntheticEvent = {
56
- currentTarget: anchorEl || document.createElement('div'),
57
- };
58
- onSelect(syntheticEvent);
59
- }
44
+ // Call onSelect with the full view object
45
+ const syntheticEvent = {
46
+ currentTarget: anchorEl || document.createElement('div'),
47
+ };
48
+ // Pass the full view object for custom views, undefined for default view
49
+ const viewToPass = item.isCustom ? item : undefined;
50
+ onSelect(syntheticEvent, viewToPass);
51
+ // Update selected view info with the view object
52
+ setSelectedViewInfo(item, viewToPass);
60
53
  };
61
54
  const toggleColumnSelection = (columnName) => {
62
55
  if (!setDefaultColumns)
@@ -193,6 +186,21 @@ function ViewsDropdown({ open, selectedViewInfo, setSelectedViewInfo, onSelect,
193
186
  handleSubmenuLeave();
194
187
  onSelect(e);
195
188
  onCreateCustomView === null || onCreateCustomView === void 0 ? void 0 : onCreateCustomView(false); // Don't use current state for "New Custom View"
196
- } }, { 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" }))] })] }) })))] })));
197
205
  }
198
206
  export default React.memo(ViewsDropdown);
@@ -26,7 +26,16 @@ export const ColumnList = ({ selectedColumns, columnNames, allSelected, someSele
26
26
  const isDate = isDateColumn(column.name);
27
27
  const hasSubmenu = column.menuItems && column.menuItems.length > 0;
28
28
  const { checked, indeterminate } = getColumnCheckState(column);
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)' }, style: { listStyle: 'none', margin: 0, padding: 0, position: 'relative', zIndex: 1, backgroundColor: '#fff' }, onDragStart: (e) => {
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
+ listStyle: 'none',
31
+ margin: 0,
32
+ padding: 0,
33
+ position: 'relative',
34
+ zIndex: 1,
35
+ backgroundColor: '#fff',
36
+ width: '100%',
37
+ willChange: 'transform',
38
+ }, onDragStart: (e) => {
30
39
  const target = e.target;
31
40
  if (target.closest('[role="checkbox"]') ||
32
41
  target.closest('input[type="checkbox"]') ||
@@ -37,7 +46,7 @@ export const ColumnList = ({ selectedColumns, columnNames, allSelected, someSele
37
46
  if (e.target.closest('[role="checkbox"]') || e.target.closest('input[type="checkbox"]')) {
38
47
  e.stopPropagation();
39
48
  }
40
- } }, { children: [_jsx(DragIconWrapper, { children: _jsx("img", { src: dragIcon, alt: "drag", draggable: false, style: { width: 16, height: 16, cursor: isDate ? 'default' : 'grab', pointerEvents: 'none' } }) }), _jsx(CheckboxWrapper, Object.assign({ onMouseDown: (e) => {
49
+ }, sx: { width: '100%', position: 'relative' } }, { children: [_jsx(DragIconWrapper, { children: _jsx("img", { src: dragIcon, alt: "drag", draggable: false, style: { width: 16, height: 16, cursor: isDate ? 'default' : 'grab', pointerEvents: 'none' } }) }), _jsx(CheckboxWrapper, Object.assign({ onMouseDown: (e) => {
41
50
  e.stopPropagation();
42
51
  }, onPointerDown: (e) => {
43
52
  e.stopPropagation();
@@ -46,7 +55,14 @@ export const ColumnList = ({ selectedColumns, columnNames, allSelected, someSele
46
55
  onColumnToggle(column.name);
47
56
  }, onClick: (e) => {
48
57
  e.stopPropagation();
49
- }, disabled: isDate, size: "small", sx: checkboxSx }) })), _jsx(Typography, Object.assign({ sx: { flex: 1, fontSize: 13, fontWeight: 400, color: 'text.primary', ml: 1 } }, { children: column.label || column.name })), hasSubmenu && (_jsx(Box, Object.assign({ sx: { display: 'flex', alignItems: 'center', ml: 1, flexShrink: 0 } }, { children: _jsx("img", { src: rightArrow, alt: "arrow", style: { width: 12, height: 12 } }) })))] })), hasSubmenu && (_jsx(Popper, Object.assign({ open: hoveredColumn === column.name, anchorEl: anchorEl, placement: "right-start", sx: { zIndex: 10000 } }, { 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) => {
58
+ }, disabled: isDate, size: "small", sx: checkboxSx }) })), _jsx(Typography, Object.assign({ sx: { flex: 1, fontSize: 13, fontWeight: 400, color: 'text.primary', ml: 1 } }, { children: column.label || column.name })), hasSubmenu && (_jsx(Box, Object.assign({ sx: { display: 'flex', alignItems: 'center', ml: 1, flexShrink: 0 } }, { children: _jsx("img", { src: rightArrow, alt: "arrow", style: { width: 12, height: 12 } }) })))] })), hasSubmenu && (_jsx(Popper, Object.assign({ open: hoveredColumn === column.name, anchorEl: anchorEl, placement: "right-start", sx: { zIndex: 10000 }, modifiers: [
59
+ {
60
+ name: 'offset',
61
+ options: {
62
+ offset: [0, 0],
63
+ },
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: (_a = column.menuItems) === null || _a === void 0 ? void 0 : _a.map((subItem, subItemIndex) => {
50
66
  var _a, _b;
51
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));
52
68
  }) })] })) })))] }), column.name));
@@ -37,7 +37,14 @@ export const ViewsSubmenu = ({ columns, allCurrentSelected, someCurrentSelected,
37
37
  alignItems: 'center',
38
38
  justifyContent: 'space-between',
39
39
  width: '100%',
40
- } }, { children: [_jsx(MenuItem, Object.assign({ isSelected: hasNestedSubmenu ? checked : column.selected, isIndeterminate: hasNestedSubmenu ? indeterminate : false, onClick: () => onColumnToggle(column.name), 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) => {
40
+ } }, { children: [_jsx(MenuItem, Object.assign({ isSelected: hasNestedSubmenu ? checked : column.selected, isIndeterminate: hasNestedSubmenu ? indeterminate : false, onClick: () => onColumnToggle(column.name), 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 }, modifiers: [
41
+ {
42
+ name: 'offset',
43
+ options: {
44
+ offset: [0, 0],
45
+ },
46
+ },
47
+ ] }, { 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) => {
41
48
  var _a, _b;
42
49
  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));
43
50
  }) })] })) })))] })), columnIndex < columns.length - 1 && _jsx(Divider, {})] }, column.name));
@@ -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))
@@ -4,6 +4,7 @@ import type { ViewMenuItem, LayoutSection, ViewMode } from '../types';
4
4
  import type { ViewOption } from '../../type';
5
5
  export interface UseViewSelectorProps {
6
6
  mode: ViewMode;
7
+ onViewChange?: (selectedView?: ViewMenuItem) => void;
7
8
  onTableViewsChange?: (tableViews: ColumnViewProps[]) => void;
8
9
  onCustomViewsChange?: (customViews: ViewMenuItem[]) => void;
9
10
  onCreateCustomView?: (data: {
@@ -25,10 +26,11 @@ export interface UseViewSelectorProps {
25
26
  tableViews: ColumnViewProps[];
26
27
  customViews: ViewMenuItem[];
27
28
  defaultColumns: ColumnViewProps[];
29
+ defaultTemplate?: ViewMenuItem;
28
30
  setInternalCustomViews: (views: ViewMenuItem[]) => void;
29
31
  setInternalTableViews: (views: ColumnViewProps[]) => void;
30
32
  }
31
- export declare const useViewSelector: ({ mode, onTableViewsChange, onCustomViewsChange, onCreateCustomView, onEditCustomView, onDeleteCustomView, resetTableViews, setTableViews, tableViews, customViews, defaultColumns, setInternalCustomViews, setInternalTableViews, }: UseViewSelectorProps) => {
33
+ export declare const useViewSelector: ({ mode, onViewChange, onTableViewsChange, onCustomViewsChange, onCreateCustomView, onEditCustomView, onDeleteCustomView, resetTableViews, setTableViews, tableViews, customViews, defaultColumns, defaultTemplate, setInternalCustomViews, setInternalTableViews, }: UseViewSelectorProps) => {
32
34
  anchorViewEl: HTMLDivElement | null;
33
35
  defaultViewEl: HTMLDivElement | null;
34
36
  setDefaultViewElement: import("react").Dispatch<import("react").SetStateAction<HTMLDivElement | null>>;
@@ -39,7 +41,7 @@ export declare const useViewSelector: ({ mode, onTableViewsChange, onCustomViews
39
41
  handleViewButtonClick: (event: MouseEvent<HTMLDivElement>) => void;
40
42
  handleCloseViewDropdown: () => void;
41
43
  handleClose: () => void;
42
- handleSelectedViewInfo: (selected: ViewOption) => void;
44
+ handleSelectedViewInfo: (selected: ViewOption, viewMenuItem?: ViewMenuItem) => void;
43
45
  handleOpenCreateDialog: (useCurrentState?: boolean) => void;
44
46
  handleOpenEditDialog: (view: ViewMenuItem) => void;
45
47
  handleCloseCreateDialog: () => void;
@@ -7,15 +7,50 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
7
7
  step((generator = generator.apply(thisArg, _arguments || [])).next());
8
8
  });
9
9
  };
10
- import { useState, useCallback } from 'react';
10
+ import { useState, useCallback, useEffect } from 'react';
11
11
  import { createCustomViewMenuItem } from '../utils';
12
- export const useViewSelector = ({ mode, onTableViewsChange, onCustomViewsChange, onCreateCustomView, onEditCustomView, onDeleteCustomView, resetTableViews, setTableViews, tableViews, customViews, defaultColumns, setInternalCustomViews, setInternalTableViews, }) => {
12
+ export const useViewSelector = ({ mode, onViewChange, onTableViewsChange, onCustomViewsChange, onCreateCustomView, onEditCustomView, onDeleteCustomView, resetTableViews, setTableViews, tableViews, customViews, defaultColumns, defaultTemplate, setInternalCustomViews, setInternalTableViews, }) => {
13
13
  const [anchorViewEl, setAnchorViewEl] = useState(null);
14
14
  const [defaultViewEl, setDefaultViewElement] = useState(null);
15
15
  const [isCreateDialogOpen, setIsCreateDialogOpen] = useState(false);
16
16
  const [editingView, setEditingView] = useState(null);
17
17
  const [selectedViewInfo, setSelectedViewInfo] = useState({ id: 'default', label: 'Default' });
18
18
  const [shouldUseCurrentState, setShouldUseCurrentState] = useState(false);
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]);
46
+ // Notify parent of initial view on mount
47
+ useEffect(() => {
48
+ // Use defaultTemplate if available, otherwise undefined (built-in default view)
49
+ const initialView = defaultTemplate || undefined;
50
+ console.log('initialView', initialView);
51
+ setSelectedView(initialView);
52
+ onViewChange === null || onViewChange === void 0 ? void 0 : onViewChange(initialView);
53
+ }, [onViewChange, defaultTemplate]);
19
54
  const handleTableViewsChange = useCallback((newTableViews) => {
20
55
  const setTableViewsState = setTableViews !== null && setTableViews !== void 0 ? setTableViews : setInternalTableViews;
21
56
  setTableViewsState(newTableViews);
@@ -37,10 +72,15 @@ export const useViewSelector = ({ mode, onTableViewsChange, onCustomViewsChange,
37
72
  setDefaultViewElement(null);
38
73
  setSelectedViewInfo({ label: 'Default', id: 'default' });
39
74
  }, []);
40
- const handleSelectedViewInfo = useCallback((selected) => {
75
+ const handleSelectedViewInfo = useCallback((selected, viewMenuItem) => {
41
76
  setSelectedViewInfo(selected);
77
+ // Update selected view and notify parent
78
+ const newSelectedView = viewMenuItem || undefined;
79
+ console.log('newSelectedView', newSelectedView);
80
+ setSelectedView(newSelectedView);
81
+ onViewChange === null || onViewChange === void 0 ? void 0 : onViewChange(newSelectedView);
42
82
  handleCloseViewDropdown();
43
- }, [handleCloseViewDropdown]);
83
+ }, [handleCloseViewDropdown, onViewChange]);
44
84
  const handleOpenCreateDialog = useCallback((useCurrentState = false) => {
45
85
  setEditingView(null);
46
86
  setShouldUseCurrentState(useCurrentState);
@@ -58,24 +98,51 @@ export const useViewSelector = ({ mode, onTableViewsChange, onCustomViewsChange,
58
98
  setShouldUseCurrentState(false);
59
99
  }, []);
60
100
  const handleSaveView = useCallback((data) => __awaiter(void 0, void 0, void 0, function* () {
61
- if (editingView) {
62
- const updatedViews = customViews.map((view) => view.id === editingView.id
63
- ? Object.assign(Object.assign({}, view), { label: data.name, columns: data.selectedColumns.map((col) => col.name), submenu: data.selectedColumns }) : view);
64
- handleCustomViewsChange(updatedViews);
65
- 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
+ }
66
123
  }
67
- else {
68
- const newView = createCustomViewMenuItem(data.name, data.selectedColumns);
69
- const updatedViews = [...customViews, newView];
70
- handleCustomViewsChange(updatedViews);
71
- 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;
72
127
  }
73
- }), [editingView, customViews, handleCustomViewsChange, onEditCustomView, onCreateCustomView]);
128
+ }), [editingView, customViews, handleCustomViewsChange, onEditCustomView, onCreateCustomView, selectedView, onViewChange]);
74
129
  const handleDeleteView = useCallback((viewId) => __awaiter(void 0, void 0, void 0, function* () {
75
- const updatedViews = customViews.filter((view) => view.id !== viewId);
76
- handleCustomViewsChange(updatedViews);
77
- yield (onDeleteCustomView === null || onDeleteCustomView === void 0 ? void 0 : onDeleteCustomView(viewId));
78
- }), [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]);
79
146
  const handleResetViews = useCallback((views) => {
80
147
  if (resetTableViews) {
81
148
  resetTableViews({ id: views[0], label: views[0] });
@@ -8,4 +8,5 @@ export declare const useViewsManager: ({ mode, templates, lang }: UseViewsManage
8
8
  setInternalTableViews: import("react").Dispatch<import("react").SetStateAction<ColumnViewProps[]>>;
9
9
  internalCustomViews: ViewMenuItem[];
10
10
  setInternalCustomViews: import("react").Dispatch<import("react").SetStateAction<ViewMenuItem[]>>;
11
+ defaultTemplate: ViewMenuItem | undefined;
11
12
  };
@@ -1,13 +1,14 @@
1
1
  import { useState, useEffect, useMemo } from 'react';
2
- import { transformTemplatesToViewMenuItems, getLayoutDataFromTemplates, getColumnsByMode } from '../utils';
2
+ import { transformTemplatesToViewMenuItems } from '../utils';
3
3
  export const useViewsManager = ({ mode, templates, lang = 'en' }) => {
4
4
  // Transform templates internally - this is the only source of data
5
5
  const transformedTemplates = useMemo(() => {
6
6
  if (!templates)
7
7
  return null;
8
8
  const templatesArray = Array.isArray(templates) ? templates : templates.templates;
9
- const { customViews, defaultTemplateColumns } = transformTemplatesToViewMenuItems(templatesArray, mode, lang);
10
- // Use default template columns if available, otherwise use layoutData from all templates
9
+ const { customViews, defaultTemplateColumns, defaultTemplate } = transformTemplatesToViewMenuItems(templatesArray, mode, lang);
10
+ // Only use default template columns - no fallback to layout data
11
+ // The default view must come from a template with default: true
11
12
  const effectiveLayoutData = defaultTemplateColumns
12
13
  ? [
13
14
  {
@@ -31,11 +32,12 @@ export const useViewsManager = ({ mode, templates, lang = 'en' }) => {
31
32
  }),
32
33
  },
33
34
  ]
34
- : getLayoutDataFromTemplates(templatesArray);
35
+ : [];
35
36
  return {
36
37
  customViews,
37
38
  layoutData: effectiveLayoutData,
38
39
  defaultTemplateColumns,
40
+ defaultTemplate,
39
41
  };
40
42
  }, [templates, mode, lang]);
41
43
  const [defaultColumns, setDefaultColumns] = useState(() => {
@@ -71,23 +73,18 @@ export const useViewsManager = ({ mode, templates, lang = 'en' }) => {
71
73
  return [];
72
74
  });
73
75
  useEffect(() => {
74
- // Only use data from templates
76
+ // Only use default template columns from template with default: true
77
+ // No fallback to layout data - default must come from templates array
75
78
  if (transformedTemplates === null || transformedTemplates === void 0 ? void 0 : transformedTemplates.defaultTemplateColumns) {
76
79
  setDefaultColumns(transformedTemplates.defaultTemplateColumns);
77
80
  setInternalTableViews(transformedTemplates.defaultTemplateColumns);
78
81
  }
79
- else if ((transformedTemplates === null || transformedTemplates === void 0 ? void 0 : transformedTemplates.layoutData) && transformedTemplates.layoutData.length > 0) {
80
- // Use layoutData from templates
81
- const columns = getColumnsByMode(mode, transformedTemplates.layoutData);
82
- setDefaultColumns(columns);
83
- setInternalTableViews(columns);
84
- }
85
82
  else {
86
- // No templates - set empty arrays
83
+ // No default template found - set empty arrays
87
84
  setDefaultColumns([]);
88
85
  setInternalTableViews([]);
89
86
  }
90
- }, [mode, transformedTemplates === null || transformedTemplates === void 0 ? void 0 : transformedTemplates.defaultTemplateColumns, transformedTemplates === null || transformedTemplates === void 0 ? void 0 : transformedTemplates.layoutData]);
87
+ }, [mode, transformedTemplates === null || transformedTemplates === void 0 ? void 0 : transformedTemplates.defaultTemplateColumns]);
91
88
  // Update custom views when templates change
92
89
  useEffect(() => {
93
90
  if (transformedTemplates === null || transformedTemplates === void 0 ? void 0 : transformedTemplates.customViews) {
@@ -104,5 +101,6 @@ export const useViewsManager = ({ mode, templates, lang = 'en' }) => {
104
101
  setInternalTableViews,
105
102
  internalCustomViews,
106
103
  setInternalCustomViews,
104
+ defaultTemplate: transformedTemplates === null || transformedTemplates === void 0 ? void 0 : transformedTemplates.defaultTemplate,
107
105
  };
108
106
  };
@@ -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;
@@ -122,8 +121,8 @@ export interface ViewSelectorProps {
122
121
  export interface ViewsDropdownProps {
123
122
  open: boolean;
124
123
  selectedViewInfo: ViewOption;
125
- setSelectedViewInfo: (selected: ViewOption) => void;
126
- onSelect: (e: React.MouseEvent<HTMLDivElement>, templateId?: string) => void;
124
+ setSelectedViewInfo: (selected: ViewOption, viewMenuItem?: ViewMenuItem) => void;
125
+ onSelect: (e: React.MouseEvent<HTMLDivElement>, selectedView?: ViewMenuItem) => void;
127
126
  setViews?: (views: string[]) => void;
128
127
  anchorEl: Element | null;
129
128
  tableViews?: ColumnViewProps[];
@@ -36,6 +36,7 @@ export declare const transformTemplatesToViewMenuItems: (templates: Array<{
36
36
  }>, mode?: ViewMode, lang?: string) => {
37
37
  customViews: ViewMenuItem[];
38
38
  defaultTemplateColumns?: ColumnViewProps[] | undefined;
39
+ defaultTemplate?: ViewMenuItem | undefined;
39
40
  };
40
41
  /**
41
42
  * Convert ColumnViewProps back to LayoutSection format for API requests
@@ -91,6 +92,7 @@ export declare const deepCloneColumns: (columns: ColumnViewProps[]) => ColumnVie
91
92
  export declare const toggleSingleColumn: (columns: ColumnViewProps[], columnName: string) => ColumnViewProps[];
92
93
  /**
93
94
  * Get submenu items for a view menu item
95
+ * Always includes the date column at the beginning
94
96
  */
95
97
  export declare const getSubmenuItems: (item: ViewMenuItem, defaultColumns: ColumnViewProps[]) => ColumnViewProps[];
96
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
@@ -99,6 +100,7 @@ export const setViewAsDefault = (views, viewId) => {
99
100
  export const transformTemplatesToViewMenuItems = (templates, mode = 'sheet', lang = 'en') => {
100
101
  const customViews = [];
101
102
  let defaultTemplateColumns;
103
+ let defaultTemplate;
102
104
  templates.forEach((template) => {
103
105
  // Get columns for the specified mode
104
106
  const section = template.layout.find((s) => s.code.toLowerCase() === mode.toLowerCase());
@@ -106,9 +108,27 @@ export const transformTemplatesToViewMenuItems = (templates, mode = 'sheet', lan
106
108
  // Handle id as either string or object
107
109
  const templateIdString = typeof template.id === 'string' ? template.id : template.templateId;
108
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;
109
119
  if (template.default) {
110
120
  // Store default template columns to merge into built-in Default view
111
- defaultTemplateColumns = columns;
121
+ defaultTemplateColumns = finalColumns;
122
+ // Also create a ViewMenuItem for the default template
123
+ defaultTemplate = {
124
+ id: 'default',
125
+ templateId: template.templateId,
126
+ label: template.name,
127
+ isCustom: false,
128
+ default: true,
129
+ columns: finalColumns.map((col) => col.name),
130
+ submenu: finalColumns,
131
+ };
112
132
  }
113
133
  else {
114
134
  // Add non-default templates as custom views
@@ -118,12 +138,12 @@ export const transformTemplatesToViewMenuItems = (templates, mode = 'sheet', lan
118
138
  label: template.name,
119
139
  isCustom: true,
120
140
  default: false,
121
- columns: columns.map((col) => col.name),
122
- submenu: columns,
141
+ columns: finalColumns.map((col) => col.name),
142
+ submenu: finalColumns,
123
143
  });
124
144
  }
125
145
  });
126
- return { customViews, defaultTemplateColumns };
146
+ return { customViews, defaultTemplateColumns, defaultTemplate };
127
147
  };
128
148
  /**
129
149
  * Convert ColumnViewProps back to LayoutSection format for API requests
@@ -310,16 +330,38 @@ export const toggleSingleColumn = (columns, columnName) => {
310
330
  };
311
331
  /**
312
332
  * Get submenu items for a view menu item
333
+ * Always includes the date column at the beginning
313
334
  */
314
335
  export const getSubmenuItems = (item, defaultColumns) => {
315
336
  var _a;
337
+ let columns = [];
316
338
  if (item.isCustom && ((_a = item.submenu) === null || _a === void 0 ? void 0 : _a.length)) {
317
- return item.submenu;
339
+ columns = item.submenu;
340
+ }
341
+ else if (item.id === 'default') {
342
+ columns = defaultColumns;
318
343
  }
319
- if (item.id === 'default') {
320
- return defaultColumns;
344
+ else {
345
+ columns = item.submenu || [];
321
346
  }
322
- return item.submenu || [];
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;
323
365
  };
324
366
  /**
325
367
  * Check if a view menu item has submenu
@@ -23,7 +23,7 @@ export interface TableHeaderProps<IStatus extends TableHeaderStatus | TableHeade
23
23
  calendarMode?: CalenderMode;
24
24
  onStatusChange?: <T extends IStatus>(status?: T) => void;
25
25
  onSearch?: (search: string) => void;
26
- onViewChange?: (templateId?: string) => void;
26
+ onViewChange?: (selectedView?: ViewMenuItem) => void;
27
27
  onDateChange?: (date: Date | [Date, Date]) => void;
28
28
  tableReportsComponent?: React.ReactNode;
29
29
  tableFilterComponent?: React.ReactNode;
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",
5
- "testVersion": 5,
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",