@spacecorexdev/core 0.0.4 → 0.0.5
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/package.json +2 -36
- package/src/api/_base.ts +243 -0
- package/src/api/index.ts +17 -0
- package/src/api/project.ts +1345 -0
- package/src/api/user.ts +1174 -0
- package/src/contract.ts +50 -0
- package/src/hooks/index.ts +2 -0
- package/{dist/hooks/index.js → src/hooks/useLongPress.ts} +53 -49
- package/src/hooks/useOnlineStatus.ts +22 -0
- package/src/index.ts +14 -0
- package/src/types/id.ts +2 -0
- package/src/types/index.ts +5 -0
- package/src/types/project/base.ts +63 -0
- package/src/types/project/contract.ts +79 -0
- package/src/types/project/contractStatus.tsx +15 -0
- package/src/types/project/index.ts +5 -0
- package/src/types/project/member.ts +46 -0
- package/src/types/project/progress.ts +43 -0
- package/src/types/projectRole.ts +17 -0
- package/src/types/theme.ts +1 -0
- package/src/types/user/index.ts +1 -0
- package/src/types/user/role.ts +7 -0
- package/src/ui/CommentTimeline/index.tsx +330 -0
- package/src/ui/FileManager/FileContextMenu.tsx +628 -0
- package/src/ui/FileManager/FileGridView.tsx +529 -0
- package/src/ui/FileManager/FileTableView.tsx +405 -0
- package/src/ui/FileManager/FileToolbar.tsx +119 -0
- package/src/ui/FileManager/FileVersionHistoryModal.tsx +175 -0
- package/src/ui/FileManager/MoveCopyToProjectModal.tsx +119 -0
- package/src/ui/FileManager/ShareToWechatModal.tsx +419 -0
- package/src/ui/FileManager/hooks/useFileManagerActions.ts +2532 -0
- package/src/ui/FileManager/hooks/useFileManagerState.ts +419 -0
- package/src/ui/FileManager/index.tsx +580 -0
- package/src/ui/FileManager/projectFileManagerApi.ts +57 -0
- package/src/ui/FileManager/types.ts +184 -0
- package/src/ui/FileManager/utils/fileDeltaWorker.ts +193 -0
- package/src/ui/FileManager/utils/fileTree.ts +178 -0
- package/src/ui/FileManager/utils/fileUpload.ts +714 -0
- package/src/ui/FileManager/utils/fileUtils.ts +65 -0
- package/src/ui/InvoiceRecordsList/index.tsx +813 -0
- package/src/ui/MyFileSelectorModal.tsx +261 -0
- package/src/ui/ProjectSelector/index.tsx +472 -0
- package/src/ui/ProjectSelector/projectCache.ts +40 -0
- package/src/ui/RoleSelector/index.tsx +473 -0
- package/src/ui/RoleSelector/roleCache.ts +40 -0
- package/src/ui/UIAlert.tsx +399 -0
- package/src/ui/UIAlertExample.tsx +129 -0
- package/src/ui/UIConfirm.tsx +335 -0
- package/src/ui/UIConfirmExample.tsx +165 -0
- package/src/ui/UIDatePicker.tsx +146 -0
- package/src/ui/UIDateRangePicker.tsx +38 -0
- package/src/ui/UIFilePreview/ExcelEditor/index.tsx +617 -0
- package/src/ui/UIFilePreview/ExcelEditor/types.ts +24 -0
- package/src/ui/UIFilePreview/ExportDropdown.css +85 -0
- package/src/ui/UIFilePreview/ExportDropdown.tsx +109 -0
- package/src/ui/UIFilePreview/IndexedDBUtils.ts +564 -0
- package/src/ui/UIFilePreview/MarkdownEditor/exportMarkdownPdf.ts +576 -0
- package/src/ui/UIFilePreview/MarkdownEditor/index.tsx +677 -0
- package/src/ui/UIFilePreview/MarkdownEditor/markdownEditor.css +1005 -0
- package/src/ui/UIFilePreview/MarkdownEditor/types.ts +15 -0
- package/src/ui/UIFilePreview/PPTXEditor/index.tsx +602 -0
- package/src/ui/UIFilePreview/RichDocEditor/exportRDocMarkdown.ts +77 -0
- package/src/ui/UIFilePreview/RichDocEditor/exportRDocPdf.ts +374 -0
- package/src/ui/UIFilePreview/RichDocEditor/index.tsx +730 -0
- package/src/ui/UIFilePreview/RichDocEditor/richdoc-editor.css +59 -0
- package/src/ui/UIFilePreview/UIFilePreview.tsx +611 -0
- package/src/ui/UIFilePreview/WordEditor/index.tsx +3933 -0
- package/src/ui/UIFilePreview/WordEditor/style.ts +1213 -0
- package/src/ui/UIFilePreview/WordEditor/word-editor.css +999 -0
- package/src/ui/UIFilePreview/filePreview.css +193 -0
- package/src/ui/UIFilePreview/filetypes/archive.tsx +66 -0
- package/src/ui/UIFilePreview/filetypes/cad.tsx +287 -0
- package/src/ui/UIFilePreview/filetypes/excel.tsx +355 -0
- package/src/ui/UIFilePreview/filetypes/image.tsx +20 -0
- package/src/ui/UIFilePreview/filetypes/imageLoader.ts +63 -0
- package/src/ui/UIFilePreview/filetypes/pdf.tsx +156 -0
- package/src/ui/UIFilePreview/filetypes/ppt.tsx +535 -0
- package/src/ui/UIFilePreview/filetypes/pptExportPdf.ts +523 -0
- package/src/ui/UIFilePreview/filetypes/video.tsx +482 -0
- package/src/ui/UIFilePreview/filetypes/word.tsx +245 -0
- package/src/ui/UIFilePreview/filetypes/wordExportMarkdown.ts +86 -0
- package/src/ui/UIFilePreview/filetypes/wordExportPdf.tsx +427 -0
- package/src/ui/UIFilePreview/index.ts +35 -0
- package/src/ui/UIFilePreview/pdfPagination.ts +143 -0
- package/src/ui/UIFilePreview/previewUtils.tsx +531 -0
- package/src/ui/UIFileUpload.tsx +382 -0
- package/src/ui/UIImageUpload.tsx +195 -0
- package/src/ui/UILoading.tsx +255 -0
- package/src/ui/UILoadingExample.tsx +139 -0
- package/src/ui/UISelect.tsx +105 -0
- package/src/ui/UIToast.tsx +381 -0
- package/src/ui/UIToastExample.tsx +69 -0
- package/src/ui/UIToastSingle.tsx +279 -0
- package/src/ui/UIViewToggle.tsx +64 -0
- package/src/ui/UserSelector/index.tsx +583 -0
- package/src/ui/index.ts +84 -0
- package/src/ui/upload/image.ts +135 -0
- package/src/ui/upload/index.ts +73 -0
- package/src/ui/upload/submitFile.ts +106 -0
- package/src/ui/upload/submitForm.ts +124 -0
- package/src/ui/upload/upload.err.ts +15 -0
- package/src/ui/upload/upload.ts +250 -0
- package/src/utils/CacheDepartmentInfo.ts +372 -0
- package/src/utils/CacheFileContent.ts +315 -0
- package/src/utils/CachePermissionInfo.ts +235 -0
- package/src/utils/CacheRoleInfo.ts +303 -0
- package/src/utils/CacheUserInfo.ts +818 -0
- package/src/utils/CacheViewToggleInfo.ts +182 -0
- package/src/utils/MessageContentUtils.ts +268 -0
- package/src/utils/clipboard.ts +70 -0
- package/src/utils/companyEmail.ts +19 -0
- package/src/utils/forbidDebugger.ts +59 -0
- package/src/utils/formatters.ts +94 -0
- package/src/utils/htmlUtils.tsx +59 -0
- package/src/utils/index.ts +18 -0
- package/src/utils/keyboard.ts +114 -0
- package/src/utils/mammothApi.ts +16 -0
- package/src/utils/polyfills.ts +928 -0
- package/src/utils/regex.ts +14 -0
- package/src/utils/storage.ts +95 -0
- package/src/utils/workerBootstrap.ts +87 -0
- package/dist/api/index.js +0 -1553
- package/dist/contract.js +0 -5
- package/dist/index.js +0 -4492
- package/dist/types/index.js +0 -49
- package/dist/ui/index.css +0 -1876
- package/dist/ui/index.js +0 -22245
- package/dist/utils/index.js +0 -4296
- /package/{dist → src}/styles/ant-modal.css +0 -0
- /package/{dist → src}/styles/ant-spin.css +0 -0
- /package/{dist → src}/styles/ant-table.css +0 -0
- /package/{dist → src}/styles/index.css +0 -0
|
@@ -0,0 +1,279 @@
|
|
|
1
|
+
/* eslint-disable react-refresh/only-export-components */
|
|
2
|
+
/**
|
|
3
|
+
* UIToastSingle - 全局唯一消息提示组件
|
|
4
|
+
*
|
|
5
|
+
* 使用示例:
|
|
6
|
+
*
|
|
7
|
+
* 1. 直接调用 API(推荐):
|
|
8
|
+
* import { UIToastSingle } from './UIToastSingle';
|
|
9
|
+
*
|
|
10
|
+
* // 简单消息
|
|
11
|
+
* UIToastSingle.success('操作成功');
|
|
12
|
+
* UIToastSingle.error('操作失败');
|
|
13
|
+
* UIToastSingle.info('提示信息');
|
|
14
|
+
* UIToastSingle.warning('警告信息');
|
|
15
|
+
*
|
|
16
|
+
* // 完整配置
|
|
17
|
+
* UIToastSingle.success({
|
|
18
|
+
* key: 'my-toast', // 唯一标识,用于更新或关闭
|
|
19
|
+
* message: '操作成功',
|
|
20
|
+
* descs: '这是一个详细描述',
|
|
21
|
+
* duration: 5, // 秒,0表示不自动关闭
|
|
22
|
+
* placement: 'topRight',
|
|
23
|
+
* onClose: () => console.log('Toast已关闭')
|
|
24
|
+
* });
|
|
25
|
+
*
|
|
26
|
+
* // 下载进度提示(不自动关闭,手动关闭)
|
|
27
|
+
* UIToastSingle.info({
|
|
28
|
+
* key: 'download-progress',
|
|
29
|
+
* message: '下载进度: 50%',
|
|
30
|
+
* duration: 0 // 不自动关闭
|
|
31
|
+
* });
|
|
32
|
+
* // 下载完成后手动关闭
|
|
33
|
+
* UIToastSingle.close('download-progress');
|
|
34
|
+
*
|
|
35
|
+
* // 销毁所有 toast
|
|
36
|
+
* UIToastSingle.destroy();
|
|
37
|
+
*
|
|
38
|
+
* 特点:
|
|
39
|
+
* - 同一类型的 toast 只会显示一个,新的会替换旧的
|
|
40
|
+
* - 可以通过 key 自定义唯一标识
|
|
41
|
+
* - 可以手动关闭指定 key 的 toast
|
|
42
|
+
*/
|
|
43
|
+
|
|
44
|
+
import React from 'react';
|
|
45
|
+
import { notification } from 'antd';
|
|
46
|
+
import { CheckCircleOutlined, CloseCircleOutlined, InfoCircleOutlined, WarningOutlined } from '@ant-design/icons';
|
|
47
|
+
|
|
48
|
+
// Toast 类型定义
|
|
49
|
+
type UIToastSingleType = 'success' | 'error' | 'info' | 'warning';
|
|
50
|
+
|
|
51
|
+
// Singleton Toast 配置选项
|
|
52
|
+
export interface UIToastSingleOptions {
|
|
53
|
+
key?: string;
|
|
54
|
+
message: React.ReactNode;
|
|
55
|
+
descs?: React.ReactNode;
|
|
56
|
+
duration?: number; // 单位:秒
|
|
57
|
+
placement?: 'topLeft' | 'topRight' | 'bottomLeft' | 'bottomRight' | 'top' | 'bottom';
|
|
58
|
+
onClose?: () => void;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
// 内部使用的完整配置对象
|
|
62
|
+
interface SingletonToastConfig {
|
|
63
|
+
key: string;
|
|
64
|
+
type: UIToastSingleType;
|
|
65
|
+
message: React.ReactNode;
|
|
66
|
+
descs?: React.ReactNode;
|
|
67
|
+
duration: number;
|
|
68
|
+
placement?: 'topLeft' | 'topRight' | 'bottomLeft' | 'bottomRight' | 'top' | 'bottom';
|
|
69
|
+
onClose?: () => void;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
// 当前活动的 toast 状态
|
|
73
|
+
interface CurrentToastState {
|
|
74
|
+
key: string;
|
|
75
|
+
type: UIToastSingleType;
|
|
76
|
+
message: React.ReactNode;
|
|
77
|
+
descs?: React.ReactNode;
|
|
78
|
+
duration: number;
|
|
79
|
+
placement?: 'topLeft' | 'topRight' | 'bottomLeft' | 'bottomRight' | 'top' | 'bottom';
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
// 图标映射
|
|
83
|
+
const iconMap: Record<UIToastSingleType, React.ReactNode> = {
|
|
84
|
+
success: <CheckCircleOutlined style={{ color: '#52c41a' }} />,
|
|
85
|
+
error: <CloseCircleOutlined style={{ color: '#ff4d4f' }} />,
|
|
86
|
+
info: <InfoCircleOutlined style={{ color: '#1890ff' }} />,
|
|
87
|
+
warning: <WarningOutlined style={{ color: '#faad14' }} />
|
|
88
|
+
};
|
|
89
|
+
|
|
90
|
+
// 全局唯一的 toast 状态管理类
|
|
91
|
+
class SingletonToastManager {
|
|
92
|
+
private currentToast: CurrentToastState | null = null;
|
|
93
|
+
// 由代码主动 destroy/close 的 key 集合:这些关闭属于"编程式替换/关闭",
|
|
94
|
+
// 不能触发调用方传入的 onClose(例如下载进度 toast 的 onClose 是取消下载,
|
|
95
|
+
// 若被其他 toast 替换或同 key 刷新时误触发,会导致下载被意外 abort)。
|
|
96
|
+
private suppressedCloseKeys = new Set<string>();
|
|
97
|
+
|
|
98
|
+
// 编程式销毁通知:抑制该通知的用户 onClose 回调
|
|
99
|
+
private destroySilently(key: string) {
|
|
100
|
+
this.suppressedCloseKeys.add(key);
|
|
101
|
+
notification.destroy(key);
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
// 显示全局唯一Toast
|
|
105
|
+
show(config: SingletonToastConfig) {
|
|
106
|
+
const { key, type, message, descs, duration, placement, onClose } = config;
|
|
107
|
+
|
|
108
|
+
// 如果是同一个 key 的 toast,直接用相同 key 再次 open:
|
|
109
|
+
// antd 5(rc-notification)对相同 key 会原位更新通知内容并重置计时,
|
|
110
|
+
// 不会触发 onClose。绝不能先 destroy 再重建——destroy 会触发旧通知的
|
|
111
|
+
// onClose,导致例如下载进度回调每次刷新都把下载 abort 掉。
|
|
112
|
+
if (this.currentToast && this.currentToast.key === key) {
|
|
113
|
+
this.createNotification({ key, type, message, descs, duration, placement, onClose });
|
|
114
|
+
} else {
|
|
115
|
+
// 不同 key 替换旧 toast 属于编程式关闭,不应执行旧 toast 的 onClose
|
|
116
|
+
if (this.currentToast) {
|
|
117
|
+
this.destroySilently(this.currentToast.key);
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
// 创建新的 toast
|
|
121
|
+
this.createNotification({ key, type, message, descs, duration, placement, onClose });
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
// 创建通知
|
|
126
|
+
private createNotification(config: SingletonToastConfig) {
|
|
127
|
+
const { key, type, message, descs, duration, placement, onClose } = config;
|
|
128
|
+
|
|
129
|
+
// 清除可能残留的编程式关闭标记(destroy 时通知已不存在,onClose 不会触发),
|
|
130
|
+
// 否则该 key 以后真正被用户手动关闭时回调会被错误吞掉
|
|
131
|
+
this.suppressedCloseKeys.delete(key);
|
|
132
|
+
|
|
133
|
+
const notificationMethod = {
|
|
134
|
+
success: notification.success,
|
|
135
|
+
error: notification.error,
|
|
136
|
+
info: notification.info,
|
|
137
|
+
warning: notification.warning
|
|
138
|
+
}[type];
|
|
139
|
+
|
|
140
|
+
notificationMethod({
|
|
141
|
+
key,
|
|
142
|
+
message,
|
|
143
|
+
description: descs,
|
|
144
|
+
duration,
|
|
145
|
+
placement: placement || 'topRight',
|
|
146
|
+
icon: iconMap[type],
|
|
147
|
+
onClose: () => {
|
|
148
|
+
// 编程式关闭(被替换/同 key 刷新/主动 close)直接忽略用户回调,
|
|
149
|
+
// 只有用户手动点关闭按钮才执行 onClose
|
|
150
|
+
if (this.suppressedCloseKeys.has(key)) {
|
|
151
|
+
this.suppressedCloseKeys.delete(key);
|
|
152
|
+
if (this.currentToast?.key === key) {
|
|
153
|
+
this.currentToast = null;
|
|
154
|
+
}
|
|
155
|
+
return;
|
|
156
|
+
}
|
|
157
|
+
if (this.currentToast?.key === key) {
|
|
158
|
+
this.currentToast = null;
|
|
159
|
+
}
|
|
160
|
+
onClose?.();
|
|
161
|
+
}
|
|
162
|
+
});
|
|
163
|
+
|
|
164
|
+
// 保存当前 toast 状态
|
|
165
|
+
this.currentToast = {
|
|
166
|
+
key,
|
|
167
|
+
type,
|
|
168
|
+
message,
|
|
169
|
+
descs,
|
|
170
|
+
duration,
|
|
171
|
+
placement
|
|
172
|
+
};
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
// 关闭当前 toast
|
|
176
|
+
close(toastKey?: string) {
|
|
177
|
+
if (!this.currentToast) {
|
|
178
|
+
// 没有活动单例 toast 时,仅尝试销毁指定 key 的通知本身
|
|
179
|
+
if (toastKey) {
|
|
180
|
+
notification.destroy(toastKey);
|
|
181
|
+
}
|
|
182
|
+
return;
|
|
183
|
+
}
|
|
184
|
+
const key = toastKey || this.currentToast.key;
|
|
185
|
+
if (key !== this.currentToast.key) {
|
|
186
|
+
// 指定关闭的不是当前 toast(例如下载进度 toast 已被其他 toast 替换),
|
|
187
|
+
// 只销毁该通知,不能清空 currentToast,否则会误伤当前活动的 toast
|
|
188
|
+
notification.destroy(toastKey);
|
|
189
|
+
return;
|
|
190
|
+
}
|
|
191
|
+
this.destroySilently(key);
|
|
192
|
+
this.currentToast = null;
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
// 销毁所有 toast
|
|
196
|
+
destroy() {
|
|
197
|
+
if (this.currentToast) {
|
|
198
|
+
this.destroySilently(this.currentToast.key);
|
|
199
|
+
this.currentToast = null;
|
|
200
|
+
}
|
|
201
|
+
// notification.destroy() 不带 key 会销毁所有(包括其他来源的通知),
|
|
202
|
+
// 无法逐个抑制;当前单例自身管理的通知已在上面静默关闭。
|
|
203
|
+
notification.destroy();
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
// 单例实例
|
|
208
|
+
const singletonManager = new SingletonToastManager();
|
|
209
|
+
|
|
210
|
+
// Singleton Toast API
|
|
211
|
+
export const UIToastSingle = {
|
|
212
|
+
success: (options: UIToastSingleOptions | React.ReactNode, duration: number = 3) => {
|
|
213
|
+
const config = buildConfig('success', options, duration);
|
|
214
|
+
singletonManager.show(config);
|
|
215
|
+
},
|
|
216
|
+
|
|
217
|
+
error: (options: UIToastSingleOptions | React.ReactNode, duration: number = 3) => {
|
|
218
|
+
const config = buildConfig('error', options, duration);
|
|
219
|
+
singletonManager.show(config);
|
|
220
|
+
},
|
|
221
|
+
|
|
222
|
+
info: (options: UIToastSingleOptions | React.ReactNode, duration: number = 3) => {
|
|
223
|
+
const config = buildConfig('info', options, duration);
|
|
224
|
+
singletonManager.show(config);
|
|
225
|
+
},
|
|
226
|
+
|
|
227
|
+
warning: (options: UIToastSingleOptions | React.ReactNode, duration: number = 3) => {
|
|
228
|
+
const config = buildConfig('warning', options, duration);
|
|
229
|
+
singletonManager.show(config);
|
|
230
|
+
},
|
|
231
|
+
|
|
232
|
+
custom: (type: UIToastSingleType, options: UIToastSingleOptions | React.ReactNode, duration: number = 3) => {
|
|
233
|
+
const config = buildConfig(type, options, duration);
|
|
234
|
+
singletonManager.show(config);
|
|
235
|
+
},
|
|
236
|
+
|
|
237
|
+
close: (key?: string) => {
|
|
238
|
+
singletonManager.close(key);
|
|
239
|
+
},
|
|
240
|
+
|
|
241
|
+
destroy: () => {
|
|
242
|
+
singletonManager.destroy();
|
|
243
|
+
}
|
|
244
|
+
};
|
|
245
|
+
|
|
246
|
+
// 构建配置对象
|
|
247
|
+
function buildConfig(
|
|
248
|
+
type: UIToastSingleType,
|
|
249
|
+
options: UIToastSingleOptions | React.ReactNode,
|
|
250
|
+
defaultDuration: number
|
|
251
|
+
): SingletonToastConfig {
|
|
252
|
+
// 如果是字符串或数字等基本类型,转换为 ReactNode
|
|
253
|
+
const config: UIToastSingleOptions = (typeof options === 'object' && options !== null
|
|
254
|
+
? options
|
|
255
|
+
: { message: options }) as UIToastSingleOptions;
|
|
256
|
+
|
|
257
|
+
// 使用固定 key,基于类型,不基于消息内容
|
|
258
|
+
// 这样同一类型的 toast 只会创建/更新一个
|
|
259
|
+
const key = config.key || `singleton-${type}`;
|
|
260
|
+
|
|
261
|
+
return {
|
|
262
|
+
key,
|
|
263
|
+
type,
|
|
264
|
+
message: config.message,
|
|
265
|
+
descs: config.descs,
|
|
266
|
+
duration: config.duration ?? defaultDuration,
|
|
267
|
+
placement: config.placement,
|
|
268
|
+
onClose: config.onClose
|
|
269
|
+
};
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
// UIToastSingleProvider - 现在只是一个空包装器,用于保持 API 兼容性
|
|
273
|
+
export interface UIToastSingleProviderProps {
|
|
274
|
+
children: React.ReactNode;
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
export const UIToastSingleProvider: React.FC<UIToastSingleProviderProps> = ({ children }) => {
|
|
278
|
+
return <>{children}</>;
|
|
279
|
+
};
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { Button } from 'antd';
|
|
3
|
+
import { TableOutlined, AppstoreOutlined } from '@ant-design/icons';
|
|
4
|
+
|
|
5
|
+
interface ViewToggleProps<T extends string> {
|
|
6
|
+
className?: string;
|
|
7
|
+
viewMode: T;
|
|
8
|
+
onToggle: (mode: T) => void;
|
|
9
|
+
options: {
|
|
10
|
+
value: T;
|
|
11
|
+
icon: React.ReactNode;
|
|
12
|
+
tooltip?: string;
|
|
13
|
+
}[];
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export function UIViewToggle<T extends string>({ className = "", viewMode, onToggle, options = [] }: ViewToggleProps<T>) {
|
|
17
|
+
return (
|
|
18
|
+
<div className={`flex justify-end ${className}`}>
|
|
19
|
+
<div className="bg-gray-100 rounded-button p-1 flex">
|
|
20
|
+
{options.map((option, index) => (
|
|
21
|
+
<Button
|
|
22
|
+
key={option.value}
|
|
23
|
+
type={viewMode === option.value ? 'primary' : 'text'}
|
|
24
|
+
icon={option.icon}
|
|
25
|
+
onClick={() => onToggle(option.value)}
|
|
26
|
+
className={`${index < options.length - 1 ? "mr-1" : ""} rounded-button`}
|
|
27
|
+
size="small"
|
|
28
|
+
title={option.tooltip}
|
|
29
|
+
/>
|
|
30
|
+
))}
|
|
31
|
+
</div>
|
|
32
|
+
</div>
|
|
33
|
+
);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export function UITableGridViewToggle({
|
|
37
|
+
viewMode,
|
|
38
|
+
onToggle,
|
|
39
|
+
className = ""
|
|
40
|
+
}: {
|
|
41
|
+
viewMode: 'table' | 'grid';
|
|
42
|
+
onToggle: (mode: 'table' | 'grid') => void;
|
|
43
|
+
className?: string;
|
|
44
|
+
}) {
|
|
45
|
+
return (
|
|
46
|
+
<UIViewToggle<'table' | 'grid'>
|
|
47
|
+
viewMode={viewMode}
|
|
48
|
+
onToggle={onToggle}
|
|
49
|
+
className={className}
|
|
50
|
+
options={[
|
|
51
|
+
{
|
|
52
|
+
value: 'table',
|
|
53
|
+
icon: <TableOutlined />,
|
|
54
|
+
tooltip: '表格视图'
|
|
55
|
+
},
|
|
56
|
+
{
|
|
57
|
+
value: 'grid',
|
|
58
|
+
icon: <AppstoreOutlined />,
|
|
59
|
+
tooltip: '网格视图'
|
|
60
|
+
}
|
|
61
|
+
]}
|
|
62
|
+
/>
|
|
63
|
+
);
|
|
64
|
+
}
|