@antscorp/antsomi-ui 1.3.7-beta.3 → 1.3.7-beta.31
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/es/components/atoms/InputDynamic/InputDynamic.js +3 -3
- package/es/components/atoms/index.d.ts +0 -2
- package/es/components/atoms/index.js +0 -2
- package/es/components/molecules/AddDynamicContent/AddDynamicContent.js +28 -2
- package/es/components/molecules/AddDynamicContent/constants.d.ts +2 -0
- package/es/components/molecules/AddDynamicContent/constants.js +2 -0
- package/es/components/molecules/EmojiPopover/EmojiPopover.d.ts +1 -0
- package/es/components/molecules/EmojiPopover/EmojiPopover.js +2 -2
- package/es/components/molecules/EmojiPopover/styled.d.ts +2 -2
- package/es/components/molecules/EmojiPopover/styled.js +1 -1
- package/es/components/molecules/SearchPopover/SearchPopover.js +2 -2
- package/es/components/molecules/SearchPopover/styled.d.ts +12 -1
- package/es/components/molecules/SearchPopover/styled.js +1 -2
- package/es/components/molecules/SearchPopover/types.d.ts +4 -3
- package/es/components/molecules/TagifyInput/TagifyInput.js +55 -19
- package/es/components/molecules/TagifyInput/types.d.ts +20 -1
- package/es/components/molecules/TagifyInput/utils.d.ts +6 -1
- package/es/components/molecules/TagifyInput/utils.js +19 -0
- package/es/components/molecules/VirtualizedMenu/VirtualizedMenu.d.ts +1 -0
- package/es/components/molecules/VirtualizedMenu/components/Item/Item.js +3 -7
- package/es/components/molecules/VirtualizedMenu/components/MenuInline/MenuInline.d.ts +10 -10
- package/es/components/molecules/VirtualizedMenu/components/MenuInline/MenuInline.js +46 -327
- package/es/components/molecules/VirtualizedMenu/components/MenuInline/hooks/index.d.ts +9 -0
- package/es/components/molecules/VirtualizedMenu/components/MenuInline/hooks/index.js +5 -0
- package/es/components/molecules/VirtualizedMenu/components/MenuInline/hooks/useFocusManagement.d.ts +23 -0
- package/es/components/molecules/VirtualizedMenu/components/MenuInline/hooks/useFocusManagement.js +81 -0
- package/es/components/molecules/VirtualizedMenu/components/MenuInline/hooks/useItemInteraction.d.ts +24 -0
- package/es/components/molecules/VirtualizedMenu/components/MenuInline/hooks/useItemInteraction.js +32 -0
- package/es/components/molecules/VirtualizedMenu/components/MenuInline/hooks/useKeyboardNavigation.d.ts +26 -0
- package/es/components/molecules/VirtualizedMenu/components/MenuInline/hooks/useKeyboardNavigation.js +93 -0
- package/es/components/molecules/VirtualizedMenu/components/MenuInline/hooks/useTreeState.d.ts +24 -0
- package/es/components/molecules/VirtualizedMenu/components/MenuInline/hooks/useTreeState.js +94 -0
- package/es/components/molecules/VirtualizedMenu/components/MenuInline/hooks/useVisibleItems.d.ts +7 -0
- package/es/components/molecules/VirtualizedMenu/components/MenuInline/hooks/useVisibleItems.js +132 -0
- package/es/components/molecules/VirtualizedMenu/styled.js +14 -3
- package/es/components/molecules/VirtualizedMenu/types.d.ts +1 -0
- package/es/components/molecules/VirtualizedMenu/utils.d.ts +1 -0
- package/es/components/molecules/VirtualizedMenu/utils.js +1 -0
- package/es/components/organism/ActivityTimeline/ActivityTimeline.js +3 -3
- package/es/components/organism/ActivityTimeline/constants.d.ts +9 -9
- package/es/components/organism/ActivityTimeline/constants.js +3 -3
- package/es/components/organism/ActivityTimeline/index.d.ts +530 -1
- package/es/components/organism/ActivityTimeline/index.js +9 -1
- package/es/components/organism/ActivityTimeline/utils.js +7 -6
- package/es/components/organism/TextEditor/TextEditor.d.ts +9 -2
- package/es/components/organism/TextEditor/TextEditor.js +181 -40
- package/es/components/organism/TextEditor/constants.d.ts +9 -0
- package/es/components/organism/TextEditor/constants.js +66 -0
- package/es/components/organism/TextEditor/extensions/BubbleMenu/bubble-menu-plugin.d.ts +6 -128
- package/es/components/organism/TextEditor/extensions/BubbleMenu/bubble-menu-plugin.js +7 -292
- package/es/components/organism/TextEditor/extensions/BubbleMenu/bubble-menu.d.ts +1 -1
- package/es/components/organism/TextEditor/extensions/BubbleMenu/bubble-menu.js +4 -0
- package/es/components/organism/TextEditor/extensions/Link.js +3 -3
- package/es/components/organism/TextEditor/extensions/ListItem.d.ts +10 -0
- package/es/components/organism/TextEditor/extensions/ListItem.js +93 -0
- package/es/components/organism/TextEditor/extensions/SmartTag.d.ts +5 -6
- package/es/components/organism/TextEditor/extensions/SmartTag.js +94 -2
- package/es/components/organism/TextEditor/hooks/useColorSet.js +7 -0
- package/es/components/organism/TextEditor/hooks/useMarkTracking.js +2 -1
- package/es/components/organism/TextEditor/index.d.ts +7 -5
- package/es/components/organism/TextEditor/index.scss +4 -7
- package/es/components/organism/TextEditor/provider.d.ts +1 -0
- package/es/components/organism/TextEditor/provider.js +6 -3
- package/es/components/organism/TextEditor/store.d.ts +11 -4
- package/es/components/organism/TextEditor/store.js +22 -2
- package/es/components/organism/TextEditor/stories/WithOldDynAndLink/froala-legacy-format.settings.json +95 -0
- package/es/components/organism/TextEditor/stories/WithOldDynAndLink/shared.d.ts +111 -0
- package/es/components/organism/TextEditor/stories/WithOldDynAndLink/shared.js +82 -0
- package/es/components/organism/TextEditor/stories/shared.d.ts +64 -0
- package/es/components/organism/TextEditor/stories/shared.js +57 -0
- package/es/components/organism/TextEditor/styled.d.ts +1 -1
- package/es/components/organism/TextEditor/styled.js +1 -0
- package/es/components/organism/TextEditor/types.d.ts +153 -9
- package/es/components/organism/TextEditor/types.js +1 -0
- package/es/components/organism/TextEditor/ui/BubbleMenu/BubbleMenu.d.ts +2 -1
- package/es/components/organism/TextEditor/ui/BubbleMenu/BubbleMenu.js +80 -51
- package/es/components/organism/TextEditor/ui/Emoji/EmojiList.js +1 -1
- package/es/components/organism/TextEditor/ui/Emoji/suggestion.d.ts +1 -1
- package/es/components/organism/TextEditor/ui/Emoji/suggestion.js +2 -2
- package/es/components/organism/TextEditor/ui/FontPopover/FontPopover.js +12 -2
- package/es/components/organism/TextEditor/ui/LinkInsertForm/LinkInsertForm.d.ts +16 -0
- package/es/components/organism/TextEditor/ui/LinkInsertForm/LinkInsertForm.js +61 -0
- package/es/components/organism/TextEditor/ui/LinkInsertForm/index.d.ts +2 -0
- package/es/components/organism/TextEditor/ui/LinkInsertForm/index.js +1 -0
- package/es/components/organism/TextEditor/ui/LinkPopover/LinkPopover.d.ts +9 -0
- package/es/components/organism/TextEditor/ui/LinkPopover/LinkPopover.js +126 -0
- package/es/components/organism/TextEditor/ui/LinkPopover/index.d.ts +2 -0
- package/es/components/organism/TextEditor/ui/LinkPopover/index.js +1 -0
- package/es/components/organism/TextEditor/ui/Popover/Popover.js +1 -1
- package/es/components/organism/TextEditor/ui/TextAlignSelect/TextAlignSelect.js +1 -3
- package/es/components/organism/TextEditor/ui/Toolbar/{Toolbar.d.ts → FormattingToolbar.d.ts} +3 -4
- package/es/components/organism/TextEditor/ui/Toolbar/FormattingToolbar.js +85 -0
- package/es/components/organism/TextEditor/ui/Toolbar/LinkPreviewToolbar.d.ts +10 -0
- package/es/components/organism/TextEditor/ui/Toolbar/LinkPreviewToolbar.js +39 -0
- package/es/components/organism/TextEditor/ui/Toolbar/actions/EmojiAction.js +4 -3
- package/es/components/organism/TextEditor/ui/Toolbar/actions/FontFamilyAction.d.ts +1 -0
- package/es/components/organism/TextEditor/ui/Toolbar/actions/FontFamilyAction.js +2 -2
- package/es/components/organism/TextEditor/ui/Toolbar/actions/FontSizeAction.js +6 -1
- package/es/components/organism/TextEditor/ui/Toolbar/index.d.ts +2 -1
- package/es/components/organism/TextEditor/ui/Toolbar/index.js +2 -1
- package/es/components/organism/TextEditor/utils/documentState.d.ts +14 -0
- package/es/components/organism/TextEditor/utils/documentState.js +25 -0
- package/es/components/organism/TextEditor/utils/htmlProcessing.js +60 -0
- package/es/components/organism/TextEditor/utils/link.d.ts +10 -1
- package/es/components/organism/TextEditor/utils/link.js +161 -7
- package/es/components/organism/TextEditor/utils/menu.js +2 -1
- package/es/components/organism/TextEditor/utils/selection.js +3 -2
- package/es/components/organism/TextEditor/utils/smartTag.js +2 -1
- package/es/components/organism/index.d.ts +1 -1
- package/es/hooks/index.d.ts +1 -1
- package/es/hooks/index.js +1 -1
- package/es/services/MediaTemplateDesign/UploadFile/index.js +4 -4
- package/es/types/index.d.ts +1 -1
- package/es/types/index.js +1 -1
- package/es/utils/common.d.ts +1 -1
- package/es/utils/common.js +3 -3
- package/package.json +23 -35
- package/es/components/organism/TextEditor/ui/BubbleToolbar/BubbleToolbar.d.ts +0 -1
- package/es/components/organism/TextEditor/ui/BubbleToolbar/BubbleToolbar.js +0 -1
- package/es/components/organism/TextEditor/ui/BubbleToolbar/index.d.ts +0 -0
- package/es/components/organism/TextEditor/ui/BubbleToolbar/index.js +0 -1
- package/es/components/organism/TextEditor/ui/Toolbar/Toolbar.js +0 -39
package/es/components/molecules/VirtualizedMenu/components/MenuInline/hooks/useKeyboardNavigation.js
ADDED
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
import { useCallback } from 'react';
|
|
2
|
+
/**
|
|
3
|
+
* Custom hook to handle keyboard navigation for tree menu
|
|
4
|
+
* Implements ARIA-compliant keyboard interaction patterns
|
|
5
|
+
*/
|
|
6
|
+
export const useKeyboardNavigation = (props) => {
|
|
7
|
+
const { visibleItems, focusId, expandedKeys, normalizeTreeItems, setFocusId, handleExpandItems, handleCollapseItems, handleSelectItem, handleToggleExpandItem, findNextFocusableItem, findFirstFocusableItem, findLastFocusableItem, onClick, } = props;
|
|
8
|
+
const handleKeyDown = useCallback((e) => {
|
|
9
|
+
if (visibleItems.length === 0)
|
|
10
|
+
return;
|
|
11
|
+
e.preventDefault();
|
|
12
|
+
const currentFocusIndex = visibleItems.findIndex(item => item.id === focusId);
|
|
13
|
+
if (currentFocusIndex === -1) {
|
|
14
|
+
const firstFocusableIndex = findFirstFocusableItem();
|
|
15
|
+
setFocusId(visibleItems[firstFocusableIndex]?.id ?? null);
|
|
16
|
+
return;
|
|
17
|
+
}
|
|
18
|
+
const currentFocusItem = visibleItems[currentFocusIndex];
|
|
19
|
+
switch (e.key) {
|
|
20
|
+
case 'ArrowDown': {
|
|
21
|
+
const nextFocusIndex = findNextFocusableItem(currentFocusIndex, 'next');
|
|
22
|
+
setFocusId(visibleItems[nextFocusIndex].id);
|
|
23
|
+
break;
|
|
24
|
+
}
|
|
25
|
+
case 'ArrowUp': {
|
|
26
|
+
const nextFocusIndex = findNextFocusableItem(currentFocusIndex, 'prev');
|
|
27
|
+
setFocusId(visibleItems[nextFocusIndex].id);
|
|
28
|
+
break;
|
|
29
|
+
}
|
|
30
|
+
case 'ArrowRight': {
|
|
31
|
+
if (currentFocusItem.childIds.length > 0 && !expandedKeys.has(currentFocusItem.id)) {
|
|
32
|
+
handleExpandItems([currentFocusItem]);
|
|
33
|
+
}
|
|
34
|
+
break;
|
|
35
|
+
}
|
|
36
|
+
case 'ArrowLeft': {
|
|
37
|
+
if (currentFocusItem.childIds.length > 0 && expandedKeys.has(currentFocusItem.id)) {
|
|
38
|
+
handleCollapseItems([currentFocusItem]);
|
|
39
|
+
}
|
|
40
|
+
else if (currentFocusItem?.parentId) {
|
|
41
|
+
// Find parent and ensure it's focusable
|
|
42
|
+
const parentItem = normalizeTreeItems.get(currentFocusItem.parentId);
|
|
43
|
+
if (parentItem && !parentItem.data.displayOnly) {
|
|
44
|
+
setFocusId(currentFocusItem.parentId);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
break;
|
|
48
|
+
}
|
|
49
|
+
case 'Home': {
|
|
50
|
+
const firstFocusableIndex = findFirstFocusableItem();
|
|
51
|
+
setFocusId(visibleItems[firstFocusableIndex].id);
|
|
52
|
+
break;
|
|
53
|
+
}
|
|
54
|
+
case 'End': {
|
|
55
|
+
const lastFocusableIndex = findLastFocusableItem();
|
|
56
|
+
setFocusId(visibleItems[lastFocusableIndex].id);
|
|
57
|
+
break;
|
|
58
|
+
}
|
|
59
|
+
case 'Enter': {
|
|
60
|
+
if (currentFocusItem && !currentFocusItem.data.displayOnly) {
|
|
61
|
+
handleSelectItem(currentFocusItem);
|
|
62
|
+
if (currentFocusItem.childIds.length > 0) {
|
|
63
|
+
handleToggleExpandItem(currentFocusItem);
|
|
64
|
+
}
|
|
65
|
+
onClick?.({
|
|
66
|
+
item: currentFocusItem.data,
|
|
67
|
+
elKey: 'item',
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
break;
|
|
71
|
+
}
|
|
72
|
+
default:
|
|
73
|
+
break;
|
|
74
|
+
}
|
|
75
|
+
}, [
|
|
76
|
+
visibleItems,
|
|
77
|
+
focusId,
|
|
78
|
+
expandedKeys,
|
|
79
|
+
normalizeTreeItems,
|
|
80
|
+
setFocusId,
|
|
81
|
+
handleExpandItems,
|
|
82
|
+
handleCollapseItems,
|
|
83
|
+
handleSelectItem,
|
|
84
|
+
handleToggleExpandItem,
|
|
85
|
+
findNextFocusableItem,
|
|
86
|
+
findFirstFocusableItem,
|
|
87
|
+
findLastFocusableItem,
|
|
88
|
+
onClick,
|
|
89
|
+
]);
|
|
90
|
+
return {
|
|
91
|
+
handleKeyDown,
|
|
92
|
+
};
|
|
93
|
+
};
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { NormalizedNode } from '@antscorp/antsomi-ui/es/utils/tree';
|
|
2
|
+
import { ItemType } from '../../../types';
|
|
3
|
+
export interface UseTreeStateReturn {
|
|
4
|
+
normalizeTreeItems: Map<string, NormalizedNode<ItemType>>;
|
|
5
|
+
rootItemIds: Set<string>;
|
|
6
|
+
rootNodes: NormalizedNode<ItemType>[];
|
|
7
|
+
expandedKeys: Set<string>;
|
|
8
|
+
selectedKeys: Set<string>;
|
|
9
|
+
handleExpandItems: (items: NormalizedNode<ItemType>[], deep?: number) => void;
|
|
10
|
+
handleCollapseItems: (items: NormalizedNode<ItemType>[]) => void;
|
|
11
|
+
handleToggleExpandItem: (item: NormalizedNode<ItemType>) => void;
|
|
12
|
+
handleSelectItem: (item: NormalizedNode<ItemType>) => void;
|
|
13
|
+
expandAll: () => void;
|
|
14
|
+
}
|
|
15
|
+
export interface UseTreeStateProps {
|
|
16
|
+
items: ItemType[];
|
|
17
|
+
expanded: string[];
|
|
18
|
+
selected: string | string[];
|
|
19
|
+
selectable: boolean;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Custom hook to manage tree state including expansion, selection, and normalization
|
|
23
|
+
*/
|
|
24
|
+
export declare const useTreeState: (props: UseTreeStateProps) => UseTreeStateReturn;
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import { useState, useCallback, useMemo, useEffect } from 'react';
|
|
2
|
+
import { useDeepCompareEffect } from '@antscorp/antsomi-ui/es/hooks';
|
|
3
|
+
import { findNodes, getChildrenRecursively, } from '@antscorp/antsomi-ui/es/utils/tree';
|
|
4
|
+
import { serializeItems } from '../../../utils';
|
|
5
|
+
/**
|
|
6
|
+
* Custom hook to manage tree state including expansion, selection, and normalization
|
|
7
|
+
*/
|
|
8
|
+
export const useTreeState = (props) => {
|
|
9
|
+
const { items: itemsProp, expanded: expandedProp, selected: selectedProp, selectable } = props;
|
|
10
|
+
const [expandedKeys, setExpandedKeys] = useState(new Set());
|
|
11
|
+
const [selectedKeys, setSelectedKeys] = useState(new Set());
|
|
12
|
+
const [{ items: normalizeTreeItems, rootItemIds }, setTreeState] = useState({
|
|
13
|
+
items: new Map(),
|
|
14
|
+
rootItemIds: new Set(),
|
|
15
|
+
});
|
|
16
|
+
// Sync external selectedProp with internal state
|
|
17
|
+
useDeepCompareEffect(() => {
|
|
18
|
+
setSelectedKeys(new Set(selectedProp));
|
|
19
|
+
}, [selectedProp]);
|
|
20
|
+
// Sync external expandedProp with internal state
|
|
21
|
+
useDeepCompareEffect(() => {
|
|
22
|
+
setExpandedKeys(new Set(expandedProp));
|
|
23
|
+
}, [expandedProp]);
|
|
24
|
+
// Serialize items into normalized tree structure
|
|
25
|
+
useEffect(() => {
|
|
26
|
+
setTreeState(serializeItems({
|
|
27
|
+
items: itemsProp,
|
|
28
|
+
}));
|
|
29
|
+
}, [itemsProp]);
|
|
30
|
+
// Compute root nodes
|
|
31
|
+
const rootNodes = useMemo(() => findNodes(node => rootItemIds.has(node.id), normalizeTreeItems), [normalizeTreeItems, rootItemIds]);
|
|
32
|
+
// Handler to collapse items
|
|
33
|
+
const handleCollapseItems = useCallback((items) => {
|
|
34
|
+
setExpandedKeys(prev => {
|
|
35
|
+
const newOpenKeys = new Set(prev);
|
|
36
|
+
items.forEach(({ data }) => {
|
|
37
|
+
if (prev.has(data.key)) {
|
|
38
|
+
newOpenKeys.delete(data.key);
|
|
39
|
+
}
|
|
40
|
+
});
|
|
41
|
+
return newOpenKeys;
|
|
42
|
+
});
|
|
43
|
+
}, []);
|
|
44
|
+
// Handler to expand items with optional deep expansion
|
|
45
|
+
const handleExpandItems = useCallback((items, deep = 0) => {
|
|
46
|
+
setExpandedKeys(prev => {
|
|
47
|
+
const updatedExpandedKeys = new Set(prev);
|
|
48
|
+
items.forEach(item => {
|
|
49
|
+
const normalizeItem = normalizeTreeItems.get(item.data.key);
|
|
50
|
+
if (normalizeItem) {
|
|
51
|
+
updatedExpandedKeys.add(normalizeItem.id);
|
|
52
|
+
if (deep > 0) {
|
|
53
|
+
getChildrenRecursively(normalizeItem.id, normalizeTreeItems, normalizeItem.level + deep).forEach(v => updatedExpandedKeys.add(v.id));
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
});
|
|
57
|
+
return updatedExpandedKeys;
|
|
58
|
+
});
|
|
59
|
+
}, [normalizeTreeItems]);
|
|
60
|
+
// Handler to toggle expansion state of an item
|
|
61
|
+
const handleToggleExpandItem = useCallback((item) => {
|
|
62
|
+
const { key } = item.data;
|
|
63
|
+
const isExpanded = expandedKeys.has(key);
|
|
64
|
+
if (isExpanded) {
|
|
65
|
+
handleCollapseItems([item]);
|
|
66
|
+
}
|
|
67
|
+
else {
|
|
68
|
+
handleExpandItems([item]);
|
|
69
|
+
}
|
|
70
|
+
}, [expandedKeys, handleCollapseItems, handleExpandItems]);
|
|
71
|
+
// Handler to select an item
|
|
72
|
+
const handleSelectItem = useCallback((item) => {
|
|
73
|
+
const { key } = item.data;
|
|
74
|
+
if (!selectable || selectedKeys.has(key) || item.data.displayOnly)
|
|
75
|
+
return;
|
|
76
|
+
setSelectedKeys(new Set([key]));
|
|
77
|
+
}, [selectable, selectedKeys]);
|
|
78
|
+
// Handler to expand all items
|
|
79
|
+
const expandAll = useCallback(() => {
|
|
80
|
+
handleExpandItems(rootNodes, Infinity);
|
|
81
|
+
}, [handleExpandItems, rootNodes]);
|
|
82
|
+
return {
|
|
83
|
+
normalizeTreeItems,
|
|
84
|
+
rootItemIds,
|
|
85
|
+
rootNodes,
|
|
86
|
+
expandedKeys,
|
|
87
|
+
selectedKeys,
|
|
88
|
+
handleExpandItems,
|
|
89
|
+
handleCollapseItems,
|
|
90
|
+
handleToggleExpandItem,
|
|
91
|
+
handleSelectItem,
|
|
92
|
+
expandAll,
|
|
93
|
+
};
|
|
94
|
+
};
|
package/es/components/molecules/VirtualizedMenu/components/MenuInline/hooks/useVisibleItems.d.ts
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { NormalizedNode } from '@antscorp/antsomi-ui/es/utils/tree';
|
|
2
|
+
import { ItemType } from '../../../types';
|
|
3
|
+
/**
|
|
4
|
+
* Custom hook to compute and optimize visible items in a tree structure
|
|
5
|
+
* Automatically selects the best strategy based on tree characteristics
|
|
6
|
+
*/
|
|
7
|
+
export declare const useVisibleItems: (normalizeTreeItems: Map<string, NormalizedNode<ItemType>>, rootItemIds: Set<string>, expandedKeys: Set<string>) => NormalizedNode<ItemType>[];
|
package/es/components/molecules/VirtualizedMenu/components/MenuInline/hooks/useVisibleItems.js
ADDED
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
import { useMemo, useEffect } from 'react';
|
|
2
|
+
import { getPathToNode } from '@antscorp/antsomi-ui/es/utils/tree';
|
|
3
|
+
/**
|
|
4
|
+
* Optimized function to compute visible items using breadth-first traversal
|
|
5
|
+
* instead of filtering all items
|
|
6
|
+
*/
|
|
7
|
+
const computeVisibleItemsOptimized = (normalizeTreeItems, rootItemIds, expandedKeys) => {
|
|
8
|
+
const visibleItems = [];
|
|
9
|
+
const queue = Array.from(rootItemIds);
|
|
10
|
+
// Process queue in breadth-first manner
|
|
11
|
+
let index = 0;
|
|
12
|
+
while (index < queue.length) {
|
|
13
|
+
const itemId = queue[index++];
|
|
14
|
+
const item = normalizeTreeItems.get(itemId);
|
|
15
|
+
if (!item)
|
|
16
|
+
continue;
|
|
17
|
+
visibleItems.push(item);
|
|
18
|
+
// Add children to queue only if this item is expanded
|
|
19
|
+
if (expandedKeys.has(item.id) && item.childIds.length > 0) {
|
|
20
|
+
queue.push(...item.childIds);
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
return visibleItems;
|
|
24
|
+
};
|
|
25
|
+
/**
|
|
26
|
+
* Alternative: Path-based optimization with memoization
|
|
27
|
+
* Caches path calculations to avoid redundant work
|
|
28
|
+
*/
|
|
29
|
+
const computeVisibleItemsWithPathCache = (normalizeTreeItems, expandedKeys, pathCache) => {
|
|
30
|
+
const visibleItems = [];
|
|
31
|
+
for (const item of normalizeTreeItems.values()) {
|
|
32
|
+
const isRootItem = item.level === 0;
|
|
33
|
+
if (isRootItem) {
|
|
34
|
+
visibleItems.push(item);
|
|
35
|
+
continue;
|
|
36
|
+
}
|
|
37
|
+
if (!item.parentId)
|
|
38
|
+
continue;
|
|
39
|
+
// Use cached path or compute and cache
|
|
40
|
+
let pathToParent = pathCache.get(item.parentId);
|
|
41
|
+
if (!pathToParent) {
|
|
42
|
+
pathToParent = getPathToNode(item.parentId, normalizeTreeItems);
|
|
43
|
+
pathCache.set(item.parentId, pathToParent);
|
|
44
|
+
}
|
|
45
|
+
// Check if all parents are expanded
|
|
46
|
+
const allParentExpanded = pathToParent.every(parent => expandedKeys.has(parent.id));
|
|
47
|
+
if (allParentExpanded) {
|
|
48
|
+
visibleItems.push(item);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
return visibleItems;
|
|
52
|
+
};
|
|
53
|
+
/**
|
|
54
|
+
* Level-based optimization: Process items level by level
|
|
55
|
+
* More efficient for deep trees with many collapsed branches
|
|
56
|
+
*/
|
|
57
|
+
const computeVisibleItemsByLevel = (normalizeTreeItems, rootItemIds, expandedKeys) => {
|
|
58
|
+
const visibleItems = [];
|
|
59
|
+
const expandedParents = new Set();
|
|
60
|
+
// Add root items and track expanded ones
|
|
61
|
+
for (const rootId of rootItemIds) {
|
|
62
|
+
const rootItem = normalizeTreeItems.get(rootId);
|
|
63
|
+
if (rootItem) {
|
|
64
|
+
visibleItems.push(rootItem);
|
|
65
|
+
if (expandedKeys.has(rootId)) {
|
|
66
|
+
expandedParents.add(rootId);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
// Process each level
|
|
71
|
+
let currentLevelParents = expandedParents;
|
|
72
|
+
let currentLevel = 1;
|
|
73
|
+
while (currentLevelParents.size > 0) {
|
|
74
|
+
const nextLevelParents = new Set();
|
|
75
|
+
// Process all items at current level
|
|
76
|
+
for (const parentId of currentLevelParents) {
|
|
77
|
+
const parent = normalizeTreeItems.get(parentId);
|
|
78
|
+
if (!parent)
|
|
79
|
+
continue;
|
|
80
|
+
// Add all children of this expanded parent
|
|
81
|
+
for (const childId of parent.childIds) {
|
|
82
|
+
const child = normalizeTreeItems.get(childId);
|
|
83
|
+
if (child && child.level === currentLevel) {
|
|
84
|
+
visibleItems.push(child);
|
|
85
|
+
// Track if this child is expanded for next level
|
|
86
|
+
if (expandedKeys.has(childId)) {
|
|
87
|
+
nextLevelParents.add(childId);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
currentLevelParents = nextLevelParents;
|
|
93
|
+
currentLevel++;
|
|
94
|
+
}
|
|
95
|
+
return visibleItems;
|
|
96
|
+
};
|
|
97
|
+
/**
|
|
98
|
+
* Custom hook to compute and optimize visible items in a tree structure
|
|
99
|
+
* Automatically selects the best strategy based on tree characteristics
|
|
100
|
+
*/
|
|
101
|
+
export const useVisibleItems = (normalizeTreeItems, rootItemIds, expandedKeys) => {
|
|
102
|
+
// Cache for path calculations to avoid redundant work
|
|
103
|
+
const pathCache = useMemo(() => new Map(), []);
|
|
104
|
+
// Clear path cache when tree structure changes
|
|
105
|
+
useEffect(() => {
|
|
106
|
+
pathCache.clear();
|
|
107
|
+
}, [normalizeTreeItems, pathCache]);
|
|
108
|
+
// Optimized visible items calculation with strategy selection
|
|
109
|
+
const visibleItems = useMemo(() => {
|
|
110
|
+
if (normalizeTreeItems.size === 0)
|
|
111
|
+
return [];
|
|
112
|
+
// Choose optimization strategy based on tree characteristics
|
|
113
|
+
const treeDepth = Math.max(...Array.from(normalizeTreeItems.values()).map(item => item.level));
|
|
114
|
+
const totalItems = normalizeTreeItems.size;
|
|
115
|
+
const expandedCount = expandedKeys.size;
|
|
116
|
+
// Strategy selection heuristics:
|
|
117
|
+
// - For shallow trees with many expanded items: use breadth-first
|
|
118
|
+
// - For deep trees with few expanded items: use level-based
|
|
119
|
+
// - For medium trees: use path-cache optimization
|
|
120
|
+
if (treeDepth <= 3 && expandedCount > totalItems * 0.3) {
|
|
121
|
+
// Shallow tree with many expanded items
|
|
122
|
+
return computeVisibleItemsOptimized(normalizeTreeItems, rootItemIds, expandedKeys);
|
|
123
|
+
}
|
|
124
|
+
if (treeDepth > 5 && expandedCount < totalItems * 0.2) {
|
|
125
|
+
// Deep tree with few expanded items
|
|
126
|
+
return computeVisibleItemsByLevel(normalizeTreeItems, rootItemIds, expandedKeys);
|
|
127
|
+
}
|
|
128
|
+
// Medium complexity - use cached path approach
|
|
129
|
+
return computeVisibleItemsWithPathCache(normalizeTreeItems, expandedKeys, pathCache);
|
|
130
|
+
}, [expandedKeys, normalizeTreeItems, rootItemIds, pathCache]);
|
|
131
|
+
return visibleItems;
|
|
132
|
+
};
|
|
@@ -32,7 +32,7 @@ export const MenuItemRoot = styled.li `
|
|
|
32
32
|
align-items: center;
|
|
33
33
|
overflow: hidden;
|
|
34
34
|
|
|
35
|
-
|
|
35
|
+
&.${CLS.Item.focused} {
|
|
36
36
|
outline: none;
|
|
37
37
|
}
|
|
38
38
|
|
|
@@ -84,8 +84,18 @@ export const MenuItemRoot = styled.li `
|
|
|
84
84
|
}
|
|
85
85
|
}
|
|
86
86
|
|
|
87
|
-
|
|
88
|
-
|
|
87
|
+
&.${CLS.Item.focused}:not(
|
|
88
|
+
.${CLS.Item.disabled},
|
|
89
|
+
.${CLS.Item.selected},
|
|
90
|
+
.${CLS.Item.selectedDescendant},
|
|
91
|
+
.${CLS.Item.displayOnly}
|
|
92
|
+
),
|
|
93
|
+
&:hover:not(
|
|
94
|
+
.${CLS.Item.disabled},
|
|
95
|
+
.${CLS.Item.selected},
|
|
96
|
+
.${CLS.Item.selectedDescendant},
|
|
97
|
+
.${CLS.Item.displayOnly}
|
|
98
|
+
) {
|
|
89
99
|
background-color: ${THEME.components?.Menu?.itemHoverBg};
|
|
90
100
|
}
|
|
91
101
|
}
|
|
@@ -101,4 +111,5 @@ export const VirtualizedMenuContainer = styled((VariableSizeList)) `
|
|
|
101
111
|
`;
|
|
102
112
|
export const StyledAutoSizer = styled(AutoSizer) `
|
|
103
113
|
flex: 1;
|
|
114
|
+
outline: none;
|
|
104
115
|
`;
|
|
@@ -37,6 +37,7 @@ export const CLS = {
|
|
|
37
37
|
disabled: componentCls('item-disabled'),
|
|
38
38
|
selected: componentCls('item-selected'),
|
|
39
39
|
expanded: componentCls('item-expanded'),
|
|
40
|
+
focused: componentCls('item-focused'),
|
|
40
41
|
selectedDescendant: componentCls('item-selected-descendant'),
|
|
41
42
|
displayOnly: componentCls('item-display-only'),
|
|
42
43
|
},
|
|
@@ -9,7 +9,7 @@ import { translate, translations } from '@antscorp/antsomi-locales';
|
|
|
9
9
|
import { isEmpty } from 'lodash';
|
|
10
10
|
import { differenceInMonths, formatUTCDateTZ, startOfMonth, subMonths, } from '@antscorp/antsomi-ui/es/utils/date';
|
|
11
11
|
import { getPortalTimeZone } from '@antscorp/antsomi-ui/es/utils/portal';
|
|
12
|
-
import { EmptyData } from '../../molecules';
|
|
12
|
+
import { EmptyData } from '../../molecules/EmptyData';
|
|
13
13
|
import clsx from 'clsx';
|
|
14
14
|
export const ActivityTimeline = (props) => {
|
|
15
15
|
const { timelines = [], isLoading = false, title = translate(translations._BLOCK_TIMELINE_CUS), timezone = getPortalTimeZone(), objectName = '_THIS_PERSON_UPPERCASE', onFetchMore, eventTracking: eventTrackingProp = [], header, className, } = props;
|
|
@@ -84,10 +84,10 @@ export const ActivityTimeline = (props) => {
|
|
|
84
84
|
lastRef(el);
|
|
85
85
|
}
|
|
86
86
|
};
|
|
87
|
-
if (item.data
|
|
87
|
+
if (item.data?.totalActivityCount === 1) {
|
|
88
88
|
result.push(_jsx(ItemEvent, { ref: setRef, keyItem: key, item: item, objectName: customerName, eventTracking: eventTracking }, key));
|
|
89
89
|
}
|
|
90
|
-
else if (item.data
|
|
90
|
+
else if (item.data?.totalActivityCount > 1) {
|
|
91
91
|
result.push(_jsx(ItemGroupEvent, { ref: setRef, keyItem: key, item: item, objectName: customerName, eventTracking: eventTracking }, key));
|
|
92
92
|
}
|
|
93
93
|
});
|
|
@@ -210,7 +210,7 @@ export declare const MAP_LIST_INFO_EVENT: {
|
|
|
210
210
|
readonly 'view page': {
|
|
211
211
|
readonly eventType: "view page";
|
|
212
212
|
readonly iconCode: "_EVENT_VIEW_PAGE";
|
|
213
|
-
readonly translateCode: "
|
|
213
|
+
readonly translateCode: "_EVENT_DES_VIEW_PAGE_NEW";
|
|
214
214
|
readonly showSlideImageAndPrice: false;
|
|
215
215
|
readonly showQuantity: false;
|
|
216
216
|
readonly showRevenue: false;
|
|
@@ -353,7 +353,7 @@ export declare const MAP_LIST_INFO_EVENT: {
|
|
|
353
353
|
readonly 'view pageview': {
|
|
354
354
|
readonly eventType: "view pageview";
|
|
355
355
|
readonly iconCode: "_EVENT_VIEW_PAGE";
|
|
356
|
-
readonly translateCode: "
|
|
356
|
+
readonly translateCode: "_EVENT_DES_VIEW_PAGE_NEW";
|
|
357
357
|
readonly showSlideImageAndPrice: false;
|
|
358
358
|
readonly showQuantity: false;
|
|
359
359
|
readonly showRevenue: false;
|
|
@@ -366,7 +366,7 @@ export declare const MAP_LIST_INFO_EVENT: {
|
|
|
366
366
|
readonly 'view screenview': {
|
|
367
367
|
readonly eventType: "view screenview";
|
|
368
368
|
readonly iconCode: "";
|
|
369
|
-
readonly translateCode: "
|
|
369
|
+
readonly translateCode: "_EVENT_VIEW_SCREEN_NEW";
|
|
370
370
|
readonly showSlideImageAndPrice: false;
|
|
371
371
|
readonly showQuantity: false;
|
|
372
372
|
readonly showRevenue: false;
|
|
@@ -690,7 +690,7 @@ export declare const DATA_EVENT: {
|
|
|
690
690
|
} | {
|
|
691
691
|
readonly eventType: "view page";
|
|
692
692
|
readonly iconCode: "_EVENT_VIEW_PAGE";
|
|
693
|
-
readonly translateCode: "
|
|
693
|
+
readonly translateCode: "_EVENT_DES_VIEW_PAGE_NEW";
|
|
694
694
|
readonly showSlideImageAndPrice: false;
|
|
695
695
|
readonly showQuantity: false;
|
|
696
696
|
readonly showRevenue: false;
|
|
@@ -822,7 +822,7 @@ export declare const DATA_EVENT: {
|
|
|
822
822
|
} | {
|
|
823
823
|
readonly eventType: "view pageview";
|
|
824
824
|
readonly iconCode: "_EVENT_VIEW_PAGE";
|
|
825
|
-
readonly translateCode: "
|
|
825
|
+
readonly translateCode: "_EVENT_DES_VIEW_PAGE_NEW";
|
|
826
826
|
readonly showSlideImageAndPrice: false;
|
|
827
827
|
readonly showQuantity: false;
|
|
828
828
|
readonly showRevenue: false;
|
|
@@ -834,7 +834,7 @@ export declare const DATA_EVENT: {
|
|
|
834
834
|
} | {
|
|
835
835
|
readonly eventType: "view screenview";
|
|
836
836
|
readonly iconCode: "";
|
|
837
|
-
readonly translateCode: "
|
|
837
|
+
readonly translateCode: "_EVENT_VIEW_SCREEN_NEW";
|
|
838
838
|
readonly showSlideImageAndPrice: false;
|
|
839
839
|
readonly showQuantity: false;
|
|
840
840
|
readonly showRevenue: false;
|
|
@@ -1164,7 +1164,7 @@ export declare const DATA_EVENT: {
|
|
|
1164
1164
|
readonly 'view page': {
|
|
1165
1165
|
readonly eventType: "view page";
|
|
1166
1166
|
readonly iconCode: "_EVENT_VIEW_PAGE";
|
|
1167
|
-
readonly translateCode: "
|
|
1167
|
+
readonly translateCode: "_EVENT_DES_VIEW_PAGE_NEW";
|
|
1168
1168
|
readonly showSlideImageAndPrice: false;
|
|
1169
1169
|
readonly showQuantity: false;
|
|
1170
1170
|
readonly showRevenue: false;
|
|
@@ -1307,7 +1307,7 @@ export declare const DATA_EVENT: {
|
|
|
1307
1307
|
readonly 'view pageview': {
|
|
1308
1308
|
readonly eventType: "view pageview";
|
|
1309
1309
|
readonly iconCode: "_EVENT_VIEW_PAGE";
|
|
1310
|
-
readonly translateCode: "
|
|
1310
|
+
readonly translateCode: "_EVENT_DES_VIEW_PAGE_NEW";
|
|
1311
1311
|
readonly showSlideImageAndPrice: false;
|
|
1312
1312
|
readonly showQuantity: false;
|
|
1313
1313
|
readonly showRevenue: false;
|
|
@@ -1320,7 +1320,7 @@ export declare const DATA_EVENT: {
|
|
|
1320
1320
|
readonly 'view screenview': {
|
|
1321
1321
|
readonly eventType: "view screenview";
|
|
1322
1322
|
readonly iconCode: "";
|
|
1323
|
-
readonly translateCode: "
|
|
1323
|
+
readonly translateCode: "_EVENT_VIEW_SCREEN_NEW";
|
|
1324
1324
|
readonly showSlideImageAndPrice: false;
|
|
1325
1325
|
readonly showQuantity: false;
|
|
1326
1326
|
readonly showRevenue: false;
|
|
@@ -224,7 +224,7 @@ export const MAP_LIST_INFO_EVENT = {
|
|
|
224
224
|
'view page': {
|
|
225
225
|
eventType: 'view page',
|
|
226
226
|
iconCode: '_EVENT_VIEW_PAGE',
|
|
227
|
-
translateCode: '
|
|
227
|
+
translateCode: '_EVENT_DES_VIEW_PAGE_NEW',
|
|
228
228
|
showSlideImageAndPrice: false,
|
|
229
229
|
showQuantity: false,
|
|
230
230
|
showRevenue: false,
|
|
@@ -367,7 +367,7 @@ export const MAP_LIST_INFO_EVENT = {
|
|
|
367
367
|
'view pageview': {
|
|
368
368
|
eventType: 'view pageview',
|
|
369
369
|
iconCode: '_EVENT_VIEW_PAGE',
|
|
370
|
-
translateCode: '
|
|
370
|
+
translateCode: '_EVENT_DES_VIEW_PAGE_NEW',
|
|
371
371
|
showSlideImageAndPrice: false,
|
|
372
372
|
showQuantity: false,
|
|
373
373
|
showRevenue: false,
|
|
@@ -380,7 +380,7 @@ export const MAP_LIST_INFO_EVENT = {
|
|
|
380
380
|
'view screenview': {
|
|
381
381
|
eventType: 'view screenview',
|
|
382
382
|
iconCode: '',
|
|
383
|
-
translateCode: '
|
|
383
|
+
translateCode: '_EVENT_VIEW_SCREEN_NEW',
|
|
384
384
|
showSlideImageAndPrice: false,
|
|
385
385
|
showQuantity: false,
|
|
386
386
|
showRevenue: false,
|