@tap-payments/os-micro-frontend-shared 0.1.372-test.4 → 0.1.373-test.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build/components/Sandbox/style.js +3 -2
- package/build/components/TableHeader/FiltersRow.d.ts +1 -1
- package/build/components/TableHeader/FiltersRow.js +4 -2
- package/build/components/TableHeader/TableHeader.d.ts +1 -1
- package/build/components/TableHeader/TableHeader.js +2 -2
- package/build/components/TableHeader/TableView/CreateViewDialog.d.ts +3 -0
- package/build/components/TableHeader/TableView/CreateViewDialog.js +92 -0
- package/build/components/TableHeader/TableView/CustomViews.js +1 -1
- package/build/components/TableHeader/TableView/TableView.js +0 -1
- package/build/components/TableHeader/TableView/ViewSelector.d.ts +5 -0
- package/build/components/TableHeader/TableView/ViewSelector.js +44 -0
- package/build/components/TableHeader/TableView/ViewsDropdown.d.ts +5 -0
- package/build/components/TableHeader/TableView/ViewsDropdown.js +206 -0
- package/build/components/TableHeader/TableView/components/ColumnList.d.ts +3 -0
- package/build/components/TableHeader/TableView/components/ColumnList.js +70 -0
- package/build/components/TableHeader/TableView/components/ViewsSubmenu.d.ts +3 -0
- package/build/components/TableHeader/TableView/components/ViewsSubmenu.js +52 -0
- package/build/components/TableHeader/TableView/components/index.d.ts +2 -0
- package/build/components/TableHeader/TableView/components/index.js +2 -0
- package/build/components/TableHeader/TableView/constants.d.ts +10 -0
- package/build/components/TableHeader/TableView/constants.js +10 -0
- package/build/components/TableHeader/TableView/data.d.ts +5 -0
- package/build/components/TableHeader/TableView/data.js +48 -0
- package/build/components/TableHeader/TableView/hooks/index.d.ts +6 -0
- package/build/components/TableHeader/TableView/hooks/index.js +6 -0
- package/build/components/TableHeader/TableView/hooks/useCreateViewDialog.d.ts +22 -0
- package/build/components/TableHeader/TableView/hooks/useCreateViewDialog.js +88 -0
- package/build/components/TableHeader/TableView/hooks/useDialogPosition.d.ts +8 -0
- package/build/components/TableHeader/TableView/hooks/useDialogPosition.js +16 -0
- package/build/components/TableHeader/TableView/hooks/useNestedSubmenu.d.ts +7 -0
- package/build/components/TableHeader/TableView/hooks/useNestedSubmenu.js +34 -0
- package/build/components/TableHeader/TableView/hooks/useOriginalColumns.d.ts +6 -0
- package/build/components/TableHeader/TableView/hooks/useOriginalColumns.js +18 -0
- package/build/components/TableHeader/TableView/hooks/useSubmenuHover.d.ts +8 -0
- package/build/components/TableHeader/TableView/hooks/useSubmenuHover.js +43 -0
- package/build/components/TableHeader/TableView/hooks/useViewSelector.d.ts +56 -0
- package/build/components/TableHeader/TableView/hooks/useViewSelector.js +177 -0
- package/build/components/TableHeader/TableView/hooks/useViewsManager.d.ts +12 -0
- package/build/components/TableHeader/TableView/hooks/useViewsManager.js +106 -0
- package/build/components/TableHeader/TableView/index.d.ts +12 -3
- package/build/components/TableHeader/TableView/index.js +13 -3
- package/build/components/TableHeader/TableView/styles.d.ts +127 -0
- package/build/components/TableHeader/TableView/styles.js +417 -0
- package/build/components/TableHeader/TableView/types.d.ts +179 -0
- package/build/components/TableHeader/TableView/types.js +1 -0
- package/build/components/TableHeader/TableView/utils.d.ts +121 -0
- package/build/components/TableHeader/TableView/utils.js +457 -0
- package/build/components/TableHeader/type.d.ts +21 -1
- package/build/components/Toolbar/Toolbar.js +1 -1
- package/build/constants/apps.js +0 -1
- package/build/constants/assets.d.ts +1 -0
- package/build/constants/assets.js +1 -0
- package/build/types/reports.d.ts +0 -21
- package/package.json +2 -2
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export declare const DIALOG_WIDTH = 450;
|
|
2
|
+
export declare const DIALOG_HEIGHT = 600;
|
|
3
|
+
export declare const SUBMENU_CLOSE_DELAY = 150;
|
|
4
|
+
export declare const MAX_CUSTOM_VIEWS = 3;
|
|
5
|
+
export declare const TEMPLATE_NAME_MAX_LENGTH = 20;
|
|
6
|
+
export declare const DATE_COLUMN_CONFIG: {
|
|
7
|
+
readonly name: "date";
|
|
8
|
+
readonly label: "Date";
|
|
9
|
+
readonly selected: true;
|
|
10
|
+
};
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export const DIALOG_WIDTH = 450;
|
|
2
|
+
export const DIALOG_HEIGHT = 600;
|
|
3
|
+
export const SUBMENU_CLOSE_DELAY = 150;
|
|
4
|
+
export const MAX_CUSTOM_VIEWS = 3;
|
|
5
|
+
export const TEMPLATE_NAME_MAX_LENGTH = 20;
|
|
6
|
+
export const DATE_COLUMN_CONFIG = {
|
|
7
|
+
name: 'date',
|
|
8
|
+
label: 'Date',
|
|
9
|
+
selected: true,
|
|
10
|
+
};
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { ColumnViewProps } from '../../../types/index.js';
|
|
2
|
+
import type { ViewMenuItem } from './types';
|
|
3
|
+
export declare const advancedColumns: ColumnViewProps[];
|
|
4
|
+
export declare const sheetColumns: ColumnViewProps[];
|
|
5
|
+
export declare const defaultViewList: ViewMenuItem[];
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
export const advancedColumns = [
|
|
2
|
+
{
|
|
3
|
+
name: 'customer',
|
|
4
|
+
label: 'Customer',
|
|
5
|
+
selected: true,
|
|
6
|
+
menuItems: [
|
|
7
|
+
{ name: 'customer_id', label: 'ID', selected: true },
|
|
8
|
+
{ name: 'customer_name', label: 'Name', selected: true },
|
|
9
|
+
{ name: 'customer_email', label: 'Email', selected: true },
|
|
10
|
+
{ name: 'customer_phone', label: 'Phone', selected: false },
|
|
11
|
+
],
|
|
12
|
+
},
|
|
13
|
+
{
|
|
14
|
+
name: 'transaction',
|
|
15
|
+
label: 'Transaction',
|
|
16
|
+
selected: true,
|
|
17
|
+
menuItems: [
|
|
18
|
+
{ name: 'transaction_id', label: 'Transaction ID', selected: true },
|
|
19
|
+
{ name: 'transaction_amount', label: 'Amount', selected: true },
|
|
20
|
+
{ name: 'transaction_status', label: 'Status', selected: false },
|
|
21
|
+
{ name: 'transaction_type', label: 'Type', selected: false },
|
|
22
|
+
],
|
|
23
|
+
},
|
|
24
|
+
{
|
|
25
|
+
name: 'payment',
|
|
26
|
+
label: 'Payment',
|
|
27
|
+
selected: false,
|
|
28
|
+
menuItems: [
|
|
29
|
+
{ name: 'payment_method', label: 'Method', selected: false },
|
|
30
|
+
{ name: 'payment_card', label: 'Card', selected: false },
|
|
31
|
+
{ name: 'payment_bank', label: 'Bank', selected: false },
|
|
32
|
+
],
|
|
33
|
+
},
|
|
34
|
+
];
|
|
35
|
+
export const sheetColumns = [
|
|
36
|
+
{ name: 'customerID', label: 'Customer ID', selected: true },
|
|
37
|
+
{ name: 'customerName', label: 'Customer Name', selected: true },
|
|
38
|
+
{ name: 'amount', label: 'Amount', selected: true },
|
|
39
|
+
{ name: 'status', label: 'Status', selected: false },
|
|
40
|
+
{ name: 'currency', label: 'Currency', selected: false },
|
|
41
|
+
{ name: 'reference', label: 'Reference', selected: true },
|
|
42
|
+
];
|
|
43
|
+
export const defaultViewList = [
|
|
44
|
+
{
|
|
45
|
+
label: 'Default',
|
|
46
|
+
id: 'default',
|
|
47
|
+
},
|
|
48
|
+
];
|
|
@@ -1,3 +1,9 @@
|
|
|
1
1
|
export { useSubMenu } from './useSubMenu';
|
|
2
2
|
export { useViewColumns } from './useViewColumns';
|
|
3
3
|
export { useColumnItem } from './useColumnItem';
|
|
4
|
+
export { useViewsManager } from './useViewsManager';
|
|
5
|
+
export { useViewSelector } from './useViewSelector';
|
|
6
|
+
export { useSubmenuHover } from './useSubmenuHover';
|
|
7
|
+
export { useOriginalColumns } from './useOriginalColumns';
|
|
8
|
+
export { useNestedSubmenu } from './useNestedSubmenu';
|
|
9
|
+
export { useCreateViewDialog } from './useCreateViewDialog';
|
|
@@ -1,3 +1,9 @@
|
|
|
1
1
|
export { useSubMenu } from './useSubMenu';
|
|
2
2
|
export { useViewColumns } from './useViewColumns';
|
|
3
3
|
export { useColumnItem } from './useColumnItem';
|
|
4
|
+
export { useViewsManager } from './useViewsManager';
|
|
5
|
+
export { useViewSelector } from './useViewSelector';
|
|
6
|
+
export { useSubmenuHover } from './useSubmenuHover';
|
|
7
|
+
export { useOriginalColumns } from './useOriginalColumns';
|
|
8
|
+
export { useNestedSubmenu } from './useNestedSubmenu';
|
|
9
|
+
export { useCreateViewDialog } from './useCreateViewDialog';
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/// <reference types="react" />
|
|
2
|
+
import type { ColumnViewProps } from '../../../../types/index.js';
|
|
3
|
+
import type { UseCreateViewDialogProps } from '../types';
|
|
4
|
+
export declare const useCreateViewDialog: ({ open, availableColumns, defaultColumns, editingView, tableViews }: UseCreateViewDialogProps) => {
|
|
5
|
+
templateName: string;
|
|
6
|
+
setTemplateName: import("react").Dispatch<import("react").SetStateAction<string>>;
|
|
7
|
+
selectedColumns: ColumnViewProps[];
|
|
8
|
+
columnNames: string[];
|
|
9
|
+
allSelected: boolean;
|
|
10
|
+
someSelected: boolean;
|
|
11
|
+
isNameValid: boolean;
|
|
12
|
+
hoveredColumn: string | null;
|
|
13
|
+
anchorEl: HTMLElement | null;
|
|
14
|
+
openSubmenu: (columnName: string, element: HTMLElement) => void;
|
|
15
|
+
closeSubmenu: () => void;
|
|
16
|
+
cancelClose: () => void;
|
|
17
|
+
handleReorder: (reorderedNames: string[]) => void;
|
|
18
|
+
handleColumnToggle: (columnName: string) => void;
|
|
19
|
+
handleSubItemToggle: (columnName: string, subItemName: string) => void;
|
|
20
|
+
handleSelectAll: () => void;
|
|
21
|
+
handleResetToDefault: () => void;
|
|
22
|
+
};
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import { useState, useEffect, useMemo, useRef } from 'react';
|
|
2
|
+
import { DATE_COLUMN_CONFIG, TEMPLATE_NAME_MAX_LENGTH } from '../constants';
|
|
3
|
+
import { initializeEditingColumns, initializeCreateColumns, initializeCreateColumnsWithCurrentState, resetColumnsToDefault, toggleColumn, toggleSubItem, toggleAllColumns, areAllColumnsSelected, areSomeColumnsSelected, isValidTemplateName, } from '../utils';
|
|
4
|
+
import { useSubmenuHover } from './useSubmenuHover';
|
|
5
|
+
export const useCreateViewDialog = ({ open, availableColumns, defaultColumns, editingView, tableViews = [] }) => {
|
|
6
|
+
const [templateName, setTemplateName] = useState(() => (editingView === null || editingView === void 0 ? void 0 : editingView.label) || '');
|
|
7
|
+
const [selectedColumns, setSelectedColumns] = useState([]);
|
|
8
|
+
const previousOpenRef = useRef(false);
|
|
9
|
+
const { hoveredColumn, anchorEl, openSubmenu, closeSubmenu, cancelClose } = useSubmenuHover();
|
|
10
|
+
const dateColumn = DATE_COLUMN_CONFIG;
|
|
11
|
+
useEffect(() => {
|
|
12
|
+
var _a, _b;
|
|
13
|
+
if (!open) {
|
|
14
|
+
previousOpenRef.current = false;
|
|
15
|
+
return;
|
|
16
|
+
}
|
|
17
|
+
const wasClosed = !previousOpenRef.current;
|
|
18
|
+
if (wasClosed && open) {
|
|
19
|
+
if (editingView) {
|
|
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);
|
|
25
|
+
setSelectedColumns([dateColumn, ...otherColumns]);
|
|
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);
|
|
29
|
+
}
|
|
30
|
+
else {
|
|
31
|
+
const otherColumns = tableViews && tableViews.length > 0
|
|
32
|
+
? initializeCreateColumnsWithCurrentState(availableColumns, tableViews)
|
|
33
|
+
: initializeCreateColumns(availableColumns);
|
|
34
|
+
setSelectedColumns([dateColumn, ...otherColumns]);
|
|
35
|
+
setTemplateName('');
|
|
36
|
+
}
|
|
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
|
+
}
|
|
43
|
+
previousOpenRef.current = open;
|
|
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]);
|
|
45
|
+
const columnNames = useMemo(() => selectedColumns.map((col) => col.name), [selectedColumns]);
|
|
46
|
+
const allSelected = useMemo(() => areAllColumnsSelected(selectedColumns), [selectedColumns]);
|
|
47
|
+
const someSelected = useMemo(() => areSomeColumnsSelected(selectedColumns, allSelected), [selectedColumns, allSelected]);
|
|
48
|
+
const isNameValid = useMemo(() => isValidTemplateName(templateName, TEMPLATE_NAME_MAX_LENGTH), [templateName]);
|
|
49
|
+
const handleReorder = (reorderedNames) => {
|
|
50
|
+
const reorderedColumns = reorderedNames
|
|
51
|
+
.map((name) => selectedColumns.find((col) => col.name === name))
|
|
52
|
+
.filter((col) => Boolean(col));
|
|
53
|
+
setSelectedColumns(reorderedColumns);
|
|
54
|
+
};
|
|
55
|
+
const handleColumnToggle = (columnName) => {
|
|
56
|
+
setSelectedColumns((prev) => toggleColumn(prev, columnName));
|
|
57
|
+
};
|
|
58
|
+
const handleSubItemToggle = (columnName, subItemName) => {
|
|
59
|
+
setSelectedColumns((prev) => toggleSubItem(prev, columnName, subItemName));
|
|
60
|
+
};
|
|
61
|
+
const handleSelectAll = () => {
|
|
62
|
+
setSelectedColumns((prev) => toggleAllColumns(prev, !allSelected));
|
|
63
|
+
};
|
|
64
|
+
const handleResetToDefault = () => {
|
|
65
|
+
const columnsSource = defaultColumns.length > 0 ? defaultColumns : availableColumns;
|
|
66
|
+
const otherColumns = resetColumnsToDefault(columnsSource);
|
|
67
|
+
setSelectedColumns([dateColumn, ...otherColumns]);
|
|
68
|
+
};
|
|
69
|
+
return {
|
|
70
|
+
templateName,
|
|
71
|
+
setTemplateName,
|
|
72
|
+
selectedColumns,
|
|
73
|
+
columnNames,
|
|
74
|
+
allSelected,
|
|
75
|
+
someSelected,
|
|
76
|
+
isNameValid,
|
|
77
|
+
hoveredColumn,
|
|
78
|
+
anchorEl,
|
|
79
|
+
openSubmenu,
|
|
80
|
+
closeSubmenu,
|
|
81
|
+
cancelClose,
|
|
82
|
+
handleReorder,
|
|
83
|
+
handleColumnToggle,
|
|
84
|
+
handleSubItemToggle,
|
|
85
|
+
handleSelectAll,
|
|
86
|
+
handleResetToDefault,
|
|
87
|
+
};
|
|
88
|
+
};
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { useState, useCallback } from 'react';
|
|
2
|
+
export const useDialogPosition = (dialogWidth, dialogHeight) => {
|
|
3
|
+
const [position, setPosition] = useState({ x: 0, y: 0 });
|
|
4
|
+
const resetPosition = useCallback(() => {
|
|
5
|
+
const centerX = window.innerWidth / 2 - dialogWidth / 2;
|
|
6
|
+
const centerY = window.innerHeight / 2 - dialogHeight / 2;
|
|
7
|
+
setPosition({
|
|
8
|
+
x: Math.max(0, centerX),
|
|
9
|
+
y: Math.max(0, centerY),
|
|
10
|
+
});
|
|
11
|
+
}, [dialogWidth, dialogHeight]);
|
|
12
|
+
const updatePosition = useCallback((x, y) => {
|
|
13
|
+
setPosition({ x, y });
|
|
14
|
+
}, []);
|
|
15
|
+
return { position, resetPosition, updatePosition };
|
|
16
|
+
};
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export declare const useNestedSubmenu: () => {
|
|
2
|
+
hoveredNestedColumn: string | null;
|
|
3
|
+
nestedSubmenuAnchorEl: HTMLElement | null;
|
|
4
|
+
openNestedSubmenu: (columnName: string, element: HTMLElement) => void;
|
|
5
|
+
closeNestedSubmenu: () => void;
|
|
6
|
+
cancelNestedClose: () => void;
|
|
7
|
+
};
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { useState, useRef, useCallback } from 'react';
|
|
2
|
+
import { SUBMENU_CLOSE_DELAY } from '../constants';
|
|
3
|
+
export const useNestedSubmenu = () => {
|
|
4
|
+
const [hoveredNestedColumn, setHoveredNestedColumn] = useState(null);
|
|
5
|
+
const [nestedSubmenuAnchorEl, setNestedSubmenuAnchorEl] = useState(null);
|
|
6
|
+
const nestedCloseTimeoutRef = useRef(null);
|
|
7
|
+
const openNestedSubmenu = useCallback((columnName, element) => {
|
|
8
|
+
if (nestedCloseTimeoutRef.current) {
|
|
9
|
+
clearTimeout(nestedCloseTimeoutRef.current);
|
|
10
|
+
nestedCloseTimeoutRef.current = null;
|
|
11
|
+
}
|
|
12
|
+
setHoveredNestedColumn(columnName);
|
|
13
|
+
setNestedSubmenuAnchorEl(element);
|
|
14
|
+
}, []);
|
|
15
|
+
const closeNestedSubmenu = useCallback(() => {
|
|
16
|
+
nestedCloseTimeoutRef.current = setTimeout(() => {
|
|
17
|
+
setHoveredNestedColumn(null);
|
|
18
|
+
setNestedSubmenuAnchorEl(null);
|
|
19
|
+
}, SUBMENU_CLOSE_DELAY);
|
|
20
|
+
}, []);
|
|
21
|
+
const cancelNestedClose = useCallback(() => {
|
|
22
|
+
if (nestedCloseTimeoutRef.current) {
|
|
23
|
+
clearTimeout(nestedCloseTimeoutRef.current);
|
|
24
|
+
nestedCloseTimeoutRef.current = null;
|
|
25
|
+
}
|
|
26
|
+
}, []);
|
|
27
|
+
return {
|
|
28
|
+
hoveredNestedColumn,
|
|
29
|
+
nestedSubmenuAnchorEl,
|
|
30
|
+
openNestedSubmenu,
|
|
31
|
+
closeNestedSubmenu,
|
|
32
|
+
cancelNestedClose,
|
|
33
|
+
};
|
|
34
|
+
};
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { useState, useCallback } from 'react';
|
|
2
|
+
export const useOriginalColumns = (defaultColumns) => {
|
|
3
|
+
const [originalColumns, setOriginalColumns] = useState([]);
|
|
4
|
+
const saveOriginalState = useCallback(() => {
|
|
5
|
+
setOriginalColumns(defaultColumns.map((col) => {
|
|
6
|
+
var _a;
|
|
7
|
+
return (Object.assign(Object.assign({}, col), { selected: col.selected, menuItems: (_a = col.menuItems) === null || _a === void 0 ? void 0 : _a.map((item) => (Object.assign(Object.assign({}, item), { selected: item.selected }))) }));
|
|
8
|
+
}));
|
|
9
|
+
}, [defaultColumns]);
|
|
10
|
+
const clearOriginalState = useCallback(() => {
|
|
11
|
+
setOriginalColumns([]);
|
|
12
|
+
}, []);
|
|
13
|
+
return {
|
|
14
|
+
originalColumns,
|
|
15
|
+
saveOriginalState,
|
|
16
|
+
clearOriginalState,
|
|
17
|
+
};
|
|
18
|
+
};
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { useState, useRef, useCallback } from 'react';
|
|
2
|
+
import { SUBMENU_CLOSE_DELAY } from '../constants';
|
|
3
|
+
export const useSubmenuHover = () => {
|
|
4
|
+
const [hoveredColumn, setHoveredColumn] = useState(null);
|
|
5
|
+
const [anchorEl, setAnchorEl] = useState(null);
|
|
6
|
+
const closeTimeoutRef = useRef(null);
|
|
7
|
+
const openSubmenu = useCallback((columnName, element) => {
|
|
8
|
+
if (closeTimeoutRef.current) {
|
|
9
|
+
clearTimeout(closeTimeoutRef.current);
|
|
10
|
+
closeTimeoutRef.current = null;
|
|
11
|
+
}
|
|
12
|
+
setHoveredColumn(columnName);
|
|
13
|
+
setAnchorEl(element);
|
|
14
|
+
}, []);
|
|
15
|
+
const closeSubmenu = useCallback(() => {
|
|
16
|
+
closeTimeoutRef.current = setTimeout(() => {
|
|
17
|
+
setHoveredColumn(null);
|
|
18
|
+
setAnchorEl(null);
|
|
19
|
+
}, SUBMENU_CLOSE_DELAY);
|
|
20
|
+
}, []);
|
|
21
|
+
const cancelClose = useCallback(() => {
|
|
22
|
+
if (closeTimeoutRef.current) {
|
|
23
|
+
clearTimeout(closeTimeoutRef.current);
|
|
24
|
+
closeTimeoutRef.current = null;
|
|
25
|
+
}
|
|
26
|
+
}, []);
|
|
27
|
+
const forceClose = useCallback(() => {
|
|
28
|
+
if (closeTimeoutRef.current) {
|
|
29
|
+
clearTimeout(closeTimeoutRef.current);
|
|
30
|
+
closeTimeoutRef.current = null;
|
|
31
|
+
}
|
|
32
|
+
setHoveredColumn(null);
|
|
33
|
+
setAnchorEl(null);
|
|
34
|
+
}, []);
|
|
35
|
+
return {
|
|
36
|
+
hoveredColumn,
|
|
37
|
+
anchorEl,
|
|
38
|
+
openSubmenu,
|
|
39
|
+
closeSubmenu,
|
|
40
|
+
cancelClose,
|
|
41
|
+
forceClose,
|
|
42
|
+
};
|
|
43
|
+
};
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { type MouseEvent } from 'react';
|
|
2
|
+
import type { ColumnViewProps } from '../../../../types/index.js';
|
|
3
|
+
import type { ViewMenuItem, LayoutSection, ViewMode } from '../types';
|
|
4
|
+
import type { ViewOption } from '../../type';
|
|
5
|
+
export interface UseViewSelectorProps {
|
|
6
|
+
mode: ViewMode;
|
|
7
|
+
onViewChange?: (selectedView?: ViewMenuItem) => void;
|
|
8
|
+
onTableViewsChange?: (tableViews: ColumnViewProps[]) => void;
|
|
9
|
+
onCustomViewsChange?: (customViews: ViewMenuItem[]) => void;
|
|
10
|
+
onCreateCustomView?: (data: {
|
|
11
|
+
name: string;
|
|
12
|
+
selectedColumns: ColumnViewProps[];
|
|
13
|
+
layout: LayoutSection;
|
|
14
|
+
}) => Promise<void>;
|
|
15
|
+
onEditCustomView?: (viewId: string, data: {
|
|
16
|
+
name: string;
|
|
17
|
+
selectedColumns: ColumnViewProps[];
|
|
18
|
+
layout: LayoutSection;
|
|
19
|
+
}) => Promise<void>;
|
|
20
|
+
onDeleteCustomView?: (viewId: string) => Promise<void>;
|
|
21
|
+
resetTableViews?: (view: {
|
|
22
|
+
id: string;
|
|
23
|
+
label: string;
|
|
24
|
+
}) => void;
|
|
25
|
+
setTableViews?: (columns: ColumnViewProps[]) => void;
|
|
26
|
+
tableViews: ColumnViewProps[];
|
|
27
|
+
customViews: ViewMenuItem[];
|
|
28
|
+
defaultColumns: ColumnViewProps[];
|
|
29
|
+
defaultTemplate?: ViewMenuItem;
|
|
30
|
+
setInternalCustomViews: (views: ViewMenuItem[]) => void;
|
|
31
|
+
setInternalTableViews: (views: ColumnViewProps[]) => void;
|
|
32
|
+
}
|
|
33
|
+
export declare const useViewSelector: ({ mode, onViewChange, onTableViewsChange, onCustomViewsChange, onCreateCustomView, onEditCustomView, onDeleteCustomView, resetTableViews, setTableViews, tableViews, customViews, defaultColumns, defaultTemplate, setInternalCustomViews, setInternalTableViews, }: UseViewSelectorProps) => {
|
|
34
|
+
anchorViewEl: HTMLDivElement | null;
|
|
35
|
+
defaultViewEl: HTMLDivElement | null;
|
|
36
|
+
setDefaultViewElement: import("react").Dispatch<import("react").SetStateAction<HTMLDivElement | null>>;
|
|
37
|
+
isCreateDialogOpen: boolean;
|
|
38
|
+
editingView: ViewMenuItem | null;
|
|
39
|
+
selectedViewInfo: ViewOption;
|
|
40
|
+
shouldUseCurrentState: boolean;
|
|
41
|
+
handleViewButtonClick: (event: MouseEvent<HTMLDivElement>) => void;
|
|
42
|
+
handleCloseViewDropdown: () => void;
|
|
43
|
+
handleClose: () => void;
|
|
44
|
+
handleSelectedViewInfo: (selected: ViewOption, viewMenuItem?: ViewMenuItem) => void;
|
|
45
|
+
handleOpenCreateDialog: (useCurrentState?: boolean) => void;
|
|
46
|
+
handleOpenEditDialog: (view: ViewMenuItem) => void;
|
|
47
|
+
handleCloseCreateDialog: () => void;
|
|
48
|
+
handleSaveView: (data: {
|
|
49
|
+
name: string;
|
|
50
|
+
selectedColumns: ColumnViewProps[];
|
|
51
|
+
layout: LayoutSection;
|
|
52
|
+
}) => Promise<void>;
|
|
53
|
+
handleDeleteView: (viewId: string) => Promise<void>;
|
|
54
|
+
handleResetViews: (views: string[]) => void;
|
|
55
|
+
handleTableViewsChange: (newTableViews: ColumnViewProps[]) => void;
|
|
56
|
+
};
|
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
2
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
3
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
4
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
5
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
6
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
7
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
|
+
});
|
|
9
|
+
};
|
|
10
|
+
import { useState, useCallback, useEffect } from 'react';
|
|
11
|
+
import { createCustomViewMenuItem } from '../utils';
|
|
12
|
+
export const useViewSelector = ({ mode, onViewChange, onTableViewsChange, onCustomViewsChange, onCreateCustomView, onEditCustomView, onDeleteCustomView, resetTableViews, setTableViews, tableViews, customViews, defaultColumns, defaultTemplate, setInternalCustomViews, setInternalTableViews, }) => {
|
|
13
|
+
const [anchorViewEl, setAnchorViewEl] = useState(null);
|
|
14
|
+
const [defaultViewEl, setDefaultViewElement] = useState(null);
|
|
15
|
+
const [isCreateDialogOpen, setIsCreateDialogOpen] = useState(false);
|
|
16
|
+
const [editingView, setEditingView] = useState(null);
|
|
17
|
+
const [selectedViewInfo, setSelectedViewInfo] = useState({ id: 'default', label: 'Default' });
|
|
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]);
|
|
54
|
+
const handleTableViewsChange = useCallback((newTableViews) => {
|
|
55
|
+
const setTableViewsState = setTableViews !== null && setTableViews !== void 0 ? setTableViews : setInternalTableViews;
|
|
56
|
+
setTableViewsState(newTableViews);
|
|
57
|
+
onTableViewsChange === null || onTableViewsChange === void 0 ? void 0 : onTableViewsChange(newTableViews);
|
|
58
|
+
}, [setTableViews, setInternalTableViews, onTableViewsChange]);
|
|
59
|
+
const handleCustomViewsChange = useCallback((newCustomViews) => {
|
|
60
|
+
setInternalCustomViews(newCustomViews);
|
|
61
|
+
onCustomViewsChange === null || onCustomViewsChange === void 0 ? void 0 : onCustomViewsChange(newCustomViews);
|
|
62
|
+
}, [setInternalCustomViews, onCustomViewsChange]);
|
|
63
|
+
const handleViewButtonClick = useCallback((event) => {
|
|
64
|
+
setAnchorViewEl(event.currentTarget);
|
|
65
|
+
setDefaultViewElement(event.currentTarget);
|
|
66
|
+
}, []);
|
|
67
|
+
const handleCloseViewDropdown = useCallback(() => {
|
|
68
|
+
setDefaultViewElement(null);
|
|
69
|
+
}, []);
|
|
70
|
+
const handleClose = useCallback(() => {
|
|
71
|
+
setAnchorViewEl(null);
|
|
72
|
+
setDefaultViewElement(null);
|
|
73
|
+
setSelectedViewInfo({ label: 'Default', id: 'default' });
|
|
74
|
+
}, []);
|
|
75
|
+
const handleSelectedViewInfo = useCallback((selected, viewMenuItem) => {
|
|
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);
|
|
82
|
+
handleCloseViewDropdown();
|
|
83
|
+
}, [handleCloseViewDropdown, onViewChange]);
|
|
84
|
+
const handleOpenCreateDialog = useCallback((useCurrentState = false) => {
|
|
85
|
+
setEditingView(null);
|
|
86
|
+
setShouldUseCurrentState(useCurrentState);
|
|
87
|
+
setIsCreateDialogOpen(true);
|
|
88
|
+
setDefaultViewElement(null);
|
|
89
|
+
}, []);
|
|
90
|
+
const handleOpenEditDialog = useCallback((view) => {
|
|
91
|
+
setEditingView(view);
|
|
92
|
+
setShouldUseCurrentState(true);
|
|
93
|
+
setIsCreateDialogOpen(true);
|
|
94
|
+
}, []);
|
|
95
|
+
const handleCloseCreateDialog = useCallback(() => {
|
|
96
|
+
setIsCreateDialogOpen(false);
|
|
97
|
+
setEditingView(null);
|
|
98
|
+
setShouldUseCurrentState(false);
|
|
99
|
+
}, []);
|
|
100
|
+
const handleSaveView = useCallback((data) => __awaiter(void 0, void 0, void 0, function* () {
|
|
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
|
+
}
|
|
123
|
+
}
|
|
124
|
+
catch (error) {
|
|
125
|
+
// Error will be handled by the toast in CreateViewDialog
|
|
126
|
+
throw error;
|
|
127
|
+
}
|
|
128
|
+
}), [editingView, customViews, handleCustomViewsChange, onEditCustomView, onCreateCustomView, selectedView, onViewChange]);
|
|
129
|
+
const handleDeleteView = useCallback((viewId) => __awaiter(void 0, void 0, void 0, function* () {
|
|
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]);
|
|
146
|
+
const handleResetViews = useCallback((views) => {
|
|
147
|
+
if (resetTableViews) {
|
|
148
|
+
resetTableViews({ id: views[0], label: views[0] });
|
|
149
|
+
}
|
|
150
|
+
else {
|
|
151
|
+
// Reset to default columns from templates
|
|
152
|
+
handleTableViewsChange([...defaultColumns]);
|
|
153
|
+
}
|
|
154
|
+
}, [resetTableViews, defaultColumns, handleTableViewsChange]);
|
|
155
|
+
return {
|
|
156
|
+
// State
|
|
157
|
+
anchorViewEl,
|
|
158
|
+
defaultViewEl,
|
|
159
|
+
setDefaultViewElement,
|
|
160
|
+
isCreateDialogOpen,
|
|
161
|
+
editingView,
|
|
162
|
+
selectedViewInfo,
|
|
163
|
+
shouldUseCurrentState,
|
|
164
|
+
// Handlers
|
|
165
|
+
handleViewButtonClick,
|
|
166
|
+
handleCloseViewDropdown,
|
|
167
|
+
handleClose,
|
|
168
|
+
handleSelectedViewInfo,
|
|
169
|
+
handleOpenCreateDialog,
|
|
170
|
+
handleOpenEditDialog,
|
|
171
|
+
handleCloseCreateDialog,
|
|
172
|
+
handleSaveView,
|
|
173
|
+
handleDeleteView,
|
|
174
|
+
handleResetViews,
|
|
175
|
+
handleTableViewsChange,
|
|
176
|
+
};
|
|
177
|
+
};
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/// <reference types="react" />
|
|
2
|
+
import type { ColumnViewProps } from '../../../../types/index.js';
|
|
3
|
+
import type { UseViewsManagerProps, ViewMenuItem } from '../types';
|
|
4
|
+
export declare const useViewsManager: ({ mode, templates, lang }: UseViewsManagerProps) => {
|
|
5
|
+
defaultColumns: ColumnViewProps[];
|
|
6
|
+
setDefaultColumns: import("react").Dispatch<import("react").SetStateAction<ColumnViewProps[]>>;
|
|
7
|
+
internalTableViews: ColumnViewProps[];
|
|
8
|
+
setInternalTableViews: import("react").Dispatch<import("react").SetStateAction<ColumnViewProps[]>>;
|
|
9
|
+
internalCustomViews: ViewMenuItem[];
|
|
10
|
+
setInternalCustomViews: import("react").Dispatch<import("react").SetStateAction<ViewMenuItem[]>>;
|
|
11
|
+
defaultTemplate: ViewMenuItem | undefined;
|
|
12
|
+
};
|