@lobehub/chat 1.96.3 → 1.96.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.cursor/rules/debug-usage.mdc +84 -0
- package/.cursor/rules/desktop-controller-tests.mdc +188 -0
- package/.cursor/rules/desktop-feature-implementation.mdc +1 -1
- package/CHANGELOG.md +17 -0
- package/README.md +1 -6
- package/changelog/v1.json +5 -0
- package/package.json +1 -1
- package/src/config/modelProviders/index.ts +0 -1
- package/src/features/InitClientDB/features/DatabaseRepair/Backup.tsx +3 -5
- package/src/features/InitClientDB/features/DatabaseRepair/Repair.tsx +2 -4
- package/src/features/KnowledgeBaseModal/AssignKnowledgeBase/Item/index.tsx +5 -7
- package/src/features/Portal/Artifacts/Header.tsx +4 -4
- package/src/features/Portal/FilePreview/Header.tsx +4 -4
- package/src/features/Portal/Home/Body/Files/FileList/Item.tsx +3 -3
- package/src/features/Portal/Home/Body/Files/FileList/index.tsx +2 -3
- package/src/features/Portal/Home/Body/Files/index.tsx +3 -3
- package/src/features/Portal/Home/Body/Plugins/ArtifactList/Item/index.tsx +3 -4
- package/src/features/Portal/Home/Body/Plugins/ArtifactList/index.tsx +3 -3
- package/src/features/Portal/Home/Body/Plugins/index.tsx +3 -3
- package/src/features/Portal/Home/Title.tsx +3 -3
- package/src/features/Portal/MessageDetail/Header.tsx +3 -3
- package/src/features/Portal/Plugins/Header.tsx +5 -6
- package/src/features/Portal/Thread/Header/Active.tsx +3 -4
- package/src/features/Portal/Thread/Header/New.tsx +4 -4
- package/src/features/SyncStatusInspector/EnableSync.tsx +5 -9
@@ -0,0 +1,84 @@
|
|
1
|
+
---
|
2
|
+
description: 包含添加 debug 日志请求时
|
3
|
+
globs:
|
4
|
+
alwaysApply: false
|
5
|
+
---
|
6
|
+
# Debug 包使用指南
|
7
|
+
|
8
|
+
本项目使用 [debug](mdc:https:/github.com/debug-js/debug) 包进行调试日志记录。使用此规则来确保团队成员统一调试日志格式。
|
9
|
+
|
10
|
+
## 基本用法
|
11
|
+
|
12
|
+
1. 导入 debug 包:
|
13
|
+
|
14
|
+
```typescript
|
15
|
+
import debug from 'debug';
|
16
|
+
```
|
17
|
+
|
18
|
+
2. 创建一个命名空间的日志记录器:
|
19
|
+
|
20
|
+
```typescript
|
21
|
+
// 格式: lobe:[模块]:[子模块]
|
22
|
+
const log = debug('lobe-[模块名]:[子模块名]');
|
23
|
+
```
|
24
|
+
|
25
|
+
3. 使用日志记录器:
|
26
|
+
|
27
|
+
```typescript
|
28
|
+
log('简单消息');
|
29
|
+
log('带变量的消息: %O', object);
|
30
|
+
log('格式化数字: %d', number);
|
31
|
+
```
|
32
|
+
|
33
|
+
## 命名空间约定
|
34
|
+
|
35
|
+
- 桌面应用相关: `lobe-desktop:[模块]`
|
36
|
+
- 服务端相关: `lobe-server:[模块]`
|
37
|
+
- 客户端相关: `lobe-client:[模块]`
|
38
|
+
- 路由相关: `lobe-[类型]-router:[模块]`
|
39
|
+
|
40
|
+
## 格式说明符
|
41
|
+
|
42
|
+
- `%O` - 对象展开(推荐用于复杂对象)
|
43
|
+
- `%o` - 对象
|
44
|
+
- `%s` - 字符串
|
45
|
+
- `%d` - 数字
|
46
|
+
|
47
|
+
## 示例
|
48
|
+
|
49
|
+
查看 [market/index.ts](mdc:src/server/routers/edge/market/index.ts) 中的使用示例:
|
50
|
+
|
51
|
+
```typescript
|
52
|
+
import debug from 'debug';
|
53
|
+
|
54
|
+
const log = debug('lobe-edge-router:market');
|
55
|
+
|
56
|
+
log('getAgent input: %O', input);
|
57
|
+
```
|
58
|
+
|
59
|
+
## 启用调试
|
60
|
+
|
61
|
+
要在开发时启用调试输出,需设置环境变量:
|
62
|
+
|
63
|
+
### 在浏览器中
|
64
|
+
|
65
|
+
在控制台执行:
|
66
|
+
```javascript
|
67
|
+
localStorage.debug = 'lobe-*'
|
68
|
+
```
|
69
|
+
|
70
|
+
### 在 Node.js 环境中
|
71
|
+
|
72
|
+
```bash
|
73
|
+
DEBUG=lobe-* npm run dev
|
74
|
+
# 或者
|
75
|
+
DEBUG=lobe-* pnpm dev
|
76
|
+
```
|
77
|
+
|
78
|
+
### 在 Electron 应用中
|
79
|
+
|
80
|
+
可以在主进程和渲染进程启动前设置环境变量:
|
81
|
+
|
82
|
+
```typescript
|
83
|
+
process.env.DEBUG = 'lobe-*';
|
84
|
+
```
|
@@ -0,0 +1,188 @@
|
|
1
|
+
---
|
2
|
+
description: 桌面端测试
|
3
|
+
globs:
|
4
|
+
alwaysApply: false
|
5
|
+
---
|
6
|
+
# 桌面端控制器单元测试指南
|
7
|
+
|
8
|
+
## 测试框架与目录结构
|
9
|
+
|
10
|
+
LobeChat 桌面端使用 Vitest 作为测试框架。控制器的单元测试应放置在对应控制器文件同级的 `__tests__` 目录下,并以原控制器文件名加 `.test.ts` 作为文件名。
|
11
|
+
|
12
|
+
```
|
13
|
+
apps/desktop/src/main/controllers/
|
14
|
+
├── __tests__/
|
15
|
+
│ ├── index.test.ts
|
16
|
+
│ ├── MenuCtr.test.ts
|
17
|
+
│ └── ...
|
18
|
+
├── McpCtr.ts
|
19
|
+
├── MenuCtr.ts
|
20
|
+
└── ...
|
21
|
+
```
|
22
|
+
|
23
|
+
## 测试文件基本结构
|
24
|
+
|
25
|
+
```typescript
|
26
|
+
import { beforeEach, describe, expect, it, vi } from 'vitest';
|
27
|
+
|
28
|
+
import type { App } from '@/core/App';
|
29
|
+
|
30
|
+
import YourController from '../YourControllerName';
|
31
|
+
|
32
|
+
// 模拟依赖
|
33
|
+
vi.mock('依赖模块', () => ({
|
34
|
+
依赖函数: vi.fn(),
|
35
|
+
}));
|
36
|
+
|
37
|
+
// 模拟 App 实例
|
38
|
+
const mockApp = {
|
39
|
+
// 按需模拟必要的 App 属性和方法
|
40
|
+
} as unknown as App;
|
41
|
+
|
42
|
+
describe('YourController', () => {
|
43
|
+
let controller: YourController;
|
44
|
+
|
45
|
+
beforeEach(() => {
|
46
|
+
vi.clearAllMocks();
|
47
|
+
controller = new YourController(mockApp);
|
48
|
+
});
|
49
|
+
|
50
|
+
describe('方法名', () => {
|
51
|
+
it('测试场景描述', async () => {
|
52
|
+
// 准备测试数据
|
53
|
+
|
54
|
+
// 执行被测方法
|
55
|
+
const result = await controller.方法名(参数);
|
56
|
+
|
57
|
+
// 验证结果
|
58
|
+
expect(result).toMatchObject(预期结果);
|
59
|
+
});
|
60
|
+
});
|
61
|
+
});
|
62
|
+
```
|
63
|
+
|
64
|
+
## 模拟外部依赖
|
65
|
+
|
66
|
+
### 模拟模块函数
|
67
|
+
|
68
|
+
```typescript
|
69
|
+
const mockFunction = vi.fn();
|
70
|
+
|
71
|
+
vi.mock('module-name', () => ({
|
72
|
+
functionName: mockFunction,
|
73
|
+
}));
|
74
|
+
```
|
75
|
+
|
76
|
+
### 模拟 Node.js 核心模块
|
77
|
+
|
78
|
+
例如模拟 `child_process.exec` 和 `util.promisify`:
|
79
|
+
|
80
|
+
```typescript
|
81
|
+
// 存储模拟的 exec 实现
|
82
|
+
const mockExecImpl = vi.fn();
|
83
|
+
|
84
|
+
// 模拟 child_process.exec
|
85
|
+
vi.mock('child_process', () => ({
|
86
|
+
exec: vi.fn((cmd, callback) => {
|
87
|
+
return mockExecImpl(cmd, callback);
|
88
|
+
}),
|
89
|
+
}));
|
90
|
+
|
91
|
+
// 模拟 util.promisify
|
92
|
+
vi.mock('util', () => ({
|
93
|
+
promisify: vi.fn((fn) => {
|
94
|
+
return async (cmd: string) => {
|
95
|
+
return new Promise((resolve, reject) => {
|
96
|
+
mockExecImpl(cmd, (error: Error | null, result: any) => {
|
97
|
+
if (error) reject(error);
|
98
|
+
else resolve(result);
|
99
|
+
});
|
100
|
+
});
|
101
|
+
};
|
102
|
+
}),
|
103
|
+
}));
|
104
|
+
```
|
105
|
+
|
106
|
+
## 编写有效的测试用例
|
107
|
+
|
108
|
+
### 测试分类
|
109
|
+
|
110
|
+
将测试用例分为不同类别,每个类别测试一个特定场景:
|
111
|
+
|
112
|
+
```typescript
|
113
|
+
// 成功场景
|
114
|
+
it('应该成功完成操作', async () => {});
|
115
|
+
|
116
|
+
// 边界条件
|
117
|
+
it('应该处理边界情况', async () => {});
|
118
|
+
|
119
|
+
// 错误处理
|
120
|
+
it('应该优雅地处理错误', async () => {});
|
121
|
+
```
|
122
|
+
|
123
|
+
### 设置测试数据
|
124
|
+
|
125
|
+
```typescript
|
126
|
+
// 模拟返回值
|
127
|
+
mockExecImpl.mockImplementation((cmd: string, callback: any) => {
|
128
|
+
if (cmd === '命令') {
|
129
|
+
callback(null, { stdout: '成功输出' });
|
130
|
+
} else {
|
131
|
+
callback(new Error('错误信息'), null);
|
132
|
+
}
|
133
|
+
});
|
134
|
+
```
|
135
|
+
|
136
|
+
### 断言
|
137
|
+
|
138
|
+
使用 Vitest 的断言函数验证结果:
|
139
|
+
|
140
|
+
```typescript
|
141
|
+
// 检查基本值
|
142
|
+
expect(result.success).toBe(true);
|
143
|
+
|
144
|
+
// 检查对象部分匹配
|
145
|
+
expect(result.data).toMatchObject({
|
146
|
+
key: 'value',
|
147
|
+
});
|
148
|
+
|
149
|
+
// 检查数组
|
150
|
+
expect(result.items).toHaveLength(2);
|
151
|
+
expect(result.items[0].name).toBe('expectedName');
|
152
|
+
|
153
|
+
// 检查函数调用
|
154
|
+
expect(mockFunction).toHaveBeenCalledWith(expectedArgs);
|
155
|
+
expect(mockFunction).toHaveBeenCalledTimes(1);
|
156
|
+
```
|
157
|
+
|
158
|
+
## 最佳实践
|
159
|
+
|
160
|
+
1. **隔离测试**:确保每个测试互不影响,使用 `beforeEach` 重置模拟和状态
|
161
|
+
2. **全面覆盖**:测试正常流程、边界条件和错误处理
|
162
|
+
3. **清晰命名**:测试名称应清晰描述测试内容和预期结果
|
163
|
+
4. **避免测试实现细节**:测试应该关注行为而非实现细节,使代码重构不会破坏测试
|
164
|
+
5. **模拟外部依赖**:使用 `vi.mock()` 模拟所有外部依赖,减少测试的不确定性
|
165
|
+
|
166
|
+
## 示例:测试 IPC 事件处理方法
|
167
|
+
|
168
|
+
```typescript
|
169
|
+
it('应该正确处理 IPC 事件', async () => {
|
170
|
+
// 模拟依赖
|
171
|
+
mockSomething.mockReturnValue({ result: 'success' });
|
172
|
+
|
173
|
+
// 调用 IPC 方法
|
174
|
+
const result = await controller.ipcMethodName({
|
175
|
+
param1: 'value1',
|
176
|
+
param2: 'value2',
|
177
|
+
});
|
178
|
+
|
179
|
+
// 验证结果
|
180
|
+
expect(result).toEqual({
|
181
|
+
success: true,
|
182
|
+
data: { result: 'success' },
|
183
|
+
});
|
184
|
+
|
185
|
+
// 验证依赖调用
|
186
|
+
expect(mockSomething).toHaveBeenCalledWith('value1', 'value2');
|
187
|
+
});
|
188
|
+
```
|
package/CHANGELOG.md
CHANGED
@@ -2,6 +2,23 @@
|
|
2
2
|
|
3
3
|
# Changelog
|
4
4
|
|
5
|
+
### [Version 1.96.4](https://github.com/lobehub/lobe-chat/compare/v1.96.3...v1.96.4)
|
6
|
+
|
7
|
+
<sup>Released on **2025-06-22**</sup>
|
8
|
+
|
9
|
+
<br/>
|
10
|
+
|
11
|
+
<details>
|
12
|
+
<summary><kbd>Improvements and Fixes</kbd></summary>
|
13
|
+
|
14
|
+
</details>
|
15
|
+
|
16
|
+
<div align="right">
|
17
|
+
|
18
|
+
[](#readme-top)
|
19
|
+
|
20
|
+
</div>
|
21
|
+
|
5
22
|
### [Version 1.96.3](https://github.com/lobehub/lobe-chat/compare/v1.96.2...v1.96.3)
|
6
23
|
|
7
24
|
<sup>Released on **2025-06-22**</sup>
|
package/README.md
CHANGED
@@ -39,12 +39,7 @@ One-click **FREE** deployment of your private OpenAI ChatGPT/Claude/Gemini/Groq/
|
|
39
39
|
|
40
40
|
<sup>Pioneering the new age of thinking and creating. Built for you, the Super Individual.</sup>
|
41
41
|
|
42
|
-
[![][github-trending-shield]][github-trending-url]
|
43
|
-
<br />
|
44
|
-
<br />
|
45
|
-
<a href="https://vercel.com/oss">
|
46
|
-
<img alt="Vercel OSS Program" src="https://vercel.com/oss/program-badge.svg" />
|
47
|
-
</a>
|
42
|
+
[![][github-trending-shield]][github-trending-url] <br /> <br /> <a href="https://vercel.com/oss"> <img alt="Vercel OSS Program" src="https://vercel.com/oss/program-badge.svg" /> </a>
|
48
43
|
|
49
44
|
![][image-overview]
|
50
45
|
|
package/changelog/v1.json
CHANGED
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "@lobehub/chat",
|
3
|
-
"version": "1.96.
|
3
|
+
"version": "1.96.4",
|
4
4
|
"description": "Lobe Chat - an open-source, high-performance chatbot framework that supports speech synthesis, multimodal, and extensible Function Call plugin system. Supports one-click free deployment of your private ChatGPT/LLM web application.",
|
5
5
|
"keywords": [
|
6
6
|
"framework",
|
@@ -1,5 +1,5 @@
|
|
1
|
-
import { Alert, Button } from '@lobehub/ui';
|
2
|
-
import { App, Card
|
1
|
+
import { Alert, Button, Text } from '@lobehub/ui';
|
2
|
+
import { App, Card } from 'antd';
|
3
3
|
import { createStyles } from 'antd-style';
|
4
4
|
import { AlertCircle } from 'lucide-react';
|
5
5
|
import { useTranslation } from 'react-i18next';
|
@@ -7,8 +7,6 @@ import { Flexbox } from 'react-layout-kit';
|
|
7
7
|
|
8
8
|
import { resetClientDatabase } from '@/database/client/db';
|
9
9
|
|
10
|
-
const { Text, Paragraph } = Typography;
|
11
|
-
|
12
10
|
const useStyles = createStyles(({ css, token }) => ({
|
13
11
|
card: css`
|
14
12
|
border-radius: ${token.borderRadiusLG}px;
|
@@ -27,7 +25,7 @@ const Backup = () => {
|
|
27
25
|
extra={<Text type="secondary">{t('clientDB.solve.backup.desc')}</Text>}
|
28
26
|
title={t('clientDB.solve.backup.title')}
|
29
27
|
>
|
30
|
-
<
|
28
|
+
<Text as={'p'}>{t('clientDB.solve.backup.exportDesc')}</Text>
|
31
29
|
<Button block type={'primary'}>
|
32
30
|
{t('clientDB.solve.backup.export')}
|
33
31
|
</Button>
|
@@ -1,7 +1,7 @@
|
|
1
1
|
'use client';
|
2
2
|
|
3
|
-
import { Alert, Button, CodeEditor, Icon } from '@lobehub/ui';
|
4
|
-
import { Card, List
|
3
|
+
import { Alert, Button, CodeEditor, Icon, Text } from '@lobehub/ui';
|
4
|
+
import { Card, List } from 'antd';
|
5
5
|
import { createStyles } from 'antd-style';
|
6
6
|
import dayjs from 'dayjs';
|
7
7
|
import isEqual from 'fast-deep-equal';
|
@@ -14,8 +14,6 @@ import { clientDB, updateMigrationRecord } from '@/database/client/db';
|
|
14
14
|
import { useGlobalStore } from '@/store/global';
|
15
15
|
import { clientDBSelectors } from '@/store/global/selectors';
|
16
16
|
|
17
|
-
const { Text } = Typography;
|
18
|
-
|
19
17
|
// 使用 antd-style 创建样式
|
20
18
|
const useStyles = createStyles(({ css, token }) => ({
|
21
19
|
actionBar: css`
|
@@ -1,4 +1,4 @@
|
|
1
|
-
import {
|
1
|
+
import { Text } from '@lobehub/ui';
|
2
2
|
import { createStyles } from 'antd-style';
|
3
3
|
import { memo } from 'react';
|
4
4
|
import { Flexbox } from 'react-layout-kit';
|
@@ -8,8 +8,6 @@ import { KnowledgeItem } from '@/types/knowledgeBase';
|
|
8
8
|
|
9
9
|
import Actions from './Action';
|
10
10
|
|
11
|
-
const { Paragraph } = Typography;
|
12
|
-
|
13
11
|
const useStyles = createStyles(({ css, token }) => ({
|
14
12
|
desc: css`
|
15
13
|
margin: 0 !important;
|
@@ -51,14 +49,14 @@ const PluginItem = memo<KnowledgeItem>(({ id, fileType, name, type, description,
|
|
51
49
|
<KnowledgeIcon fileType={fileType} name={name} size={{ file: 40, repo: 40 }} type={type} />
|
52
50
|
<Flexbox flex={1} gap={4} style={{ overflow: 'hidden', position: 'relative' }}>
|
53
51
|
<Flexbox align={'center'} gap={8} horizontal>
|
54
|
-
<
|
52
|
+
<Text className={styles.title} ellipsis>
|
55
53
|
{name}
|
56
|
-
</
|
54
|
+
</Text>
|
57
55
|
</Flexbox>
|
58
56
|
{description && (
|
59
|
-
<
|
57
|
+
<Text className={styles.desc} ellipsis>
|
60
58
|
{description}
|
61
|
-
</
|
59
|
+
</Text>
|
62
60
|
)}
|
63
61
|
</Flexbox>
|
64
62
|
</Flexbox>
|
@@ -1,5 +1,5 @@
|
|
1
|
-
import { ActionIcon, Icon, Segmented } from '@lobehub/ui';
|
2
|
-
import { ConfigProvider
|
1
|
+
import { ActionIcon, Icon, Segmented, Text } from '@lobehub/ui';
|
2
|
+
import { ConfigProvider } from 'antd';
|
3
3
|
import { cx } from 'antd-style';
|
4
4
|
import { ArrowLeft, CodeIcon, EyeIcon } from 'lucide-react';
|
5
5
|
import { useTranslation } from 'react-i18next';
|
@@ -34,9 +34,9 @@ const Header = () => {
|
|
34
34
|
<Flexbox align={'center'} flex={1} gap={12} horizontal justify={'space-between'} width={'100%'}>
|
35
35
|
<Flexbox align={'center'} gap={4} horizontal>
|
36
36
|
<ActionIcon icon={ArrowLeft} onClick={() => closeArtifact()} size={'small'} />
|
37
|
-
<
|
37
|
+
<Text className={cx(oneLineEllipsis)} type={'secondary'}>
|
38
38
|
{artifactTitle}
|
39
|
-
</
|
39
|
+
</Text>
|
40
40
|
</Flexbox>
|
41
41
|
<ConfigProvider
|
42
42
|
theme={{
|
@@ -1,5 +1,5 @@
|
|
1
|
-
import { ActionIcon } from '@lobehub/ui';
|
2
|
-
import { Skeleton
|
1
|
+
import { ActionIcon, Text } from '@lobehub/ui';
|
2
|
+
import { Skeleton } from 'antd';
|
3
3
|
import { ArrowLeft } from 'lucide-react';
|
4
4
|
import { Flexbox } from 'react-layout-kit';
|
5
5
|
|
@@ -25,9 +25,9 @@ const Header = () => {
|
|
25
25
|
{isLoading ? (
|
26
26
|
<Skeleton.Button active style={{ height: 28 }} />
|
27
27
|
) : (
|
28
|
-
<
|
28
|
+
<Text className={oneLineEllipsis} style={{ fontSize: 16 }} type={'secondary'}>
|
29
29
|
{data?.name}
|
30
|
-
</
|
30
|
+
</Text>
|
31
31
|
)}
|
32
32
|
</Flexbox>
|
33
33
|
);
|
@@ -1,4 +1,4 @@
|
|
1
|
-
import {
|
1
|
+
import { Text } from '@lobehub/ui';
|
2
2
|
import { createStyles } from 'antd-style';
|
3
3
|
import { memo } from 'react';
|
4
4
|
import { Flexbox } from 'react-layout-kit';
|
@@ -43,8 +43,8 @@ const FileItem = memo<ChatFileItem>(({ name, fileType, size, id }) => {
|
|
43
43
|
>
|
44
44
|
<FileIcon fileName={name} fileType={fileType} />
|
45
45
|
<Flexbox>
|
46
|
-
<
|
47
|
-
<
|
46
|
+
<Text ellipsis={{ tooltip: true }}>{name}</Text>
|
47
|
+
<Text type={'secondary'}>{formatSize(size)}</Text>
|
48
48
|
</Flexbox>
|
49
49
|
</Flexbox>
|
50
50
|
);
|
@@ -1,5 +1,4 @@
|
|
1
|
-
import { Avatar, Icon } from '@lobehub/ui';
|
2
|
-
import { Typography } from 'antd';
|
1
|
+
import { Avatar, Icon, Text } from '@lobehub/ui';
|
3
2
|
import { useTheme } from 'antd-style';
|
4
3
|
import isEqual from 'fast-deep-equal';
|
5
4
|
import { InboxIcon } from 'lucide-react';
|
@@ -35,7 +34,7 @@ const FileList = () => {
|
|
35
34
|
size={48}
|
36
35
|
/>
|
37
36
|
<Balancer>
|
38
|
-
<
|
37
|
+
<Text type={'secondary'}>{t('emptyKnowledgeList')}</Text>
|
39
38
|
</Balancer>
|
40
39
|
</Center>
|
41
40
|
) : (
|
@@ -1,4 +1,4 @@
|
|
1
|
-
import {
|
1
|
+
import { Text } from '@lobehub/ui';
|
2
2
|
import { memo } from 'react';
|
3
3
|
import { useTranslation } from 'react-i18next';
|
4
4
|
import { Flexbox } from 'react-layout-kit';
|
@@ -10,9 +10,9 @@ export const Files = memo(() => {
|
|
10
10
|
|
11
11
|
return (
|
12
12
|
<Flexbox gap={8}>
|
13
|
-
<
|
13
|
+
<Text as={'h5'} style={{ marginInline: 12 }}>
|
14
14
|
{t('files')}
|
15
|
-
</
|
15
|
+
</Text>
|
16
16
|
<FileList />
|
17
17
|
</Flexbox>
|
18
18
|
);
|
@@ -1,5 +1,4 @@
|
|
1
|
-
import { Icon, Tag } from '@lobehub/ui';
|
2
|
-
import { Typography } from 'antd';
|
1
|
+
import { Icon, Tag, Text } from '@lobehub/ui';
|
3
2
|
import isEqual from 'fast-deep-equal';
|
4
3
|
import { CircuitBoard } from 'lucide-react';
|
5
4
|
import { memo } from 'react';
|
@@ -53,9 +52,9 @@ const ArtifactItem = memo<ArtifactItemProps>(({ payload, messageId, identifier =
|
|
53
52
|
<Tag>{payload?.apiName}</Tag>
|
54
53
|
</Flexbox>
|
55
54
|
<div>
|
56
|
-
<
|
55
|
+
<Text ellipsis style={{ fontSize: 12 }} type={'secondary'}>
|
57
56
|
{args}
|
58
|
-
</
|
57
|
+
</Text>
|
59
58
|
</div>
|
60
59
|
</Flexbox>
|
61
60
|
</Flexbox>
|
@@ -1,5 +1,5 @@
|
|
1
|
-
import { Avatar, Icon } from '@lobehub/ui';
|
2
|
-
import { Skeleton
|
1
|
+
import { Avatar, Icon, Text } from '@lobehub/ui';
|
2
|
+
import { Skeleton } from 'antd';
|
3
3
|
import { useTheme } from 'antd-style';
|
4
4
|
import isEqual from 'fast-deep-equal';
|
5
5
|
import { Origami } from 'lucide-react';
|
@@ -41,7 +41,7 @@ const ArtifactList = () => {
|
|
41
41
|
size={48}
|
42
42
|
/>
|
43
43
|
<Balancer>
|
44
|
-
<
|
44
|
+
<Text type={'secondary'}>{t('emptyArtifactList')}</Text>
|
45
45
|
</Balancer>
|
46
46
|
</Center>
|
47
47
|
) : (
|
@@ -1,4 +1,4 @@
|
|
1
|
-
import {
|
1
|
+
import { Text } from '@lobehub/ui';
|
2
2
|
import { memo } from 'react';
|
3
3
|
import { useTranslation } from 'react-i18next';
|
4
4
|
import { Flexbox } from 'react-layout-kit';
|
@@ -10,9 +10,9 @@ export const Artifacts = memo(() => {
|
|
10
10
|
|
11
11
|
return (
|
12
12
|
<Flexbox gap={8}>
|
13
|
-
<
|
13
|
+
<Text as={'h5'} style={{ marginInline: 12 }}>
|
14
14
|
{t('Plugins')}
|
15
|
-
</
|
15
|
+
</Text>
|
16
16
|
<ArtifactList />
|
17
17
|
</Flexbox>
|
18
18
|
);
|
@@ -1,6 +1,6 @@
|
|
1
1
|
'use client';
|
2
2
|
|
3
|
-
import {
|
3
|
+
import { Text } from '@lobehub/ui';
|
4
4
|
import { memo } from 'react';
|
5
5
|
import { useTranslation } from 'react-i18next';
|
6
6
|
|
@@ -8,9 +8,9 @@ const Title = memo(() => {
|
|
8
8
|
const { t } = useTranslation('portal');
|
9
9
|
|
10
10
|
return (
|
11
|
-
<
|
11
|
+
<Text style={{ fontSize: 16 }} type={'secondary'}>
|
12
12
|
{t('title')}
|
13
|
-
</
|
13
|
+
</Text>
|
14
14
|
);
|
15
15
|
});
|
16
16
|
|
@@ -1,4 +1,4 @@
|
|
1
|
-
import {
|
1
|
+
import { Text } from '@lobehub/ui';
|
2
2
|
import { useTranslation } from 'react-i18next';
|
3
3
|
import { Flexbox } from 'react-layout-kit';
|
4
4
|
|
@@ -9,9 +9,9 @@ const Header = () => {
|
|
9
9
|
|
10
10
|
return (
|
11
11
|
<Flexbox align={'center'} gap={4} horizontal>
|
12
|
-
<
|
12
|
+
<Text className={oneLineEllipsis} style={{ fontSize: 16 }} type={'secondary'}>
|
13
13
|
{t('messageDetail')}
|
14
|
-
</
|
14
|
+
</Text>
|
15
15
|
</Flexbox>
|
16
16
|
);
|
17
17
|
};
|
@@ -1,5 +1,4 @@
|
|
1
|
-
import { ActionIcon, Icon } from '@lobehub/ui';
|
2
|
-
import { Typography } from 'antd';
|
1
|
+
import { ActionIcon, Icon, Text } from '@lobehub/ui';
|
3
2
|
import isEqual from 'fast-deep-equal';
|
4
3
|
import { ArrowLeft, Globe } from 'lucide-react';
|
5
4
|
import { useTranslation } from 'react-i18next';
|
@@ -27,9 +26,9 @@ const Header = () => {
|
|
27
26
|
<Flexbox align={'center'} gap={8} horizontal>
|
28
27
|
<ActionIcon icon={ArrowLeft} onClick={() => closeToolUI()} size={'small'} />
|
29
28
|
<Icon icon={Globe} size={16} />
|
30
|
-
<
|
29
|
+
<Text style={{ fontSize: 16 }} type={'secondary'}>
|
31
30
|
{t('search.title')}
|
32
|
-
</
|
31
|
+
</Text>
|
33
32
|
</Flexbox>
|
34
33
|
);
|
35
34
|
}
|
@@ -37,9 +36,9 @@ const Header = () => {
|
|
37
36
|
<Flexbox align={'center'} gap={4} horizontal>
|
38
37
|
<ActionIcon icon={ArrowLeft} onClick={() => closeToolUI()} size={'small'} />
|
39
38
|
<PluginAvatar identifier={toolUIIdentifier} size={28} />
|
40
|
-
<
|
39
|
+
<Text style={{ fontSize: 16 }} type={'secondary'}>
|
41
40
|
{pluginTitle}
|
42
|
-
</
|
41
|
+
</Text>
|
43
42
|
</Flexbox>
|
44
43
|
);
|
45
44
|
};
|
@@ -1,5 +1,4 @@
|
|
1
|
-
import { Icon } from '@lobehub/ui';
|
2
|
-
import { Typography } from 'antd';
|
1
|
+
import { Icon, Text } from '@lobehub/ui';
|
3
2
|
import { useTheme } from 'antd-style';
|
4
3
|
import isEqual from 'fast-deep-equal';
|
5
4
|
import { ListTree } from 'lucide-react';
|
@@ -20,7 +19,7 @@ const Active = memo(() => {
|
|
20
19
|
currentThread && (
|
21
20
|
<Flexbox align={'center'} gap={8} horizontal style={{ marginInlineStart: 4 }}>
|
22
21
|
<Icon color={theme.colorTextSecondary} icon={ListTree} size={18} />
|
23
|
-
<
|
22
|
+
<Text
|
24
23
|
className={oneLineEllipsis}
|
25
24
|
ellipsis={true}
|
26
25
|
style={{ color: theme.colorTextSecondary, fontSize: 14 }}
|
@@ -32,7 +31,7 @@ const Active = memo(() => {
|
|
32
31
|
) : (
|
33
32
|
currentThread?.title
|
34
33
|
)}
|
35
|
-
</
|
34
|
+
</Text>
|
36
35
|
</Flexbox>
|
37
36
|
)
|
38
37
|
);
|
@@ -1,5 +1,5 @@
|
|
1
|
-
import { Icon } from '@lobehub/ui';
|
2
|
-
import { Switch
|
1
|
+
import { Icon, Text } from '@lobehub/ui';
|
2
|
+
import { Switch } from 'antd';
|
3
3
|
import { GitBranch } from 'lucide-react';
|
4
4
|
import { useTranslation } from 'react-i18next';
|
5
5
|
import { Flexbox } from 'react-layout-kit';
|
@@ -17,9 +17,9 @@ const NewThreadHeader = () => {
|
|
17
17
|
return (
|
18
18
|
<Flexbox align={'center'} gap={8} horizontal style={{ marginInlineStart: 4 }}>
|
19
19
|
<Icon icon={GitBranch} size={18} />
|
20
|
-
<
|
20
|
+
<Text className={oneLineEllipsis} ellipsis style={{ fontSize: 14 }}>
|
21
21
|
{t('newPortalThread.title')}
|
22
|
-
</
|
22
|
+
</Text>
|
23
23
|
<Flexbox align={'center'} gap={8} horizontal>
|
24
24
|
<Switch
|
25
25
|
checked={newThreadMode === ThreadType.Continuation}
|
@@ -1,5 +1,5 @@
|
|
1
|
-
import { ActionIcon, Avatar, Icon, Tag } from '@lobehub/ui';
|
2
|
-
import { Divider, Popover, Switch
|
1
|
+
import { ActionIcon, Avatar, Icon, Tag, Text } from '@lobehub/ui';
|
2
|
+
import { Divider, Popover, Switch } from 'antd';
|
3
3
|
import { createStyles } from 'antd-style';
|
4
4
|
import { TooltipPlacement } from 'antd/es/tooltip';
|
5
5
|
import isEqual from 'fast-deep-equal';
|
@@ -15,8 +15,6 @@ import { pathString } from '@/utils/url';
|
|
15
15
|
|
16
16
|
import EnableTag from './EnableTag';
|
17
17
|
|
18
|
-
const { Text } = Typography;
|
19
|
-
|
20
18
|
const useStyles = createStyles(({ css, token, prefixCls }) => ({
|
21
19
|
text: css`
|
22
20
|
max-width: 100%;
|
@@ -67,9 +65,7 @@ const EnableSync = memo<EnableSyncProps>(({ hiddenActions, placement = 'bottomLe
|
|
67
65
|
style={{ paddingInlineEnd: 12 }}
|
68
66
|
>
|
69
67
|
{t('sync.channel')}
|
70
|
-
<Text className={styles.text}
|
71
|
-
{channelName}
|
72
|
-
</Text>
|
68
|
+
<Text className={styles.text}>{channelName}</Text>
|
73
69
|
</Flexbox>
|
74
70
|
</Flexbox>
|
75
71
|
<Divider dashed style={{ margin: 0 }} />
|
@@ -99,9 +95,9 @@ const EnableSync = memo<EnableSyncProps>(({ hiddenActions, placement = 'bottomLe
|
|
99
95
|
</Flexbox>
|
100
96
|
)}
|
101
97
|
</Flexbox>
|
102
|
-
<
|
98
|
+
<Text type={'secondary'}>
|
103
99
|
{user.os} · {user.browser}
|
104
|
-
</
|
100
|
+
</Text>
|
105
101
|
</Flexbox>
|
106
102
|
</Flexbox>
|
107
103
|
))}
|