@baishuyun/ai-design 2.0.37 → 2.1.0-alpha.0
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/.storybook/main.ts +31 -31
- package/.storybook/preview.ts +16 -16
- package/CHANGELOG.md +512 -492
- package/components.json +22 -22
- package/package.json +9 -6
- package/scripts/strip-layers.cjs +41 -41
- package/src/components/abs-fullscreen-gradient-bg.tsx +35 -35
- package/src/components/agent-helper/agent-category-select-menu/index.tsx +57 -57
- package/src/components/agent-helper/agent-entry-card/index.tsx +94 -94
- package/src/components/agent-helper/agent-helper-card/index.tsx +179 -179
- package/src/components/agent-helper/agent-helper-card-list/index.tsx +59 -59
- package/src/components/agent-helper/agent-helper-main-layout/index.tsx +60 -60
- package/src/components/agent-helper/agent-sort-select/index.tsx +89 -89
- package/src/components/agent-helper/agent-tag/index.tsx +29 -29
- package/src/components/agent-helper/app-select/index.tsx +559 -559
- package/src/components/agent-helper/condition-group/index.tsx +75 -75
- package/src/components/agent-helper/condition-input/index.tsx +233 -233
- package/src/components/agent-helper/condition-item/index.tsx +237 -237
- package/src/components/agent-helper/condition-quantifier-select/index.tsx +142 -142
- package/src/components/agent-helper/condition-trigger-description/index.tsx +49 -49
- package/src/components/agent-helper/date-picker/calendar-panel.tsx +164 -164
- package/src/components/agent-helper/date-picker/date-input.tsx +91 -91
- package/src/components/agent-helper/date-picker/date-picker.tsx +327 -327
- package/src/components/agent-helper/date-picker/footer-panel.tsx +44 -44
- package/src/components/agent-helper/date-picker/index.ts +3 -3
- package/src/components/agent-helper/date-picker/month-panel.tsx +82 -82
- package/src/components/agent-helper/date-picker/time-panel.tsx +146 -146
- package/src/components/agent-helper/date-picker/types.ts +37 -37
- package/src/components/agent-helper/date-picker/utils.ts +121 -121
- package/src/components/agent-helper/date-picker/year-panel.tsx +86 -86
- package/src/components/agent-helper/exec-log-filter/index.tsx +232 -232
- package/src/components/agent-helper/field-edit-preference-select/index.tsx +291 -291
- package/src/components/agent-helper/field-select/index.tsx +466 -466
- package/src/components/agent-helper/field-value-input/china-address-data.ts +4117 -4117
- package/src/components/agent-helper/field-value-input/display.tsx +71 -71
- package/src/components/agent-helper/field-value-input/icons.tsx +38 -38
- package/src/components/agent-helper/field-value-input/index.tsx +144 -144
- package/src/components/agent-helper/field-value-input/inputs.tsx +247 -247
- package/src/components/agent-helper/field-value-input/picker-inputs.tsx +1141 -1141
- package/src/components/agent-helper/flow-node-action-trigger-select/index.tsx +57 -57
- package/src/components/agent-helper/form-action-trigger-select/index.tsx +60 -60
- package/src/components/agent-helper/form-divider/index.tsx +44 -44
- package/src/components/agent-helper/form-select/index.tsx +732 -732
- package/src/components/agent-helper/monthdays-select/index.tsx +378 -378
- package/src/components/agent-helper/offset-preference-select/index.tsx +268 -268
- package/src/components/agent-helper/offset-type-select/index.tsx +66 -66
- package/src/components/agent-helper/offset-unit-select/index.tsx +54 -54
- package/src/components/agent-helper/placeholder-card/index.tsx +75 -75
- package/src/components/agent-helper/prompt-input/index.tsx +646 -640
- package/src/components/agent-helper/relational-operator-select/index.tsx +179 -179
- package/src/components/agent-helper/repeat-by-type-select/index.tsx +53 -53
- package/src/components/agent-helper/repeat-preference-select/index.tsx +162 -162
- package/src/components/agent-helper/repeat-preference-type-select/index.tsx +58 -58
- package/src/components/agent-helper/search-input/index.tsx +35 -35
- package/src/components/agent-helper/table/index.tsx +114 -114
- package/src/components/agent-helper/trigger-select/index.tsx +121 -121
- package/src/components/agent-helper/trigger-time-preference-select/index.tsx +189 -189
- package/src/components/agent-helper/trigger-time-source-type-select/index.tsx +53 -53
- package/src/components/agent-helper/weekdays-select/index.tsx +230 -230
- package/src/components/agent-scroll-selector.tsx +193 -193
- package/src/components/agent-select.tsx +154 -154
- package/src/components/attachment-part-group.tsx +35 -35
- package/src/components/attachment-part.tsx +296 -296
- package/src/components/attachments-previewer.tsx +272 -272
- package/src/components/base-button.tsx +49 -49
- package/src/components/border-animation.tsx +107 -107
- package/src/components/border-color-animation.tsx +66 -66
- package/src/components/bot-avatar-name.tsx +36 -36
- package/src/components/bot-icon.tsx +23 -23
- package/src/components/bs-entry-select/app-group-folder.tsx +61 -61
- package/src/components/bs-entry-select/bs-entry-select.tsx +296 -296
- package/src/components/bs-entry-select/build-tree.ts +265 -265
- package/src/components/bs-entry-select/entry-item.tsx +45 -45
- package/src/components/bs-entry-select/entry-popover.tsx +99 -99
- package/src/components/bs-entry-select/index.ts +7 -7
- package/src/components/bs-entry-select/other-app-section.tsx +96 -96
- package/src/components/bs-entry-select/scroll-slider.tsx +872 -872
- package/src/components/bs-entry-select/search-input.tsx +4 -4
- package/src/components/bs-entry-select/tree-item-node.tsx +84 -84
- package/src/components/bs-entry-select/types.ts +46 -46
- package/src/components/bs-icons.tsx +1362 -1362
- package/src/components/card-field.tsx +23 -23
- package/src/components/card.tsx +36 -36
- package/src/components/chat-area-header.tsx +65 -65
- package/src/components/check-card.tsx +77 -77
- package/src/components/circle-checker.tsx +66 -66
- package/src/components/collapsible-txt-msg.tsx +75 -75
- package/src/components/collapsible.tsx +9 -9
- package/src/components/confirm-dialog.tsx +139 -139
- package/src/components/date-range-picker.tsx +91 -91
- package/src/components/fake-bot-msg.tsx +51 -51
- package/src/components/field-checker-list-msg.tsx +146 -146
- package/src/components/field-checker.tsx +185 -185
- package/src/components/field-icon.tsx +13 -13
- package/src/components/field-value-checker.tsx +116 -116
- package/src/components/fields-design-info-table.tsx +160 -160
- package/src/components/fields-generating-indicator.tsx +95 -95
- package/src/components/fields-portal.tsx +18 -18
- package/src/components/fields-previewer.tsx +216 -216
- package/src/components/font-icon.tsx +65 -65
- package/src/components/form-info-editor.tsx +263 -263
- package/src/components/formula-tag.tsx +32 -32
- package/src/components/generate-animation.tsx +56 -56
- package/src/components/icon-btn.tsx +43 -43
- package/src/components/icon-card.tsx +67 -67
- package/src/components/icons/calendar-icon.tsx +5 -5
- package/src/components/icons/clear-all-icon.tsx +5 -5
- package/src/components/icons/empty-agent-icon.tsx +93 -93
- package/src/components/icons/empty-table-icon.tsx +104 -104
- package/src/components/icons/grids-icon.tsx +5 -5
- package/src/components/img-part.tsx +27 -27
- package/src/components/legacy-slot.tsx +110 -110
- package/src/components/line-checker.tsx +168 -168
- package/src/components/linear-gradient-border-btn.tsx +48 -48
- package/src/components/linear-gradient-color-bg-animation.tsx +103 -103
- package/src/components/memoized-markdown.tsx +32 -32
- package/src/components/message-content.tsx +21 -21
- package/src/components/number-part.tsx +46 -46
- package/src/components/office-container.tsx +289 -265
- package/src/components/option-item.tsx +27 -27
- package/src/components/output-config-editor.tsx +478 -478
- package/src/components/previewer-header.tsx +270 -270
- package/src/components/primary-confirm-btn.tsx +58 -58
- package/src/components/primary-entry-btn.tsx +48 -48
- package/src/components/radio-card.tsx +63 -63
- package/src/components/scroll-to-bottom-btn.tsx +28 -28
- package/src/components/split-line.tsx +9 -9
- package/src/components/square-checker.tsx +87 -87
- package/src/components/subform-fields-value-checker.tsx +184 -184
- package/src/components/tab-radio-group.tsx +83 -83
- package/src/components/tooltip.tsx +53 -53
- package/src/components/ui/button.tsx +51 -51
- package/src/components/ui/calendar.tsx +57 -57
- package/src/components/ui/dialog.tsx +104 -104
- package/src/components/ui/drawer.tsx +279 -279
- package/src/components/ui/form.tsx +202 -202
- package/src/components/ui/icons.tsx +1267 -1267
- package/src/components/ui/input.tsx +28 -28
- package/src/components/ui/label.tsx +30 -30
- package/src/components/ui/popover.tsx +85 -85
- package/src/components/ui/select.tsx +236 -236
- package/src/components/ui/spinner.tsx +17 -17
- package/src/components/ui/switch.tsx +33 -33
- package/src/components/ui/tabs.tsx +62 -62
- package/src/components/ui/textarea.tsx +28 -28
- package/src/components/ui/tooltip.tsx +53 -53
- package/src/components/user-txt-msg-bubble.tsx +47 -47
- package/src/components/warning-msg.tsx +27 -27
- package/src/const/ui.ts +119 -119
- package/src/css.d.ts +4 -4
- package/src/hooks/use-column-appear.ts +78 -78
- package/src/hooks/use-portal-container.ts +27 -27
- package/src/hooks/use-resizable-width.ts +129 -129
- package/src/hooks/use-select-popover-position.ts +74 -74
- package/src/hooks/use-shadow.ts +127 -127
- package/src/index.ts +226 -226
- package/src/lib/utils.ts +138 -138
- package/src/stories/AbsFullscreenGradientBg.stories.tsx +36 -36
- package/src/stories/AgentCategorySelectMenu.stories.tsx +33 -33
- package/src/stories/AgentEntryCard.stories.tsx +90 -90
- package/src/stories/AgentHelperCard.stories.tsx +105 -105
- package/src/stories/AgentHelperCardList.stories.tsx +120 -120
- package/src/stories/AgentHelperMainLayout.stories.tsx +71 -71
- package/src/stories/AgentScrollSelector.stories.tsx +95 -95
- package/src/stories/AgentSelect.stories.tsx +134 -134
- package/src/stories/AgentTag.stories.tsx +44 -44
- package/src/stories/AppSelect.stories.tsx +250 -250
- package/src/stories/AttachmentPart.stories.tsx +122 -122
- package/src/stories/AttachmentPartGroup.stories.tsx +152 -152
- package/src/stories/AttachmentsPreviewer.stories.tsx +306 -306
- package/src/stories/BaseButton.stories.tsx +33 -33
- package/src/stories/BorderAnimation.stories.tsx +116 -116
- package/src/stories/BorderColorAnimation.stories.tsx +63 -63
- package/src/stories/BotAvatarAndName.stories.ts +24 -24
- package/src/stories/BotIcon.stories.ts +22 -22
- package/src/stories/BsConditionInput.stories.tsx +460 -460
- package/src/stories/BsEntrySelect.stories.tsx +343 -343
- package/src/stories/BsTooltip.stories.tsx +32 -32
- package/src/stories/Card.stories.tsx +28 -28
- package/src/stories/CardField.stories.tsx +87 -87
- package/src/stories/ChatAreaHeader.stories.ts +26 -26
- package/src/stories/CheckCard.stories.tsx +114 -114
- package/src/stories/CircleChecker.stories.tsx +89 -89
- package/src/stories/CollapsibleTextMsg.stories.ts +44 -44
- package/src/stories/ConditionGroup.stories.tsx +216 -216
- package/src/stories/ConditionInput.stories.tsx +502 -502
- package/src/stories/ConditionItem.stories.tsx +163 -163
- package/src/stories/ConditonQuantifierSelect.stories.tsx +54 -54
- package/src/stories/ConditonTriggerDescription.stories.tsx +61 -61
- package/src/stories/ConfirmDialog.stories.tsx +123 -123
- package/src/stories/DataTable.stories.tsx +191 -191
- package/src/stories/DatePicker.stories.tsx +174 -174
- package/src/stories/ExecLogFilter.stories.tsx +145 -145
- package/src/stories/FakeBotMsg.stories.tsx +36 -36
- package/src/stories/FieldEditPreferenceSelect.stories.tsx +161 -161
- package/src/stories/FieldSelect.stories.tsx +228 -228
- package/src/stories/FieldValueInput.stories.tsx +442 -442
- package/src/stories/FlowNodeActionTriggerSelect.stories.tsx +80 -80
- package/src/stories/Form.stories.tsx +302 -302
- package/src/stories/FormActionTriggerSelect.stories.tsx +80 -80
- package/src/stories/FormDivider.stories.tsx +31 -31
- package/src/stories/FormInfoEditor.stories.tsx +173 -173
- package/src/stories/FormSelect.stories.tsx +222 -222
- package/src/stories/FormulaTag.stories.tsx +68 -68
- package/src/stories/GenerateAnimation.stories.ts +20 -20
- package/src/stories/IconBtn.stories.tsx +32 -32
- package/src/stories/IconCard.stories.tsx +35 -35
- package/src/stories/IconLib.tsx +45 -45
- package/src/stories/Icons.stories.ts +22 -22
- package/src/stories/ImgMsgPart.stories.tsx +42 -42
- package/src/stories/Input.stories.tsx +102 -102
- package/src/stories/Label.stories.tsx +66 -66
- package/src/stories/LegacySlot.stories.tsx +56 -56
- package/src/stories/LineChecker.stories.tsx +133 -133
- package/src/stories/LinearGradientBorderBtn.stories.tsx +86 -86
- package/src/stories/LinearGradientColorBgAnimation.stories.tsx +60 -60
- package/src/stories/MemoizedMarkdown.stories.tsx +102 -102
- package/src/stories/MessageContent.stories.tsx +36 -36
- package/src/stories/MonthdaysSelect.stories.tsx +78 -78
- package/src/stories/NumbersMsgPart.stories.tsx +42 -42
- package/src/stories/OfficeContainer.stories.tsx +287 -287
- package/src/stories/OffsetPreferenceSelect.stories.tsx +118 -118
- package/src/stories/OffsetTypeSelect.stories.tsx +75 -75
- package/src/stories/OffsetUnitSelect.stories.tsx +61 -61
- package/src/stories/OptionItem.stories.tsx +77 -77
- package/src/stories/OutputConfigEditor.stories.tsx +96 -96
- package/src/stories/PlaceholderCard.stories.tsx +35 -35
- package/src/stories/PreviewerHeader.stories.tsx +91 -91
- package/src/stories/PrimaryConfirmBtn.stories.tsx +60 -60
- package/src/stories/PrimaryEntryBtn.stories.tsx +74 -74
- package/src/stories/PromptInput.stories.tsx +228 -228
- package/src/stories/RadioCard.stories.tsx +103 -103
- package/src/stories/RelationalOperatorSelect.stories.tsx +61 -61
- package/src/stories/RepeatByTypeSelect.stories.tsx +58 -58
- package/src/stories/RepeatPreferenceSelect.stories.tsx +107 -107
- package/src/stories/RepeatPreferenceTypeSelect.stories.tsx +58 -58
- package/src/stories/ScrollToBottom.stories.tsx +24 -24
- package/src/stories/SearchInput.stories.tsx +50 -50
- package/src/stories/Select.stories.tsx +128 -128
- package/src/stories/SplitLine.stories.tsx +40 -40
- package/src/stories/SquareChecker.stories.tsx +96 -96
- package/src/stories/TabRadioGroup.stories.tsx +84 -84
- package/src/stories/Textarea.stories.tsx +67 -67
- package/src/stories/TriggerSelect.stories.tsx +48 -48
- package/src/stories/TriggerTimePreferenceSelect.stories.tsx +106 -106
- package/src/stories/TriggerTimeSourceTypeSelect.stories.tsx +68 -68
- package/src/stories/UserTextMsgBubble.stories.ts +24 -24
- package/src/stories/WarningMessage.stories.tsx +23 -23
- package/src/stories/WeekdaysSelect.stories.tsx +66 -66
- package/src/stories/assets/demo.css +539 -539
- package/src/stories/assets/demo_index.html +7988 -7988
- package/src/stories/assets/iconfont.css +1377 -1377
- package/src/stories/assets/iconfont.json +2382 -2382
- package/src/stories/assets/iconfont.svg +697 -697
- package/src/stories/collapsible.stories.tsx +47 -47
- package/src/stories/drawer.stories.tsx +196 -196
- package/src/stories/field-checker-list-msg.stories.tsx +95 -95
- package/src/stories/field-checker.stories.tsx +117 -117
- package/src/stories/field-icon.stories.tsx +70 -70
- package/src/stories/field-value-checker.stories.tsx +113 -113
- package/src/stories/fields-design-info-table.stories.tsx +203 -203
- package/src/stories/fields-generating.stories.tsx +41 -41
- package/src/stories/fields-previewer.stories.tsx +77 -77
- package/src/stories/subform-fields-value-checker.stories.tsx +98 -98
- package/src/style.css +226 -226
- package/src/types.ts +8 -8
- package/style.css +3652 -3652
- package/tsconfig.json +13 -13
- package/vite.config.ts +44 -44
package/src/lib/utils.ts
CHANGED
|
@@ -1,138 +1,138 @@
|
|
|
1
|
-
import { clsx, type ClassValue } from 'clsx';
|
|
2
|
-
import { twMerge } from 'tailwind-merge';
|
|
3
|
-
import {
|
|
4
|
-
FieldType,
|
|
5
|
-
IAddress,
|
|
6
|
-
ILocation,
|
|
7
|
-
IField,
|
|
8
|
-
ILinkedData,
|
|
9
|
-
IFormAttachment,
|
|
10
|
-
} from '@baishuyun/types';
|
|
11
|
-
|
|
12
|
-
export function cn(...inputs: ClassValue[]) {
|
|
13
|
-
return twMerge(clsx(inputs));
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
// 复制文本的核心函数(TypeScript 版本)
|
|
17
|
-
export async function copyTextToClipboard(text: string): Promise<boolean> {
|
|
18
|
-
// 校验输入:确保复制的文本是字符串且非空
|
|
19
|
-
if (typeof text !== 'string' || text.trim() === '') {
|
|
20
|
-
console.error('要复制的文本必须是非空字符串');
|
|
21
|
-
return false;
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
try {
|
|
25
|
-
// 方案1:优先使用现代浏览器的 Clipboard API(更安全、无DOM操作)
|
|
26
|
-
if (navigator.clipboard && window.isSecureContext) {
|
|
27
|
-
await navigator.clipboard.writeText(text);
|
|
28
|
-
console.log('文本复制成功(Clipboard API)');
|
|
29
|
-
return true;
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
// 方案2:降级使用 execCommand(兼容旧浏览器,需创建临时DOM元素)
|
|
33
|
-
// 1. 创建临时textarea元素(隐藏,避免影响页面布局)
|
|
34
|
-
const textarea = document.createElement('textarea');
|
|
35
|
-
textarea.value = text;
|
|
36
|
-
textarea.style.position = 'fixed'; // 避免滚动条偏移
|
|
37
|
-
textarea.style.left = '-9999px';
|
|
38
|
-
textarea.style.top = '-9999px';
|
|
39
|
-
document.body.appendChild(textarea);
|
|
40
|
-
|
|
41
|
-
// 2. 选中文本并执行复制
|
|
42
|
-
textarea.focus();
|
|
43
|
-
textarea.select();
|
|
44
|
-
const success = document.execCommand('copy');
|
|
45
|
-
|
|
46
|
-
// 3. 移除临时元素
|
|
47
|
-
document.body.removeChild(textarea);
|
|
48
|
-
|
|
49
|
-
if (success) {
|
|
50
|
-
console.log('文本复制成功(execCommand 降级方案)');
|
|
51
|
-
return true;
|
|
52
|
-
} else {
|
|
53
|
-
throw new Error('execCommand 复制失败');
|
|
54
|
-
}
|
|
55
|
-
} catch (error) {
|
|
56
|
-
// 捕获复制失败的异常(如用户拒绝权限、浏览器不支持等)
|
|
57
|
-
console.error('文本复制失败:', error);
|
|
58
|
-
return false;
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
function isOptionArray(value: unknown): value is Array<{ label: string; value: string }> {
|
|
63
|
-
if (!Array.isArray(value)) {
|
|
64
|
-
return false;
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
return value.every(
|
|
68
|
-
(item) =>
|
|
69
|
-
typeof item === 'object' &&
|
|
70
|
-
item !== null &&
|
|
71
|
-
'label' in item &&
|
|
72
|
-
'value' in item &&
|
|
73
|
-
typeof (item as any).label === 'string' &&
|
|
74
|
-
typeof (item as any).value === 'string'
|
|
75
|
-
);
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
export const toHumanReadable = (value: unknown, type: FieldType): string | unknown => {
|
|
79
|
-
if (type === 'address' && typeof value === 'object') {
|
|
80
|
-
const v = value as IAddress;
|
|
81
|
-
return `${v.province} ${v.city} ${v.district} ${v.detail}`;
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
if (type === 'location' && typeof value === 'object') {
|
|
85
|
-
const v = value as ILocation;
|
|
86
|
-
const lnglatXY = v.lnglatXY || ['', ''];
|
|
87
|
-
return `经度: ${lnglatXY[0] || ''}, 纬度: ${lnglatXY[1] || ''}`;
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
if (
|
|
91
|
-
(type === 'upload' || type === 'image' || type === 'signature') &&
|
|
92
|
-
typeof value !== 'string'
|
|
93
|
-
) {
|
|
94
|
-
const a = value as IFormAttachment;
|
|
95
|
-
return a.name;
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
if (type === 'linkdata') {
|
|
99
|
-
return (value as ILinkedData).label;
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
if (Array.isArray(value)) {
|
|
103
|
-
return value.join(', ');
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
if (isOptionArray(value)) {
|
|
107
|
-
const values = value.map((item) => item.value);
|
|
108
|
-
return values.join(', ');
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
return value;
|
|
112
|
-
};
|
|
113
|
-
|
|
114
|
-
export const isSubformFieldEqual = (f1: IField, f2: IField, widgetArrKey: string = 'value') => {
|
|
115
|
-
// 不是子表单字段,不进行比较,视为相等
|
|
116
|
-
if (f1?.widget?.type !== 'subform' || f2?.widget?.type !== 'subform') {
|
|
117
|
-
return true;
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
const subFields1 = (f1?.widget as any)[widgetArrKey] || [];
|
|
121
|
-
const subFields2 = (f2?.widget as any)[widgetArrKey] || [];
|
|
122
|
-
|
|
123
|
-
// 子表单字段长度不等,视为不同
|
|
124
|
-
if (subFields1.length !== subFields2.length) {
|
|
125
|
-
return false;
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
for (let i = 0; i < subFields1.length; i++) {
|
|
129
|
-
const subField1 = subFields1[i];
|
|
130
|
-
const subField2 = subFields2[i];
|
|
131
|
-
|
|
132
|
-
if (subField1.length !== subField2.length) {
|
|
133
|
-
return false;
|
|
134
|
-
}
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
return true;
|
|
138
|
-
};
|
|
1
|
+
import { clsx, type ClassValue } from 'clsx';
|
|
2
|
+
import { twMerge } from 'tailwind-merge';
|
|
3
|
+
import {
|
|
4
|
+
FieldType,
|
|
5
|
+
IAddress,
|
|
6
|
+
ILocation,
|
|
7
|
+
IField,
|
|
8
|
+
ILinkedData,
|
|
9
|
+
IFormAttachment,
|
|
10
|
+
} from '@baishuyun/types';
|
|
11
|
+
|
|
12
|
+
export function cn(...inputs: ClassValue[]) {
|
|
13
|
+
return twMerge(clsx(inputs));
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
// 复制文本的核心函数(TypeScript 版本)
|
|
17
|
+
export async function copyTextToClipboard(text: string): Promise<boolean> {
|
|
18
|
+
// 校验输入:确保复制的文本是字符串且非空
|
|
19
|
+
if (typeof text !== 'string' || text.trim() === '') {
|
|
20
|
+
console.error('要复制的文本必须是非空字符串');
|
|
21
|
+
return false;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
try {
|
|
25
|
+
// 方案1:优先使用现代浏览器的 Clipboard API(更安全、无DOM操作)
|
|
26
|
+
if (navigator.clipboard && window.isSecureContext) {
|
|
27
|
+
await navigator.clipboard.writeText(text);
|
|
28
|
+
console.log('文本复制成功(Clipboard API)');
|
|
29
|
+
return true;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
// 方案2:降级使用 execCommand(兼容旧浏览器,需创建临时DOM元素)
|
|
33
|
+
// 1. 创建临时textarea元素(隐藏,避免影响页面布局)
|
|
34
|
+
const textarea = document.createElement('textarea');
|
|
35
|
+
textarea.value = text;
|
|
36
|
+
textarea.style.position = 'fixed'; // 避免滚动条偏移
|
|
37
|
+
textarea.style.left = '-9999px';
|
|
38
|
+
textarea.style.top = '-9999px';
|
|
39
|
+
document.body.appendChild(textarea);
|
|
40
|
+
|
|
41
|
+
// 2. 选中文本并执行复制
|
|
42
|
+
textarea.focus();
|
|
43
|
+
textarea.select();
|
|
44
|
+
const success = document.execCommand('copy');
|
|
45
|
+
|
|
46
|
+
// 3. 移除临时元素
|
|
47
|
+
document.body.removeChild(textarea);
|
|
48
|
+
|
|
49
|
+
if (success) {
|
|
50
|
+
console.log('文本复制成功(execCommand 降级方案)');
|
|
51
|
+
return true;
|
|
52
|
+
} else {
|
|
53
|
+
throw new Error('execCommand 复制失败');
|
|
54
|
+
}
|
|
55
|
+
} catch (error) {
|
|
56
|
+
// 捕获复制失败的异常(如用户拒绝权限、浏览器不支持等)
|
|
57
|
+
console.error('文本复制失败:', error);
|
|
58
|
+
return false;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
function isOptionArray(value: unknown): value is Array<{ label: string; value: string }> {
|
|
63
|
+
if (!Array.isArray(value)) {
|
|
64
|
+
return false;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
return value.every(
|
|
68
|
+
(item) =>
|
|
69
|
+
typeof item === 'object' &&
|
|
70
|
+
item !== null &&
|
|
71
|
+
'label' in item &&
|
|
72
|
+
'value' in item &&
|
|
73
|
+
typeof (item as any).label === 'string' &&
|
|
74
|
+
typeof (item as any).value === 'string'
|
|
75
|
+
);
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
export const toHumanReadable = (value: unknown, type: FieldType): string | unknown => {
|
|
79
|
+
if (type === 'address' && typeof value === 'object') {
|
|
80
|
+
const v = value as IAddress;
|
|
81
|
+
return `${v.province} ${v.city} ${v.district} ${v.detail}`;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
if (type === 'location' && typeof value === 'object') {
|
|
85
|
+
const v = value as ILocation;
|
|
86
|
+
const lnglatXY = v.lnglatXY || ['', ''];
|
|
87
|
+
return `经度: ${lnglatXY[0] || ''}, 纬度: ${lnglatXY[1] || ''}`;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
if (
|
|
91
|
+
(type === 'upload' || type === 'image' || type === 'signature') &&
|
|
92
|
+
typeof value !== 'string'
|
|
93
|
+
) {
|
|
94
|
+
const a = value as IFormAttachment;
|
|
95
|
+
return a.name;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
if (type === 'linkdata') {
|
|
99
|
+
return (value as ILinkedData).label;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
if (Array.isArray(value)) {
|
|
103
|
+
return value.join(', ');
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
if (isOptionArray(value)) {
|
|
107
|
+
const values = value.map((item) => item.value);
|
|
108
|
+
return values.join(', ');
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
return value;
|
|
112
|
+
};
|
|
113
|
+
|
|
114
|
+
export const isSubformFieldEqual = (f1: IField, f2: IField, widgetArrKey: string = 'value') => {
|
|
115
|
+
// 不是子表单字段,不进行比较,视为相等
|
|
116
|
+
if (f1?.widget?.type !== 'subform' || f2?.widget?.type !== 'subform') {
|
|
117
|
+
return true;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
const subFields1 = (f1?.widget as any)[widgetArrKey] || [];
|
|
121
|
+
const subFields2 = (f2?.widget as any)[widgetArrKey] || [];
|
|
122
|
+
|
|
123
|
+
// 子表单字段长度不等,视为不同
|
|
124
|
+
if (subFields1.length !== subFields2.length) {
|
|
125
|
+
return false;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
for (let i = 0; i < subFields1.length; i++) {
|
|
129
|
+
const subField1 = subFields1[i];
|
|
130
|
+
const subField2 = subFields2[i];
|
|
131
|
+
|
|
132
|
+
if (subField1.length !== subField2.length) {
|
|
133
|
+
return false;
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
return true;
|
|
138
|
+
};
|
|
@@ -1,36 +1,36 @@
|
|
|
1
|
-
import type { Meta, StoryObj } from '@storybook/react-vite';
|
|
2
|
-
|
|
3
|
-
import { AbsFullscreenGradientBg } from '../components/abs-fullscreen-gradient-bg';
|
|
4
|
-
|
|
5
|
-
const meta = {
|
|
6
|
-
title: 'Example/Chat/AbsFullscreenGradientBg',
|
|
7
|
-
component: AbsFullscreenGradientBg,
|
|
8
|
-
tags: ['autodocs'],
|
|
9
|
-
parameters: {
|
|
10
|
-
layout: 'fullscreen',
|
|
11
|
-
},
|
|
12
|
-
args: {
|
|
13
|
-
zIndex: 1,
|
|
14
|
-
},
|
|
15
|
-
} satisfies Meta<typeof AbsFullscreenGradientBg>;
|
|
16
|
-
|
|
17
|
-
export default meta;
|
|
18
|
-
type Story = StoryObj<typeof meta>;
|
|
19
|
-
|
|
20
|
-
export const Default: Story = {
|
|
21
|
-
args: {
|
|
22
|
-
zIndex: 1,
|
|
23
|
-
},
|
|
24
|
-
};
|
|
25
|
-
|
|
26
|
-
export const WithContent: Story = {
|
|
27
|
-
args: {
|
|
28
|
-
zIndex: 1,
|
|
29
|
-
children: (
|
|
30
|
-
<div style={{ position: 'relative', zIndex: 1, padding: '40px', color: '#333' }}>
|
|
31
|
-
<h1>Content over gradient background</h1>
|
|
32
|
-
<p>This demonstrates how content can be placed over the gradient background.</p>
|
|
33
|
-
</div>
|
|
34
|
-
),
|
|
35
|
-
},
|
|
36
|
-
};
|
|
1
|
+
import type { Meta, StoryObj } from '@storybook/react-vite';
|
|
2
|
+
|
|
3
|
+
import { AbsFullscreenGradientBg } from '../components/abs-fullscreen-gradient-bg';
|
|
4
|
+
|
|
5
|
+
const meta = {
|
|
6
|
+
title: 'Example/Chat/AbsFullscreenGradientBg',
|
|
7
|
+
component: AbsFullscreenGradientBg,
|
|
8
|
+
tags: ['autodocs'],
|
|
9
|
+
parameters: {
|
|
10
|
+
layout: 'fullscreen',
|
|
11
|
+
},
|
|
12
|
+
args: {
|
|
13
|
+
zIndex: 1,
|
|
14
|
+
},
|
|
15
|
+
} satisfies Meta<typeof AbsFullscreenGradientBg>;
|
|
16
|
+
|
|
17
|
+
export default meta;
|
|
18
|
+
type Story = StoryObj<typeof meta>;
|
|
19
|
+
|
|
20
|
+
export const Default: Story = {
|
|
21
|
+
args: {
|
|
22
|
+
zIndex: 1,
|
|
23
|
+
},
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
export const WithContent: Story = {
|
|
27
|
+
args: {
|
|
28
|
+
zIndex: 1,
|
|
29
|
+
children: (
|
|
30
|
+
<div style={{ position: 'relative', zIndex: 1, padding: '40px', color: '#333' }}>
|
|
31
|
+
<h1>Content over gradient background</h1>
|
|
32
|
+
<p>This demonstrates how content can be placed over the gradient background.</p>
|
|
33
|
+
</div>
|
|
34
|
+
),
|
|
35
|
+
},
|
|
36
|
+
};
|
|
@@ -1,33 +1,33 @@
|
|
|
1
|
-
import type { Meta, StoryObj } from '@storybook/react-vite';
|
|
2
|
-
|
|
3
|
-
import { AgentCategorySelectMenu } from '../components/agent-helper/agent-category-select-menu';
|
|
4
|
-
|
|
5
|
-
const meta = {
|
|
6
|
-
title: 'Agent Helper/AgentCategorySelectMenu',
|
|
7
|
-
component: AgentCategorySelectMenu,
|
|
8
|
-
tags: ['autodocs'],
|
|
9
|
-
parameters: {
|
|
10
|
-
layout: 'centered',
|
|
11
|
-
},
|
|
12
|
-
args: {
|
|
13
|
-
value: 'all-agent',
|
|
14
|
-
onChange: () => {},
|
|
15
|
-
},
|
|
16
|
-
} satisfies Meta<typeof AgentCategorySelectMenu>;
|
|
17
|
-
|
|
18
|
-
export default meta;
|
|
19
|
-
type Story = StoryObj<typeof meta>;
|
|
20
|
-
|
|
21
|
-
export const Default: Story = {};
|
|
22
|
-
|
|
23
|
-
export const SystemSelected: Story = {
|
|
24
|
-
args: {
|
|
25
|
-
value: 'system-agent',
|
|
26
|
-
},
|
|
27
|
-
};
|
|
28
|
-
|
|
29
|
-
export const CustomSelected: Story = {
|
|
30
|
-
args: {
|
|
31
|
-
value: 'custom-agent',
|
|
32
|
-
},
|
|
33
|
-
};
|
|
1
|
+
import type { Meta, StoryObj } from '@storybook/react-vite';
|
|
2
|
+
|
|
3
|
+
import { AgentCategorySelectMenu } from '../components/agent-helper/agent-category-select-menu';
|
|
4
|
+
|
|
5
|
+
const meta = {
|
|
6
|
+
title: 'Agent Helper/AgentCategorySelectMenu',
|
|
7
|
+
component: AgentCategorySelectMenu,
|
|
8
|
+
tags: ['autodocs'],
|
|
9
|
+
parameters: {
|
|
10
|
+
layout: 'centered',
|
|
11
|
+
},
|
|
12
|
+
args: {
|
|
13
|
+
value: 'all-agent',
|
|
14
|
+
onChange: () => {},
|
|
15
|
+
},
|
|
16
|
+
} satisfies Meta<typeof AgentCategorySelectMenu>;
|
|
17
|
+
|
|
18
|
+
export default meta;
|
|
19
|
+
type Story = StoryObj<typeof meta>;
|
|
20
|
+
|
|
21
|
+
export const Default: Story = {};
|
|
22
|
+
|
|
23
|
+
export const SystemSelected: Story = {
|
|
24
|
+
args: {
|
|
25
|
+
value: 'system-agent',
|
|
26
|
+
},
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
export const CustomSelected: Story = {
|
|
30
|
+
args: {
|
|
31
|
+
value: 'custom-agent',
|
|
32
|
+
},
|
|
33
|
+
};
|
|
@@ -1,90 +1,90 @@
|
|
|
1
|
-
import type { Meta, StoryObj } from '@storybook/react-vite';
|
|
2
|
-
|
|
3
|
-
import { AgentEntryCard } from '../components/agent-helper/agent-entry-card';
|
|
4
|
-
import type { IAgentInfo } from '@baishuyun/types';
|
|
5
|
-
|
|
6
|
-
const sampleAgent: IAgentInfo = {
|
|
7
|
-
id: 'agent-1',
|
|
8
|
-
name: 'AI翻译',
|
|
9
|
-
description:
|
|
10
|
-
'懂语境,不只是翻译字面——支持多语言互译,精准把握专业术语与日常口语。无论是工作中的外文邮件、旅行中的路标菜单,还是追剧时的生肉,交给它,准确又自然。内容最多两行,超出省略',
|
|
11
|
-
icon: 'https://picsum.photos/80/80',
|
|
12
|
-
version: 'V56',
|
|
13
|
-
lastUpdated: '2026-05-21 13:12:12',
|
|
14
|
-
installCount: 8000,
|
|
15
|
-
};
|
|
16
|
-
|
|
17
|
-
const meta = {
|
|
18
|
-
title: 'Agent Helper/AgentEntryCard',
|
|
19
|
-
component: AgentEntryCard,
|
|
20
|
-
tags: ['autodocs'],
|
|
21
|
-
parameters: {
|
|
22
|
-
layout: 'centered',
|
|
23
|
-
},
|
|
24
|
-
args: {
|
|
25
|
-
agent: sampleAgent,
|
|
26
|
-
onSelect: () => {},
|
|
27
|
-
onLogClick: () => {},
|
|
28
|
-
},
|
|
29
|
-
} satisfies Meta<typeof AgentEntryCard>;
|
|
30
|
-
|
|
31
|
-
export default meta;
|
|
32
|
-
type Story = StoryObj<typeof meta>;
|
|
33
|
-
|
|
34
|
-
export const Default: Story = {};
|
|
35
|
-
|
|
36
|
-
export const NoVersion: Story = {
|
|
37
|
-
args: {
|
|
38
|
-
agent: {
|
|
39
|
-
...sampleAgent,
|
|
40
|
-
version: undefined,
|
|
41
|
-
},
|
|
42
|
-
},
|
|
43
|
-
};
|
|
44
|
-
|
|
45
|
-
export const NoLastUpdated: Story = {
|
|
46
|
-
args: {
|
|
47
|
-
agent: {
|
|
48
|
-
...sampleAgent,
|
|
49
|
-
lastUpdated: undefined,
|
|
50
|
-
},
|
|
51
|
-
},
|
|
52
|
-
};
|
|
53
|
-
|
|
54
|
-
export const NoInstallCount: Story = {
|
|
55
|
-
args: {
|
|
56
|
-
agent: {
|
|
57
|
-
...sampleAgent,
|
|
58
|
-
installCount: undefined,
|
|
59
|
-
},
|
|
60
|
-
},
|
|
61
|
-
};
|
|
62
|
-
|
|
63
|
-
export const Minimal: Story = {
|
|
64
|
-
args: {
|
|
65
|
-
agent: {
|
|
66
|
-
id: 'agent-minimal',
|
|
67
|
-
name: 'AI翻译',
|
|
68
|
-
icon: 'https://picsum.photos/80/80',
|
|
69
|
-
},
|
|
70
|
-
},
|
|
71
|
-
};
|
|
72
|
-
|
|
73
|
-
export const LongDescription: Story = {
|
|
74
|
-
args: {
|
|
75
|
-
agent: {
|
|
76
|
-
...sampleAgent,
|
|
77
|
-
description:
|
|
78
|
-
'这是一段非常长的描述文字,用于测试两行省略的效果。当描述内容超过两行时,需要自动省略并在末尾显示省略号,确保卡片整体布局不被超长文本所破坏。这段文字应该足够长以达到测试效果。',
|
|
79
|
-
},
|
|
80
|
-
},
|
|
81
|
-
};
|
|
82
|
-
|
|
83
|
-
export const NoDescription: Story = {
|
|
84
|
-
args: {
|
|
85
|
-
agent: {
|
|
86
|
-
...sampleAgent,
|
|
87
|
-
description: undefined,
|
|
88
|
-
},
|
|
89
|
-
},
|
|
90
|
-
};
|
|
1
|
+
import type { Meta, StoryObj } from '@storybook/react-vite';
|
|
2
|
+
|
|
3
|
+
import { AgentEntryCard } from '../components/agent-helper/agent-entry-card';
|
|
4
|
+
import type { IAgentInfo } from '@baishuyun/types';
|
|
5
|
+
|
|
6
|
+
const sampleAgent: IAgentInfo = {
|
|
7
|
+
id: 'agent-1',
|
|
8
|
+
name: 'AI翻译',
|
|
9
|
+
description:
|
|
10
|
+
'懂语境,不只是翻译字面——支持多语言互译,精准把握专业术语与日常口语。无论是工作中的外文邮件、旅行中的路标菜单,还是追剧时的生肉,交给它,准确又自然。内容最多两行,超出省略',
|
|
11
|
+
icon: 'https://picsum.photos/80/80',
|
|
12
|
+
version: 'V56',
|
|
13
|
+
lastUpdated: '2026-05-21 13:12:12',
|
|
14
|
+
installCount: 8000,
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
const meta = {
|
|
18
|
+
title: 'Agent Helper/AgentEntryCard',
|
|
19
|
+
component: AgentEntryCard,
|
|
20
|
+
tags: ['autodocs'],
|
|
21
|
+
parameters: {
|
|
22
|
+
layout: 'centered',
|
|
23
|
+
},
|
|
24
|
+
args: {
|
|
25
|
+
agent: sampleAgent,
|
|
26
|
+
onSelect: () => {},
|
|
27
|
+
onLogClick: () => {},
|
|
28
|
+
},
|
|
29
|
+
} satisfies Meta<typeof AgentEntryCard>;
|
|
30
|
+
|
|
31
|
+
export default meta;
|
|
32
|
+
type Story = StoryObj<typeof meta>;
|
|
33
|
+
|
|
34
|
+
export const Default: Story = {};
|
|
35
|
+
|
|
36
|
+
export const NoVersion: Story = {
|
|
37
|
+
args: {
|
|
38
|
+
agent: {
|
|
39
|
+
...sampleAgent,
|
|
40
|
+
version: undefined,
|
|
41
|
+
},
|
|
42
|
+
},
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
export const NoLastUpdated: Story = {
|
|
46
|
+
args: {
|
|
47
|
+
agent: {
|
|
48
|
+
...sampleAgent,
|
|
49
|
+
lastUpdated: undefined,
|
|
50
|
+
},
|
|
51
|
+
},
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
export const NoInstallCount: Story = {
|
|
55
|
+
args: {
|
|
56
|
+
agent: {
|
|
57
|
+
...sampleAgent,
|
|
58
|
+
installCount: undefined,
|
|
59
|
+
},
|
|
60
|
+
},
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
export const Minimal: Story = {
|
|
64
|
+
args: {
|
|
65
|
+
agent: {
|
|
66
|
+
id: 'agent-minimal',
|
|
67
|
+
name: 'AI翻译',
|
|
68
|
+
icon: 'https://picsum.photos/80/80',
|
|
69
|
+
},
|
|
70
|
+
},
|
|
71
|
+
};
|
|
72
|
+
|
|
73
|
+
export const LongDescription: Story = {
|
|
74
|
+
args: {
|
|
75
|
+
agent: {
|
|
76
|
+
...sampleAgent,
|
|
77
|
+
description:
|
|
78
|
+
'这是一段非常长的描述文字,用于测试两行省略的效果。当描述内容超过两行时,需要自动省略并在末尾显示省略号,确保卡片整体布局不被超长文本所破坏。这段文字应该足够长以达到测试效果。',
|
|
79
|
+
},
|
|
80
|
+
},
|
|
81
|
+
};
|
|
82
|
+
|
|
83
|
+
export const NoDescription: Story = {
|
|
84
|
+
args: {
|
|
85
|
+
agent: {
|
|
86
|
+
...sampleAgent,
|
|
87
|
+
description: undefined,
|
|
88
|
+
},
|
|
89
|
+
},
|
|
90
|
+
};
|