@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.
- package/build/components/TableHeader/TableView/CreateViewDialog.d.ts +1 -1
- package/build/components/TableHeader/TableView/CreateViewDialog.js +42 -10
- package/build/components/TableHeader/TableView/ViewSelector.js +4 -3
- package/build/components/TableHeader/TableView/ViewsDropdown.js +25 -17
- package/build/components/TableHeader/TableView/components/ColumnList.js +19 -3
- package/build/components/TableHeader/TableView/components/ViewsSubmenu.js +8 -1
- package/build/components/TableHeader/TableView/constants.d.ts +1 -1
- package/build/components/TableHeader/TableView/constants.js +1 -1
- package/build/components/TableHeader/TableView/hooks/useCreateViewDialog.js +17 -5
- package/build/components/TableHeader/TableView/hooks/useViewSelector.d.ts +4 -2
- package/build/components/TableHeader/TableView/hooks/useViewSelector.js +86 -19
- package/build/components/TableHeader/TableView/hooks/useViewsManager.d.ts +1 -0
- package/build/components/TableHeader/TableView/hooks/useViewsManager.js +11 -13
- package/build/components/TableHeader/TableView/types.d.ts +2 -3
- package/build/components/TableHeader/TableView/utils.d.ts +2 -0
- package/build/components/TableHeader/TableView/utils.js +50 -8
- package/build/components/TableHeader/type.d.ts +1 -1
- package/package.json +2 -2
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import type { CreateCustomViewDialogProps } from './types';
|
|
2
|
-
declare function CreateViewDialog({ open, onClose, onCreate, availableColumns,
|
|
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 = [],
|
|
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
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
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
|
-
|
|
46
|
-
|
|
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
|
|
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,
|
|
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
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
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: "
|
|
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)'
|
|
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 }
|
|
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 }
|
|
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));
|
|
@@ -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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
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
|
-
|
|
68
|
-
|
|
69
|
-
|
|
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
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
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
|
|
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
|
-
//
|
|
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
|
-
:
|
|
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
|
|
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
|
|
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
|
|
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>,
|
|
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 =
|
|
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:
|
|
122
|
-
submenu:
|
|
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
|
-
|
|
339
|
+
columns = item.submenu;
|
|
340
|
+
}
|
|
341
|
+
else if (item.id === 'default') {
|
|
342
|
+
columns = defaultColumns;
|
|
318
343
|
}
|
|
319
|
-
|
|
320
|
-
|
|
344
|
+
else {
|
|
345
|
+
columns = item.submenu || [];
|
|
321
346
|
}
|
|
322
|
-
|
|
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?: (
|
|
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":
|
|
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",
|