@lobehub/lobehub 2.0.0-next.298 → 2.0.0-next.299
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/CHANGELOG.md +33 -0
- package/changelog/v1.json +9 -0
- package/package.json +2 -2
- package/src/app/[variants]/(main)/agent/_layout/Sidebar/Cron/Actions.tsx +4 -13
- package/src/app/[variants]/(main)/agent/_layout/Sidebar/Topic/Actions.tsx +4 -13
- package/src/app/[variants]/(main)/agent/_layout/Sidebar/Topic/index.tsx +2 -9
- package/src/app/[variants]/(main)/agent/features/Conversation/ConversationArea.tsx +2 -2
- package/src/app/[variants]/(main)/agent/features/Conversation/Header/Tags/KnowledgeTag.tsx +3 -4
- package/src/app/[variants]/(main)/agent/profile/features/ProfileEditor/MentionList/types.ts +4 -2
- package/src/app/[variants]/(main)/community/(detail)/model/features/Sidebar/ActionButton/ChatWithModel.tsx +3 -8
- package/src/app/[variants]/(main)/community/(list)/assistant/features/MarketSourceSwitch.tsx +44 -23
- package/src/app/[variants]/(main)/community/(list)/features/SortButton/index.tsx +40 -19
- package/src/app/[variants]/(main)/group/_layout/Sidebar/Topic/Actions.tsx +4 -13
- package/src/app/[variants]/(main)/group/_layout/Sidebar/Topic/index.tsx +2 -9
- package/src/app/[variants]/(main)/group/features/Conversation/ConversationArea.tsx +2 -2
- package/src/app/[variants]/(main)/group/features/Conversation/Header/Tags/KnowledgeTag.tsx +3 -4
- package/src/app/[variants]/(main)/group/profile/features/AgentBuilder/AgentBuilderProvider.tsx +2 -2
- package/src/app/[variants]/(main)/group/profile/features/MemberProfile/MentionList/types.ts +4 -2
- package/src/app/[variants]/(main)/home/_layout/Body/Agent/Actions.tsx +3 -11
- package/src/app/[variants]/(main)/home/_layout/Body/Agent/List/Group/Actions.tsx +3 -12
- package/src/app/[variants]/(main)/home/_layout/Body/Agent/List/Group/Item.tsx +2 -9
- package/src/app/[variants]/(main)/home/_layout/Body/Agent/index.tsx +2 -9
- package/src/app/[variants]/(main)/home/_layout/Body/Project/index.tsx +2 -9
- package/src/app/[variants]/(main)/home/features/CommunityAgents/index.tsx +11 -13
- package/src/app/[variants]/(main)/home/features/FeaturedPlugins/index.tsx +11 -13
- package/src/app/[variants]/(main)/home/features/RecentPage/index.tsx +12 -14
- package/src/app/[variants]/(main)/home/features/RecentResource/index.tsx +12 -14
- package/src/app/[variants]/(main)/memory/contexts/features/ContextDropdown.tsx +5 -3
- package/src/app/[variants]/(main)/memory/experiences/features/ExperienceDropdown.tsx +5 -3
- package/src/app/[variants]/(main)/memory/identities/features/IdentityDropdown.tsx +5 -3
- package/src/app/[variants]/(main)/memory/preferences/features/PreferenceDropdown.tsx +5 -3
- package/src/app/[variants]/(main)/page/_layout/Body/Actions.tsx +3 -13
- package/src/app/[variants]/(main)/page/_layout/Body/index.tsx +2 -9
- package/src/app/[variants]/(main)/resource/features/DndContextWrapper.tsx +1 -1
- package/src/app/[variants]/(main)/settings/profile/features/SSOProvidersList/index.tsx +3 -3
- package/src/app/[variants]/(main)/settings/provider/ProviderMenu/Actions.tsx +3 -11
- package/src/app/[variants]/(main)/settings/provider/ProviderMenu/List.tsx +12 -28
- package/src/app/[variants]/(main)/settings/provider/features/ModelList/DisabledModels.tsx +7 -8
- package/src/app/[variants]/(main)/settings/provider/features/ModelList/ModelTitle/index.tsx +18 -20
- package/src/app/[variants]/(mobile)/(home)/features/SessionListContent/CollapseGroup/Actions.tsx +10 -14
- package/src/app/[variants]/(mobile)/(home)/features/SessionListContent/List/Item/Actions.tsx +3 -13
- package/src/app/[variants]/share/t/[id]/SharedMessageList.tsx +2 -2
- package/src/business/server/lambda-routers/file.ts +1 -1
- package/src/features/AgentBuilder/AgentBuilderProvider.tsx +2 -2
- package/src/features/ChatInput/ActionBar/History/index.tsx +1 -1
- package/src/features/ChatInput/ActionBar/STT/common.tsx +1 -1
- package/src/features/ChatInput/ActionBar/Search/index.tsx +1 -1
- package/src/features/ChatInput/ActionBar/Upload/ServerMode.tsx +1 -0
- package/src/features/ChatInput/ActionBar/components/Action.tsx +4 -8
- package/src/features/ChatInput/ActionBar/components/ActionDropdown.tsx +225 -37
- package/src/features/Conversation/ConversationProvider.tsx +2 -1
- package/src/features/Conversation/Messages/Assistant/Actions/index.tsx +10 -6
- package/src/features/Conversation/Messages/AssistantGroup/Actions/index.tsx +10 -6
- package/src/features/Conversation/Messages/AssistantGroup/Tool/Detail/Intervention/ApprovalActions.tsx +11 -13
- package/src/features/Conversation/Messages/AssistantGroup/Tool/Detail/Intervention/ModeSelector.tsx +8 -10
- package/src/features/Conversation/Messages/Supervisor/Actions/index.tsx +10 -6
- package/src/features/Conversation/Messages/Task/Actions/index.tsx +10 -6
- package/src/features/Conversation/Messages/User/Actions/index.tsx +10 -6
- package/src/features/Conversation/StoreUpdater.tsx +1 -1
- package/src/features/Conversation/store/initialState.ts +3 -1
- package/src/features/Conversation/store/slices/data/action.ts +6 -5
- package/src/features/LibraryModal/AssignKnowledgeBase/Item/Action.tsx +23 -26
- package/src/features/ModelSwitchPanel/components/List/MultipleProvidersModelItem.tsx +16 -18
- package/src/features/ModelSwitchPanel/styles.ts +18 -1
- package/src/features/PageEditor/Copilot/AgentSelector/Actions.tsx +6 -13
- package/src/features/PageEditor/PageAgentProvider.tsx +2 -2
- package/src/features/PluginStore/InstalledList/List/Item/Action.tsx +33 -36
- package/src/features/PluginStore/McpList/List/Action.tsx +25 -28
- package/src/features/PluginStore/PluginList/List/Action.tsx +25 -28
- package/src/features/PluginTag/index.tsx +3 -4
- package/src/features/Portal/Artifacts/Body/Renderer/SVG.tsx +14 -11
- package/src/features/Portal/Thread/Chat/index.tsx +2 -2
- package/src/features/ProfileEditor/AgentTool.tsx +1 -1
- package/src/features/ResourceManager/components/Explorer/ToolBar/SortDropdown.tsx +21 -18
- package/src/features/ResourceManager/components/Explorer/ToolBar/ViewSwitcher.tsx +7 -13
- package/src/features/ResourceManager/components/Header/AddButton.tsx +4 -11
- package/src/features/User/UserPanel/LangButton.tsx +56 -44
- package/src/layout/AuthProvider/MarketAuth/MarketAuthProvider.tsx +1 -1
- package/src/services/document/index.ts +11 -1
- package/src/store/page/slices/crud/action.ts +0 -48
- package/src/styles/global.ts +2 -2
- package/src/types/shim-lobe-ui.d.ts +7 -0
package/src/app/[variants]/(mobile)/(home)/features/SessionListContent/List/Item/Actions.tsx
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ActionIcon,
|
|
1
|
+
import { ActionIcon, DropdownMenu, Icon } from '@lobehub/ui';
|
|
2
2
|
import { App } from 'antd';
|
|
3
3
|
import { createStaticStyles } from 'antd-style';
|
|
4
4
|
import { type ItemType } from 'antd/es/menu/interface';
|
|
@@ -183,17 +183,7 @@ const Actions = memo<ActionProps>(({ group, id, openCreateGroupModal, parentType
|
|
|
183
183
|
);
|
|
184
184
|
|
|
185
185
|
return (
|
|
186
|
-
<
|
|
187
|
-
arrow={false}
|
|
188
|
-
menu={{
|
|
189
|
-
items,
|
|
190
|
-
onClick: ({ domEvent }) => {
|
|
191
|
-
domEvent.stopPropagation();
|
|
192
|
-
},
|
|
193
|
-
}}
|
|
194
|
-
onOpenChange={setOpen}
|
|
195
|
-
trigger={['click']}
|
|
196
|
-
>
|
|
186
|
+
<DropdownMenu items={items} onOpenChange={setOpen}>
|
|
197
187
|
<ActionIcon
|
|
198
188
|
icon={MoreVertical}
|
|
199
189
|
size={{
|
|
@@ -201,7 +191,7 @@ const Actions = memo<ActionProps>(({ group, id, openCreateGroupModal, parentType
|
|
|
201
191
|
size: 16,
|
|
202
192
|
}}
|
|
203
193
|
/>
|
|
204
|
-
</
|
|
194
|
+
</DropdownMenu>
|
|
205
195
|
);
|
|
206
196
|
});
|
|
207
197
|
|
|
@@ -40,8 +40,8 @@ const SharedMessageList = memo<SharedMessageListProps>(({ agentId, groupId, shar
|
|
|
40
40
|
context={context}
|
|
41
41
|
hasInitMessages={!!messages}
|
|
42
42
|
messages={messages}
|
|
43
|
-
onMessagesChange={(messages) => {
|
|
44
|
-
replaceMessages(messages, { context });
|
|
43
|
+
onMessagesChange={(messages, ctx) => {
|
|
44
|
+
replaceMessages(messages, { context: ctx });
|
|
45
45
|
}}
|
|
46
46
|
>
|
|
47
47
|
<Flexbox flex={1}>
|
|
@@ -8,5 +8,5 @@ export interface BusinessFileUploadCheckParams {
|
|
|
8
8
|
|
|
9
9
|
export async function businessFileUploadCheck(
|
|
10
10
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
11
|
-
|
|
11
|
+
_params: BusinessFileUploadCheckParams,
|
|
12
12
|
): Promise<void> {}
|
|
@@ -46,8 +46,8 @@ const AgentBuilderProvider = memo<AgentBuilderProviderProps>(({ agentId, childre
|
|
|
46
46
|
context={context}
|
|
47
47
|
hasInitMessages={!!messages}
|
|
48
48
|
messages={messages}
|
|
49
|
-
onMessagesChange={(msgs) => {
|
|
50
|
-
replaceMessages(msgs, { context });
|
|
49
|
+
onMessagesChange={(msgs, ctx) => {
|
|
50
|
+
replaceMessages(msgs, { context: ctx });
|
|
51
51
|
}}
|
|
52
52
|
operationState={operationState}
|
|
53
53
|
>
|
|
@@ -55,7 +55,7 @@ const History = memo(() => {
|
|
|
55
55
|
popover={{
|
|
56
56
|
content: <Controls setUpdating={setUpdating} updating={updating} />,
|
|
57
57
|
minWidth: 240,
|
|
58
|
-
trigger: isMobile ?
|
|
58
|
+
trigger: isMobile ? 'click' : 'hover',
|
|
59
59
|
}}
|
|
60
60
|
showTooltip={false}
|
|
61
61
|
title={title}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
|
|
3
|
-
import { ActionIcon, type ActionIconProps } from '@lobehub/ui';
|
|
3
|
+
import { ActionIcon, type ActionIconProps, type PopoverTrigger } from '@lobehub/ui';
|
|
4
4
|
import { isUndefined } from 'es-toolkit/compat';
|
|
5
5
|
import { memo } from 'react';
|
|
6
6
|
import useMergeState from 'use-merge-value';
|
|
@@ -12,12 +12,12 @@ import ActionDropdown, { type ActionDropdownProps } from './ActionDropdown';
|
|
|
12
12
|
import ActionPopover, { type ActionPopoverProps } from './ActionPopover';
|
|
13
13
|
|
|
14
14
|
interface ActionProps extends Omit<ActionIconProps, 'popover'> {
|
|
15
|
-
dropdown?: ActionDropdownProps
|
|
15
|
+
dropdown?: Omit<ActionDropdownProps, 'children'>;
|
|
16
16
|
onOpenChange?: (open: boolean) => void;
|
|
17
17
|
open?: boolean;
|
|
18
18
|
popover?: ActionPopoverProps;
|
|
19
19
|
showTooltip?: boolean;
|
|
20
|
-
trigger?:
|
|
20
|
+
trigger?: PopoverTrigger;
|
|
21
21
|
}
|
|
22
22
|
|
|
23
23
|
const Action = memo<ActionProps>(
|
|
@@ -84,11 +84,7 @@ const Action = memo<ActionProps>(
|
|
|
84
84
|
<ActionPopover
|
|
85
85
|
onOpenChange={setShow}
|
|
86
86
|
open={show}
|
|
87
|
-
trigger={
|
|
88
|
-
Array.isArray(trigger)
|
|
89
|
-
? (trigger.filter((t) => t !== 'contextMenu') as ('click' | 'hover')[])
|
|
90
|
-
: trigger
|
|
91
|
-
}
|
|
87
|
+
trigger={trigger}
|
|
92
88
|
{...popover}
|
|
93
89
|
minWidth={mobile ? '100%' : popover.minWidth}
|
|
94
90
|
placement={mobile ? 'top' : (dropdownPlacement ?? popover.placement)}
|
|
@@ -1,68 +1,256 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
|
|
3
|
-
import {
|
|
3
|
+
import {
|
|
4
|
+
DropdownMenuPopup,
|
|
5
|
+
type DropdownMenuPopupProps,
|
|
6
|
+
DropdownMenuPortal,
|
|
7
|
+
DropdownMenuPositioner,
|
|
8
|
+
type DropdownMenuProps,
|
|
9
|
+
DropdownMenuRoot,
|
|
10
|
+
DropdownMenuTrigger,
|
|
11
|
+
type MenuProps,
|
|
12
|
+
type PopoverTrigger,
|
|
13
|
+
renderDropdownMenuItems,
|
|
14
|
+
} from '@lobehub/ui';
|
|
4
15
|
import { createStaticStyles, cx } from 'antd-style';
|
|
5
|
-
import {
|
|
16
|
+
import {
|
|
17
|
+
type CSSProperties,
|
|
18
|
+
type ReactNode,
|
|
19
|
+
memo,
|
|
20
|
+
useCallback,
|
|
21
|
+
useEffect,
|
|
22
|
+
useMemo,
|
|
23
|
+
useRef,
|
|
24
|
+
useState,
|
|
25
|
+
} from 'react';
|
|
6
26
|
|
|
7
27
|
import { useIsMobile } from '@/hooks/useIsMobile';
|
|
8
28
|
|
|
9
|
-
const prefixCls = 'ant';
|
|
10
|
-
|
|
11
29
|
const styles = createStaticStyles(({ css }) => ({
|
|
12
30
|
dropdownMenu: css`
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
margin: 0;
|
|
16
|
-
}
|
|
17
|
-
.${prefixCls}-avatar {
|
|
18
|
-
margin-inline-end: var(--ant-margin-xs);
|
|
19
|
-
}
|
|
31
|
+
.ant-avatar {
|
|
32
|
+
margin-inline-end: var(--ant-margin-xs);
|
|
20
33
|
}
|
|
21
34
|
`,
|
|
22
35
|
}));
|
|
23
36
|
|
|
24
|
-
|
|
37
|
+
type ActionDropdownMenu = Omit<Pick<MenuProps, 'className' | 'onClick' | 'style'>, 'items'> & {
|
|
38
|
+
items: MenuProps['items'] | (() => MenuProps['items']);
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
export interface ActionDropdownProps extends Omit<DropdownMenuProps, 'items'> {
|
|
25
42
|
maxHeight?: number | string;
|
|
26
43
|
maxWidth?: number | string;
|
|
44
|
+
menu: ActionDropdownMenu;
|
|
27
45
|
minHeight?: number | string;
|
|
28
46
|
minWidth?: number | string;
|
|
47
|
+
popupRender?: (menu: ReactNode) => ReactNode;
|
|
29
48
|
/**
|
|
30
49
|
* 是否在挂载时预渲染弹层,避免首次触发展开时的渲染卡顿
|
|
31
50
|
*/
|
|
32
51
|
prefetch?: boolean;
|
|
52
|
+
trigger?: PopoverTrigger;
|
|
33
53
|
}
|
|
34
54
|
|
|
35
55
|
const ActionDropdown = memo<ActionDropdownProps>(
|
|
36
|
-
({
|
|
56
|
+
({
|
|
57
|
+
children,
|
|
58
|
+
defaultOpen,
|
|
59
|
+
menu,
|
|
60
|
+
trigger,
|
|
61
|
+
maxHeight,
|
|
62
|
+
maxWidth,
|
|
63
|
+
minHeight,
|
|
64
|
+
minWidth,
|
|
65
|
+
onOpenChange,
|
|
66
|
+
onOpenChangeComplete,
|
|
67
|
+
open,
|
|
68
|
+
placement = 'top',
|
|
69
|
+
popupProps,
|
|
70
|
+
popupRender,
|
|
71
|
+
portalProps,
|
|
72
|
+
positionerProps,
|
|
73
|
+
prefetch,
|
|
74
|
+
|
|
75
|
+
triggerProps,
|
|
76
|
+
...rest
|
|
77
|
+
}) => {
|
|
37
78
|
const isMobile = useIsMobile();
|
|
79
|
+
const [uncontrolledOpen, setUncontrolledOpen] = useState(Boolean(defaultOpen));
|
|
80
|
+
const menuItemsRef = useRef<ReactNode[] | null>(null);
|
|
81
|
+
|
|
82
|
+
useEffect(() => {
|
|
83
|
+
if (open === undefined) return;
|
|
84
|
+
setUncontrolledOpen(open);
|
|
85
|
+
}, [open]);
|
|
86
|
+
|
|
87
|
+
const handleOpenChange = useCallback(
|
|
88
|
+
(nextOpen: boolean, details: Parameters<NonNullable<typeof onOpenChange>>[1]) => {
|
|
89
|
+
onOpenChange?.(nextOpen, details);
|
|
90
|
+
if (open === undefined) setUncontrolledOpen(nextOpen);
|
|
91
|
+
},
|
|
92
|
+
[onOpenChange, open],
|
|
93
|
+
);
|
|
94
|
+
|
|
95
|
+
const handleOpenChangeComplete = useCallback(
|
|
96
|
+
(nextOpen: boolean) => {
|
|
97
|
+
onOpenChangeComplete?.(nextOpen);
|
|
98
|
+
if (!nextOpen) menuItemsRef.current = null;
|
|
99
|
+
},
|
|
100
|
+
[onOpenChangeComplete],
|
|
101
|
+
);
|
|
102
|
+
|
|
103
|
+
const isOpen = open ?? uncontrolledOpen;
|
|
104
|
+
const openOnHover = useMemo(() => {
|
|
105
|
+
if (!trigger) return undefined;
|
|
106
|
+
if (trigger === 'both') return true;
|
|
107
|
+
if (Array.isArray(trigger)) return trigger.includes('hover');
|
|
108
|
+
return trigger === 'hover';
|
|
109
|
+
}, [trigger]);
|
|
110
|
+
const resolvedTriggerProps = useMemo(() => {
|
|
111
|
+
if (openOnHover === undefined) return triggerProps;
|
|
112
|
+
return {
|
|
113
|
+
...triggerProps,
|
|
114
|
+
openOnHover,
|
|
115
|
+
};
|
|
116
|
+
}, [openOnHover, triggerProps]);
|
|
117
|
+
|
|
118
|
+
const decorateMenuItems = useCallback(
|
|
119
|
+
(items: MenuProps['items']): MenuProps['items'] => {
|
|
120
|
+
if (!items) return items;
|
|
121
|
+
|
|
122
|
+
return items.map((item) => {
|
|
123
|
+
if (!item) return item;
|
|
124
|
+
if ('type' in item && item.type === 'divider') return item;
|
|
125
|
+
if ('type' in item && item.type === 'group') {
|
|
126
|
+
return {
|
|
127
|
+
...item,
|
|
128
|
+
children: item.children ? decorateMenuItems(item.children) : item.children,
|
|
129
|
+
};
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
if ('children' in item && item.children) {
|
|
133
|
+
return {
|
|
134
|
+
...item,
|
|
135
|
+
children: decorateMenuItems(item.children),
|
|
136
|
+
};
|
|
137
|
+
}
|
|
138
|
+
const itemOnClick = 'onClick' in item ? item.onClick : undefined;
|
|
139
|
+
|
|
140
|
+
return {
|
|
141
|
+
...item,
|
|
142
|
+
onClick: (info) => {
|
|
143
|
+
info.domEvent.preventDefault();
|
|
144
|
+
menu.onClick?.(info);
|
|
145
|
+
itemOnClick?.(info);
|
|
146
|
+
},
|
|
147
|
+
};
|
|
148
|
+
});
|
|
149
|
+
},
|
|
150
|
+
[menu],
|
|
151
|
+
);
|
|
152
|
+
|
|
153
|
+
const renderedItems = useMemo(() => {
|
|
154
|
+
if (!prefetch && !isOpen) return menuItemsRef.current;
|
|
155
|
+
const sourceItems = typeof menu.items === 'function' ? menu.items() : menu.items;
|
|
156
|
+
const nextItems = renderDropdownMenuItems(decorateMenuItems(sourceItems ?? []));
|
|
157
|
+
|
|
158
|
+
menuItemsRef.current = nextItems;
|
|
159
|
+
|
|
160
|
+
return nextItems;
|
|
161
|
+
}, [decorateMenuItems, isOpen, menu.items, prefetch]);
|
|
162
|
+
|
|
163
|
+
const menuContent = useMemo(() => {
|
|
164
|
+
if (!popupRender) return renderedItems;
|
|
165
|
+
return popupRender(renderedItems ?? null);
|
|
166
|
+
}, [popupRender, renderedItems]);
|
|
167
|
+
|
|
168
|
+
const resolvedPopupClassName = useMemo<DropdownMenuPopupProps['className']>(() => {
|
|
169
|
+
const popupClassName = popupProps?.className;
|
|
170
|
+
if (typeof popupClassName === 'function') {
|
|
171
|
+
return (state) => cx(styles.dropdownMenu, menu.className, popupClassName(state));
|
|
172
|
+
}
|
|
173
|
+
return cx(styles.dropdownMenu, menu.className, popupClassName);
|
|
174
|
+
}, [menu.className, popupProps?.className]);
|
|
175
|
+
|
|
176
|
+
const resolvedPopupStyle = useMemo<DropdownMenuPopupProps['style']>(() => {
|
|
177
|
+
const baseStyle: CSSProperties = {
|
|
178
|
+
maxHeight,
|
|
179
|
+
maxWidth: isMobile ? undefined : maxWidth,
|
|
180
|
+
minHeight,
|
|
181
|
+
minWidth: isMobile ? undefined : minWidth,
|
|
182
|
+
overflowX: 'hidden',
|
|
183
|
+
overflowY: 'scroll',
|
|
184
|
+
width: isMobile ? '100vw' : undefined,
|
|
185
|
+
};
|
|
186
|
+
const popupStyle = popupProps?.style;
|
|
187
|
+
|
|
188
|
+
if (typeof popupStyle === 'function') {
|
|
189
|
+
return (state) => ({
|
|
190
|
+
...baseStyle,
|
|
191
|
+
...menu.style,
|
|
192
|
+
...popupStyle(state),
|
|
193
|
+
});
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
return {
|
|
197
|
+
...baseStyle,
|
|
198
|
+
...menu.style,
|
|
199
|
+
...popupStyle,
|
|
200
|
+
};
|
|
201
|
+
}, [isMobile, maxHeight, maxWidth, menu.style, minHeight, minWidth, popupProps?.style]);
|
|
202
|
+
|
|
203
|
+
const resolvedPopupProps = useMemo(() => {
|
|
204
|
+
if (!popupProps) {
|
|
205
|
+
return {
|
|
206
|
+
className: resolvedPopupClassName,
|
|
207
|
+
style: resolvedPopupStyle,
|
|
208
|
+
};
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
return {
|
|
212
|
+
...popupProps,
|
|
213
|
+
className: resolvedPopupClassName,
|
|
214
|
+
style: resolvedPopupStyle,
|
|
215
|
+
};
|
|
216
|
+
}, [popupProps, resolvedPopupClassName, resolvedPopupStyle]);
|
|
217
|
+
|
|
218
|
+
const { container: portalContainer, ...restPortalProps } = portalProps ?? {};
|
|
219
|
+
const resolvedPortalContainer = useMemo<HTMLElement | null | undefined>(() => {
|
|
220
|
+
if (!portalContainer) return portalContainer ?? undefined;
|
|
221
|
+
if (typeof portalContainer === 'object' && 'current' in portalContainer) {
|
|
222
|
+
const current = portalContainer.current;
|
|
223
|
+
if (!current) return null;
|
|
224
|
+
if (typeof ShadowRoot !== 'undefined' && current instanceof ShadowRoot) {
|
|
225
|
+
return current.host as HTMLElement;
|
|
226
|
+
}
|
|
227
|
+
return current as HTMLElement;
|
|
228
|
+
}
|
|
229
|
+
if (typeof ShadowRoot !== 'undefined' && portalContainer instanceof ShadowRoot) {
|
|
230
|
+
return portalContainer.host as HTMLElement;
|
|
231
|
+
}
|
|
232
|
+
return portalContainer as HTMLElement;
|
|
233
|
+
}, [portalContainer]);
|
|
38
234
|
|
|
39
235
|
return (
|
|
40
|
-
<
|
|
41
|
-
arrow={false}
|
|
42
|
-
destroyOnHidden={false}
|
|
43
|
-
menu={{
|
|
44
|
-
...menu,
|
|
45
|
-
className: cx(styles.dropdownMenu, menu.className),
|
|
46
|
-
onClick: (e) => {
|
|
47
|
-
e.domEvent.preventDefault();
|
|
48
|
-
menu.onClick?.(e);
|
|
49
|
-
},
|
|
50
|
-
style: {
|
|
51
|
-
maxHeight,
|
|
52
|
-
maxWidth: isMobile ? undefined : maxWidth,
|
|
53
|
-
minHeight,
|
|
54
|
-
minWidth: isMobile ? undefined : minWidth,
|
|
55
|
-
overflowX: 'hidden',
|
|
56
|
-
overflowY: 'scroll',
|
|
57
|
-
width: isMobile ? '100vw' : undefined,
|
|
58
|
-
...menu.style,
|
|
59
|
-
},
|
|
60
|
-
}}
|
|
61
|
-
placement={isMobile ? 'top' : placement}
|
|
236
|
+
<DropdownMenuRoot
|
|
62
237
|
{...rest}
|
|
238
|
+
defaultOpen={defaultOpen}
|
|
239
|
+
onOpenChange={handleOpenChange}
|
|
240
|
+
onOpenChangeComplete={handleOpenChangeComplete}
|
|
241
|
+
open={open}
|
|
63
242
|
>
|
|
64
|
-
{children}
|
|
65
|
-
|
|
243
|
+
<DropdownMenuTrigger {...resolvedTriggerProps}>{children}</DropdownMenuTrigger>
|
|
244
|
+
<DropdownMenuPortal container={resolvedPortalContainer} {...restPortalProps}>
|
|
245
|
+
<DropdownMenuPositioner
|
|
246
|
+
{...positionerProps}
|
|
247
|
+
hoverTrigger={Boolean(resolvedTriggerProps?.openOnHover)}
|
|
248
|
+
placement={isMobile ? 'top' : placement}
|
|
249
|
+
>
|
|
250
|
+
<DropdownMenuPopup {...resolvedPopupProps}>{menuContent}</DropdownMenuPopup>
|
|
251
|
+
</DropdownMenuPositioner>
|
|
252
|
+
</DropdownMenuPortal>
|
|
253
|
+
</DropdownMenuRoot>
|
|
66
254
|
);
|
|
67
255
|
},
|
|
68
256
|
);
|
|
@@ -42,8 +42,9 @@ export interface ConversationProviderProps {
|
|
|
42
42
|
* Use this to sync messages back to external state (e.g., ChatStore)
|
|
43
43
|
*
|
|
44
44
|
* @param messages - The updated messages array
|
|
45
|
+
* @param context - The context that this data belongs to (prevents race conditions)
|
|
45
46
|
*/
|
|
46
|
-
onMessagesChange?: (messages: UIChatMessage[]) => void;
|
|
47
|
+
onMessagesChange?: (messages: UIChatMessage[], context: ConversationContext) => void;
|
|
47
48
|
/**
|
|
48
49
|
* External operation state (from ChatStore)
|
|
49
50
|
*
|
|
@@ -22,16 +22,20 @@ import { useAssistantActions } from './useAssistantActions';
|
|
|
22
22
|
// Helper to strip handleClick from action items before passing to ActionIconGroup
|
|
23
23
|
const stripHandleClick = (item: MessageActionItemOrDivider): ActionIconGroupItemType => {
|
|
24
24
|
if ('type' in item && item.type === 'divider') return item as unknown as ActionIconGroupItemType;
|
|
25
|
-
|
|
26
|
-
const
|
|
25
|
+
const { children, ...rest } = item as MessageActionItem;
|
|
26
|
+
const baseItem = { ...rest } as MessageActionItem;
|
|
27
|
+
delete (baseItem as { handleClick?: unknown }).handleClick;
|
|
27
28
|
if (children) {
|
|
28
29
|
return {
|
|
29
|
-
...
|
|
30
|
-
|
|
31
|
-
|
|
30
|
+
...baseItem,
|
|
31
|
+
children: children.map((child) => {
|
|
32
|
+
const nextChild = { ...child } as MessageActionItem;
|
|
33
|
+
delete (nextChild as { handleClick?: unknown }).handleClick;
|
|
34
|
+
return nextChild;
|
|
35
|
+
}),
|
|
32
36
|
} as ActionIconGroupItemType;
|
|
33
37
|
}
|
|
34
|
-
return
|
|
38
|
+
return baseItem as ActionIconGroupItemType;
|
|
35
39
|
};
|
|
36
40
|
|
|
37
41
|
// Build action items map for handleAction lookup
|
|
@@ -21,16 +21,20 @@ import { useGroupActions } from './useGroupActions';
|
|
|
21
21
|
// Helper to strip handleClick from action items before passing to ActionIconGroup
|
|
22
22
|
const stripHandleClick = (item: MessageActionItemOrDivider): ActionIconGroupItemType => {
|
|
23
23
|
if ('type' in item && item.type === 'divider') return item as unknown as ActionIconGroupItemType;
|
|
24
|
-
|
|
25
|
-
const
|
|
24
|
+
const { children, ...rest } = item as MessageActionItem;
|
|
25
|
+
const baseItem = { ...rest } as MessageActionItem;
|
|
26
|
+
delete (baseItem as { handleClick?: unknown }).handleClick;
|
|
26
27
|
if (children) {
|
|
27
28
|
return {
|
|
28
|
-
...
|
|
29
|
-
|
|
30
|
-
|
|
29
|
+
...baseItem,
|
|
30
|
+
children: children.map((child) => {
|
|
31
|
+
const nextChild = { ...child } as MessageActionItem;
|
|
32
|
+
delete (nextChild as { handleClick?: unknown }).handleClick;
|
|
33
|
+
return nextChild;
|
|
34
|
+
}),
|
|
31
35
|
} as ActionIconGroupItemType;
|
|
32
36
|
}
|
|
33
|
-
return
|
|
37
|
+
return baseItem as ActionIconGroupItemType;
|
|
34
38
|
};
|
|
35
39
|
|
|
36
40
|
// Build action items map for handleAction lookup
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Button,
|
|
1
|
+
import { Button, DropdownMenu, Flexbox, Popover } from '@lobehub/ui';
|
|
2
2
|
import { Input, Space } from 'antd';
|
|
3
3
|
import { ChevronDown } from 'lucide-react';
|
|
4
4
|
import { memo, useState } from 'react';
|
|
@@ -140,17 +140,15 @@ const ApprovalActions = memo<ApprovalActionsProps>(
|
|
|
140
140
|
>
|
|
141
141
|
{t('tool.intervention.approveAndRemember')}
|
|
142
142
|
</Button>
|
|
143
|
-
<
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
],
|
|
153
|
-
}}
|
|
143
|
+
<DropdownMenu
|
|
144
|
+
items={[
|
|
145
|
+
{
|
|
146
|
+
disabled: approveLoading || isMessageCreating,
|
|
147
|
+
key: 'once',
|
|
148
|
+
label: t('tool.intervention.approveOnce'),
|
|
149
|
+
onClick: () => handleApprove(false),
|
|
150
|
+
},
|
|
151
|
+
]}
|
|
154
152
|
>
|
|
155
153
|
<Button
|
|
156
154
|
disabled={approveLoading || isMessageCreating}
|
|
@@ -158,7 +156,7 @@ const ApprovalActions = memo<ApprovalActionsProps>(
|
|
|
158
156
|
size="small"
|
|
159
157
|
type="primary"
|
|
160
158
|
/>
|
|
161
|
-
</
|
|
159
|
+
</DropdownMenu>
|
|
162
160
|
</Space.Compact>
|
|
163
161
|
) : (
|
|
164
162
|
<Button
|
package/src/features/Conversation/Messages/AssistantGroup/Tool/Detail/Intervention/ModeSelector.tsx
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
|
-
import { Button,
|
|
2
|
-
import { Center } from '@lobehub/ui';
|
|
1
|
+
import { Button, Center, DropdownMenu, Icon, type MenuProps } from '@lobehub/ui';
|
|
3
2
|
import { createStaticStyles } from 'antd-style';
|
|
4
|
-
import { ChevronDown, Hand, ListChecks, Zap } from 'lucide-react';
|
|
3
|
+
import { Check, ChevronDown, Hand, ListChecks, Zap } from 'lucide-react';
|
|
5
4
|
import { memo, useCallback, useMemo } from 'react';
|
|
6
5
|
import { useTranslation } from 'react-i18next';
|
|
7
6
|
|
|
@@ -61,6 +60,7 @@ const ModeSelector = memo(() => {
|
|
|
61
60
|
const menuItems = useMemo<MenuProps['items']>(
|
|
62
61
|
() => [
|
|
63
62
|
{
|
|
63
|
+
extra: approvalMode === 'auto-run' ? <Icon icon={Check} /> : undefined,
|
|
64
64
|
icon: (
|
|
65
65
|
<Center className={styles.icon} height={32} width={32}>
|
|
66
66
|
<Icon icon={Zap} />
|
|
@@ -76,6 +76,7 @@ const ModeSelector = memo(() => {
|
|
|
76
76
|
onClick: () => handleModeChange('auto-run'),
|
|
77
77
|
},
|
|
78
78
|
{
|
|
79
|
+
extra: approvalMode === 'allow-list' ? <Icon icon={Check} /> : undefined,
|
|
79
80
|
icon: (
|
|
80
81
|
<Center className={styles.icon} height={32} width={32}>
|
|
81
82
|
<Icon icon={ListChecks} />
|
|
@@ -91,6 +92,7 @@ const ModeSelector = memo(() => {
|
|
|
91
92
|
onClick: () => handleModeChange('allow-list'),
|
|
92
93
|
},
|
|
93
94
|
{
|
|
95
|
+
extra: approvalMode === 'manual' ? <Icon icon={Check} /> : undefined,
|
|
94
96
|
icon: (
|
|
95
97
|
<Center className={styles.icon} height={32} width={32}>
|
|
96
98
|
<Icon icon={Hand} />
|
|
@@ -106,15 +108,11 @@ const ModeSelector = memo(() => {
|
|
|
106
108
|
onClick: () => handleModeChange('manual'),
|
|
107
109
|
},
|
|
108
110
|
],
|
|
109
|
-
[modeLabels, handleModeChange, styles, t],
|
|
111
|
+
[approvalMode, modeLabels, handleModeChange, styles, t],
|
|
110
112
|
);
|
|
111
113
|
|
|
112
114
|
return (
|
|
113
|
-
<
|
|
114
|
-
// @ts-expect-error activeKey 没在 Dropdown key 里很奇怪
|
|
115
|
-
menu={{ activeKey: approvalMode, items: menuItems }}
|
|
116
|
-
placement="bottomLeft"
|
|
117
|
-
>
|
|
115
|
+
<DropdownMenu items={menuItems} placement="bottomLeft">
|
|
118
116
|
<Button
|
|
119
117
|
className={styles.modeButton}
|
|
120
118
|
color={'default'}
|
|
@@ -125,7 +123,7 @@ const ModeSelector = memo(() => {
|
|
|
125
123
|
>
|
|
126
124
|
{modeLabels[approvalMode]}
|
|
127
125
|
</Button>
|
|
128
|
-
</
|
|
126
|
+
</DropdownMenu>
|
|
129
127
|
);
|
|
130
128
|
});
|
|
131
129
|
|
|
@@ -21,16 +21,20 @@ import { useGroupActions } from './useGroupActions';
|
|
|
21
21
|
// Helper to strip handleClick from action items before passing to ActionIconGroup
|
|
22
22
|
const stripHandleClick = (item: MessageActionItemOrDivider): ActionIconGroupItemType => {
|
|
23
23
|
if ('type' in item && item.type === 'divider') return item as unknown as ActionIconGroupItemType;
|
|
24
|
-
|
|
25
|
-
const
|
|
24
|
+
const { children, ...rest } = item as MessageActionItem;
|
|
25
|
+
const baseItem = { ...rest } as MessageActionItem;
|
|
26
|
+
delete (baseItem as { handleClick?: unknown }).handleClick;
|
|
26
27
|
if (children) {
|
|
27
28
|
return {
|
|
28
|
-
...
|
|
29
|
-
|
|
30
|
-
|
|
29
|
+
...baseItem,
|
|
30
|
+
children: children.map((child) => {
|
|
31
|
+
const nextChild = { ...child } as MessageActionItem;
|
|
32
|
+
delete (nextChild as { handleClick?: unknown }).handleClick;
|
|
33
|
+
return nextChild;
|
|
34
|
+
}),
|
|
31
35
|
} as ActionIconGroupItemType;
|
|
32
36
|
}
|
|
33
|
-
return
|
|
37
|
+
return baseItem as ActionIconGroupItemType;
|
|
34
38
|
};
|
|
35
39
|
|
|
36
40
|
// Build action items map for handleAction lookup
|
|
@@ -18,16 +18,20 @@ import { useAssistantActions } from './useAssistantActions';
|
|
|
18
18
|
// Helper to strip handleClick from action items before passing to ActionIconGroup
|
|
19
19
|
const stripHandleClick = (item: MessageActionItemOrDivider): ActionIconGroupItemType => {
|
|
20
20
|
if ('type' in item && item.type === 'divider') return item as unknown as ActionIconGroupItemType;
|
|
21
|
-
|
|
22
|
-
const
|
|
21
|
+
const { children, ...rest } = item as MessageActionItem;
|
|
22
|
+
const baseItem = { ...rest } as MessageActionItem;
|
|
23
|
+
delete (baseItem as { handleClick?: unknown }).handleClick;
|
|
23
24
|
if (children) {
|
|
24
25
|
return {
|
|
25
|
-
...
|
|
26
|
-
|
|
27
|
-
|
|
26
|
+
...baseItem,
|
|
27
|
+
children: children.map((child) => {
|
|
28
|
+
const nextChild = { ...child } as MessageActionItem;
|
|
29
|
+
delete (nextChild as { handleClick?: unknown }).handleClick;
|
|
30
|
+
return nextChild;
|
|
31
|
+
}),
|
|
28
32
|
} as ActionIconGroupItemType;
|
|
29
33
|
}
|
|
30
|
-
return
|
|
34
|
+
return baseItem as ActionIconGroupItemType;
|
|
31
35
|
};
|
|
32
36
|
|
|
33
37
|
// Build action items map for handleAction lookup
|