mirror of
https://github.com/lobehub/lobe-chat.git
synced 2026-06-13 19:20:04 +00:00
♻️ refactor(modal): migrate confirm modals to @lobehub/ui/base-ui (Phase 1) (#15259)
* ♻️ refactor(modal): migrate confirm modals to @lobehub/ui/base-ui Replace all `App.useApp().modal.confirm`, `Modal.confirm` and `AntModal.confirm` call sites with the headless `confirmModal` from `@lobehub/ui/base-ui`, dropping antd-only props (`centered`, `type`, `width`, `okButtonProps.type='primary'`, `okButtonProps.loading`, `classNames.root`) that the base-ui imperative API does not accept. - 82 files touched; `modal.confirm`/`Modal.confirm` call sites now zero - `PageEditor/store/action.ts`: drop `modal` arg from `handleDelete` - `ResourceManager/useUploadFolder`: replace dynamic `import('antd').Modal` - `Eval/DatasetsTab`: migrate `modal.success` to `confirmModal` Part of LOBE-9645 Phase 1. * ♻️ refactor(ui): migrate select/modal call sites to @lobehub/ui/base-ui - Convert imperative-modal factories (createXxxModal + Content split) for apikey, creds (Create/Edit/View), provider (CreateNewProvider), and messenger LinkModal. - Switch Select usages to base-ui Select (Messenger AgentSelect, provider sdkType). - Restructure CreateNewProvider form to vertical layout with manual section titles for tighter spacing; drop FormModal/Form group nesting. - Standardize small ActionIcon sizing via DESKTOP_HEADER_ICON_SMALL_SIZE (WideScreenButton, ToggleRightPanelButton, ContextDropdown, AddNewProvider). - Fix missing title on ResourceManager delete confirm modal so the header (title + close X) renders. - Update react skill and AGENTS.md to require base-ui priority over root @lobehub/ui / antd; expand component table and Common Mistakes with explicit base-ui rules. * ♻️ refactor(ui): swap antd Select to base-ui Select and migrate createStyles to createStaticStyles * ✅ test: update test mocks for base-ui confirmModal migration * ✅ test(e2e): switch delete confirm selector to base-ui dialog role
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
---
|
||||
name: react
|
||||
description: "LobeHub React component conventions — styling via `antd-style` `createStaticStyles` + `cssVar.*` (zero-runtime preferred over `createStyles` + `token`), `@lobehub/ui` over antd when both exist, routing via `react-router-dom` (not `next/link`). Use when writing or editing any `.tsx` under `src/**`. Triggers on `createStaticStyles`, `createStyles`, `cssVar`, `antd-style`, `Flexbox`, `Center`, `Select`, `Modal`, `Drawer`, `Button`, `Tooltip`, `DropdownMenu`, `Popover`, `Switch`, `ScrollArea`, `Link`, `useNavigate`, `react-router-dom`, `next/link`, `desktopRouter`, `componentMap.desktop`, `.desktop.tsx`, 'new component', 'new page', 'edit layout', 'add styles', 'zustand selector', '@lobehub/ui', 'antd import'."
|
||||
description: "LobeHub React component conventions — base-ui (`@lobehub/ui/base-ui`) first for headless primitives (Select, Modal, DropdownMenu, ContextMenu, Popover, ScrollArea, Switch, Toast, FloatingSheet), then `@lobehub/ui` root, antd as last resort; styling via `antd-style` `createStaticStyles` + `cssVar.*` (zero-runtime preferred over `createStyles` + `token`); routing via `react-router-dom` (not `next/link`). Use when writing or editing any `.tsx` under `src/**`. Triggers on `createStaticStyles`, `createStyles`, `cssVar`, `antd-style`, `Flexbox`, `Center`, `Select`, `Modal`, `Drawer`, `Button`, `Tooltip`, `DropdownMenu`, `ContextMenu`, `Popover`, `Switch`, `ScrollArea`, `Toast`, `FloatingSheet`, `Link`, `useNavigate`, `react-router-dom`, `next/link`, `desktopRouter`, `componentMap.desktop`, `.desktop.tsx`, `base-ui`, `@lobehub/ui/base-ui`, 'new component', 'new page', 'edit layout', 'add styles', 'zustand selector', '@lobehub/ui', 'antd import'."
|
||||
user-invocable: false
|
||||
---
|
||||
|
||||
@@ -17,22 +17,41 @@ user-invocable: false
|
||||
## Component Priority
|
||||
|
||||
1. **`src/components`** — project-specific reusable components
|
||||
2. **`@lobehub/ui/base-ui`** — headless primitives (Select, Modal, DropdownMenu, Popover, Switch, ScrollArea…)
|
||||
3. **`@lobehub/ui`** — higher-level components (ActionIcon, Markdown, DragPage…)
|
||||
4. **Custom implementation** — last resort; never reach for antd directly
|
||||
2. **`@lobehub/ui/base-ui`** — headless primitives. **If the component lives here, use it. Do NOT import the same-named root export.**
|
||||
3. **`@lobehub/ui`** — higher-level / antd-wrapping components (only when no base-ui equivalent)
|
||||
4. **antd** — only when neither base-ui nor `@lobehub/ui` root provides it
|
||||
5. **Custom implementation** — true last resort
|
||||
|
||||
If unsure about available components, search existing code or check `node_modules/@lobehub/ui/es/index.mjs`.
|
||||
If unsure about available components, search existing code or check `node_modules/@lobehub/ui/es/index.mjs` and `node_modules/@lobehub/ui/es/base-ui/`.
|
||||
|
||||
### Common @lobehub/ui Components
|
||||
### `@lobehub/ui/base-ui` — always prefer for these
|
||||
|
||||
| Component | Import |
|
||||
| ------------------------------------------ | ------------------------------------------------------------------------------------------------------- |
|
||||
| `Select` (+ `SelectProps`, `SelectOption`) | `import { Select } from '@lobehub/ui/base-ui';` |
|
||||
| `Modal` (imperative API) | `import { createModal, confirmModal, useModalContext, type ModalInstance } from '@lobehub/ui/base-ui';` |
|
||||
| `DropdownMenu` | `import { DropdownMenu } from '@lobehub/ui/base-ui';` |
|
||||
| `ContextMenu` | `import { ContextMenu } from '@lobehub/ui/base-ui';` |
|
||||
| `Popover` | `import { Popover } from '@lobehub/ui/base-ui';` |
|
||||
| `ScrollArea` | `import { ScrollArea } from '@lobehub/ui/base-ui';` |
|
||||
| `Switch` | `import { Switch } from '@lobehub/ui/base-ui';` |
|
||||
| `Toast` | `import { Toast } from '@lobehub/ui/base-ui';` |
|
||||
| `FloatingSheet` | `import { FloatingSheet } from '@lobehub/ui/base-ui';` |
|
||||
|
||||
For Modal specifically, see the dedicated **modal** skill — use the imperative `createModal({ content: … })` pattern over the legacy `<Modal open … />` declarative pattern. base-ui has its own `ModalHost` already mounted in `SPAGlobalProvider`.
|
||||
|
||||
> Common slip: `import { Select } from '@lobehub/ui'` looks fine but it's the antd-backed Select. Use base-ui Select. Same for `Modal`, `DropdownMenu`, etc.
|
||||
|
||||
### `@lobehub/ui` root — use when base-ui has no equivalent
|
||||
|
||||
| Category | Components |
|
||||
| ------------ | ------------------------------------------------------------------------------- |
|
||||
| ------------ | ------------------------------------------------------------------------------------- |
|
||||
| General | ActionIcon, ActionIconGroup, Block, Button, Icon |
|
||||
| Data Display | Avatar, Collapse, Empty, Highlighter, Markdown, Tag, Tooltip |
|
||||
| Data Entry | CodeEditor, CopyButton, EditableText, Form, FormModal, Input, SearchBar, Select |
|
||||
| Feedback | Alert, Drawer, Modal |
|
||||
| Data Entry | CodeEditor, CopyButton, EditableText, Form, Input, InputPassword, SearchBar, TextArea |
|
||||
| Feedback | Alert, Drawer |
|
||||
| Layout | Center, DraggablePanel, Flexbox, Grid, Header, MaskShadow |
|
||||
| Navigation | Burger, Dropdown, Menu, SideNav, Tabs |
|
||||
| Navigation | Burger, Menu, SideNav, Tabs |
|
||||
|
||||
## Layout
|
||||
|
||||
@@ -86,9 +105,12 @@ errorElement: <ErrorBoundary />;
|
||||
## Common Mistakes
|
||||
|
||||
| Mistake | Fix |
|
||||
| ----------------------------------------------------------------- | ----------------------------------------------------------------- |
|
||||
| ------------------------------------------------------------------ | --------------------------------------------------------------------------- |
|
||||
| Using `next/link` in SPA | Use `react-router-dom` `Link` |
|
||||
| Using antd directly | Use `@lobehub/ui/base-ui` first, then `@lobehub/ui` |
|
||||
| `import { Select } from '@lobehub/ui'` | `import { Select } from '@lobehub/ui/base-ui'` |
|
||||
| `import { Modal } from '@lobehub/ui'` + `<Modal open>` declarative | `createModal` / `confirmModal` from `@lobehub/ui/base-ui` (see modal skill) |
|
||||
| `import { DropdownMenu/Popover/Switch } from '@lobehub/ui'` | Import same name from `@lobehub/ui/base-ui` instead |
|
||||
| `createStyles` for static styles | Use `createStaticStyles` + `cssVar` |
|
||||
| Editing only `desktopRouter.config.tsx` | Must edit both `.tsx` and `.desktop.tsx` |
|
||||
| Using `margin` for flex spacing | Use `gap` prop on Flexbox |
|
||||
|
||||
@@ -7,6 +7,7 @@ Guidelines for using AI coding agents in this LobeHub repository.
|
||||
- Next.js 16 + React 19 + TypeScript
|
||||
- SPA inside Next.js with `react-router-dom`
|
||||
- `@lobehub/ui`, antd for components; antd-style for CSS-in-JS — **prefer `createStaticStyles` with `cssVar.*`** (zero-runtime); only fall back to `createStyles` + `token` when styles genuinely need runtime computation. See `.cursor/docs/createStaticStyles_migration_guide.md`.
|
||||
- **Component priority**: `@lobehub/ui/base-ui` (headless primitives) **first**, then `@lobehub/ui` root, then antd as last resort. When the component exists in base-ui, use it — never reach for the root or antd counterpart. Base-ui covers `Select`, `Modal` / `createModal` / `confirmModal`, `DropdownMenu`, `ContextMenu`, `Popover`, `ScrollArea`, `Switch`, `Toast`, `FloatingSheet`. Prefer `@lobehub/ui/base-ui` for new code and migrate root-package call sites opportunistically.
|
||||
- react-i18next for i18n; zustand for state management
|
||||
- SWR for data fetching; TRPC for type-safe backend
|
||||
- Drizzle ORM with PostgreSQL; Vitest for testing
|
||||
|
||||
@@ -427,10 +427,10 @@ When('用户选择删除选项', async function (this: CustomWorld) {
|
||||
When('用户确认删除', async function (this: CustomWorld) {
|
||||
console.log(' 📍 Step: 确认删除...');
|
||||
|
||||
// A confirmation modal should appear
|
||||
const confirmButton = this.page.locator('.ant-modal-confirm-btns button.ant-btn-dangerous');
|
||||
const confirmButton = this.page
|
||||
.getByRole('dialog')
|
||||
.getByRole('button', { name: /^(ok|delete|删除|确认|确定)$/i });
|
||||
|
||||
// Wait for modal to appear
|
||||
await expect(confirmButton).toBeVisible({ timeout: 5000 });
|
||||
await confirmButton.click();
|
||||
|
||||
|
||||
@@ -294,7 +294,9 @@ When('用户在菜单中选择删除', async function (this: CustomWorld) {
|
||||
When('用户在弹窗中确认删除', async function (this: CustomWorld) {
|
||||
console.log(' 📍 Step: 确认删除...');
|
||||
|
||||
const confirmButton = this.page.locator('.ant-modal-confirm-btns button.ant-btn-dangerous');
|
||||
const confirmButton = this.page
|
||||
.getByRole('dialog')
|
||||
.getByRole('button', { name: /^(ok|delete|删除|确认|确定)$/i });
|
||||
await expect(confirmButton).toBeVisible({ timeout: 5000 });
|
||||
await confirmButton.click();
|
||||
await this.page.waitForTimeout(500);
|
||||
|
||||
@@ -1,36 +1,32 @@
|
||||
import { createStyles, keyframes } from 'antd-style';
|
||||
import { createStaticStyles, cssVar, cx } from 'antd-style';
|
||||
import { type CSSProperties, memo } from 'react';
|
||||
|
||||
const fade = keyframes`
|
||||
0%, 100% {
|
||||
opacity: 0.3;
|
||||
}
|
||||
50% {
|
||||
opacity: 1;
|
||||
}
|
||||
`;
|
||||
|
||||
interface StyleParams {
|
||||
color?: string;
|
||||
gap: number;
|
||||
size: number;
|
||||
}
|
||||
|
||||
const useStyles = createStyles(({ css, token }, { size, gap, color }: StyleParams) => ({
|
||||
const styles = createStaticStyles(({ css }) => ({
|
||||
container: css`
|
||||
display: inline-flex;
|
||||
flex-direction: row;
|
||||
gap: ${gap}px;
|
||||
gap: var(--dots-loading-gap);
|
||||
align-items: center;
|
||||
`,
|
||||
dot: css`
|
||||
width: ${size}px;
|
||||
height: ${size}px;
|
||||
width: var(--dots-loading-size);
|
||||
height: var(--dots-loading-size);
|
||||
border-radius: 50%;
|
||||
|
||||
background-color: ${color || token.colorTextSecondary};
|
||||
background-color: var(--dots-loading-color);
|
||||
|
||||
animation: ${fade} 1.2s ease-in-out infinite;
|
||||
animation: dots-loading-fade 1.2s ease-in-out infinite;
|
||||
|
||||
@keyframes dots-loading-fade {
|
||||
0%,
|
||||
100% {
|
||||
opacity: 0.3;
|
||||
}
|
||||
|
||||
50% {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
`,
|
||||
}));
|
||||
|
||||
@@ -46,12 +42,17 @@ interface DotsLoadingProps extends StyleArgs {
|
||||
}
|
||||
|
||||
const DotsLoading = memo<DotsLoadingProps>(({ size = 4, gap = 3, color, className, style }) => {
|
||||
const { styles: s, cx } = useStyles({ color, gap, size });
|
||||
const cssVars = {
|
||||
'--dots-loading-color': color || cssVar.colorTextSecondary,
|
||||
'--dots-loading-gap': `${gap}px`,
|
||||
'--dots-loading-size': `${size}px`,
|
||||
} as CSSProperties;
|
||||
|
||||
return (
|
||||
<div className={cx(s.container, className)} style={style}>
|
||||
<div className={s.dot} style={{ animationDelay: '0s' }} />
|
||||
<div className={s.dot} style={{ animationDelay: '0.15s' }} />
|
||||
<div className={s.dot} style={{ animationDelay: '0.3s' }} />
|
||||
<div className={cx(styles.container, className)} style={{ ...cssVars, ...style }}>
|
||||
<div className={styles.dot} style={{ animationDelay: '0s' }} />
|
||||
<div className={styles.dot} style={{ animationDelay: '0.15s' }} />
|
||||
<div className={styles.dot} style={{ animationDelay: '0.3s' }} />
|
||||
</div>
|
||||
);
|
||||
});
|
||||
|
||||
@@ -30,7 +30,6 @@ vi.mock('antd-style', async (importOriginal) => {
|
||||
cssVar: {},
|
||||
}),
|
||||
),
|
||||
createStyles: vi.fn(() => () => ({ styles: {} })),
|
||||
useTheme: () => ({
|
||||
colorTextSecondary: '#999',
|
||||
}),
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
'use client';
|
||||
|
||||
import { confirmModal, Select } from '@lobehub/ui/base-ui';
|
||||
import type { TableColumnsType } from 'antd';
|
||||
import { App, Button, Popconfirm, Select, Space, Table, Tag, Typography } from 'antd';
|
||||
import { App, Button, Popconfirm, Space, Table, Tag, Typography } from 'antd';
|
||||
import { memo, useMemo, useState } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
@@ -28,7 +29,7 @@ const FILE_PREVIEW_LIMIT = 5;
|
||||
|
||||
const AgentDocuments = memo(() => {
|
||||
const { t } = useTranslation(['setting', 'common']);
|
||||
const { message, modal } = App.useApp();
|
||||
const { message } = App.useApp();
|
||||
const agentId = useAgentStore((s) => s.activeAgentId);
|
||||
const [templateId, setTemplateId] = useState(DEFAULT_TEMPLATE_ID);
|
||||
const [isInitializingTemplate, setIsInitializingTemplate] = useState(false);
|
||||
@@ -160,7 +161,7 @@ const AgentDocuments = memo(() => {
|
||||
const previewFilenames = overwrittenFilenames.slice(0, FILE_PREVIEW_LIMIT);
|
||||
const remainingCount = overwrittenCount - previewFilenames.length;
|
||||
|
||||
modal.confirm({
|
||||
confirmModal({
|
||||
content: (
|
||||
<Space direction={'vertical'} size={8}>
|
||||
<Typography.Text>
|
||||
|
||||
@@ -12,7 +12,7 @@ import {
|
||||
Markdown,
|
||||
Text,
|
||||
} from '@lobehub/ui';
|
||||
import { App } from 'antd';
|
||||
import { confirmModal } from '@lobehub/ui/base-ui';
|
||||
import { cssVar } from 'antd-style';
|
||||
import { MessageCircle, MoreHorizontal, Pencil, Trash } from 'lucide-react';
|
||||
import { memo, useCallback, useMemo, useState } from 'react';
|
||||
@@ -29,7 +29,6 @@ interface CommentCardProps {
|
||||
|
||||
const CommentCard = memo<CommentCardProps>(({ activity }) => {
|
||||
const { t } = useTranslation('chat');
|
||||
const { modal } = App.useApp();
|
||||
const deleteComment = useTaskStore((s) => s.deleteComment);
|
||||
const updateComment = useTaskStore((s) => s.updateComment);
|
||||
|
||||
@@ -64,16 +63,14 @@ const CommentCard = memo<CommentCardProps>(({ activity }) => {
|
||||
|
||||
const handleDelete = useCallback(() => {
|
||||
if (!commentId) return;
|
||||
modal.confirm({
|
||||
centered: true,
|
||||
confirmModal({
|
||||
content: t('taskDetail.comment.deleteConfirm.content'),
|
||||
okButtonProps: { danger: true },
|
||||
okText: t('taskDetail.comment.deleteConfirm.ok'),
|
||||
onOk: () => deleteComment(commentId),
|
||||
title: t('taskDetail.comment.deleteConfirm.title'),
|
||||
type: 'error',
|
||||
});
|
||||
}, [commentId, deleteComment, modal, t]);
|
||||
}, [commentId, deleteComment, t]);
|
||||
|
||||
const menuItems = useMemo<DropdownItem[]>(
|
||||
() => [
|
||||
|
||||
@@ -9,7 +9,7 @@ import {
|
||||
Tag,
|
||||
Text,
|
||||
} from '@lobehub/ui';
|
||||
import { App } from 'antd';
|
||||
import { confirmModal } from '@lobehub/ui/base-ui';
|
||||
import { cssVar } from 'antd-style';
|
||||
import { FileTextIcon, MoreHorizontal, Package, Trash } from 'lucide-react';
|
||||
import { memo, useCallback, useMemo, useState } from 'react';
|
||||
@@ -30,7 +30,6 @@ const flattenWorkspace = (nodes: TaskDetailWorkspaceNode[]): TaskDetailWorkspace
|
||||
|
||||
const ArtifactCard = memo<{ node: TaskDetailWorkspaceNode }>(({ node }) => {
|
||||
const { t } = useTranslation('chat');
|
||||
const { modal } = App.useApp();
|
||||
const openDocumentPreview = useDocumentStore((s) => s.openDocumentPreview);
|
||||
const unpinDocument = useTaskStore((s) => s.unpinDocument);
|
||||
const activeTaskId = useTaskStore(taskDetailSelectors.activeTaskId);
|
||||
@@ -41,16 +40,14 @@ const ArtifactCard = memo<{ node: TaskDetailWorkspaceNode }>(({ node }) => {
|
||||
const handleDelete = useCallback(() => {
|
||||
const taskId = node.sourceTaskId ?? activeTaskId;
|
||||
if (!taskId) return;
|
||||
modal.confirm({
|
||||
centered: true,
|
||||
confirmModal({
|
||||
content: t('taskDetail.artifactMenu.deleteConfirm.content'),
|
||||
okButtonProps: { danger: true },
|
||||
okText: t('taskDetail.artifactMenu.deleteConfirm.ok'),
|
||||
onOk: () => unpinDocument(taskId, node.documentId),
|
||||
title: t('taskDetail.artifactMenu.deleteConfirm.title'),
|
||||
type: 'error',
|
||||
});
|
||||
}, [activeTaskId, modal, node.documentId, node.sourceTaskId, t, unpinDocument]);
|
||||
}, [activeTaskId, node.documentId, node.sourceTaskId, t, unpinDocument]);
|
||||
|
||||
const menuItems = useMemo<DropdownItem[]>(
|
||||
() => [
|
||||
|
||||
@@ -7,7 +7,7 @@ import {
|
||||
Icon,
|
||||
Text,
|
||||
} from '@lobehub/ui';
|
||||
import { App } from 'antd';
|
||||
import { confirmModal } from '@lobehub/ui/base-ui';
|
||||
import { cssVar } from 'antd-style';
|
||||
import { Check, ChevronDownIcon, ChevronUpIcon, MoreHorizontal, Trash } from 'lucide-react';
|
||||
import { memo, useCallback, useMemo, useState } from 'react';
|
||||
@@ -32,15 +32,13 @@ interface TaskBriefCardProps {
|
||||
const TaskBriefCard = memo<TaskBriefCardProps>(
|
||||
({ brief, onAfterResolve, onAfterAddComment, onAfterDelete }) => {
|
||||
const { t } = useTranslation('home');
|
||||
const { modal } = App.useApp();
|
||||
const deleteBrief = useBriefStore((s) => s.deleteBrief);
|
||||
const isResolved = Boolean(brief.resolvedAction);
|
||||
const [expanded, setExpanded] = useState(false);
|
||||
const showFull = !isResolved || expanded;
|
||||
|
||||
const handleDelete = useCallback(() => {
|
||||
modal.confirm({
|
||||
centered: true,
|
||||
confirmModal({
|
||||
content: t('brief.deleteConfirm.content'),
|
||||
okButtonProps: { danger: true },
|
||||
okText: t('brief.deleteConfirm.ok'),
|
||||
@@ -49,9 +47,8 @@ const TaskBriefCard = memo<TaskBriefCardProps>(
|
||||
await onAfterDelete?.();
|
||||
},
|
||||
title: t('brief.deleteConfirm.title'),
|
||||
type: 'error',
|
||||
});
|
||||
}, [brief.id, deleteBrief, modal, onAfterDelete, t]);
|
||||
}, [brief.id, deleteBrief, onAfterDelete, t]);
|
||||
|
||||
const menuItems = useMemo<DropdownItem[]>(
|
||||
() => [
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { ActionIcon, copyToClipboard, type DropdownItem, DropdownMenu, Icon } from '@lobehub/ui';
|
||||
import { confirmModal } from '@lobehub/ui/base-ui';
|
||||
import { App } from 'antd';
|
||||
import { CopyIcon, LinkIcon, MoreHorizontal, Trash } from 'lucide-react';
|
||||
import { memo, useCallback, useMemo } from 'react';
|
||||
@@ -13,7 +14,7 @@ import { taskDetailPath } from '../shared/taskDetailPath';
|
||||
|
||||
const TaskDetailHeaderActions = memo(() => {
|
||||
const { t } = useTranslation(['chat', 'common']);
|
||||
const { modal, message } = App.useApp();
|
||||
const { message } = App.useApp();
|
||||
const navigate = useNavigate();
|
||||
const appOrigin = useAppOrigin();
|
||||
const taskId = useTaskStore(taskDetailSelectors.activeTaskId);
|
||||
@@ -22,8 +23,7 @@ const TaskDetailHeaderActions = memo(() => {
|
||||
|
||||
const triggerDelete = useCallback(() => {
|
||||
if (!taskId) return;
|
||||
modal.confirm({
|
||||
centered: true,
|
||||
confirmModal({
|
||||
content: t('taskDetail.deleteConfirm.content'),
|
||||
okButtonProps: { danger: true },
|
||||
okText: t('taskDetail.deleteConfirm.ok'),
|
||||
@@ -32,9 +32,8 @@ const TaskDetailHeaderActions = memo(() => {
|
||||
navigate('/tasks');
|
||||
},
|
||||
title: t('taskDetail.deleteConfirm.title'),
|
||||
type: 'error',
|
||||
});
|
||||
}, [taskId, modal, t, deleteTask, navigate]);
|
||||
}, [taskId, t, deleteTask, navigate]);
|
||||
|
||||
const menuItems = useMemo<DropdownItem[]>(() => {
|
||||
if (!taskId) return [];
|
||||
|
||||
@@ -81,6 +81,10 @@ vi.mock('antd-style', () => ({
|
||||
},
|
||||
}));
|
||||
|
||||
vi.mock('@lobehub/ui/base-ui', () => ({
|
||||
confirmModal: vi.fn(),
|
||||
}));
|
||||
|
||||
vi.mock('react-i18next', () => ({
|
||||
useTranslation: () => ({ t: (key: string) => key }),
|
||||
}));
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import type { TaskDetailSubtask } from '@lobechat/types';
|
||||
import { ActionIcon, Block, Flexbox, Icon, showContextMenu, Text } from '@lobehub/ui';
|
||||
import { confirmModal } from '@lobehub/ui/base-ui';
|
||||
import { App, ConfigProvider, Tree } from 'antd';
|
||||
import type { DataNode } from 'antd/es/tree';
|
||||
import { cssVar } from 'antd-style';
|
||||
@@ -127,7 +128,7 @@ const toTreeData = (tree: TaskTreeNode[]): DataNode[] => {
|
||||
|
||||
const TaskSubtasks = memo(() => {
|
||||
const { t } = useTranslation('chat');
|
||||
const { message, modal } = App.useApp();
|
||||
const { message } = App.useApp();
|
||||
const navigate = useNavigate();
|
||||
const agentId = useTaskStore(taskDetailSelectors.activeTaskAgentId);
|
||||
const subtasks = useTaskStore(taskDetailSelectors.activeTaskSubtasks);
|
||||
@@ -210,9 +211,8 @@ const TaskSubtasks = memo(() => {
|
||||
}
|
||||
|
||||
const canRun = plan.totalRunnable > 0;
|
||||
modal.confirm({
|
||||
confirmModal({
|
||||
cancelText: t('taskDetail.runAll.cancel'),
|
||||
centered: true,
|
||||
content: <RunSubtasksPreview plan={plan} />,
|
||||
okButtonProps: canRun ? undefined : { disabled: true },
|
||||
okText: t('taskDetail.runAll.confirm', { count: plan.totalRunnable }),
|
||||
@@ -234,7 +234,6 @@ const TaskSubtasks = memo(() => {
|
||||
}
|
||||
},
|
||||
title: t('taskDetail.runAll.title'),
|
||||
width: 520,
|
||||
});
|
||||
} catch (error) {
|
||||
console.error('[TaskSubtasks] Failed to plan subtasks:', error);
|
||||
@@ -242,7 +241,7 @@ const TaskSubtasks = memo(() => {
|
||||
} finally {
|
||||
setIsPlanning(false);
|
||||
}
|
||||
}, [taskId, isPlanning, message, modal, t, runReadySubtasks]);
|
||||
}, [taskId, isPlanning, message, t, runReadySubtasks]);
|
||||
|
||||
if (!taskId) return null;
|
||||
|
||||
|
||||
@@ -7,6 +7,7 @@ import {
|
||||
Icon,
|
||||
type MenuInfo,
|
||||
} from '@lobehub/ui';
|
||||
import { confirmModal } from '@lobehub/ui/base-ui';
|
||||
import { App } from 'antd';
|
||||
import { cssVar } from 'antd-style';
|
||||
import {
|
||||
@@ -55,7 +56,7 @@ export interface TaskContextMenuActions {
|
||||
|
||||
export const useTaskContextMenuActions = (): TaskContextMenuActions => {
|
||||
const { t } = useTranslation(['chat', 'common']);
|
||||
const { modal, message } = App.useApp();
|
||||
const { message } = App.useApp();
|
||||
const appOrigin = useAppOrigin();
|
||||
|
||||
const updateTaskStatus = useTaskStore((s) => s.updateTaskStatus);
|
||||
@@ -72,8 +73,7 @@ export const useTaskContextMenuActions = (): TaskContextMenuActions => {
|
||||
|
||||
return useMemo<TaskContextMenuActions>(() => {
|
||||
const triggerDelete = (identifier: string) => {
|
||||
modal.confirm({
|
||||
centered: true,
|
||||
confirmModal({
|
||||
content: t('taskDetail.deleteConfirm.content'),
|
||||
okButtonProps: { danger: true },
|
||||
okText: t('taskDetail.deleteConfirm.ok'),
|
||||
@@ -81,7 +81,6 @@ export const useTaskContextMenuActions = (): TaskContextMenuActions => {
|
||||
await deleteTask(identifier);
|
||||
},
|
||||
title: t('taskDetail.deleteConfirm.title'),
|
||||
type: 'error',
|
||||
});
|
||||
};
|
||||
|
||||
@@ -277,7 +276,6 @@ export const useTaskContextMenuActions = (): TaskContextMenuActions => {
|
||||
|
||||
return { buildItems, installKeyboardHandlers };
|
||||
}, [
|
||||
modal,
|
||||
message,
|
||||
t,
|
||||
appOrigin,
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
'use client';
|
||||
|
||||
import { ActionIcon, Flexbox, Text } from '@lobehub/ui';
|
||||
import { App } from 'antd';
|
||||
import { confirmModal } from '@lobehub/ui/base-ui';
|
||||
import { createStaticStyles, cssVar } from 'antd-style';
|
||||
import { Archive, Star, Trash2, X } from 'lucide-react';
|
||||
import { memo, useCallback } from 'react';
|
||||
@@ -44,7 +44,6 @@ const styles = createStaticStyles(({ css }) => ({
|
||||
|
||||
const BulkActionBar = memo(() => {
|
||||
const { t } = useTranslation('topic');
|
||||
const { modal } = App.useApp();
|
||||
|
||||
const selectedIds = useTopicsViewStore((s) => s.selectedIds);
|
||||
const exitSelectMode = useTopicsViewStore((s) => s.exitSelectMode);
|
||||
@@ -68,7 +67,7 @@ const BulkActionBar = memo(() => {
|
||||
}, [selectedIds, updateTopicStatus, exitSelectMode]);
|
||||
|
||||
const handleBatchDelete = useCallback(() => {
|
||||
modal.confirm({
|
||||
confirmModal({
|
||||
content: t('management.bulk.deleteConfirm', { count: selectedIds.length }),
|
||||
okButtonProps: { danger: true },
|
||||
okText: t('management.bulk.delete'),
|
||||
@@ -82,7 +81,7 @@ const BulkActionBar = memo(() => {
|
||||
},
|
||||
title: t('management.bulk.deleteTitle'),
|
||||
});
|
||||
}, [selectedIds, modal, t, removeTopic, exitSelectMode]);
|
||||
}, [selectedIds, t, removeTopic, exitSelectMode]);
|
||||
|
||||
if (selectedIds.length === 0) return null;
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
'use client';
|
||||
|
||||
import { ActionIcon, type DropdownItem, DropdownMenu } from '@lobehub/ui';
|
||||
import { confirmModal } from '@lobehub/ui/base-ui';
|
||||
import { App } from 'antd';
|
||||
import { Archive, MoreHorizontal } from 'lucide-react';
|
||||
import { memo, useCallback, useMemo } from 'react';
|
||||
@@ -13,7 +14,7 @@ const THREE_MONTHS_MS = 90 * 24 * 60 * 60 * 1000;
|
||||
|
||||
const ToolbarActions = memo(() => {
|
||||
const { t } = useTranslation('topic');
|
||||
const { modal, message } = App.useApp();
|
||||
const { message } = App.useApp();
|
||||
|
||||
// Operate on the management page's own bucket — not the sidebar's — since
|
||||
// the management view is the one the user is acting on here.
|
||||
@@ -34,7 +35,7 @@ const ToolbarActions = memo(() => {
|
||||
return;
|
||||
}
|
||||
|
||||
modal.confirm({
|
||||
confirmModal({
|
||||
content: t('management.actionsMenu.archiveStale.confirm', { count: stale.length }),
|
||||
okText: t('management.actionsMenu.archiveStale.confirmOk'),
|
||||
onOk: async () => {
|
||||
@@ -47,7 +48,7 @@ const ToolbarActions = memo(() => {
|
||||
},
|
||||
title: t('management.actionsMenu.archiveStale.title'),
|
||||
});
|
||||
}, [topics, updateTopicStatus, modal, message, t]);
|
||||
}, [topics, updateTopicStatus, message, t]);
|
||||
|
||||
const items: DropdownItem[] = useMemo(
|
||||
() => [
|
||||
|
||||
+1
@@ -50,6 +50,7 @@ const styles = createStaticStyles(({ css, cssVar }) => ({
|
||||
margin-block-start: -4px;
|
||||
padding-block-end: 8px;
|
||||
padding-inline: 16px;
|
||||
|
||||
font-size: ${cssVar.fontSizeSM};
|
||||
line-height: 1.45;
|
||||
color: ${cssVar.colorTextSecondary};
|
||||
|
||||
@@ -10,7 +10,7 @@ import {
|
||||
Tabs,
|
||||
type TabsProps,
|
||||
} from '@lobehub/ui';
|
||||
import { App } from 'antd';
|
||||
import { confirmModal } from '@lobehub/ui/base-ui';
|
||||
import { createStaticStyles, cx } from 'antd-style';
|
||||
import isEqual from 'fast-deep-equal';
|
||||
import { ChevronDown, ChevronUp, History, Sparkles, Undo2 } from 'lucide-react';
|
||||
@@ -68,7 +68,6 @@ export interface CompressedGroupMessageProps {
|
||||
|
||||
const CompressedGroupMessage = memo<CompressedGroupMessageProps>(({ id }) => {
|
||||
const { t } = useTranslation('chat');
|
||||
const { modal } = App.useApp();
|
||||
const [activeTab, setActiveTab] = useState<string>(() => getStoredTab(id));
|
||||
|
||||
const handleTabChange = useCallback(
|
||||
@@ -86,13 +85,12 @@ const CompressedGroupMessage = memo<CompressedGroupMessageProps>(({ id }) => {
|
||||
const cancelCompression = useConversationStore((s) => s.cancelCompression);
|
||||
|
||||
const handleCancelCompression = useCallback(() => {
|
||||
modal.confirm({
|
||||
centered: true,
|
||||
confirmModal({
|
||||
content: t('compression.cancelConfirm'),
|
||||
onOk: () => cancelCompression(id),
|
||||
title: t('compression.cancel'),
|
||||
});
|
||||
}, [id, cancelCompression, modal, t]);
|
||||
}, [id, cancelCompression, t]);
|
||||
|
||||
const content = message?.content;
|
||||
const rawCompressedMessages = (message as UIChatMessage)?.compressedMessages;
|
||||
|
||||
@@ -5,8 +5,9 @@ import {
|
||||
type RemoteHeterogeneousAgentType,
|
||||
} from '@lobechat/heterogeneous-agents';
|
||||
import { Button, Flexbox, Icon } from '@lobehub/ui';
|
||||
import { Alert, Input, Modal, Select, Steps, Tag, Typography } from 'antd';
|
||||
import { createStyles } from 'antd-style';
|
||||
import { Select } from '@lobehub/ui/base-ui';
|
||||
import { Alert, Input, Modal, Steps, Tag, Typography } from 'antd';
|
||||
import { createStaticStyles, cssVar } from 'antd-style';
|
||||
import {
|
||||
BotIcon,
|
||||
CheckCircle2,
|
||||
@@ -23,7 +24,7 @@ import { lambdaClient, lambdaQuery } from '@/libs/trpc/client';
|
||||
import { useAgentStore } from '@/store/agent';
|
||||
import { useHomeStore } from '@/store/home';
|
||||
|
||||
const useStyles = createStyles(({ css, token }) => ({
|
||||
const styles = createStaticStyles(({ css }) => ({
|
||||
avatarPreview: css`
|
||||
display: flex;
|
||||
align-items: center;
|
||||
@@ -31,12 +32,12 @@ const useStyles = createStyles(({ css, token }) => ({
|
||||
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
border-radius: ${token.borderRadiusLG}px;
|
||||
border-radius: ${cssVar.borderRadiusLG};
|
||||
|
||||
font-size: 28px;
|
||||
line-height: 1;
|
||||
|
||||
background: ${token.colorFillSecondary};
|
||||
background: ${cssVar.colorFillSecondary};
|
||||
`,
|
||||
deviceItem: css`
|
||||
display: flex;
|
||||
@@ -53,20 +54,20 @@ const useStyles = createStyles(({ css, token }) => ({
|
||||
|
||||
padding-block: 12px;
|
||||
padding-inline: 16px;
|
||||
border: 1.5px solid ${token.colorBorderSecondary};
|
||||
border-radius: ${token.borderRadiusLG}px;
|
||||
border: 1.5px solid ${cssVar.colorBorderSecondary};
|
||||
border-radius: ${cssVar.borderRadiusLG};
|
||||
|
||||
background: ${token.colorBgContainer};
|
||||
background: ${cssVar.colorBgContainer};
|
||||
|
||||
transition: border-color 0.2s;
|
||||
|
||||
&:hover {
|
||||
border-color: ${token.colorPrimary};
|
||||
border-color: ${cssVar.colorPrimary};
|
||||
}
|
||||
|
||||
&[data-selected='true'] {
|
||||
border-color: ${token.colorPrimary};
|
||||
background: ${token.colorPrimaryBg};
|
||||
border-color: ${cssVar.colorPrimary};
|
||||
background: ${cssVar.colorPrimaryBg};
|
||||
}
|
||||
|
||||
&[data-disabled='true'] {
|
||||
@@ -74,18 +75,18 @@ const useStyles = createStyles(({ css, token }) => ({
|
||||
opacity: 0.5;
|
||||
|
||||
&:hover {
|
||||
border-color: ${token.colorBorderSecondary};
|
||||
border-color: ${cssVar.colorBorderSecondary};
|
||||
}
|
||||
}
|
||||
`,
|
||||
platformDesc: css`
|
||||
font-size: 13px;
|
||||
color: ${token.colorTextSecondary};
|
||||
color: ${cssVar.colorTextSecondary};
|
||||
`,
|
||||
platformName: css`
|
||||
font-size: 15px;
|
||||
font-weight: 500;
|
||||
color: ${token.colorText};
|
||||
color: ${cssVar.colorText};
|
||||
`,
|
||||
}));
|
||||
|
||||
@@ -104,7 +105,6 @@ interface CreatePlatformAgentModalProps {
|
||||
const CreatePlatformAgentModal = memo<CreatePlatformAgentModalProps>(
|
||||
({ open, onClose, groupId }) => {
|
||||
const { t } = useTranslation('chat');
|
||||
const { styles } = useStyles();
|
||||
const navigate = useNavigate();
|
||||
const storeCreateAgent = useAgentStore((s) => s.createAgent);
|
||||
const refreshAgentList = useHomeStore((s) => s.refreshAgentList);
|
||||
|
||||
@@ -1,12 +1,11 @@
|
||||
import { useEditor } from '@lobehub/editor/react';
|
||||
import { type ModalProps } from '@lobehub/ui';
|
||||
import { createRawModal, Modal } from '@lobehub/ui';
|
||||
import { Modal, type ModalComponentProps } from '@lobehub/ui/base-ui';
|
||||
import { memo, useState } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
import EditorCanvas from './EditorCanvas';
|
||||
|
||||
interface EditorModalProps extends ModalProps {
|
||||
interface EditorModalProps extends ModalComponentProps {
|
||||
editorData?: unknown;
|
||||
onConfirm?: (value: string, editorData?: unknown) => Promise<void>;
|
||||
value?: string;
|
||||
@@ -47,5 +46,3 @@ export const EditorModal = memo<EditorModalProps>(
|
||||
);
|
||||
},
|
||||
);
|
||||
|
||||
export const createEditorModal = (props: EditorModalProps) => createRawModal(EditorModal, props);
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
'use client';
|
||||
|
||||
import { Avatar, Flexbox, Select, type SelectProps, Text } from '@lobehub/ui';
|
||||
import { Avatar, Flexbox, Text } from '@lobehub/ui';
|
||||
import { Select, type SelectProps } from '@lobehub/ui/base-ui';
|
||||
import { memo, useMemo } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import useSWR from 'swr';
|
||||
@@ -8,21 +9,11 @@ import useSWR from 'swr';
|
||||
import { DEFAULT_AVATAR } from '@/const/meta';
|
||||
import { messengerService } from '@/services/messenger';
|
||||
|
||||
interface AgentSelectProps extends Omit<
|
||||
SelectProps,
|
||||
'options' | 'showSearch' | 'optionFilterProp' | 'value' | 'onChange'
|
||||
> {
|
||||
interface AgentSelectProps extends Omit<SelectProps<string>, 'options' | 'value' | 'onChange'> {
|
||||
onChange?: (agentId: string | undefined) => void;
|
||||
value?: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Shared agent picker used wherever the messenger feature asks the user to
|
||||
* pick which agent receives messages. Single source of truth for the option
|
||||
* shape (avatar + title, locale-aware fallback) so verify-im and the Settings
|
||||
* panel render identically. Fetches `messenger.listAgentsForBinding` (which
|
||||
* already pins LobeAI to the top and matches the bot's `/agents` ordering).
|
||||
*/
|
||||
const AgentSelect = memo<AgentSelectProps>(({ value, onChange, ...rest }) => {
|
||||
const { t: tCommon } = useTranslation('common');
|
||||
const agentsSWR = useSWR('messenger:agentsForBinding', () =>
|
||||
@@ -36,7 +27,7 @@ const AgentSelect = memo<AgentSelectProps>(({ value, onChange, ...rest }) => {
|
||||
const title = agent.title || defaultAgentTitle;
|
||||
return {
|
||||
label: (
|
||||
<Flexbox horizontal align="center" gap={8}>
|
||||
<Flexbox horizontal align={'center'} gap={8}>
|
||||
<Avatar
|
||||
avatar={agent.avatar || DEFAULT_AVATAR}
|
||||
background={agent.backgroundColor ?? undefined}
|
||||
@@ -45,7 +36,6 @@ const AgentSelect = memo<AgentSelectProps>(({ value, onChange, ...rest }) => {
|
||||
<Text ellipsis>{title}</Text>
|
||||
</Flexbox>
|
||||
),
|
||||
searchValue: title,
|
||||
title,
|
||||
value: agent.id,
|
||||
};
|
||||
@@ -55,10 +45,10 @@ const AgentSelect = memo<AgentSelectProps>(({ value, onChange, ...rest }) => {
|
||||
|
||||
return (
|
||||
<Select
|
||||
optionFilterProp="searchValue"
|
||||
showSearch
|
||||
options={options}
|
||||
value={value}
|
||||
onChange={(next) => onChange?.(next as string | undefined)}
|
||||
value={value ?? null}
|
||||
onChange={(next) => onChange?.((next as string | null) ?? undefined)}
|
||||
{...rest}
|
||||
/>
|
||||
);
|
||||
|
||||
@@ -2,11 +2,11 @@
|
||||
|
||||
import { Button, Icon, Text } from '@lobehub/ui';
|
||||
import { LinkIcon, ServerIcon, Trash2Icon, UserIcon } from 'lucide-react';
|
||||
import { memo, useState } from 'react';
|
||||
import { memo } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
import { buildDiscordOpenBotUrl } from '../constants';
|
||||
import LinkModal from '../LinkModal';
|
||||
import { createMessengerLinkModal } from '../LinkModal';
|
||||
import {
|
||||
ConnectionRow,
|
||||
DetailLayout,
|
||||
@@ -32,7 +32,6 @@ interface DiscordDetailProps {
|
||||
// (`messenger.discord.connections.*`) makes that distinction explicit.
|
||||
const DiscordDetail = memo<DiscordDetailProps>(({ appId, botUsername, name, onBack }) => {
|
||||
const { t } = useTranslation('messenger');
|
||||
const [linkOpen, setLinkOpen] = useState(false);
|
||||
|
||||
const data = useMessengerData('discord');
|
||||
const { handleSetActive, handleUnlink } = useLinkActions({
|
||||
@@ -61,18 +60,20 @@ const DiscordDetail = memo<DiscordDetailProps>(({ appId, botUsername, name, onBa
|
||||
const hasLinks = links.length > 0;
|
||||
const link = links[0];
|
||||
|
||||
const handleOpenLink = () =>
|
||||
createMessengerLinkModal({ appId, botUsername, name, platform: 'discord' });
|
||||
|
||||
const headerAction = (
|
||||
<Button
|
||||
icon={<Icon icon={LinkIcon} />}
|
||||
type={hasInstallations ? 'default' : 'primary'}
|
||||
onClick={() => setLinkOpen(true)}
|
||||
onClick={handleOpenLink}
|
||||
>
|
||||
{hasInstallations ? t('messenger.detail.addServer') : t('messenger.linkCta')}
|
||||
</Button>
|
||||
);
|
||||
|
||||
return (
|
||||
<>
|
||||
<DetailLayout
|
||||
hasConnections={hasInstallations || hasLinks}
|
||||
headerAction={headerAction}
|
||||
@@ -135,16 +136,6 @@ const DiscordDetail = memo<DiscordDetailProps>(({ appId, botUsername, name, onBa
|
||||
<div className={styles.emptyRow}>{t('messenger.detail.connections.empty')}</div>
|
||||
)}
|
||||
</DetailLayout>
|
||||
|
||||
<LinkModal
|
||||
appId={appId}
|
||||
botUsername={botUsername}
|
||||
name={name}
|
||||
open={linkOpen}
|
||||
platform="discord"
|
||||
onClose={() => setLinkOpen(false)}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
});
|
||||
|
||||
|
||||
@@ -2,10 +2,10 @@
|
||||
|
||||
import { Button, Icon } from '@lobehub/ui';
|
||||
import { BriefcaseIcon, LinkIcon, Trash2Icon } from 'lucide-react';
|
||||
import { memo, useState } from 'react';
|
||||
import { memo } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
import LinkModal from '../LinkModal';
|
||||
import { createMessengerLinkModal } from '../LinkModal';
|
||||
import {
|
||||
ConnectionRow,
|
||||
DetailLayout,
|
||||
@@ -26,7 +26,6 @@ interface SlackDetailProps {
|
||||
|
||||
const SlackDetail = memo<SlackDetailProps>(({ appId, botUsername, name, onBack }) => {
|
||||
const { t } = useTranslation('messenger');
|
||||
const [linkOpen, setLinkOpen] = useState(false);
|
||||
|
||||
const data = useMessengerData('slack');
|
||||
const { handleSetActive, handleUnlink } = useLinkActions({
|
||||
@@ -57,11 +56,14 @@ const SlackDetail = memo<SlackDetailProps>(({ appId, botUsername, name, onBack }
|
||||
const hasInstallations = installations.length > 0;
|
||||
const hasLinks = links.length > 0;
|
||||
|
||||
const handleOpenLink = () =>
|
||||
createMessengerLinkModal({ appId, botUsername, name, platform: 'slack' });
|
||||
|
||||
const headerAction = (
|
||||
<Button
|
||||
icon={<Icon icon={LinkIcon} />}
|
||||
type={hasInstallations ? 'default' : 'primary'}
|
||||
onClick={() => setLinkOpen(true)}
|
||||
onClick={handleOpenLink}
|
||||
>
|
||||
{hasInstallations ? t('messenger.detail.addWorkspace') : t('messenger.linkCta')}
|
||||
</Button>
|
||||
@@ -75,7 +77,6 @@ const SlackDetail = memo<SlackDetailProps>(({ appId, botUsername, name, onBack }
|
||||
hasInstallations && installations.every((install) => !linkByTenantId.has(install.tenantId));
|
||||
|
||||
return (
|
||||
<>
|
||||
<DetailLayout
|
||||
hasConnections={hasInstallations || hasLinks}
|
||||
headerAction={headerAction}
|
||||
@@ -114,21 +115,10 @@ const SlackDetail = memo<SlackDetailProps>(({ appId, botUsername, name, onBack }
|
||||
/>
|
||||
);
|
||||
})}
|
||||
{/* Installs without any user link yet — gentle nudge to /start in Slack. */}
|
||||
{allInstallsUnlinked && !hasLinks && (
|
||||
<div className={styles.emptyRow}>{t('messenger.detail.connections.linkHint')}</div>
|
||||
)}
|
||||
</DetailLayout>
|
||||
|
||||
<LinkModal
|
||||
appId={appId}
|
||||
botUsername={botUsername}
|
||||
name={name}
|
||||
open={linkOpen}
|
||||
platform="slack"
|
||||
onClose={() => setLinkOpen(false)}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
});
|
||||
|
||||
|
||||
@@ -2,10 +2,10 @@
|
||||
|
||||
import { Button, Icon } from '@lobehub/ui';
|
||||
import { LinkIcon, Trash2Icon } from 'lucide-react';
|
||||
import { memo, useState } from 'react';
|
||||
import { memo } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
import LinkModal from '../LinkModal';
|
||||
import { createMessengerLinkModal } from '../LinkModal';
|
||||
import {
|
||||
DetailLayout,
|
||||
IntegrationDetailSkeleton,
|
||||
@@ -27,7 +27,6 @@ interface TelegramDetailProps {
|
||||
// header.
|
||||
const TelegramDetail = memo<TelegramDetailProps>(({ appId, botUsername, name, onBack }) => {
|
||||
const { t } = useTranslation('messenger');
|
||||
const [linkOpen, setLinkOpen] = useState(false);
|
||||
|
||||
const data = useMessengerData('telegram');
|
||||
const { handleSetActive, handleUnlink } = useLinkActions({
|
||||
@@ -43,18 +42,20 @@ const TelegramDetail = memo<TelegramDetailProps>(({ appId, botUsername, name, on
|
||||
const hasLinks = links.length > 0;
|
||||
const link = links[0];
|
||||
|
||||
const handleOpenLink = () =>
|
||||
createMessengerLinkModal({ appId, botUsername, name, platform: 'telegram' });
|
||||
|
||||
const headerAction = hasLinks ? (
|
||||
<Button danger icon={<Icon icon={Trash2Icon} />} onClick={() => handleUnlink('')}>
|
||||
{t('messenger.unlinkCta')}
|
||||
</Button>
|
||||
) : (
|
||||
<Button icon={<Icon icon={LinkIcon} />} type="primary" onClick={() => setLinkOpen(true)}>
|
||||
<Button icon={<Icon icon={LinkIcon} />} type="primary" onClick={handleOpenLink}>
|
||||
{t('messenger.linkCta')}
|
||||
</Button>
|
||||
);
|
||||
|
||||
return (
|
||||
<>
|
||||
<DetailLayout
|
||||
hasConnections={hasLinks}
|
||||
headerAction={headerAction}
|
||||
@@ -72,16 +73,6 @@ const TelegramDetail = memo<TelegramDetailProps>(({ appId, botUsername, name, on
|
||||
<div className={styles.emptyRow}>{t('messenger.detail.connections.empty')}</div>
|
||||
)}
|
||||
</DetailLayout>
|
||||
|
||||
<LinkModal
|
||||
appId={appId}
|
||||
botUsername={botUsername}
|
||||
name={name}
|
||||
open={linkOpen}
|
||||
platform="telegram"
|
||||
onClose={() => setLinkOpen(false)}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
});
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
'use client';
|
||||
|
||||
import { Block, Button, Flexbox, Icon, Skeleton, Tag, Text } from '@lobehub/ui';
|
||||
import { confirmModal } from '@lobehub/ui/base-ui';
|
||||
import { App } from 'antd';
|
||||
import { createStaticStyles } from 'antd-style';
|
||||
import { ArrowLeftIcon, CheckCircle2Icon, Trash2Icon, UserIcon } from 'lucide-react';
|
||||
@@ -294,7 +295,7 @@ export const useLinkActions = ({
|
||||
platform,
|
||||
}: UseLinkActionsArgs) => {
|
||||
const { t } = useTranslation('messenger');
|
||||
const { message, modal } = App.useApp();
|
||||
const { message } = App.useApp();
|
||||
|
||||
const handleSetActive = async (tenantId: string, agentId: string | null) => {
|
||||
try {
|
||||
@@ -311,7 +312,7 @@ export const useLinkActions = ({
|
||||
};
|
||||
|
||||
const handleUnlink = (tenantId: string) => {
|
||||
modal.confirm({
|
||||
confirmModal({
|
||||
content: t('messenger.unlinkConfirm', { platform: name }),
|
||||
okButtonProps: { danger: true },
|
||||
onOk: async () => {
|
||||
@@ -359,10 +360,10 @@ export const useDisconnectInstallation = ({
|
||||
linksMutate,
|
||||
}: UseDisconnectInstallationArgs) => {
|
||||
const { t } = useTranslation('messenger');
|
||||
const { message, modal } = App.useApp();
|
||||
const { message } = App.useApp();
|
||||
|
||||
return (id: string, copy: DisconnectInstallationCopy) => {
|
||||
modal.confirm({
|
||||
confirmModal({
|
||||
content: copy.confirm,
|
||||
okButtonProps: { danger: true },
|
||||
onOk: async () => {
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
'use client';
|
||||
|
||||
import { Flexbox } from '@lobehub/ui';
|
||||
import { memo } from 'react';
|
||||
|
||||
import type { MessengerPlatform } from '../constants';
|
||||
import DiscordLinkBody from './Discord';
|
||||
import SlackLinkBody from './Slack';
|
||||
import TelegramLinkBody from './Telegram';
|
||||
|
||||
export interface LinkModalContentProps {
|
||||
appId?: string;
|
||||
botUsername?: string;
|
||||
name: string;
|
||||
platform: MessengerPlatform;
|
||||
}
|
||||
|
||||
const LinkModalContent = memo<LinkModalContentProps>(({ appId, botUsername, name, platform }) => {
|
||||
const renderBody = () => {
|
||||
switch (platform) {
|
||||
case 'slack': {
|
||||
return <SlackLinkBody />;
|
||||
}
|
||||
case 'discord': {
|
||||
return <DiscordLinkBody appId={appId} name={name} />;
|
||||
}
|
||||
case 'telegram': {
|
||||
return <TelegramLinkBody botUsername={botUsername} name={name} />;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<Flexbox align={'center'} gap={20} style={{ paddingBlockEnd: 16, paddingBlockStart: 24 }}>
|
||||
{renderBody()}
|
||||
</Flexbox>
|
||||
);
|
||||
});
|
||||
|
||||
LinkModalContent.displayName = 'MessengerLinkModalContent';
|
||||
|
||||
export default LinkModalContent;
|
||||
@@ -1,47 +1,14 @@
|
||||
'use client';
|
||||
|
||||
import { Flexbox, Modal } from '@lobehub/ui';
|
||||
import { memo } from 'react';
|
||||
import { createModal, type ModalInstance } from '@lobehub/ui/base-ui';
|
||||
|
||||
import type { MessengerPlatform } from '../constants';
|
||||
import DiscordLinkBody from './Discord';
|
||||
import SlackLinkBody from './Slack';
|
||||
import TelegramLinkBody from './Telegram';
|
||||
import LinkModalContent, { type LinkModalContentProps } from './Content';
|
||||
|
||||
interface LinkModalProps {
|
||||
appId?: string;
|
||||
botUsername?: string;
|
||||
/** Brand-name label (e.g. `"Slack"`) sourced from the registry. */
|
||||
name: string;
|
||||
onClose: () => void;
|
||||
open: boolean;
|
||||
platform: MessengerPlatform;
|
||||
}
|
||||
|
||||
const LinkModal = memo<LinkModalProps>(({ appId, botUsername, name, onClose, open, platform }) => {
|
||||
const renderBody = () => {
|
||||
switch (platform) {
|
||||
case 'slack': {
|
||||
return <SlackLinkBody />;
|
||||
}
|
||||
case 'discord': {
|
||||
return <DiscordLinkBody appId={appId} name={name} />;
|
||||
}
|
||||
case 'telegram': {
|
||||
return <TelegramLinkBody botUsername={botUsername} name={name} />;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<Modal footer={null} open={open} title={null} width={480} onCancel={onClose}>
|
||||
<Flexbox align="center" gap={20} style={{ paddingBlockEnd: 16, paddingBlockStart: 40 }}>
|
||||
{renderBody()}
|
||||
</Flexbox>
|
||||
</Modal>
|
||||
);
|
||||
export const createMessengerLinkModal = (props: LinkModalContentProps): ModalInstance =>
|
||||
createModal({
|
||||
content: <LinkModalContent {...props} />,
|
||||
footer: null,
|
||||
maskClosable: true,
|
||||
title: null,
|
||||
width: 'min(90vw, 480px)',
|
||||
});
|
||||
|
||||
LinkModal.displayName = 'MessengerLinkModal';
|
||||
|
||||
export default LinkModal;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Select } from 'antd';
|
||||
import { Select } from '@lobehub/ui/base-ui';
|
||||
import { memo, useMemo } from 'react';
|
||||
|
||||
import { useAgentId } from '@/features/ChatInput/hooks/useAgentId';
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Select } from 'antd';
|
||||
import { Select } from '@lobehub/ui/base-ui';
|
||||
import { memo, useMemo } from 'react';
|
||||
|
||||
import { useAgentId } from '@/features/ChatInput/hooks/useAgentId';
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { type MenuProps } from '@lobehub/ui';
|
||||
import { Icon } from '@lobehub/ui';
|
||||
import { App } from 'antd';
|
||||
import { confirmModal } from '@lobehub/ui/base-ui';
|
||||
import { Trash2 } from 'lucide-react';
|
||||
import { useMemo } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
@@ -20,13 +20,11 @@ export const useDropdownMenu = ({
|
||||
onClose,
|
||||
}: UseDropdownMenuProps): MenuProps['items'] => {
|
||||
const { t } = useTranslation(['common', 'chat']);
|
||||
const { modal } = App.useApp();
|
||||
const removeAgent = useHomeStore((s) => s.removeAgent);
|
||||
|
||||
const handleDelete = () => {
|
||||
modal.confirm({
|
||||
confirmModal({
|
||||
cancelText: t('cancel'),
|
||||
centered: true,
|
||||
okButtonProps: { danger: true },
|
||||
okText: t('delete'),
|
||||
onOk: async () => {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { type MenuProps } from '@lobehub/ui';
|
||||
import { Icon } from '@lobehub/ui';
|
||||
import { App } from 'antd';
|
||||
import { confirmModal } from '@lobehub/ui/base-ui';
|
||||
import { Trash2 } from 'lucide-react';
|
||||
import { useCallback } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
@@ -20,7 +20,6 @@ export const useDropdownMenu = ({
|
||||
topicId,
|
||||
}: UseDropdownMenuProps): (() => MenuProps['items']) => {
|
||||
const { t } = useTranslation(['common', 'topic']);
|
||||
const { modal } = App.useApp();
|
||||
const removeTopic = useChatStore((s) => s.removeTopic);
|
||||
|
||||
return useCallback(
|
||||
@@ -32,9 +31,8 @@ export const useDropdownMenu = ({
|
||||
key: 'delete',
|
||||
label: t('delete'),
|
||||
onClick: () => {
|
||||
modal.confirm({
|
||||
confirmModal({
|
||||
cancelText: t('cancel'),
|
||||
centered: true,
|
||||
content: t('actions.confirmRemoveTopic', { ns: 'topic' }),
|
||||
okButtonProps: { danger: true },
|
||||
okText: t('delete'),
|
||||
@@ -48,6 +46,6 @@ export const useDropdownMenu = ({
|
||||
},
|
||||
},
|
||||
].filter(Boolean) as MenuProps['items'],
|
||||
[t, modal, removeTopic, topicId, onDelete, onClose],
|
||||
[t, removeTopic, topicId, onDelete, onClose],
|
||||
);
|
||||
};
|
||||
|
||||
@@ -21,7 +21,7 @@ import { usePageEditorStore, useStoreApi } from '../store';
|
||||
*/
|
||||
export const useMenu = (): { menuItems: any[] } => {
|
||||
const { t } = useTranslation(['file', 'common', 'chat']);
|
||||
const { message, modal } = App.useApp();
|
||||
const { message } = App.useApp();
|
||||
const storeApi = useStoreApi();
|
||||
const { lg = true } = useResponsive();
|
||||
|
||||
@@ -137,7 +137,7 @@ export const useMenu = (): { menuItems: any[] } => {
|
||||
label: t('delete', { ns: 'common' }),
|
||||
onClick: async () => {
|
||||
const state = storeApi.getState();
|
||||
await state.handleDelete(t as any, message, modal, state.onDelete);
|
||||
await state.handleDelete(t as any, message, state.onDelete);
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -185,7 +185,6 @@ export const useMenu = (): { menuItems: any[] } => {
|
||||
storeApi,
|
||||
t,
|
||||
message,
|
||||
modal,
|
||||
setRightPanelMode,
|
||||
wideScreen,
|
||||
toggleWideScreen,
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
'use client';
|
||||
|
||||
import { Button, Flexbox, Text } from '@lobehub/ui';
|
||||
import { createStyles, cssVar } from 'antd-style';
|
||||
import { createStaticStyles, cssVar } from 'antd-style';
|
||||
import dayjs from 'dayjs';
|
||||
import { RotateCcwIcon } from 'lucide-react';
|
||||
import { memo, useMemo, useState } from 'react';
|
||||
@@ -16,10 +16,10 @@ import DocumentHistoryDiff from '../DocumentHistoryDiff';
|
||||
import { formatHistoryAbsoluteTime } from '../formatHistoryDate';
|
||||
import HistorySidebar from './HistorySidebar';
|
||||
|
||||
const useStyles = createStyles(({ css, token }) => ({
|
||||
const styles = createStaticStyles(({ css }) => ({
|
||||
arrow: css`
|
||||
font-size: 12px;
|
||||
color: ${token.colorTextTertiary};
|
||||
color: ${cssVar.colorTextTertiary};
|
||||
`,
|
||||
badgeNew: css`
|
||||
display: inline-flex;
|
||||
@@ -33,9 +33,9 @@ const useStyles = createStyles(({ css, token }) => ({
|
||||
font-size: 11px;
|
||||
font-weight: 600;
|
||||
line-height: 1.2;
|
||||
color: ${token.colorSuccess};
|
||||
color: ${cssVar.colorSuccess};
|
||||
|
||||
background: ${token.colorSuccessBg};
|
||||
background: ${cssVar.colorSuccessBg};
|
||||
`,
|
||||
badgeOld: css`
|
||||
display: inline-flex;
|
||||
@@ -48,9 +48,9 @@ const useStyles = createStyles(({ css, token }) => ({
|
||||
font-size: 11px;
|
||||
font-weight: 600;
|
||||
line-height: 1.2;
|
||||
color: ${token.colorError};
|
||||
color: ${cssVar.colorError};
|
||||
|
||||
background: ${token.colorErrorBg};
|
||||
background: ${cssVar.colorErrorBg};
|
||||
`,
|
||||
cmpbar: css`
|
||||
display: flex;
|
||||
@@ -59,9 +59,9 @@ const useStyles = createStyles(({ css, token }) => ({
|
||||
|
||||
padding-block: 10px;
|
||||
padding-inline: 16px;
|
||||
border-block-end: 1px solid ${token.colorBorderSecondary};
|
||||
border-block-end: 1px solid ${cssVar.colorBorderSecondary};
|
||||
|
||||
background: ${token.colorBgLayout};
|
||||
background: ${cssVar.colorBgLayout};
|
||||
`,
|
||||
diffArea: css`
|
||||
overflow: hidden;
|
||||
@@ -104,7 +104,6 @@ export interface CompareContentProps {
|
||||
const CompareContent = memo<CompareContentProps>(
|
||||
({ documentId, initialHistoryId, items, onRestore, saveSourceLabels }) => {
|
||||
const { t } = useTranslation('file');
|
||||
const { styles } = useStyles();
|
||||
|
||||
const [selectedHistoryId, setSelectedHistoryId] = useState<string>(initialHistoryId);
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
'use client';
|
||||
|
||||
import { Flexbox, Tag, Text } from '@lobehub/ui';
|
||||
import { createStyles, cssVar, cx } from 'antd-style';
|
||||
import { createStaticStyles, cssVar, cx } from 'antd-style';
|
||||
import dayjs from 'dayjs';
|
||||
import { memo, useCallback, useMemo } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
@@ -13,7 +13,7 @@ import type {
|
||||
|
||||
import { formatHistoryRowTime } from '../formatHistoryDate';
|
||||
|
||||
const useStyles = createStyles(({ css, token }) => ({
|
||||
const styles = createStaticStyles(({ css }) => ({
|
||||
container: css`
|
||||
overflow-y: auto;
|
||||
flex-shrink: 0;
|
||||
@@ -21,9 +21,9 @@ const useStyles = createStyles(({ css, token }) => ({
|
||||
width: 232px;
|
||||
padding-block: 4px 12px;
|
||||
padding-inline: 8px;
|
||||
border-inline-start: 1px solid ${token.colorBorderSecondary};
|
||||
border-inline-start: 1px solid ${cssVar.colorBorderSecondary};
|
||||
|
||||
background: ${token.colorBgContainer};
|
||||
background: ${cssVar.colorBgContainer};
|
||||
`,
|
||||
dot: css`
|
||||
position: absolute;
|
||||
@@ -32,19 +32,19 @@ const useStyles = createStyles(({ css, token }) => ({
|
||||
|
||||
width: 8px;
|
||||
height: 8px;
|
||||
border: 1px solid ${token.colorBorder};
|
||||
border: 1px solid ${cssVar.colorBorder};
|
||||
border-radius: 999px;
|
||||
|
||||
background: ${token.colorBgContainer};
|
||||
box-shadow: 0 0 0 2px ${token.colorBgContainer};
|
||||
background: ${cssVar.colorBgContainer};
|
||||
box-shadow: 0 0 0 2px ${cssVar.colorBgContainer};
|
||||
`,
|
||||
dotCurrent: css`
|
||||
border-color: ${token.colorSuccess};
|
||||
background: ${token.colorSuccess};
|
||||
border-color: ${cssVar.colorSuccess};
|
||||
background: ${cssVar.colorSuccess};
|
||||
`,
|
||||
dotSelected: css`
|
||||
border-color: ${token.colorPrimary};
|
||||
background: ${token.colorPrimary};
|
||||
border-color: ${cssVar.colorPrimary};
|
||||
background: ${cssVar.colorPrimary};
|
||||
`,
|
||||
group: css`
|
||||
position: relative;
|
||||
@@ -61,7 +61,7 @@ const useStyles = createStyles(({ css, token }) => ({
|
||||
font-weight: 500;
|
||||
line-height: 1.2;
|
||||
|
||||
background: ${token.colorBgContainer};
|
||||
background: ${cssVar.colorBgContainer};
|
||||
`,
|
||||
item: css`
|
||||
cursor: pointer;
|
||||
@@ -73,17 +73,17 @@ const useStyles = createStyles(({ css, token }) => ({
|
||||
transition: background ${cssVar.motionDurationMid} ${cssVar.motionEaseInOut};
|
||||
|
||||
&:hover {
|
||||
background: ${token.colorFillQuaternary};
|
||||
background: ${cssVar.colorFillQuaternary};
|
||||
}
|
||||
`,
|
||||
itemCurrent: css`
|
||||
cursor: default;
|
||||
`,
|
||||
itemSelected: css`
|
||||
background: ${token.colorFillSecondary};
|
||||
background: ${cssVar.colorFillSecondary};
|
||||
|
||||
&:hover {
|
||||
background: ${token.colorFillSecondary};
|
||||
background: ${cssVar.colorFillSecondary};
|
||||
}
|
||||
`,
|
||||
meta: css`
|
||||
@@ -101,7 +101,7 @@ const useStyles = createStyles(({ css, token }) => ({
|
||||
|
||||
width: 1px;
|
||||
|
||||
background: ${token.colorFillTertiary};
|
||||
background: ${cssVar.colorFillTertiary};
|
||||
`,
|
||||
row: css`
|
||||
position: relative;
|
||||
@@ -160,7 +160,6 @@ interface HistorySidebarProps {
|
||||
const HistorySidebar = memo<HistorySidebarProps>(
|
||||
({ items, onSelect, saveSourceLabels, selectedHistoryId }) => {
|
||||
const { t } = useTranslation('file');
|
||||
const { styles } = useStyles();
|
||||
|
||||
const formatLabel = useCallback(
|
||||
(savedAt: string) => {
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { EDITOR_DEBOUNCE_TIME, EDITOR_MAX_WAIT, isDesktop } from '@lobechat/const';
|
||||
import { confirmModal } from '@lobehub/ui/base-ui';
|
||||
import debug from 'debug';
|
||||
import { debounce } from 'es-toolkit/compat';
|
||||
import { type StateCreator } from 'zustand';
|
||||
@@ -19,7 +20,6 @@ export interface Action {
|
||||
handleDelete: (
|
||||
t: (key: string) => string,
|
||||
message: any,
|
||||
modal: any,
|
||||
onDeleteCallback?: () => void,
|
||||
) => Promise<void>;
|
||||
handleTitleSubmit: () => Promise<void>;
|
||||
@@ -75,12 +75,12 @@ export const store: (initState?: Partial<State>) => StateCreator<Store> =
|
||||
}
|
||||
},
|
||||
|
||||
handleDelete: async (t, message, modal, onDeleteCallback) => {
|
||||
handleDelete: async (t, message, onDeleteCallback) => {
|
||||
const { documentId } = get();
|
||||
if (!documentId) return;
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
modal.confirm({
|
||||
confirmModal({
|
||||
cancelText: t('cancel'),
|
||||
content: t('pageEditor.deleteConfirm.content'),
|
||||
okButtonProps: { danger: true },
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { type MenuProps } from '@lobehub/ui';
|
||||
import { Icon } from '@lobehub/ui';
|
||||
import { confirmModal } from '@lobehub/ui/base-ui';
|
||||
import { App } from 'antd';
|
||||
import { CopyPlus, PanelTop, Pencil, Trash2 } from 'lucide-react';
|
||||
import { useCallback } from 'react';
|
||||
@@ -20,14 +21,14 @@ export const useDropdownMenu = ({
|
||||
toggleEditing,
|
||||
}: ActionProps): (() => MenuProps['items']) => {
|
||||
const { t } = useTranslation(['common', 'file']);
|
||||
const { message, modal } = App.useApp();
|
||||
const { message } = App.useApp();
|
||||
const navigate = useNavigate();
|
||||
const addTab = useElectronStore((s) => s.addTab);
|
||||
const removePage = usePageStore((s) => s.removePage);
|
||||
const duplicatePage = usePageStore((s) => s.duplicatePage);
|
||||
|
||||
const handleDelete = () => {
|
||||
modal.confirm({
|
||||
confirmModal({
|
||||
cancelText: t('cancel'),
|
||||
content: t('pageEditor.deleteConfirm.content', { ns: 'file' }),
|
||||
okButtonProps: { danger: true },
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { type NotebookDocument } from '@lobechat/types';
|
||||
import { ActionIcon, Flexbox, Text } from '@lobehub/ui';
|
||||
import { App } from 'antd';
|
||||
import { confirmModal } from '@lobehub/ui/base-ui';
|
||||
import { createStaticStyles } from 'antd-style';
|
||||
import { FileTextIcon, Trash2Icon } from 'lucide-react';
|
||||
import { type MouseEvent } from 'react';
|
||||
@@ -38,7 +38,6 @@ interface DocumentItemProps {
|
||||
|
||||
const DocumentItem = memo<DocumentItemProps>(({ document, topicId }) => {
|
||||
const { t } = useTranslation('portal');
|
||||
const { modal } = App.useApp();
|
||||
const [deleting, setDeleting] = useState(false);
|
||||
|
||||
const openDocument = useChatStore((s) => s.openDocument);
|
||||
@@ -51,8 +50,7 @@ const DocumentItem = memo<DocumentItemProps>(({ document, topicId }) => {
|
||||
const handleDelete = async (e: MouseEvent) => {
|
||||
e.stopPropagation();
|
||||
|
||||
modal.confirm({
|
||||
centered: true,
|
||||
confirmModal({
|
||||
okButtonProps: { danger: true },
|
||||
onOk: async () => {
|
||||
setDeleting(true);
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
'use client';
|
||||
|
||||
import { ActionIcon, Flexbox } from '@lobehub/ui';
|
||||
import { confirmModal } from '@lobehub/ui/base-ui';
|
||||
import { App } from 'antd';
|
||||
import { cssVar } from 'antd-style';
|
||||
import { BookMinusIcon, FileBoxIcon, Trash2Icon } from 'lucide-react';
|
||||
@@ -25,7 +26,7 @@ import SearchInput from './SearchInput';
|
||||
*/
|
||||
const Header = memo(() => {
|
||||
const { t } = useTranslation(['components', 'common', 'file', 'knowledgeBase']);
|
||||
const { modal, message } = App.useApp();
|
||||
const { message } = App.useApp();
|
||||
|
||||
// Get state and actions from store
|
||||
const [libraryId, category, onActionClick, selectAllState, selectFileIds] =
|
||||
@@ -52,7 +53,7 @@ const Header = memo(() => {
|
||||
icon={BookMinusIcon}
|
||||
title={t('FileManager.actions.removeFromLibrary')}
|
||||
onClick={() => {
|
||||
modal.confirm({
|
||||
confirmModal({
|
||||
okButtonProps: {
|
||||
danger: true,
|
||||
},
|
||||
@@ -80,7 +81,7 @@ const Header = memo(() => {
|
||||
icon={Trash2Icon}
|
||||
title={t('delete', { ns: 'common' })}
|
||||
onClick={() => {
|
||||
modal.confirm({
|
||||
confirmModal({
|
||||
okButtonProps: {
|
||||
danger: true,
|
||||
},
|
||||
|
||||
+5
-4
@@ -1,4 +1,5 @@
|
||||
import { copyToClipboard, createRawModal, Icon } from '@lobehub/ui';
|
||||
import { confirmModal } from '@lobehub/ui/base-ui';
|
||||
import { App } from 'antd';
|
||||
import { type ItemType } from 'antd/es/menu/interface';
|
||||
import {
|
||||
@@ -54,7 +55,7 @@ export const useFileItemDropdown = ({
|
||||
onRenameStart,
|
||||
}: UseFileItemDropdownParams): UseFileItemDropdownReturn => {
|
||||
const { t } = useTranslation(['components', 'common', 'knowledgeBase']);
|
||||
const { message, modal } = App.useApp();
|
||||
const { message } = App.useApp();
|
||||
const appOrigin = useAppOrigin();
|
||||
|
||||
const { deleteResource, moveResource, refreshFileList } = useFileStore(
|
||||
@@ -168,7 +169,7 @@ export const useFileItemDropdown = ({
|
||||
onClick: async ({ domEvent }) => {
|
||||
domEvent.stopPropagation();
|
||||
|
||||
modal.confirm({
|
||||
confirmModal({
|
||||
okButtonProps: {
|
||||
danger: true,
|
||||
},
|
||||
@@ -301,11 +302,12 @@ export const useFileItemDropdown = ({
|
||||
label: t('delete', { ns: 'common' }),
|
||||
onClick: async ({ domEvent }) => {
|
||||
domEvent.stopPropagation();
|
||||
modal.confirm({
|
||||
confirmModal({
|
||||
content: isFolder
|
||||
? t('FileManager.actions.confirmDeleteFolder')
|
||||
: t('FileManager.actions.confirmDelete'),
|
||||
okButtonProps: { danger: true },
|
||||
title: t('delete', { ns: 'common' }),
|
||||
onOk: async () => {
|
||||
// Use optimistic delete - instant UI update, sync in background
|
||||
await deleteResource(id);
|
||||
@@ -335,7 +337,6 @@ export const useFileItemDropdown = ({
|
||||
libraries,
|
||||
libraryId,
|
||||
message,
|
||||
modal,
|
||||
moveResource,
|
||||
onRenameStart,
|
||||
refreshFileList,
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { type DropdownItem } from '@lobehub/ui';
|
||||
import { DropdownMenu, Icon } from '@lobehub/ui';
|
||||
import { confirmModal } from '@lobehub/ui/base-ui';
|
||||
import { App } from 'antd';
|
||||
import {
|
||||
BookMinusIcon,
|
||||
@@ -33,7 +34,7 @@ interface BatchActionsDropdownProps {
|
||||
|
||||
const BatchActionsDropdown = memo<BatchActionsDropdownProps>(({ selectCount, onActionClick }) => {
|
||||
const { t } = useTranslation(['components', 'common', 'file', 'knowledgeBase']);
|
||||
const { modal, message } = App.useApp();
|
||||
const { message } = App.useApp();
|
||||
|
||||
const libraryId = useResourceManagerStore((s) => s.libraryId);
|
||||
const [resolveSelectedResourceIds, selectAllState] = useResourceManagerStore((s) => [
|
||||
@@ -54,7 +55,7 @@ const BatchActionsDropdown = memo<BatchActionsDropdownProps>(({ selectCount, onA
|
||||
key: 'deleteLibrary',
|
||||
label: t('header.actions.deleteLibrary', { ns: 'file' }),
|
||||
onClick: async () => {
|
||||
modal.confirm({
|
||||
confirmModal({
|
||||
okButtonProps: {
|
||||
danger: true,
|
||||
},
|
||||
@@ -100,7 +101,7 @@ const BatchActionsDropdown = memo<BatchActionsDropdownProps>(({ selectCount, onA
|
||||
key: 'removeFromKnowledgeBase',
|
||||
label: t('FileManager.actions.removeFromLibrary'),
|
||||
onClick: () => {
|
||||
modal.confirm({
|
||||
confirmModal({
|
||||
okButtonProps: {
|
||||
danger: true,
|
||||
},
|
||||
@@ -154,7 +155,7 @@ const BatchActionsDropdown = memo<BatchActionsDropdownProps>(({ selectCount, onA
|
||||
key: 'delete',
|
||||
label: t('delete', { ns: 'common' }),
|
||||
onClick: async () => {
|
||||
modal.confirm({
|
||||
confirmModal({
|
||||
okButtonProps: {
|
||||
danger: true,
|
||||
},
|
||||
@@ -177,7 +178,6 @@ const BatchActionsDropdown = memo<BatchActionsDropdownProps>(({ selectCount, onA
|
||||
addFilesToKnowledgeBase,
|
||||
resolveSelectedResourceIds,
|
||||
t,
|
||||
modal,
|
||||
message,
|
||||
knowledgeBases,
|
||||
]);
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { Button, Checkbox, Flexbox, Icon, Skeleton } from '@lobehub/ui';
|
||||
import { confirmModal } from '@lobehub/ui/base-ui';
|
||||
import { App } from 'antd';
|
||||
import { createStaticStyles, cssVar } from 'antd-style';
|
||||
import { BookMinusIcon, BookPlusIcon, FileBoxIcon, Trash2Icon } from 'lucide-react';
|
||||
@@ -34,7 +35,7 @@ const MultiSelectActions = memo<MultiSelectActionsProps>(
|
||||
const { t } = useTranslation(['components', 'common']);
|
||||
|
||||
const isSelectedFiles = selectCount > 0;
|
||||
const { modal, message } = App.useApp();
|
||||
const { message } = App.useApp();
|
||||
|
||||
const libraryId = useResourceManagerStore((s) => s.libraryId);
|
||||
|
||||
@@ -83,7 +84,7 @@ const MultiSelectActions = memo<MultiSelectActionsProps>(
|
||||
icon={BookMinusIcon}
|
||||
size={'small'}
|
||||
onClick={() => {
|
||||
modal.confirm({
|
||||
confirmModal({
|
||||
okButtonProps: {
|
||||
danger: true,
|
||||
},
|
||||
@@ -142,7 +143,7 @@ const MultiSelectActions = memo<MultiSelectActionsProps>(
|
||||
size={'small'}
|
||||
variant={'filled'}
|
||||
onClick={async () => {
|
||||
modal.confirm({
|
||||
confirmModal({
|
||||
okButtonProps: {
|
||||
danger: true,
|
||||
},
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { confirmModal } from '@lobehub/ui/base-ui';
|
||||
import { type TFunction } from 'i18next';
|
||||
import { type ChangeEvent } from 'react';
|
||||
import { useCallback } from 'react';
|
||||
@@ -55,16 +56,13 @@ const useUploadFolder = ({
|
||||
const gitignoreContent = await readGitignoreContent(gitignoreFile);
|
||||
const gitignoreOriginalCount = files.length;
|
||||
|
||||
const { Modal } = await import('antd');
|
||||
|
||||
Modal.confirm({
|
||||
confirmModal({
|
||||
cancelText: t('header.actions.gitignore.cancel'),
|
||||
content: t('header.actions.gitignore.content', {
|
||||
count: gitignoreOriginalCount,
|
||||
}),
|
||||
okText: t('header.actions.gitignore.apply'),
|
||||
onCancel: () => {
|
||||
// Upload without awaiting - let it run in background
|
||||
upload(files);
|
||||
},
|
||||
onOk: async () => {
|
||||
|
||||
@@ -8,7 +8,7 @@ import { type ReactNode } from 'react';
|
||||
import { memo } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
import { DESKTOP_HEADER_ICON_SIZE } from '@/const/layoutTokens';
|
||||
import { DESKTOP_HEADER_ICON_SMALL_SIZE } from '@/const/layoutTokens';
|
||||
import { useGlobalStore } from '@/store/global';
|
||||
import { systemStatusSelectors } from '@/store/global/selectors';
|
||||
import { useUserStore } from '@/store/user';
|
||||
@@ -55,7 +55,7 @@ const ToggleRightPanelButton = memo<ToggleRightPanelButtonProps>(
|
||||
active={showActive ? expand : undefined}
|
||||
icon={icon || (expand ? PanelRightClose : PanelRightOpen)}
|
||||
id={TOGGLE_BUTTON_ID}
|
||||
size={size || DESKTOP_HEADER_ICON_SIZE}
|
||||
size={size || DESKTOP_HEADER_ICON_SMALL_SIZE}
|
||||
title={title || t('toggleRightPanel.title', { ns: 'hotkey' })}
|
||||
tooltipProps={{
|
||||
hotkey,
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
'use client';
|
||||
|
||||
import { type ConversationContext } from '@lobechat/types';
|
||||
import { type ModalInstance } from '@lobehub/ui';
|
||||
import { createModal, Flexbox, Segmented, Skeleton } from '@lobehub/ui';
|
||||
import { Flexbox, Segmented, Skeleton } from '@lobehub/ui';
|
||||
import { createModal, type ModalInstance } from '@lobehub/ui/base-ui';
|
||||
import { t } from 'i18next';
|
||||
import { memo, useMemo, useState } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
@@ -92,21 +92,18 @@ export const openShareModal = ({
|
||||
context,
|
||||
}: OpenShareModalOptions = {}): ModalInstance =>
|
||||
createModal({
|
||||
afterClose,
|
||||
allowFullscreen: true,
|
||||
centered: true,
|
||||
children: (
|
||||
content: (
|
||||
<ShareDataProvider context={context}>
|
||||
<ShareModalContent />
|
||||
</ShareDataProvider>
|
||||
),
|
||||
destroyOnHidden: true,
|
||||
footer: null,
|
||||
height: '80vh',
|
||||
styles: {
|
||||
body: {
|
||||
height: '80vh',
|
||||
maskClosable: true,
|
||||
onOpenChangeComplete: (open) => {
|
||||
if (!open) afterClose?.();
|
||||
},
|
||||
styles: {
|
||||
content: { height: 'min(80vh, 800px)' },
|
||||
},
|
||||
title: t('share', { ns: 'common' }),
|
||||
width: 'min(90vw, 1024px)',
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
'use client';
|
||||
|
||||
import { type ConversationContext } from '@lobechat/types';
|
||||
import { type ModalInstance } from '@lobehub/ui';
|
||||
import { type ModalInstance } from '@lobehub/ui/base-ui';
|
||||
import { useCallback, useEffect, useRef } from 'react';
|
||||
|
||||
import { openShareModal as createShareModal } from './Modal';
|
||||
|
||||
@@ -10,7 +10,7 @@ import {
|
||||
Text,
|
||||
usePopoverContext,
|
||||
} from '@lobehub/ui';
|
||||
import { Select } from '@lobehub/ui/base-ui';
|
||||
import { confirmModal, Select } from '@lobehub/ui/base-ui';
|
||||
import { App, Divider } from 'antd';
|
||||
import { ExternalLinkIcon, LinkIcon, LockIcon } from 'lucide-react';
|
||||
import { type ReactNode } from 'react';
|
||||
@@ -36,7 +36,7 @@ interface SharePopoverContentProps {
|
||||
|
||||
const SharePopoverContent = memo<SharePopoverContentProps>(({ onOpenModal, topicId }) => {
|
||||
const { t } = useTranslation('chat');
|
||||
const { message, modal } = App.useApp();
|
||||
const { message } = App.useApp();
|
||||
const [updating, setUpdating] = useState(false);
|
||||
const { close } = usePopoverContext();
|
||||
const containerRef = useRef<HTMLDivElement>(null);
|
||||
@@ -97,9 +97,8 @@ const SharePopoverContent = memo<SharePopoverContentProps>(({ onOpenModal, topic
|
||||
) {
|
||||
let doNotShowAgain = false;
|
||||
|
||||
modal.confirm({
|
||||
confirmModal({
|
||||
cancelText: t('cancel', { ns: 'common' }),
|
||||
centered: true,
|
||||
content: (
|
||||
<div>
|
||||
<p>{t('shareModal.popover.privacyWarning.content')}</p>
|
||||
@@ -122,7 +121,6 @@ const SharePopoverContent = memo<SharePopoverContentProps>(({ onOpenModal, topic
|
||||
updateVisibility(visibility);
|
||||
},
|
||||
title: t('shareModal.popover.privacyWarning.title'),
|
||||
type: 'warning',
|
||||
});
|
||||
} else {
|
||||
updateVisibility(visibility);
|
||||
@@ -131,7 +129,6 @@ const SharePopoverContent = memo<SharePopoverContentProps>(({ onOpenModal, topic
|
||||
[
|
||||
currentVisibility,
|
||||
hideTopicSharePrivacyWarning,
|
||||
modal,
|
||||
t,
|
||||
updateSystemStatus,
|
||||
updateVisibility,
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
'use client';
|
||||
|
||||
import { ActionIcon, Block, DropdownMenu, Flexbox, Icon, Modal, Tag } from '@lobehub/ui';
|
||||
import { confirmModal } from '@lobehub/ui/base-ui';
|
||||
import { SkillsIcon } from '@lobehub/ui/icons';
|
||||
import { App } from 'antd';
|
||||
import { createStaticStyles, cssVar } from 'antd-style';
|
||||
import { DownloadIcon, MoreVerticalIcon, PackageSearch, Trash2 } from 'lucide-react';
|
||||
import { lazy, memo, Suspense, useState } from 'react';
|
||||
@@ -44,7 +44,6 @@ interface AgentSkillItemProps {
|
||||
const AgentSkillItem = memo<AgentSkillItemProps>(({ skill }) => {
|
||||
const { t } = useTranslation('plugin');
|
||||
const { t: tc } = useTranslation('common');
|
||||
const { modal } = App.useApp();
|
||||
const [detailOpen, setDetailOpen] = useState(false);
|
||||
const [editOpen, setEditOpen] = useState(false);
|
||||
const [loading, setLoading] = useState(false);
|
||||
@@ -65,14 +64,12 @@ const AgentSkillItem = memo<AgentSkillItemProps>(({ skill }) => {
|
||||
};
|
||||
|
||||
const handleDelete = () => {
|
||||
modal.confirm({
|
||||
centered: true,
|
||||
confirmModal({
|
||||
okButtonProps: { danger: true },
|
||||
onOk: async () => {
|
||||
await deleteAgentSkill(skill.id);
|
||||
},
|
||||
title: t('store.actions.confirmUninstall'),
|
||||
type: 'error',
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@ import {
|
||||
Icon,
|
||||
stopPropagation,
|
||||
} from '@lobehub/ui';
|
||||
import { App } from 'antd';
|
||||
import { confirmModal } from '@lobehub/ui/base-ui';
|
||||
import { MoreVerticalIcon, Plus, Trash2 } from 'lucide-react';
|
||||
import { memo } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
@@ -30,7 +30,6 @@ interface ItemProps {
|
||||
const Item = memo<ItemProps>(({ avatar, description, identifier, onOpenDetail, title }) => {
|
||||
const { t } = useTranslation(['setting', 'plugin']);
|
||||
const styles = itemStyles;
|
||||
const { modal } = App.useApp();
|
||||
|
||||
const [installBuiltinTool, uninstallBuiltinTool, isInstalled] = useToolStore((s) => [
|
||||
s.installBuiltinTool,
|
||||
@@ -43,14 +42,12 @@ const Item = memo<ItemProps>(({ avatar, description, identifier, onOpenDetail, t
|
||||
};
|
||||
|
||||
const handleUninstall = () => {
|
||||
modal.confirm({
|
||||
centered: true,
|
||||
confirmModal({
|
||||
okButtonProps: { danger: true },
|
||||
onOk: async () => {
|
||||
await uninstallBuiltinTool(identifier);
|
||||
},
|
||||
title: t('store.actions.confirmUninstall', { ns: 'plugin' }),
|
||||
type: 'error',
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
@@ -9,7 +9,8 @@ import {
|
||||
Modal,
|
||||
stopPropagation,
|
||||
} from '@lobehub/ui';
|
||||
import { App, Button } from 'antd';
|
||||
import { confirmModal } from '@lobehub/ui/base-ui';
|
||||
import { Button } from 'antd';
|
||||
import isEqual from 'fast-deep-equal';
|
||||
import { MoreVerticalIcon, Plus, Trash2 } from 'lucide-react';
|
||||
import React, { memo, Suspense, useState } from 'react';
|
||||
@@ -32,7 +33,6 @@ import { itemStyles } from '../style';
|
||||
const Item = memo<DiscoverMcpItem>(({ name, description, icon, identifier }) => {
|
||||
const styles = itemStyles;
|
||||
const { t } = useTranslation('plugin');
|
||||
const { modal } = App.useApp();
|
||||
const [detailOpen, setDetailOpen] = useState(false);
|
||||
|
||||
const [installed, installing, installMCPPlugin, cancelInstallMCPPlugin, unInstallPlugin, plugin] =
|
||||
@@ -91,8 +91,7 @@ const Item = memo<DiscoverMcpItem>(({ name, description, icon, identifier }) =>
|
||||
key: 'uninstall',
|
||||
label: t('store.actions.uninstall'),
|
||||
onClick: () => {
|
||||
modal.confirm({
|
||||
centered: true,
|
||||
confirmModal({
|
||||
okButtonProps: { danger: true },
|
||||
onOk: async () => {
|
||||
if (isPluginEnabledInAgent) {
|
||||
@@ -101,7 +100,6 @@ const Item = memo<DiscoverMcpItem>(({ name, description, icon, identifier }) =>
|
||||
await unInstallPlugin(identifier);
|
||||
},
|
||||
title: t('store.actions.confirmUninstall'),
|
||||
type: 'error',
|
||||
});
|
||||
},
|
||||
},
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
'use client';
|
||||
|
||||
import { ActionIcon, Avatar, Block, DropdownMenu, Flexbox, Icon, Modal, Tag } from '@lobehub/ui';
|
||||
import { confirmModal } from '@lobehub/ui/base-ui';
|
||||
import { SkillsIcon } from '@lobehub/ui/icons';
|
||||
import { App } from 'antd';
|
||||
import { createStaticStyles, cssVar } from 'antd-style';
|
||||
import { DownloadIcon, Loader2, MoreVerticalIcon, Plus, Trash2 } from 'lucide-react';
|
||||
import { lazy, memo, Suspense, useCallback, useState } from 'react';
|
||||
@@ -42,7 +42,6 @@ const MarketSkillItem = memo<DiscoverSkillItem>(({ name, icon, description, iden
|
||||
const [detailOpen, setDetailOpen] = useState(false);
|
||||
const [installing, setInstalling] = useState(false);
|
||||
const [loading, setLoading] = useState(false);
|
||||
const { modal } = App.useApp();
|
||||
|
||||
const installed = useToolStore(agentSkillsSelectors.isAgentSkill(identifier));
|
||||
const installedSkill = useToolStore(agentSkillsSelectors.getAgentSkillByIdentifier(identifier));
|
||||
@@ -66,16 +65,14 @@ const MarketSkillItem = memo<DiscoverSkillItem>(({ name, icon, description, iden
|
||||
|
||||
const handleUninstall = useCallback(() => {
|
||||
if (!installedSkill) return;
|
||||
modal.confirm({
|
||||
centered: true,
|
||||
confirmModal({
|
||||
okButtonProps: { danger: true },
|
||||
onOk: async () => {
|
||||
await deleteAgentSkill(installedSkill.id);
|
||||
},
|
||||
title: t('store.actions.confirmUninstall'),
|
||||
type: 'error',
|
||||
});
|
||||
}, [installedSkill, deleteAgentSkill, modal, t]);
|
||||
}, [installedSkill, deleteAgentSkill, t]);
|
||||
|
||||
const handleDownload = useCallback(async () => {
|
||||
if (!installedSkill?.zipFileHash) return;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
'use client';
|
||||
|
||||
import { ActionIcon, Block, DropdownMenu, Flexbox, Icon } from '@lobehub/ui';
|
||||
import { App } from 'antd';
|
||||
import { confirmModal } from '@lobehub/ui/base-ui';
|
||||
import { createStaticStyles, cssVar } from 'antd-style';
|
||||
import { MoreVerticalIcon, PackageSearch, Trash2 } from 'lucide-react';
|
||||
import { memo, useState } from 'react';
|
||||
@@ -45,7 +45,6 @@ interface ItemProps {
|
||||
|
||||
const Item = memo<ItemProps>(({ identifier, title, description, avatar }) => {
|
||||
const { t } = useTranslation('plugin');
|
||||
const { modal } = App.useApp();
|
||||
const [configOpen, setConfigOpen] = useState(false);
|
||||
const [detailOpen, setDetailOpen] = useState(false);
|
||||
|
||||
@@ -62,8 +61,7 @@ const Item = memo<ItemProps>(({ identifier, title, description, avatar }) => {
|
||||
]);
|
||||
|
||||
const handleDelete = () => {
|
||||
modal.confirm({
|
||||
centered: true,
|
||||
confirmModal({
|
||||
okButtonProps: { danger: true },
|
||||
onOk: async () => {
|
||||
if (isPluginEnabledInAgent) {
|
||||
@@ -72,7 +70,6 @@ const Item = memo<ItemProps>(({ identifier, title, description, avatar }) => {
|
||||
await uninstallPlugin(identifier);
|
||||
},
|
||||
title: t('store.actions.confirmUninstall'),
|
||||
type: 'error',
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
'use client';
|
||||
|
||||
import { ActionIcon, Block, DropdownMenu, Flexbox, Icon, stopPropagation } from '@lobehub/ui';
|
||||
import { App } from 'antd';
|
||||
import { confirmModal } from '@lobehub/ui/base-ui';
|
||||
import { cssVar } from 'antd-style';
|
||||
import type { Klavis } from 'klavis';
|
||||
import { Loader2, MoreVerticalIcon, Plus, Unplug } from 'lucide-react';
|
||||
@@ -26,7 +26,6 @@ const Item = memo<ItemProps>(
|
||||
({ description, icon, identifier, label, onOpenDetail, serverName, type }) => {
|
||||
const { t } = useTranslation('setting');
|
||||
const styles = itemStyles;
|
||||
const { modal } = App.useApp();
|
||||
|
||||
const { handleConnect, handleDisconnect, isConnected, isConnecting } = useSkillConnect({
|
||||
identifier,
|
||||
@@ -42,9 +41,8 @@ const Item = memo<ItemProps>(
|
||||
});
|
||||
|
||||
const confirmDisconnect = () => {
|
||||
modal.confirm({
|
||||
confirmModal({
|
||||
cancelText: t('cancel', { ns: 'common' }),
|
||||
centered: true,
|
||||
content: t('tools.lobehubSkill.disconnectConfirm.desc', { name: label }),
|
||||
okButtonProps: { danger: true },
|
||||
okText: t('tools.lobehubSkill.disconnect'),
|
||||
|
||||
@@ -5,7 +5,7 @@ import { PanelLeftRightDashedIcon, SquareChartGanttIcon } from 'lucide-react';
|
||||
import { memo } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
import { DESKTOP_HEADER_ICON_SIZE } from '@/const/layoutTokens';
|
||||
import { DESKTOP_HEADER_ICON_SMALL_SIZE } from '@/const/layoutTokens';
|
||||
import { useGlobalStore } from '@/store/global';
|
||||
import { systemStatusSelectors } from '@/store/global/selectors';
|
||||
|
||||
@@ -20,7 +20,7 @@ const WideScreenButton = memo(() => {
|
||||
return (
|
||||
<ActionIcon
|
||||
icon={wideScreen ? SquareChartGanttIcon : PanelLeftRightDashedIcon}
|
||||
size={DESKTOP_HEADER_ICON_SIZE}
|
||||
size={DESKTOP_HEADER_ICON_SMALL_SIZE}
|
||||
title={t(wideScreen ? 'toggleWideScreen.off' : 'toggleWideScreen.on')}
|
||||
tooltipProps={{
|
||||
placement: 'bottom',
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
'use client';
|
||||
|
||||
import { Center, Flexbox, Icon, Input, Text, TextArea, Tooltip } from '@lobehub/ui';
|
||||
import { Modal } from '@lobehub/ui/base-ui';
|
||||
import { confirmModal, Modal } from '@lobehub/ui/base-ui';
|
||||
import { type UploadProps } from 'antd';
|
||||
import { App, Form, Modal as AntModal, Upload } from 'antd';
|
||||
import { App, Form, Upload } from 'antd';
|
||||
import { cssVar } from 'antd-style';
|
||||
import { CircleHelp, Globe, ImagePlus, Trash2 } from 'lucide-react';
|
||||
import { memo, useCallback, useEffect, useState } from 'react';
|
||||
@@ -332,7 +332,7 @@ const ProfileSetupModal = memo<ProfileSetupModalProps>(
|
||||
|
||||
// If userName changed and it's not first-time setup, show confirmation
|
||||
if (!isFirstTimeSetup && oldUserName && values.userName !== oldUserName) {
|
||||
AntModal.confirm({
|
||||
confirmModal({
|
||||
cancelText: t('profileSetup.confirmChangeUserId.cancel'),
|
||||
content: t('profileSetup.confirmChangeUserId.description', {
|
||||
newId: values.userName,
|
||||
@@ -369,20 +369,22 @@ const ProfileSetupModal = memo<ProfileSetupModalProps>(
|
||||
maskClosable={!isFirstTimeSetup}
|
||||
okText={isFirstTimeSetup ? t('profileSetup.getStarted') : t('profileSetup.save')}
|
||||
open={open}
|
||||
title={false}
|
||||
width={640}
|
||||
onCancel={handleCancel}
|
||||
onOk={handleSubmit}
|
||||
>
|
||||
<Text strong fontSize={20} style={{ marginTop: 16 }}>
|
||||
title={
|
||||
<Flexbox gap={4}>
|
||||
<Text strong fontSize={16} lineHeight={1.4}>
|
||||
{isFirstTimeSetup ? t('profileSetup.titleFirstTime') : t('profileSetup.titleEdit')}
|
||||
</Text>
|
||||
<Text style={{ display: 'block', marginBottom: 24 }} type="secondary">
|
||||
<Text fontSize={13} lineHeight={1.4} type="secondary">
|
||||
{isFirstTimeSetup
|
||||
? t('profileSetup.descriptionFirstTime')
|
||||
: t('profileSetup.descriptionEdit')}
|
||||
</Text>
|
||||
|
||||
</Flexbox>
|
||||
}
|
||||
onCancel={handleCancel}
|
||||
onOk={handleSubmit}
|
||||
>
|
||||
<Form form={form} layout="vertical">
|
||||
<Flexbox horizontal gap={24}>
|
||||
<Flexbox flex={1}>
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
import { Icon } from '@lobehub/ui';
|
||||
import { type MenuProps } from '@lobehub/ui';
|
||||
import { App } from 'antd';
|
||||
import { confirmModal } from '@lobehub/ui/base-ui';
|
||||
import { Trash } from 'lucide-react';
|
||||
import type { CSSProperties } from 'react';
|
||||
import { memo, useState } from 'react';
|
||||
@@ -23,7 +23,6 @@ interface TopicItemProps {
|
||||
const TopicItem = memo<TopicItemProps>(({ topic, showMoreInfo, style }) => {
|
||||
const { useStore, namespace } = useGenerationTopicContext();
|
||||
const { t } = useTranslation(namespace);
|
||||
const { modal } = App.useApp();
|
||||
const [isUpdating, setIsUpdating] = useState(false);
|
||||
const isLoading = useStore((s) => s.loadingGenerationTopicIds.includes(topic.id));
|
||||
const removeGenerationTopic = useStore((s) => s.removeGenerationTopic);
|
||||
@@ -40,7 +39,7 @@ const TopicItem = memo<TopicItemProps>(({ topic, showMoreInfo, style }) => {
|
||||
e.stopPropagation();
|
||||
e.preventDefault();
|
||||
|
||||
modal.confirm({
|
||||
confirmModal({
|
||||
cancelText: t('cancel', { ns: 'common' }),
|
||||
content: t('topic.deleteConfirmDesc'),
|
||||
okButtonProps: { danger: true },
|
||||
@@ -65,7 +64,7 @@ const TopicItem = memo<TopicItemProps>(({ topic, showMoreInfo, style }) => {
|
||||
key: 'delete',
|
||||
label: t('delete', { ns: 'common' }),
|
||||
onClick: () => {
|
||||
modal.confirm({
|
||||
confirmModal({
|
||||
cancelText: t('cancel', { ns: 'common' }),
|
||||
content: t('topic.deleteConfirmDesc'),
|
||||
okButtonProps: { danger: true },
|
||||
|
||||
@@ -26,13 +26,6 @@ vi.mock('antd-style', () => ({
|
||||
neonDot: 'neonDot',
|
||||
neonDotWrapper: 'neonDotWrapper',
|
||||
}),
|
||||
createStyles: () => () => ({
|
||||
cx: (...classNames: Array<false | string | undefined>) => classNames.filter(Boolean).join(' '),
|
||||
styles: {
|
||||
container: 'container',
|
||||
dot: 'dot',
|
||||
},
|
||||
}),
|
||||
cssVar: {
|
||||
colorInfo: '#00f',
|
||||
colorTextDescription: '#999',
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import type { ChatTopicStatus } from '@lobechat/types';
|
||||
import { type MenuProps } from '@lobehub/ui';
|
||||
import { Icon } from '@lobehub/ui';
|
||||
import { confirmModal } from '@lobehub/ui/base-ui';
|
||||
import { App } from 'antd';
|
||||
import {
|
||||
CheckCircle2,
|
||||
@@ -44,7 +45,7 @@ export const useTopicItemDropdownMenu = ({
|
||||
title,
|
||||
}: TopicItemDropdownMenuProps) => {
|
||||
const { t } = useTranslation(['topic', 'common']);
|
||||
const { modal, message } = App.useApp();
|
||||
const { message } = App.useApp();
|
||||
const navigate = useNavigate();
|
||||
|
||||
const openTopicInNewWindow = useGlobalStore((s) => s.openTopicInNewWindow);
|
||||
@@ -205,8 +206,7 @@ export const useTopicItemDropdownMenu = ({
|
||||
key: 'delete',
|
||||
label: t('delete', { ns: 'common' }),
|
||||
onClick: () => {
|
||||
modal.confirm({
|
||||
centered: true,
|
||||
confirmModal({
|
||||
okButtonProps: { danger: true },
|
||||
onOk: async () => {
|
||||
await removeTopic(id);
|
||||
@@ -234,7 +234,6 @@ export const useTopicItemDropdownMenu = ({
|
||||
addTab,
|
||||
navigate,
|
||||
t,
|
||||
modal,
|
||||
message,
|
||||
handleOpenShareModal,
|
||||
]);
|
||||
|
||||
+3
-5
@@ -1,6 +1,6 @@
|
||||
import { type MenuProps } from '@lobehub/ui';
|
||||
import { Icon } from '@lobehub/ui';
|
||||
import { App } from 'antd';
|
||||
import { confirmModal } from '@lobehub/ui/base-ui';
|
||||
import { PencilLine, Trash } from 'lucide-react';
|
||||
import { useCallback } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
@@ -17,7 +17,6 @@ export const useThreadItemDropdownMenu = ({
|
||||
toggleEditing,
|
||||
}: ThreadItemDropdownMenuProps): (() => MenuProps['items']) => {
|
||||
const { t } = useTranslation(['thread', 'common']);
|
||||
const { modal } = App.useApp();
|
||||
|
||||
const [removeThread] = useChatStore((s) => [s.removeThread]);
|
||||
|
||||
@@ -40,8 +39,7 @@ export const useThreadItemDropdownMenu = ({
|
||||
key: 'delete',
|
||||
label: t('delete', { ns: 'common' }),
|
||||
onClick: () => {
|
||||
modal.confirm({
|
||||
centered: true,
|
||||
confirmModal({
|
||||
okButtonProps: { danger: true },
|
||||
onOk: async () => {
|
||||
await removeThread(id);
|
||||
@@ -51,5 +49,5 @@ export const useThreadItemDropdownMenu = ({
|
||||
},
|
||||
},
|
||||
].filter(Boolean) as MenuProps['items'];
|
||||
}, [id, removeThread, toggleEditing, t, modal]);
|
||||
}, [id, removeThread, toggleEditing, t]);
|
||||
};
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { type MenuProps } from '@lobehub/ui';
|
||||
import { Icon } from '@lobehub/ui';
|
||||
import { confirmModal } from '@lobehub/ui/base-ui';
|
||||
import { App, Upload } from 'antd';
|
||||
import { css, cx } from 'antd-style';
|
||||
import { Hash, Import, LucideCheck, Trash } from 'lucide-react';
|
||||
@@ -100,9 +101,8 @@ export const useTopicActionsDropdownMenu = (
|
||||
key: 'deleteUnstarred',
|
||||
label: t('actions.removeUnstarred'),
|
||||
onClick: () => {
|
||||
modal.confirm({
|
||||
confirmModal({
|
||||
cancelText: t('cancel', { ns: 'common' }),
|
||||
centered: true,
|
||||
okButtonProps: { danger: true },
|
||||
okText: t('ok', { ns: 'common' }),
|
||||
onOk: removeUnstarredTopic,
|
||||
@@ -116,9 +116,8 @@ export const useTopicActionsDropdownMenu = (
|
||||
key: 'deleteAll',
|
||||
label: t('actions.removeAll'),
|
||||
onClick: () => {
|
||||
modal.confirm({
|
||||
confirmModal({
|
||||
cancelText: t('cancel', { ns: 'common' }),
|
||||
centered: true,
|
||||
okButtonProps: { danger: true },
|
||||
okText: t('ok', { ns: 'common' }),
|
||||
onOk: removeAllTopic,
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
'use client';
|
||||
|
||||
import { confirmModal } from '@lobehub/ui/base-ui';
|
||||
import { App, Form } from 'antd';
|
||||
import { createStaticStyles } from 'antd-style';
|
||||
import { memo, useCallback, useEffect, useRef, useState } from 'react';
|
||||
@@ -69,7 +70,7 @@ interface PlatformDetailProps {
|
||||
const PlatformDetail = memo<PlatformDetailProps>(
|
||||
({ platformDef, agentId, currentConfig, runtimeStatus }) => {
|
||||
const { t } = useTranslation('agent');
|
||||
const { message: msg, modal } = App.useApp();
|
||||
const { message: msg } = App.useApp();
|
||||
const [form] = Form.useForm<ChannelFormValues>();
|
||||
|
||||
const [
|
||||
@@ -402,7 +403,7 @@ const PlatformDetail = memo<PlatformDetailProps>(
|
||||
const handleDelete = useCallback(async () => {
|
||||
if (!currentConfig) return;
|
||||
|
||||
modal.confirm({
|
||||
confirmModal({
|
||||
content: t('channel.deleteConfirmDesc'),
|
||||
okButtonProps: { danger: true },
|
||||
onOk: async () => {
|
||||
@@ -416,7 +417,7 @@ const PlatformDetail = memo<PlatformDetailProps>(
|
||||
},
|
||||
title: t('channel.deleteConfirm'),
|
||||
});
|
||||
}, [currentConfig, agentId, deleteBotProvider, msg, t, modal, form]);
|
||||
}, [currentConfig, agentId, deleteBotProvider, msg, t, form]);
|
||||
|
||||
const handleToggleEnable = useCallback(
|
||||
async (enabled: boolean) => {
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
import { exportJSONFile } from '@lobechat/utils/client';
|
||||
import { Icon, Tag } from '@lobehub/ui';
|
||||
import { confirmModal } from '@lobehub/ui/base-ui';
|
||||
import { App, Dropdown, type MenuProps } from 'antd';
|
||||
import { createStaticStyles, cx, useTheme } from 'antd-style';
|
||||
import { Book, Download, MoreHorizontal, Trash2, Upload } from 'lucide-react';
|
||||
@@ -88,7 +89,7 @@ const PlatformList = memo<PlatformListProps>(
|
||||
({ platforms, activeId, agentId, onSelect, providers, runtimeStatuses }) => {
|
||||
const { t } = useTranslation('agent');
|
||||
const theme = useTheme();
|
||||
const { modal, message } = App.useApp();
|
||||
const { message } = App.useApp();
|
||||
const fileInputRef = useRef<HTMLInputElement>(null);
|
||||
const deleteAllBotProviders = useAgentStore((s) => s.deleteAllBotProviders);
|
||||
const createBotProvider = useAgentStore((s) => s.createBotProvider);
|
||||
@@ -154,7 +155,7 @@ const PlatformList = memo<PlatformListProps>(
|
||||
|
||||
const handleDeleteAll = useCallback(() => {
|
||||
if (!providers?.length) return;
|
||||
modal.confirm({
|
||||
confirmModal({
|
||||
content: t('channel.deleteAllConfirmDesc'),
|
||||
okButtonProps: { danger: true },
|
||||
okText: t('channel.deleteAllChannels'),
|
||||
@@ -167,9 +168,8 @@ const PlatformList = memo<PlatformListProps>(
|
||||
}
|
||||
},
|
||||
title: t('channel.deleteAllConfirm'),
|
||||
type: 'warning',
|
||||
});
|
||||
}, [agentId, deleteAllBotProviders, message, modal, providers, t]);
|
||||
}, [agentId, deleteAllBotProviders, message, providers, t]);
|
||||
|
||||
const hasProviders = !!providers?.length;
|
||||
const menuItems: MenuProps['items'] = [
|
||||
|
||||
@@ -36,7 +36,7 @@ import { systemStatusSelectors } from '@/store/global/selectors';
|
||||
|
||||
export const useMenu = (): { menuItems: DropdownItem[] } => {
|
||||
const { t } = useTranslation(['chat', 'topic', 'common', 'file']);
|
||||
const { modal, message } = App.useApp();
|
||||
const { message } = App.useApp();
|
||||
const { pathname } = useLocation();
|
||||
|
||||
const [wideScreen, toggleWideScreen] = useGlobalStore((s) => [
|
||||
@@ -260,8 +260,7 @@ export const useMenu = (): { menuItems: DropdownItem[] } => {
|
||||
key: 'delete',
|
||||
label: t('delete', { ns: 'common' }),
|
||||
onClick: () => {
|
||||
modal.confirm({
|
||||
centered: true,
|
||||
confirmModal({
|
||||
okButtonProps: { danger: true },
|
||||
onOk: async () => {
|
||||
await removeTopic(topicId);
|
||||
@@ -291,7 +290,6 @@ export const useMenu = (): { menuItems: DropdownItem[] } => {
|
||||
toggleWideScreen,
|
||||
openCompareModal,
|
||||
t,
|
||||
modal,
|
||||
message,
|
||||
]);
|
||||
|
||||
|
||||
+4
-1
@@ -10,6 +10,10 @@ const messageError = vi.hoisted(() => vi.fn());
|
||||
const messageSuccess = vi.hoisted(() => vi.fn());
|
||||
const removeDocumentMock = vi.hoisted(() => vi.fn());
|
||||
|
||||
vi.mock('@lobehub/ui/base-ui', () => ({
|
||||
confirmModal: modalConfirm,
|
||||
}));
|
||||
|
||||
vi.mock('@lobehub/ui', () => ({
|
||||
Accordion: ({ children }: { children?: ReactNode }) => <div>{children}</div>,
|
||||
AccordionItem: ({ children, title }: { children?: ReactNode; title?: ReactNode }) => (
|
||||
@@ -45,7 +49,6 @@ vi.mock('antd', () => ({
|
||||
App: {
|
||||
useApp: () => ({
|
||||
message: { error: messageError, success: messageSuccess },
|
||||
modal: { confirm: modalConfirm },
|
||||
}),
|
||||
},
|
||||
}));
|
||||
|
||||
+4
-4
@@ -1,5 +1,6 @@
|
||||
import { buildAgentSkillIdentifier } from '@lobechat/const';
|
||||
import { ActionIcon, Center, Empty, Flexbox, Text } from '@lobehub/ui';
|
||||
import { confirmModal } from '@lobehub/ui/base-ui';
|
||||
import { SkillsIcon } from '@lobehub/ui/icons';
|
||||
import { App } from 'antd';
|
||||
import { createStaticStyles, cx } from 'antd-style';
|
||||
@@ -112,7 +113,7 @@ interface DocumentItemProps {
|
||||
const DocumentItem = memo<DocumentItemProps>(
|
||||
({ agentId, document, hideDelete = false, mutate }) => {
|
||||
const { t } = useTranslation(['chat', 'common']);
|
||||
const { message, modal } = App.useApp();
|
||||
const { message } = App.useApp();
|
||||
const [deleting, setDeleting] = useState(false);
|
||||
const openDocument = useChatStore((s) => s.openDocument);
|
||||
const closeDocument = useChatStore((s) => s.closeDocument);
|
||||
@@ -138,11 +139,10 @@ const DocumentItem = memo<DocumentItemProps>(
|
||||
|
||||
const handleDelete = (e: MouseEvent) => {
|
||||
e.stopPropagation();
|
||||
modal.confirm({
|
||||
confirmModal({
|
||||
cancelText: t('cancel', { ns: 'common' }),
|
||||
centered: true,
|
||||
content: t('workingPanel.resources.deleteConfirm', { ns: 'chat' }),
|
||||
okButtonProps: { danger: true, type: 'primary' },
|
||||
okButtonProps: { danger: true },
|
||||
okText: t('delete', { ns: 'common' }),
|
||||
onOk: async () => {
|
||||
setDeleting(true);
|
||||
|
||||
@@ -67,6 +67,10 @@ vi.mock('@lobehub/ui/icons', () => ({
|
||||
ShapesUploadIcon: () => null,
|
||||
}));
|
||||
|
||||
vi.mock('@lobehub/ui/base-ui', () => ({
|
||||
confirmModal: vi.fn(),
|
||||
}));
|
||||
|
||||
vi.mock('antd', () => ({
|
||||
App: {
|
||||
useApp: () => ({
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { ActionIcon, DropdownMenu, Flexbox, Icon } from '@lobehub/ui';
|
||||
import { confirmModal } from '@lobehub/ui/base-ui';
|
||||
import { ShapesUploadIcon } from '@lobehub/ui/icons';
|
||||
import { App, Modal } from 'antd';
|
||||
import isEqual from 'fast-deep-equal';
|
||||
import { BotMessageSquareIcon, MoreHorizontal, Settings2Icon, Trash } from 'lucide-react';
|
||||
import { memo, useCallback, useMemo, useState } from 'react';
|
||||
@@ -29,7 +29,6 @@ import AutoSaveHint from './AutoSaveHint';
|
||||
|
||||
const Header = memo(() => {
|
||||
const { t } = useTranslation(['setting', 'marketAuth', 'chat']);
|
||||
const { modal } = App.useApp();
|
||||
const navigate = useNavigate();
|
||||
|
||||
const meta = useAgentStore(agentSelectors.currentAgentMeta, isEqual);
|
||||
@@ -97,8 +96,7 @@ const Header = memo(() => {
|
||||
return;
|
||||
}
|
||||
|
||||
Modal.confirm({
|
||||
okButtonProps: { type: 'primary' },
|
||||
confirmModal({
|
||||
onOk: async () => {
|
||||
if (!isAuthenticated) {
|
||||
try {
|
||||
@@ -128,8 +126,7 @@ const Header = memo(() => {
|
||||
|
||||
const handleDelete = useCallback(() => {
|
||||
if (!activeAgentId) return;
|
||||
modal.confirm({
|
||||
centered: true,
|
||||
confirmModal({
|
||||
okButtonProps: { danger: true },
|
||||
onOk: async () => {
|
||||
await removeAgent(activeAgentId);
|
||||
@@ -138,7 +135,7 @@ const Header = memo(() => {
|
||||
},
|
||||
title: t('confirmRemoveSessionItemAlert', { ns: 'chat' }),
|
||||
});
|
||||
}, [activeAgentId, modal, navigate, removeAgent, t]);
|
||||
}, [activeAgentId, navigate, removeAgent, t]);
|
||||
|
||||
const menuItems = useMemo(
|
||||
() => [
|
||||
|
||||
+13
-16
@@ -4,7 +4,7 @@ import { type HeterogeneousProviderConfig, type UserCredSummary } from '@lobecha
|
||||
import { Github } from '@lobehub/icons';
|
||||
import { Flexbox } from '@lobehub/ui';
|
||||
import { Avatar, Button, Input, Select, Spin, Tag, Typography } from 'antd';
|
||||
import { createStyles } from 'antd-style';
|
||||
import { createStaticStyles, cssVar } from 'antd-style';
|
||||
import { CheckCircle2, KeyRound, X } from 'lucide-react';
|
||||
import { memo, useState } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
@@ -15,14 +15,14 @@ import { lambdaClient, lambdaQuery } from '@/libs/trpc/client';
|
||||
// Fixed cred key for Claude Code OAuth token — never changes
|
||||
const CLAUDE_TOKEN_CRED_KEY = 'CLAUDE_CODE_OAUTH_TOKEN';
|
||||
|
||||
const useStyles = createStyles(({ css, token, cssVar }) => ({
|
||||
const styles = createStaticStyles(({ css }) => ({
|
||||
card: css`
|
||||
padding-block: 16px 12px;
|
||||
padding-inline: 16px;
|
||||
border: 1px solid ${token.colorBorderSecondary};
|
||||
border-radius: ${token.borderRadiusLG}px;
|
||||
border: 1px solid ${cssVar.colorBorderSecondary};
|
||||
border-radius: ${cssVar.borderRadiusLG};
|
||||
|
||||
background: ${token.colorBgContainer};
|
||||
background: ${cssVar.colorBgContainer};
|
||||
`,
|
||||
credOption: css`
|
||||
display: flex;
|
||||
@@ -48,12 +48,12 @@ const useStyles = createStyles(({ css, token, cssVar }) => ({
|
||||
min-height: 36px;
|
||||
padding-block: 6px;
|
||||
padding-inline: 8px;
|
||||
border-radius: ${token.borderRadiusSM}px;
|
||||
border-radius: ${cssVar.borderRadiusSM};
|
||||
|
||||
transition: background 0.15s;
|
||||
|
||||
&:hover {
|
||||
background: ${token.colorFillTertiary};
|
||||
background: ${cssVar.colorFillTertiary};
|
||||
|
||||
.repo-delete-btn {
|
||||
opacity: 1;
|
||||
@@ -61,7 +61,7 @@ const useStyles = createStyles(({ css, token, cssVar }) => ({
|
||||
}
|
||||
`,
|
||||
repoItemActive: css`
|
||||
background: ${token.colorFillSecondary};
|
||||
background: ${cssVar.colorFillSecondary};
|
||||
`,
|
||||
repoDeleteBtn: css`
|
||||
cursor: pointer;
|
||||
@@ -73,7 +73,7 @@ const useStyles = createStyles(({ css, token, cssVar }) => ({
|
||||
border: none;
|
||||
border-radius: 4px;
|
||||
|
||||
color: ${token.colorTextTertiary};
|
||||
color: ${cssVar.colorTextTertiary};
|
||||
|
||||
opacity: 0;
|
||||
background: transparent;
|
||||
@@ -83,7 +83,7 @@ const useStyles = createStyles(({ css, token, cssVar }) => ({
|
||||
color 0.15s;
|
||||
|
||||
&:hover {
|
||||
color: ${token.colorError};
|
||||
color: ${cssVar.colorError};
|
||||
}
|
||||
`,
|
||||
repoList: css`
|
||||
@@ -93,15 +93,15 @@ const useStyles = createStyles(({ css, token, cssVar }) => ({
|
||||
`,
|
||||
sectionDesc: css`
|
||||
font-size: 12px;
|
||||
color: ${token.colorTextSecondary};
|
||||
color: ${cssVar.colorTextSecondary};
|
||||
`,
|
||||
sectionDivider: css`
|
||||
margin-block: 12px;
|
||||
border-block-start: 1px solid ${token.colorBorderSecondary};
|
||||
border-block-start: 1px solid ${cssVar.colorBorderSecondary};
|
||||
`,
|
||||
sectionLabel: css`
|
||||
font-size: 12px;
|
||||
color: ${token.colorTextTertiary};
|
||||
color: ${cssVar.colorTextTertiary};
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.04em;
|
||||
`,
|
||||
@@ -121,7 +121,6 @@ interface TokenSectionProps {
|
||||
|
||||
const TokenSection = memo<TokenSectionProps>(({ existingCred, onSaved, onEnvChange }) => {
|
||||
const { t } = useTranslation('setting');
|
||||
const { styles } = useStyles();
|
||||
const [editing, setEditing] = useState(!existingCred);
|
||||
const [tokenInput, setTokenInput] = useState('');
|
||||
const [saving, setSaving] = useState(false);
|
||||
@@ -211,7 +210,6 @@ interface RepoListSectionProps {
|
||||
|
||||
const RepoListSection = memo<RepoListSectionProps>(({ repos, onReposChange }) => {
|
||||
const { t } = useTranslation('setting');
|
||||
const { styles } = useStyles();
|
||||
const [input, setInput] = useState('');
|
||||
|
||||
const addRepo = () => {
|
||||
@@ -269,7 +267,6 @@ const RepoListSection = memo<RepoListSectionProps>(({ repos, onReposChange }) =>
|
||||
const CloudHeterogeneousConfig = memo<CloudHeterogeneousConfigProps>(
|
||||
({ provider, onEnvChange }) => {
|
||||
const { t } = useTranslation('setting');
|
||||
const { styles } = useStyles();
|
||||
const navigate = useNavigate();
|
||||
|
||||
const currentEnv = provider.env ?? {};
|
||||
|
||||
+2
-3
@@ -83,13 +83,12 @@ vi.mock('@lobehub/ui', () => ({
|
||||
}));
|
||||
|
||||
vi.mock('antd-style', () => ({
|
||||
createStyles: () => () => ({
|
||||
styles: {
|
||||
createStaticStyles: () => ({
|
||||
card: 'card',
|
||||
label: 'label',
|
||||
path: 'path',
|
||||
},
|
||||
}),
|
||||
cssVar: new Proxy({}, { get: (_, key) => `var(--${String(key)})` }),
|
||||
}));
|
||||
|
||||
vi.mock('lucide-react', () => ({
|
||||
|
||||
+19
-20
@@ -8,7 +8,7 @@ import {
|
||||
} from '@lobechat/heterogeneous-agents/client';
|
||||
import type { HeterogeneousProviderConfig } from '@lobechat/types';
|
||||
import { ActionIcon, CopyButton, Flexbox, Icon, Input, Tag, Text, Tooltip } from '@lobehub/ui';
|
||||
import { createStyles } from 'antd-style';
|
||||
import { createStaticStyles, cssVar } from 'antd-style';
|
||||
import { Loader2Icon, PencilLine, RefreshCw, XCircle } from 'lucide-react';
|
||||
import { memo, useCallback, useEffect, useRef, useState } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
@@ -19,14 +19,14 @@ import { toolDetectorService } from '@/services/electron/toolDetector';
|
||||
|
||||
const COMMAND_LINE_HEIGHT = 28;
|
||||
|
||||
const useStyles = createStyles(({ css, token }) => ({
|
||||
const styles = createStaticStyles(({ css }) => ({
|
||||
card: css`
|
||||
padding-block: 16px 4px;
|
||||
padding-inline: 16px;
|
||||
border: 1px solid ${token.colorBorderSecondary};
|
||||
border-radius: ${token.borderRadiusLG}px;
|
||||
border: 1px solid ${cssVar.colorBorderSecondary};
|
||||
border-radius: ${cssVar.borderRadiusLG};
|
||||
|
||||
background: ${token.colorBgContainer};
|
||||
background: ${cssVar.colorBgContainer};
|
||||
`,
|
||||
cardHeader: css`
|
||||
display: flex;
|
||||
@@ -57,7 +57,7 @@ const useStyles = createStyles(({ css, token }) => ({
|
||||
`,
|
||||
metaText: css`
|
||||
font-size: 13px;
|
||||
color: ${token.colorTextSecondary};
|
||||
color: ${cssVar.colorTextSecondary};
|
||||
`,
|
||||
pathWrap: css`
|
||||
display: flex;
|
||||
@@ -69,7 +69,7 @@ const useStyles = createStyles(({ css, token }) => ({
|
||||
`,
|
||||
detailList: css`
|
||||
margin-block-start: 4px;
|
||||
border-block-start: 1px solid ${token.colorBorderSecondary};
|
||||
border-block-start: 1px solid ${cssVar.colorBorderSecondary};
|
||||
`,
|
||||
detailRow: css`
|
||||
display: flex;
|
||||
@@ -80,7 +80,7 @@ const useStyles = createStyles(({ css, token }) => ({
|
||||
padding-block: 8px;
|
||||
|
||||
& + & {
|
||||
border-block-start: 1px solid ${token.colorBorderSecondary};
|
||||
border-block-start: 1px solid ${cssVar.colorBorderSecondary};
|
||||
}
|
||||
`,
|
||||
detailLabel: css`
|
||||
@@ -89,7 +89,7 @@ const useStyles = createStyles(({ css, token }) => ({
|
||||
width: 96px;
|
||||
|
||||
font-size: 12px;
|
||||
color: ${token.colorTextTertiary};
|
||||
color: ${cssVar.colorTextTertiary};
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.04em;
|
||||
`,
|
||||
@@ -111,7 +111,7 @@ const useStyles = createStyles(({ css, token }) => ({
|
||||
`,
|
||||
commandInput: css`
|
||||
width: 100%;
|
||||
font-family: ${token.fontFamilyCode};
|
||||
font-family: ${cssVar.fontFamilyCode};
|
||||
|
||||
&,
|
||||
&.ant-input,
|
||||
@@ -127,7 +127,7 @@ const useStyles = createStyles(({ css, token }) => ({
|
||||
max-height: ${COMMAND_LINE_HEIGHT}px;
|
||||
border-radius: 999px !important;
|
||||
|
||||
font-family: ${token.fontFamilyCode};
|
||||
font-family: ${cssVar.fontFamilyCode};
|
||||
font-size: 14px;
|
||||
line-height: ${COMMAND_LINE_HEIGHT - 2}px;
|
||||
}
|
||||
@@ -174,10 +174,10 @@ const useStyles = createStyles(({ css, token }) => ({
|
||||
height: ${COMMAND_LINE_HEIGHT}px;
|
||||
padding-block: 0;
|
||||
padding-inline: 12px;
|
||||
border: 1px solid ${token.colorBorderSecondary};
|
||||
border: 1px solid ${cssVar.colorBorderSecondary};
|
||||
border-radius: 999px;
|
||||
|
||||
background: ${token.colorFillSecondary};
|
||||
background: ${cssVar.colorFillSecondary};
|
||||
`,
|
||||
commandEditButton: css`
|
||||
pointer-events: none;
|
||||
@@ -187,23 +187,23 @@ const useStyles = createStyles(({ css, token }) => ({
|
||||
commandText: css`
|
||||
min-width: 0;
|
||||
|
||||
font-family: ${token.fontFamilyCode};
|
||||
font-family: ${cssVar.fontFamilyCode};
|
||||
font-size: 14px;
|
||||
line-height: 20px;
|
||||
color: ${token.colorText};
|
||||
color: ${cssVar.colorText};
|
||||
`,
|
||||
accountValue: css`
|
||||
font-size: 15px;
|
||||
color: ${token.colorText};
|
||||
color: ${cssVar.colorText};
|
||||
`,
|
||||
path: css`
|
||||
font-family: ${token.fontFamilyCode};
|
||||
font-family: ${cssVar.fontFamilyCode};
|
||||
font-size: 12px;
|
||||
color: ${token.colorTextTertiary};
|
||||
color: ${cssVar.colorTextTertiary};
|
||||
`,
|
||||
unavailableText: css`
|
||||
font-size: 13px;
|
||||
color: ${token.colorTextSecondary};
|
||||
color: ${cssVar.colorTextSecondary};
|
||||
`,
|
||||
}));
|
||||
|
||||
@@ -215,7 +215,6 @@ interface HeterogeneousAgentStatusCardProps {
|
||||
const HeterogeneousAgentStatusCard = memo<HeterogeneousAgentStatusCardProps>(
|
||||
({ provider, onCommandChange }) => {
|
||||
const { t } = useTranslation('setting');
|
||||
const { styles } = useStyles();
|
||||
const navigate = useNavigate();
|
||||
const providerConfig = getHeterogeneousAgentClientConfig(provider.type);
|
||||
const defaultCommand = providerConfig?.command || '';
|
||||
|
||||
@@ -6,8 +6,9 @@ import {
|
||||
} from '@lobechat/heterogeneous-agents';
|
||||
import type { HeterogeneousProviderConfig } from '@lobechat/types';
|
||||
import { ActionIcon, Flexbox, Icon, Text, Tooltip } from '@lobehub/ui';
|
||||
import { Button, Modal, Select, Tag } from 'antd';
|
||||
import { createStyles } from 'antd-style';
|
||||
import { Select } from '@lobehub/ui/base-ui';
|
||||
import { Button, Modal, Tag } from 'antd';
|
||||
import { createStaticStyles, cssVar } from 'antd-style';
|
||||
import { BotIcon, CheckCircle2, MonitorSmartphone, RefreshCw, XCircle } from 'lucide-react';
|
||||
import { memo, useCallback, useEffect, useState } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
@@ -15,14 +16,14 @@ import { useTranslation } from 'react-i18next';
|
||||
import { lambdaClient, lambdaQuery } from '@/libs/trpc/client';
|
||||
import { useAgentStore } from '@/store/agent';
|
||||
|
||||
const useStyles = createStyles(({ css, token }) => ({
|
||||
const styles = createStaticStyles(({ css }) => ({
|
||||
card: css`
|
||||
padding-block: 16px 4px;
|
||||
padding-inline: 16px;
|
||||
border: 1px solid ${token.colorBorderSecondary};
|
||||
border-radius: ${token.borderRadiusLG}px;
|
||||
border: 1px solid ${cssVar.colorBorderSecondary};
|
||||
border-radius: ${cssVar.borderRadiusLG};
|
||||
|
||||
background: ${token.colorBgContainer};
|
||||
background: ${cssVar.colorBgContainer};
|
||||
`,
|
||||
cardHeader: css`
|
||||
display: flex;
|
||||
@@ -37,7 +38,7 @@ const useStyles = createStyles(({ css, token }) => ({
|
||||
font-weight: 500;
|
||||
`,
|
||||
detailList: css`
|
||||
border-block-start: 1px solid ${token.colorBorderSecondary};
|
||||
border-block-start: 1px solid ${cssVar.colorBorderSecondary};
|
||||
`,
|
||||
detailRow: css`
|
||||
display: flex;
|
||||
@@ -48,7 +49,7 @@ const useStyles = createStyles(({ css, token }) => ({
|
||||
padding-block: 6px;
|
||||
|
||||
& + & {
|
||||
border-block-start: 1px solid ${token.colorBorderSecondary};
|
||||
border-block-start: 1px solid ${cssVar.colorBorderSecondary};
|
||||
}
|
||||
`,
|
||||
detailLabel: css`
|
||||
@@ -57,7 +58,7 @@ const useStyles = createStyles(({ css, token }) => ({
|
||||
width: 96px;
|
||||
|
||||
font-size: 12px;
|
||||
color: ${token.colorTextTertiary};
|
||||
color: ${cssVar.colorTextTertiary};
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.04em;
|
||||
`,
|
||||
@@ -85,7 +86,6 @@ interface RemoteAgentConfigCardProps {
|
||||
const RemoteAgentConfigCard = memo<RemoteAgentConfigCardProps>(
|
||||
({ provider, onBoundDeviceChange }) => {
|
||||
const { t } = useTranslation('setting');
|
||||
const { styles } = useStyles();
|
||||
|
||||
const agentId = useAgentStore((s) => s.activeAgentId);
|
||||
const boundDeviceId = useAgentStore((s) =>
|
||||
|
||||
+3
-2
@@ -1,6 +1,7 @@
|
||||
'use client';
|
||||
|
||||
import { Button, DropdownMenu, Flexbox, Icon } from '@lobehub/ui';
|
||||
import { confirmModal } from '@lobehub/ui/base-ui';
|
||||
import { App } from 'antd';
|
||||
import { createStaticStyles } from 'antd-style';
|
||||
import { ChevronDownIcon } from 'lucide-react';
|
||||
@@ -37,7 +38,7 @@ const AddAgent = memo<{ mobile?: boolean }>(({ mobile }) => {
|
||||
const [isLoading, setIsLoading] = useState(false);
|
||||
const createAgent = useAgentStore((s) => s.createAgent);
|
||||
const refreshAgentList = useHomeStore((s) => s.refreshAgentList);
|
||||
const { message, modal } = App.useApp();
|
||||
const { message } = App.useApp();
|
||||
const navigate = useNavigate();
|
||||
const { t } = useTranslation('discover');
|
||||
|
||||
@@ -56,7 +57,7 @@ const AddAgent = memo<{ mobile?: boolean }>(({ mobile }) => {
|
||||
};
|
||||
|
||||
const showDuplicateConfirmation = (callback: () => void) => {
|
||||
modal.confirm({
|
||||
confirmModal({
|
||||
cancelText: t('cancel', { ns: 'common' }),
|
||||
content: t('assistants.duplicateAdd.content', { title }),
|
||||
okText: t('assistants.duplicateAdd.ok'),
|
||||
|
||||
@@ -7,11 +7,11 @@ import {
|
||||
CopyButton,
|
||||
Flexbox,
|
||||
Input,
|
||||
Modal,
|
||||
Skeleton,
|
||||
Tag,
|
||||
Text,
|
||||
} from '@lobehub/ui';
|
||||
import { Modal } from '@lobehub/ui/base-ui';
|
||||
import { createStaticStyles, cssVar } from 'antd-style';
|
||||
import { startCase } from 'es-toolkit/compat';
|
||||
import { LinkIcon, Share2Icon } from 'lucide-react';
|
||||
|
||||
+3
-2
@@ -1,6 +1,7 @@
|
||||
'use client';
|
||||
|
||||
import { Button, DropdownMenu, Flexbox, Icon } from '@lobehub/ui';
|
||||
import { confirmModal } from '@lobehub/ui/base-ui';
|
||||
import { App } from 'antd';
|
||||
import { createStaticStyles } from 'antd-style';
|
||||
import { ChevronDownIcon } from 'lucide-react';
|
||||
@@ -42,7 +43,7 @@ const AddGroupAgent = memo<{ mobile?: boolean }>(() => {
|
||||
memberAgents = [],
|
||||
} = useDetailContext();
|
||||
const [isLoading, setIsLoading] = useState(false);
|
||||
const { message, modal } = App.useApp();
|
||||
const { message } = App.useApp();
|
||||
const { t } = useTranslation('discover');
|
||||
const navigate = useNavigate();
|
||||
const loadGroups = useAgentGroupStore((s) => s.loadGroups);
|
||||
@@ -67,7 +68,7 @@ const AddGroupAgent = memo<{ mobile?: boolean }>(() => {
|
||||
};
|
||||
|
||||
const showDuplicateConfirmation = (callback: () => void) => {
|
||||
modal.confirm({
|
||||
confirmModal({
|
||||
cancelText: t('cancel', { ns: 'common' }),
|
||||
content: t('groupAgents.duplicateAdd.content', {
|
||||
defaultValue: 'This group agent has already been added. Do you want to add it again?',
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
'use client';
|
||||
|
||||
import { Select } from 'antd';
|
||||
import { Select } from '@lobehub/ui/base-ui';
|
||||
import { memo } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
'use client';
|
||||
|
||||
import { confirmModal } from '@lobehub/ui/base-ui';
|
||||
import { App } from 'antd';
|
||||
import { useCallback } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
@@ -17,7 +18,7 @@ interface UseUserDetailOptions {
|
||||
|
||||
export const useUserDetail = ({ onMutate }: UseUserDetailOptions = {}) => {
|
||||
const { t } = useTranslation('setting');
|
||||
const { message, modal } = App.useApp();
|
||||
const { message } = App.useApp();
|
||||
const { session } = useMarketAuth();
|
||||
const enableMarketTrustedClient = useServerConfigStore(
|
||||
serverConfigSelectors.enableMarketTrustedClient,
|
||||
@@ -88,7 +89,7 @@ export const useUserDetail = ({ onMutate }: UseUserDetailOptions = {}) => {
|
||||
}
|
||||
|
||||
if (action === 'deprecate') {
|
||||
modal.confirm({
|
||||
confirmModal({
|
||||
cancelText: t('myAgents.actions.cancel'),
|
||||
content: t('myAgents.actions.deprecateConfirmContent'),
|
||||
okButtonProps: { danger: true },
|
||||
@@ -103,7 +104,7 @@ export const useUserDetail = ({ onMutate }: UseUserDetailOptions = {}) => {
|
||||
|
||||
await executeStatusChange(identifier, action, type);
|
||||
},
|
||||
[enableMarketTrustedClient, session?.accessToken, message, modal, t, onMutate],
|
||||
[enableMarketTrustedClient, session?.accessToken, message, t, onMutate],
|
||||
);
|
||||
|
||||
return {
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
'use client';
|
||||
|
||||
import { Button, Flexbox } from '@lobehub/ui';
|
||||
import { confirmModal } from '@lobehub/ui/base-ui';
|
||||
import { App, Typography } from 'antd';
|
||||
import { ArrowLeft, Database, Pencil, Plus, Trash2 } from 'lucide-react';
|
||||
import { memo, useCallback, useMemo, useState } from 'react';
|
||||
@@ -24,7 +25,7 @@ const DatasetDetail = memo(() => {
|
||||
const { t } = useTranslation('eval');
|
||||
const { benchmarkId, datasetId } = useParams<{ benchmarkId: string; datasetId: string }>();
|
||||
const navigate = useNavigate();
|
||||
const { modal, message } = App.useApp();
|
||||
const { message } = App.useApp();
|
||||
|
||||
const [pagination, setPagination] = useState({ current: 1, pageSize: 10 });
|
||||
const [search, setSearch] = useState('');
|
||||
@@ -78,7 +79,7 @@ const DatasetDetail = memo(() => {
|
||||
|
||||
const handleDeleteCase = useCallback(
|
||||
(testCase: any) => {
|
||||
modal.confirm({
|
||||
confirmModal({
|
||||
content: t('testCase.delete.confirm'),
|
||||
okButtonProps: { danger: true },
|
||||
okText: t('common.delete'),
|
||||
@@ -94,11 +95,11 @@ const DatasetDetail = memo(() => {
|
||||
title: t('common.delete'),
|
||||
});
|
||||
},
|
||||
[handleRefresh, message, modal, t],
|
||||
[handleRefresh, message, t],
|
||||
);
|
||||
|
||||
const handleDelete = useCallback(() => {
|
||||
modal.confirm({
|
||||
confirmModal({
|
||||
content: t('dataset.delete.confirm'),
|
||||
okButtonProps: { danger: true },
|
||||
okText: t('common.delete'),
|
||||
@@ -113,7 +114,7 @@ const DatasetDetail = memo(() => {
|
||||
},
|
||||
title: t('common.delete'),
|
||||
});
|
||||
}, [benchmarkId, datasetId, message, modal, navigate, t]);
|
||||
}, [benchmarkId, datasetId, message, navigate, t]);
|
||||
|
||||
if (!dataset) return null;
|
||||
|
||||
|
||||
@@ -3,7 +3,8 @@
|
||||
import type { AgentEvalRunListItem } from '@lobechat/types';
|
||||
import { formatCost } from '@lobechat/utils';
|
||||
import { Button, Flexbox, Icon } from '@lobehub/ui';
|
||||
import { App, Badge, Dropdown } from 'antd';
|
||||
import { confirmModal } from '@lobehub/ui/base-ui';
|
||||
import { Badge, Dropdown } from 'antd';
|
||||
import { createStaticStyles, cssVar } from 'antd-style';
|
||||
import {
|
||||
CircleDollarSign,
|
||||
@@ -97,7 +98,6 @@ const BenchmarkHeader = memo<BenchmarkHeaderProps>(
|
||||
totalCases,
|
||||
}) => {
|
||||
const { t } = useTranslation('eval');
|
||||
const { modal } = App.useApp();
|
||||
const navigate = useNavigate();
|
||||
const deleteBenchmark = useEvalStore((s) => s.deleteBenchmark);
|
||||
const refreshBenchmarkDetail = useEvalStore((s) => s.refreshBenchmarkDetail);
|
||||
@@ -109,7 +109,7 @@ const BenchmarkHeader = memo<BenchmarkHeaderProps>(
|
||||
};
|
||||
|
||||
const handleDelete = () => {
|
||||
modal.confirm({
|
||||
confirmModal({
|
||||
content: t('benchmark.actions.delete.confirm'),
|
||||
okButtonProps: { danger: true },
|
||||
okText: t('benchmark.actions.delete'),
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { Button, Flexbox, Tag } from '@lobehub/ui';
|
||||
import { confirmModal } from '@lobehub/ui/base-ui';
|
||||
import { App, Card, Dropdown } from 'antd';
|
||||
import { createStaticStyles } from 'antd-style';
|
||||
import { ArrowRight, ChevronRight, Database, Ellipsis, Pencil, Play, Trash2 } from 'lucide-react';
|
||||
@@ -135,10 +136,10 @@ const DatasetCard = memo<DatasetCardProps>(
|
||||
onRun,
|
||||
}) => {
|
||||
const { t } = useTranslation('eval');
|
||||
const { modal, message } = App.useApp();
|
||||
const { message } = App.useApp();
|
||||
|
||||
const handleDelete = useCallback(() => {
|
||||
modal.confirm({
|
||||
confirmModal({
|
||||
content: t('dataset.delete.confirm'),
|
||||
okButtonProps: { danger: true },
|
||||
okText: t('common.delete'),
|
||||
@@ -153,7 +154,7 @@ const DatasetCard = memo<DatasetCardProps>(
|
||||
},
|
||||
title: t('common.delete'),
|
||||
});
|
||||
}, [dataset.id, message, modal, onRefresh, t]);
|
||||
}, [dataset.id, message, onRefresh, t]);
|
||||
|
||||
return (
|
||||
<Card className={styles.card}>
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
'use client';
|
||||
|
||||
import { Button, Flexbox } from '@lobehub/ui';
|
||||
import { confirmModal } from '@lobehub/ui/base-ui';
|
||||
import { App, Card, Skeleton } from 'antd';
|
||||
import { createStaticStyles } from 'antd-style';
|
||||
import { Plus } from 'lucide-react';
|
||||
@@ -52,7 +53,7 @@ interface DatasetsTabProps {
|
||||
const DatasetsTab = memo<DatasetsTabProps>(
|
||||
({ benchmarkId, datasets, loading: datasetsLoading, onImport, onRefresh }) => {
|
||||
const { t } = useTranslation('eval');
|
||||
const { modal, message } = App.useApp();
|
||||
const { message } = App.useApp();
|
||||
const [expandedDs, setExpandedDs] = useState<string | null>(null);
|
||||
const [pagination, setPagination] = useState({ current: 1, pageSize: 5 });
|
||||
const [search, setSearch] = useState('');
|
||||
@@ -115,7 +116,7 @@ const DatasetsTab = memo<DatasetsTabProps>(
|
||||
|
||||
const handleDeleteCase = useCallback(
|
||||
(testCase: any) => {
|
||||
modal.confirm({
|
||||
confirmModal({
|
||||
content: t('testCase.delete.confirm'),
|
||||
okButtonProps: { danger: true },
|
||||
okText: t('common.delete'),
|
||||
@@ -132,7 +133,7 @@ const DatasetsTab = memo<DatasetsTabProps>(
|
||||
title: t('common.delete'),
|
||||
});
|
||||
},
|
||||
[expandedDs, message, modal, onRefresh, refreshTestCases, t],
|
||||
[expandedDs, message, onRefresh, refreshTestCases, t],
|
||||
);
|
||||
|
||||
return (
|
||||
@@ -218,10 +219,9 @@ const DatasetsTab = memo<DatasetsTabProps>(
|
||||
onSuccess={(dataset) => {
|
||||
onRefresh();
|
||||
// Ask if user wants to import data immediately
|
||||
modal.success({
|
||||
confirmModal({
|
||||
cancelText: t('common.later'),
|
||||
content: t('dataset.create.importNow'),
|
||||
okCancel: true,
|
||||
okText: t('dataset.actions.import'),
|
||||
onOk: () => {
|
||||
setImportDatasetId(dataset.id);
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import type { AgentEvalRunListItem } from '@lobechat/types';
|
||||
import { Flexbox, Icon } from '@lobehub/ui';
|
||||
import { confirmModal } from '@lobehub/ui/base-ui';
|
||||
import { App, Card, Dropdown, Progress } from 'antd';
|
||||
import { createStaticStyles } from 'antd-style';
|
||||
import {
|
||||
@@ -122,7 +123,7 @@ interface RunCardProps {
|
||||
|
||||
const RunCard = memo<RunCardProps>(({ benchmarkId, run, onRefresh, onEdit }) => {
|
||||
const { t } = useTranslation('eval');
|
||||
const { modal, message } = App.useApp();
|
||||
const { message } = App.useApp();
|
||||
const deleteRun = useEvalStore((s) => s.deleteRun);
|
||||
const startRun = useEvalStore((s) => s.startRun);
|
||||
const abortRun = useEvalStore((s) => s.abortRun);
|
||||
@@ -148,7 +149,7 @@ const RunCard = memo<RunCardProps>(({ benchmarkId, run, onRefresh, onEdit }) =>
|
||||
const handleStart = (e: React.MouseEvent) => {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
modal.confirm({
|
||||
confirmModal({
|
||||
content: t('run.actions.start.confirm'),
|
||||
okText: t('run.actions.start'),
|
||||
onOk: async () => {
|
||||
@@ -166,7 +167,7 @@ const RunCard = memo<RunCardProps>(({ benchmarkId, run, onRefresh, onEdit }) =>
|
||||
const handleAbort = (e?: React.MouseEvent) => {
|
||||
e?.preventDefault();
|
||||
e?.stopPropagation();
|
||||
modal.confirm({
|
||||
confirmModal({
|
||||
content: t('run.actions.abort.confirm'),
|
||||
okText: t('run.actions.abort'),
|
||||
okButtonProps: { danger: true },
|
||||
@@ -181,7 +182,7 @@ const RunCard = memo<RunCardProps>(({ benchmarkId, run, onRefresh, onEdit }) =>
|
||||
const handleDelete = (e?: React.MouseEvent) => {
|
||||
e?.preventDefault();
|
||||
e?.stopPropagation();
|
||||
modal.confirm({
|
||||
confirmModal({
|
||||
content: t('run.actions.delete.confirm'),
|
||||
okButtonProps: { danger: true },
|
||||
okText: t('run.actions.delete'),
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
import type { AgentEvalRunListItem } from '@lobechat/types';
|
||||
import { Button, Flexbox } from '@lobehub/ui';
|
||||
import { Select } from 'antd';
|
||||
import { Select } from '@lobehub/ui/base-ui';
|
||||
import { Plus } from 'lucide-react';
|
||||
import { memo, useMemo, useState } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
+2
-1
@@ -3,7 +3,8 @@
|
||||
import type { EvalThreadResult } from '@lobechat/types';
|
||||
import { formatCost, formatShortenNumber } from '@lobechat/utils';
|
||||
import { ActionIcon, Flexbox, Icon, Tag } from '@lobehub/ui';
|
||||
import { Badge, Input, Select, Table, Tooltip } from 'antd';
|
||||
import { Select } from '@lobehub/ui/base-ui';
|
||||
import { Badge, Input, Table, Tooltip } from 'antd';
|
||||
import type { ColumnsType } from 'antd/es/table';
|
||||
import { createStaticStyles, cssVar } from 'antd-style';
|
||||
import { Footprints, Play, RotateCcw } from 'lucide-react';
|
||||
|
||||
+3
-2
@@ -1,6 +1,7 @@
|
||||
'use client';
|
||||
|
||||
import { Button, Icon } from '@lobehub/ui';
|
||||
import { confirmModal } from '@lobehub/ui/base-ui';
|
||||
import { App } from 'antd';
|
||||
import { createStaticStyles, cx } from 'antd-style';
|
||||
import { Brain, ChartBar, MessageSquare, Play } from 'lucide-react';
|
||||
@@ -105,12 +106,12 @@ interface IdleStateProps {
|
||||
|
||||
const IdleState = memo<IdleStateProps>(({ run }) => {
|
||||
const { t } = useTranslation('eval');
|
||||
const { modal, message } = App.useApp();
|
||||
const { message } = App.useApp();
|
||||
const startRun = useEvalStore((s) => s.startRun);
|
||||
const [starting, setStarting] = useState(false);
|
||||
|
||||
const handleStart = () => {
|
||||
modal.confirm({
|
||||
confirmModal({
|
||||
content: t('run.actions.start.confirm'),
|
||||
okText: t('run.actions.start'),
|
||||
onOk: async () => {
|
||||
|
||||
+5
-4
@@ -3,6 +3,7 @@
|
||||
import { AGENT_PROFILE_URL } from '@lobechat/const';
|
||||
import type { AgentEvalRunDetail } from '@lobechat/types';
|
||||
import { ActionIcon, Avatar, copyToClipboard, Flexbox, Highlighter, Markdown } from '@lobehub/ui';
|
||||
import { confirmModal } from '@lobehub/ui/base-ui';
|
||||
import { App, Button, Card, Tag, Typography } from 'antd';
|
||||
import { createStaticStyles } from 'antd-style';
|
||||
import {
|
||||
@@ -115,7 +116,7 @@ interface RunHeaderProps {
|
||||
|
||||
const RunHeader = memo<RunHeaderProps>(({ run, benchmarkId, hideStart }) => {
|
||||
const { t } = useTranslation('eval');
|
||||
const { modal, message } = App.useApp();
|
||||
const { message } = App.useApp();
|
||||
const navigate = useNavigate();
|
||||
const abortRun = useEvalStore((s) => s.abortRun);
|
||||
const deleteRun = useEvalStore((s) => s.deleteRun);
|
||||
@@ -133,7 +134,7 @@ const RunHeader = memo<RunHeaderProps>(({ run, benchmarkId, hideStart }) => {
|
||||
const agentProvider = snapshot?.provider || run.targetAgent?.provider;
|
||||
|
||||
const handleAbort = () => {
|
||||
modal.confirm({
|
||||
confirmModal({
|
||||
content: t('run.actions.abort.confirm'),
|
||||
okButtonProps: { danger: true },
|
||||
okText: t('run.actions.abort'),
|
||||
@@ -143,7 +144,7 @@ const RunHeader = memo<RunHeaderProps>(({ run, benchmarkId, hideStart }) => {
|
||||
};
|
||||
|
||||
const handleDelete = () => {
|
||||
modal.confirm({
|
||||
confirmModal({
|
||||
content: t('run.actions.delete.confirm'),
|
||||
okButtonProps: { danger: true },
|
||||
okText: t('run.actions.delete'),
|
||||
@@ -156,7 +157,7 @@ const RunHeader = memo<RunHeaderProps>(({ run, benchmarkId, hideStart }) => {
|
||||
};
|
||||
|
||||
const handleStart = () => {
|
||||
modal.confirm({
|
||||
confirmModal({
|
||||
content: t('run.actions.start.confirm'),
|
||||
okText: t('run.actions.start'),
|
||||
onOk: async () => {
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
'use client';
|
||||
|
||||
import { Flexbox } from '@lobehub/ui';
|
||||
import { App, Button, Card, Progress, Typography } from 'antd';
|
||||
import { confirmModal } from '@lobehub/ui/base-ui';
|
||||
import { Button, Card, Progress, Typography } from 'antd';
|
||||
import { Play, RotateCcw } from 'lucide-react';
|
||||
import { memo, useState } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
@@ -23,7 +24,6 @@ const POLLING_INTERVAL = 3000;
|
||||
|
||||
const RunDetail = memo(() => {
|
||||
const { t } = useTranslation('eval');
|
||||
const { modal } = App.useApp();
|
||||
const { benchmarkId, runId } = useParams<{ benchmarkId: string; runId: string }>();
|
||||
const useFetchRunDetail = useEvalStore((s) => s.useFetchRunDetail);
|
||||
const useFetchRunResults = useEvalStore((s) => s.useFetchRunResults);
|
||||
@@ -165,7 +165,7 @@ const RunDetail = memo(() => {
|
||||
loading={retrying}
|
||||
size="small"
|
||||
onClick={() => {
|
||||
modal.confirm({
|
||||
confirmModal({
|
||||
content: t('run.actions.retryErrors.confirm'),
|
||||
onOk: async () => {
|
||||
setRetrying(true);
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
'use client';
|
||||
|
||||
import { Center, Flexbox, Icon, Modal, Text } from '@lobehub/ui';
|
||||
import { App, Form, Input, Select } from 'antd';
|
||||
import { Select } from '@lobehub/ui/base-ui';
|
||||
import { App, Form, Input } from 'antd';
|
||||
import { cssVar } from 'antd-style';
|
||||
import { memo, useEffect, useState } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
'use client';
|
||||
|
||||
import { Center, Flexbox, Icon, Input, Modal, type ModalProps, Text, TextArea } from '@lobehub/ui';
|
||||
import { App, Form, Select } from 'antd';
|
||||
import { Select } from '@lobehub/ui/base-ui';
|
||||
import { App, Form } from 'antd';
|
||||
import { cssVar } from 'antd-style';
|
||||
import { memo, useEffect, useState } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
'use client';
|
||||
|
||||
import { Flexbox } from '@lobehub/ui';
|
||||
import { Checkbox, Input, Select, Table } from 'antd';
|
||||
import { Select } from '@lobehub/ui/base-ui';
|
||||
import { Checkbox, Input, Table } from 'antd';
|
||||
import { cssVar } from 'antd-style';
|
||||
import { memo, type ReactNode, useMemo, useState } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
'use client';
|
||||
|
||||
import { Accordion, AccordionItem, Flexbox, Modal, Text } from '@lobehub/ui';
|
||||
import { App, Form, Input, Select } from 'antd';
|
||||
import { Select } from '@lobehub/ui/base-ui';
|
||||
import { App, Form, Input } from 'antd';
|
||||
import { memo, useCallback, useState } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
'use client';
|
||||
|
||||
import { Accordion, AccordionItem, Flexbox, Modal, Text } from '@lobehub/ui';
|
||||
import { App, Form, Input, Select } from 'antd';
|
||||
import { Select } from '@lobehub/ui/base-ui';
|
||||
import { App, Form, Input } from 'antd';
|
||||
import { memo, useCallback, useEffect, useState } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import type { ChatTopicStatus } from '@lobechat/types';
|
||||
import { type MenuProps } from '@lobehub/ui';
|
||||
import { Icon } from '@lobehub/ui';
|
||||
import { confirmModal } from '@lobehub/ui/base-ui';
|
||||
import { App } from 'antd';
|
||||
import {
|
||||
CheckCircle2,
|
||||
@@ -37,7 +38,7 @@ export const useTopicItemDropdownMenu = ({
|
||||
toggleEditing,
|
||||
}: TopicItemDropdownMenuProps): (() => MenuProps['items']) => {
|
||||
const { t } = useTranslation(['topic', 'common']);
|
||||
const { modal, message } = App.useApp();
|
||||
const { message } = App.useApp();
|
||||
const navigate = useNavigate();
|
||||
|
||||
const openGroupTopicInNewWindow = useGlobalStore((s) => s.openGroupTopicInNewWindow);
|
||||
@@ -162,8 +163,7 @@ export const useTopicItemDropdownMenu = ({
|
||||
key: 'delete',
|
||||
label: t('delete', { ns: 'common' }),
|
||||
onClick: () => {
|
||||
modal.confirm({
|
||||
centered: true,
|
||||
confirmModal({
|
||||
okButtonProps: { danger: true },
|
||||
onOk: async () => {
|
||||
await removeTopic(id);
|
||||
@@ -188,7 +188,6 @@ export const useTopicItemDropdownMenu = ({
|
||||
navigate,
|
||||
toggleEditing,
|
||||
t,
|
||||
modal,
|
||||
message,
|
||||
]);
|
||||
};
|
||||
|
||||
+3
-5
@@ -1,6 +1,6 @@
|
||||
import { type MenuProps } from '@lobehub/ui';
|
||||
import { Icon } from '@lobehub/ui';
|
||||
import { App } from 'antd';
|
||||
import { confirmModal } from '@lobehub/ui/base-ui';
|
||||
import { PencilLine, Trash } from 'lucide-react';
|
||||
import { useCallback } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
@@ -17,7 +17,6 @@ export const useThreadItemDropdownMenu = ({
|
||||
toggleEditing,
|
||||
}: ThreadItemDropdownMenuProps): (() => MenuProps['items']) => {
|
||||
const { t } = useTranslation(['thread', 'common']);
|
||||
const { modal } = App.useApp();
|
||||
|
||||
const [removeThread] = useChatStore((s) => [s.removeThread]);
|
||||
|
||||
@@ -40,8 +39,7 @@ export const useThreadItemDropdownMenu = ({
|
||||
key: 'delete',
|
||||
label: t('delete', { ns: 'common' }),
|
||||
onClick: () => {
|
||||
modal.confirm({
|
||||
centered: true,
|
||||
confirmModal({
|
||||
okButtonProps: { danger: true },
|
||||
onOk: async () => {
|
||||
await removeThread(id);
|
||||
@@ -51,5 +49,5 @@ export const useThreadItemDropdownMenu = ({
|
||||
},
|
||||
},
|
||||
].filter(Boolean) as MenuProps['items'];
|
||||
}, [id, removeThread, toggleEditing, t, modal]);
|
||||
}, [id, removeThread, toggleEditing, t]);
|
||||
};
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { type MenuProps } from '@lobehub/ui';
|
||||
import { Icon } from '@lobehub/ui';
|
||||
import { confirmModal } from '@lobehub/ui/base-ui';
|
||||
import { App, Upload } from 'antd';
|
||||
import { css, cx } from 'antd-style';
|
||||
import { Hash, Import, LucideCheck, Trash } from 'lucide-react';
|
||||
@@ -100,9 +101,8 @@ export const useTopicActionsDropdownMenu = (
|
||||
key: 'deleteUnstarred',
|
||||
label: t('actions.removeUnstarred'),
|
||||
onClick: () => {
|
||||
modal.confirm({
|
||||
confirmModal({
|
||||
cancelText: t('cancel', { ns: 'common' }),
|
||||
centered: true,
|
||||
okButtonProps: { danger: true },
|
||||
okText: t('ok', { ns: 'common' }),
|
||||
onOk: removeUnstarredTopic,
|
||||
@@ -116,9 +116,8 @@ export const useTopicActionsDropdownMenu = (
|
||||
key: 'deleteAll',
|
||||
label: t('actions.removeAll'),
|
||||
onClick: () => {
|
||||
modal.confirm({
|
||||
confirmModal({
|
||||
cancelText: t('cancel', { ns: 'common' }),
|
||||
centered: true,
|
||||
okButtonProps: { danger: true },
|
||||
okText: t('ok', { ns: 'common' }),
|
||||
onOk: removeAllTopic,
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { type MenuProps } from '@lobehub/ui';
|
||||
import { Icon } from '@lobehub/ui';
|
||||
import { confirmModal } from '@lobehub/ui/base-ui';
|
||||
import { App } from 'antd';
|
||||
import { LucideCopy, Pen, PictureInPicture2Icon, Pin, PinOff, Trash } from 'lucide-react';
|
||||
import { useMemo } from 'react';
|
||||
@@ -29,7 +30,7 @@ export const useGroupDropdownMenu = ({
|
||||
title,
|
||||
}: UseGroupDropdownMenuParams): (() => MenuProps['items']) => {
|
||||
const { t } = useTranslation('chat');
|
||||
const { modal, message } = App.useApp();
|
||||
const { message } = App.useApp();
|
||||
|
||||
const openAgentInNewWindow = useGlobalStore((s) => s.openAgentInNewWindow);
|
||||
const [pinAgentGroup, duplicateAgentGroup, removeAgentGroup] = useHomeStore((s) => [
|
||||
@@ -92,8 +93,7 @@ export const useGroupDropdownMenu = ({
|
||||
label: t('delete', { ns: 'common' }),
|
||||
onClick: ({ domEvent }: any) => {
|
||||
domEvent.stopPropagation();
|
||||
modal.confirm({
|
||||
centered: true,
|
||||
confirmModal({
|
||||
okButtonProps: { danger: true },
|
||||
onOk: async () => {
|
||||
await removeAgentGroup(id);
|
||||
@@ -116,7 +116,6 @@ export const useGroupDropdownMenu = ({
|
||||
title,
|
||||
duplicateAgentGroup,
|
||||
openAgentInNewWindow,
|
||||
modal,
|
||||
removeAgentGroup,
|
||||
message,
|
||||
],
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { SessionDefaultGroup } from '@lobechat/types';
|
||||
import { type MenuProps } from '@lobehub/ui';
|
||||
import { Icon } from '@lobehub/ui';
|
||||
import { confirmModal } from '@lobehub/ui/base-ui';
|
||||
import { App } from 'antd';
|
||||
import isEqual from 'fast-deep-equal';
|
||||
import {
|
||||
@@ -42,7 +43,7 @@ export const useAgentDropdownMenu = ({
|
||||
title,
|
||||
}: UseAgentDropdownMenuParams): (() => MenuProps['items']) => {
|
||||
const { t } = useTranslation('chat');
|
||||
const { modal, message } = App.useApp();
|
||||
const { message } = App.useApp();
|
||||
|
||||
const openAgentInNewWindow = useGlobalStore((s) => s.openAgentInNewWindow);
|
||||
const sessionCustomGroups = useHomeStore(homeAgentListSelectors.agentGroups, isEqual);
|
||||
@@ -131,8 +132,7 @@ export const useAgentDropdownMenu = ({
|
||||
label: t('delete', { ns: 'common' }),
|
||||
onClick: ({ domEvent }: any) => {
|
||||
domEvent.stopPropagation();
|
||||
modal.confirm({
|
||||
centered: true,
|
||||
confirmModal({
|
||||
okButtonProps: { danger: true },
|
||||
onOk: async () => {
|
||||
await removeAgent(id);
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { ActionIcon, EditableText, SortableList } from '@lobehub/ui';
|
||||
import { confirmModal } from '@lobehub/ui/base-ui';
|
||||
import { App } from 'antd';
|
||||
import { createStaticStyles } from 'antd-style';
|
||||
import { PencilLine, Trash } from 'lucide-react';
|
||||
@@ -24,7 +25,7 @@ const styles = createStaticStyles(({ css }) => ({
|
||||
|
||||
const GroupItem = memo<SessionGroupItemBase>(({ id, name }) => {
|
||||
const { t } = useTranslation('chat');
|
||||
const { message, modal } = App.useApp();
|
||||
const { message } = App.useApp();
|
||||
|
||||
const [editing, setEditing] = useState(false);
|
||||
const [updateGroupName, removeGroup] = useHomeStore((s) => [s.updateGroupName, s.removeGroup]);
|
||||
@@ -40,11 +41,9 @@ const GroupItem = memo<SessionGroupItemBase>(({ id, name }) => {
|
||||
icon={Trash}
|
||||
size={'small'}
|
||||
onClick={() => {
|
||||
modal.confirm({
|
||||
centered: true,
|
||||
confirmModal({
|
||||
okButtonProps: {
|
||||
danger: true,
|
||||
type: 'primary',
|
||||
},
|
||||
onOk: async () => {
|
||||
await removeGroup(id);
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { type MenuProps } from '@lobehub/ui';
|
||||
import { Icon } from '@lobehub/ui';
|
||||
import { App } from 'antd';
|
||||
import { confirmModal } from '@lobehub/ui/base-ui';
|
||||
import { PencilLine, Trash } from 'lucide-react';
|
||||
import { useCallback } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
@@ -18,7 +18,6 @@ export const useProjectItemDropdownMenu = ({
|
||||
}: ProjectItemDropdownMenuProps): (() => MenuProps['items']) => {
|
||||
const { t } = useTranslation(['home', 'common']);
|
||||
const [removeKnowledgeBase] = useKnowledgeBaseStore((s) => [s.removeKnowledgeBase]);
|
||||
const { modal } = App.useApp();
|
||||
|
||||
return useCallback(
|
||||
() => [
|
||||
@@ -40,8 +39,7 @@ export const useProjectItemDropdownMenu = ({
|
||||
label: t('delete', { ns: 'common' }),
|
||||
onClick: () => {
|
||||
if (!id) return;
|
||||
modal.confirm({
|
||||
centered: true,
|
||||
confirmModal({
|
||||
okButtonProps: { danger: true },
|
||||
onOk: async () => {
|
||||
await removeKnowledgeBase(id);
|
||||
@@ -51,6 +49,6 @@ export const useProjectItemDropdownMenu = ({
|
||||
},
|
||||
},
|
||||
],
|
||||
[t, id, modal, removeKnowledgeBase, toggleEditing],
|
||||
[t, id, removeKnowledgeBase, toggleEditing],
|
||||
);
|
||||
};
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { Icon } from '@lobehub/ui';
|
||||
import { confirmModal } from '@lobehub/ui/base-ui';
|
||||
import { App } from 'antd';
|
||||
import { type ItemType } from 'antd/es/menu/interface';
|
||||
import { createStaticStyles } from 'antd-style';
|
||||
@@ -25,7 +26,7 @@ const styles = createStaticStyles(({ css }) => ({
|
||||
*/
|
||||
export const useSessionGroupMenuItems = () => {
|
||||
const { t } = useTranslation('chat');
|
||||
const { modal, message } = App.useApp();
|
||||
const { message } = App.useApp();
|
||||
const groupTemplates = useGroupTemplates();
|
||||
|
||||
const [storeCreateAgent] = useAgentStore((s) => [s.createAgent]);
|
||||
@@ -88,11 +89,7 @@ export const useSessionGroupMenuItems = () => {
|
||||
label: t('delete', { ns: 'common' }),
|
||||
onClick: (info: any) => {
|
||||
info.domEvent?.stopPropagation();
|
||||
modal.confirm({
|
||||
centered: true,
|
||||
classNames: {
|
||||
root: styles.modalRoot,
|
||||
},
|
||||
confirmModal({
|
||||
okButtonProps: { danger: true },
|
||||
onOk: async () => {
|
||||
await removeGroup(groupId);
|
||||
@@ -102,7 +99,7 @@ export const useSessionGroupMenuItems = () => {
|
||||
},
|
||||
};
|
||||
},
|
||||
[t, modal, removeGroup, styles.modalRoot],
|
||||
[t, removeGroup],
|
||||
);
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { type MenuProps } from '@lobehub/ui';
|
||||
import { Icon } from '@lobehub/ui';
|
||||
import { App } from 'antd';
|
||||
import { confirmModal } from '@lobehub/ui/base-ui';
|
||||
import { PencilLineIcon, Trash } from 'lucide-react';
|
||||
import { useCallback } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
@@ -16,7 +16,6 @@ export const useRecentItemDropdownMenu = (
|
||||
toggleEditing: (visible?: boolean) => void,
|
||||
) => {
|
||||
const { t } = useTranslation(['common', 'topic', 'components']);
|
||||
const { modal } = App.useApp();
|
||||
const [updateRecentTitle, refreshRecents] = useHomeStore((s) => [
|
||||
s.updateRecentTitle,
|
||||
s.refreshRecents,
|
||||
@@ -52,8 +51,7 @@ export const useRecentItemDropdownMenu = (
|
||||
topic: t('actions.confirmRemoveTopic', { ns: 'topic' }),
|
||||
};
|
||||
|
||||
modal.confirm({
|
||||
centered: true,
|
||||
confirmModal({
|
||||
okButtonProps: { danger: true },
|
||||
onOk: async () => {
|
||||
switch (item.type) {
|
||||
@@ -75,7 +73,7 @@ export const useRecentItemDropdownMenu = (
|
||||
},
|
||||
title: confirmMessages[item.type] || t('delete', { ns: 'common' }),
|
||||
});
|
||||
}, [item, modal, t, refreshRecents]);
|
||||
}, [item, t, refreshRecents]);
|
||||
|
||||
const dropdownMenu = useCallback((): MenuProps['items'] => {
|
||||
const canRename = true;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { type ActionIconProps } from '@lobehub/ui';
|
||||
import { ActionIcon, DropdownMenu } from '@lobehub/ui';
|
||||
import { App } from 'antd';
|
||||
import { confirmModal } from '@lobehub/ui/base-ui';
|
||||
import { MoreHorizontal, Pencil, Trash2 } from 'lucide-react';
|
||||
import { type KeyboardEvent, type MouseEvent } from 'react';
|
||||
import { memo } from 'react';
|
||||
@@ -15,7 +15,6 @@ interface ActivityDropdownProps {
|
||||
|
||||
const ActivityDropdown = memo<ActivityDropdownProps>(({ id, size = 'small' }) => {
|
||||
const { t } = useTranslation(['memory', 'common']);
|
||||
const { modal } = App.useApp();
|
||||
|
||||
const activities = useUserMemoryStore((s) => s.activities);
|
||||
const deleteActivity = useUserMemoryStore((s) => s.deleteActivity);
|
||||
@@ -30,7 +29,7 @@ const ActivityDropdown = memo<ActivityDropdownProps>(({ id, size = 'small' }) =>
|
||||
setEditingMemory(id, activity.narrative || activity.notes || '', 'activity');
|
||||
}
|
||||
} else if (info.key === 'delete') {
|
||||
modal.confirm({
|
||||
confirmModal({
|
||||
cancelText: t('cancel', { ns: 'common' }),
|
||||
content: t('activity.deleteConfirm'),
|
||||
okButtonProps: { danger: true },
|
||||
@@ -39,7 +38,6 @@ const ActivityDropdown = memo<ActivityDropdownProps>(({ id, size = 'small' }) =>
|
||||
await deleteActivity(id);
|
||||
},
|
||||
title: t('activity.deleteTitle'),
|
||||
type: 'warning',
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user