@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
|
@@ -1,265 +1,265 @@
|
|
|
1
|
-
import type { IAppDetail, IEntryAliasItem, IEntryDetail, IEntryRef } from '@baishuyun/types';
|
|
2
|
-
import type { EntryTreeItem, BsEntrySelectChangeResult } from './types';
|
|
3
|
-
import { FLOW_CENTER_GROUP_ID, FLOW_CENTER_ENTRIES } from './types';
|
|
4
|
-
import { FormSelectItem } from '../agent-helper/form-select';
|
|
5
|
-
|
|
6
|
-
export const DEPTH_PADDING: Record<number, string> = {
|
|
7
|
-
0: 'pl-[10px]',
|
|
8
|
-
1: 'pl-[32px]',
|
|
9
|
-
2: 'pl-[32px]',
|
|
10
|
-
3: 'pl-[54px]',
|
|
11
|
-
4: 'pl-[78px]',
|
|
12
|
-
5: 'pl-[102px]',
|
|
13
|
-
};
|
|
14
|
-
|
|
15
|
-
export function getDepthPadding(depth: number): string {
|
|
16
|
-
return DEPTH_PADDING[Math.min(depth, 5)] ?? DEPTH_PADDING[5];
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
export function getEntryIconClass(entry: IEntryDetail): string {
|
|
20
|
-
const isNew = entry.icon >= 25;
|
|
21
|
-
const newStr = isNew ? '-new' : '';
|
|
22
|
-
return `node-icon icon-bsy-form${newStr} icon${newStr}-bsy-form-${entry.icon}`;
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
export function buildEntryTreeFromAliasMap(
|
|
26
|
-
appDetail: IAppDetail,
|
|
27
|
-
searchQuery: string
|
|
28
|
-
): EntryTreeItem[] {
|
|
29
|
-
const { entryIdAliasMap: originMap, entryMap, entryList } = appDetail;
|
|
30
|
-
|
|
31
|
-
const formIdWhiteList = new Set(flattenEntryList(entryList).map((e) => e.id));
|
|
32
|
-
|
|
33
|
-
const entryIdAliasMap: Record<string, IEntryAliasItem> = {
|
|
34
|
-
// ...originMap,
|
|
35
|
-
};
|
|
36
|
-
|
|
37
|
-
for (const [_, v] of Object.entries(originMap ?? {})) {
|
|
38
|
-
if (formIdWhiteList.has(v.formId)) {
|
|
39
|
-
entryIdAliasMap[v.formId as string] = v;
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
const aliasKeys = Object.keys(entryIdAliasMap);
|
|
44
|
-
if (aliasKeys.length === 0) return [];
|
|
45
|
-
|
|
46
|
-
const childrenByParent = new Map<string, string[]>();
|
|
47
|
-
for (const id of aliasKeys) {
|
|
48
|
-
const aliasItem = entryIdAliasMap[id];
|
|
49
|
-
const parentKey = aliasItem.parent || '0';
|
|
50
|
-
if (!childrenByParent.has(parentKey)) {
|
|
51
|
-
childrenByParent.set(parentKey, []);
|
|
52
|
-
}
|
|
53
|
-
childrenByParent.get(parentKey)!.push(aliasItem.formId);
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
// Root parents: any parent value that is not itself a key in entryIdAliasMap.
|
|
57
|
-
// Also include the sentinel '0' for entries with empty/falsy parent.
|
|
58
|
-
const allParentValues = new Set(childrenByParent.keys());
|
|
59
|
-
const rootParents = Array.from(allParentValues).filter((p) => p === '0' || !entryIdAliasMap[p]);
|
|
60
|
-
|
|
61
|
-
const lowerQuery = searchQuery.toLowerCase().trim();
|
|
62
|
-
|
|
63
|
-
function buildRecursive(parentId: string, depth: number): EntryTreeItem[] {
|
|
64
|
-
const childIds = childrenByParent.get(parentId) || [];
|
|
65
|
-
const nodes: EntryTreeItem[] = [];
|
|
66
|
-
|
|
67
|
-
for (const id of childIds) {
|
|
68
|
-
const aliasItem = entryIdAliasMap[id];
|
|
69
|
-
const entryDetail = entryMap[id] || null;
|
|
70
|
-
const name = entryDetail?.name || id;
|
|
71
|
-
const icon = entryDetail?.icon || 0;
|
|
72
|
-
const isGroup = aliasItem.type === 'group';
|
|
73
|
-
|
|
74
|
-
const children = buildRecursive(id, depth + 1);
|
|
75
|
-
const selfMatch = !lowerQuery || name?.toLowerCase().includes(lowerQuery);
|
|
76
|
-
|
|
77
|
-
if (isGroup) {
|
|
78
|
-
if (selfMatch || children.length > 0) {
|
|
79
|
-
nodes.push({
|
|
80
|
-
id,
|
|
81
|
-
name,
|
|
82
|
-
icon,
|
|
83
|
-
type: 'group',
|
|
84
|
-
children,
|
|
85
|
-
depth,
|
|
86
|
-
isSelectable: false,
|
|
87
|
-
entry: entryDetail,
|
|
88
|
-
});
|
|
89
|
-
}
|
|
90
|
-
} else {
|
|
91
|
-
if (selfMatch) {
|
|
92
|
-
nodes.push({
|
|
93
|
-
id,
|
|
94
|
-
name,
|
|
95
|
-
icon,
|
|
96
|
-
type: aliasItem.type,
|
|
97
|
-
children: [],
|
|
98
|
-
depth,
|
|
99
|
-
isSelectable: true,
|
|
100
|
-
entry: entryDetail,
|
|
101
|
-
});
|
|
102
|
-
}
|
|
103
|
-
}
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
return nodes;
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
// Build from each root parent, all at depth 0
|
|
110
|
-
const result: EntryTreeItem[] = [];
|
|
111
|
-
for (const rootId of rootParents) {
|
|
112
|
-
result.push(...buildRecursive(rootId, 0));
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
return result;
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
const flattenFormEntries = (entries: IEntryDetail[]): FormSelectItem[] => {
|
|
119
|
-
const result: FormSelectItem[] = [];
|
|
120
|
-
for (const entry of entries) {
|
|
121
|
-
result.push({
|
|
122
|
-
id: entry.entryId,
|
|
123
|
-
name: entry?.name || entry.entryId,
|
|
124
|
-
icon: entry?.icon || 0,
|
|
125
|
-
type: entry.type,
|
|
126
|
-
parent: entry.parent || undefined,
|
|
127
|
-
itemType: entry.type === 'group' ? 'group' : 'form',
|
|
128
|
-
});
|
|
129
|
-
if (entry.child?.length) {
|
|
130
|
-
for (const child of flattenFormEntries(entry.child)) {
|
|
131
|
-
result.push({ ...child, parent: entry.entryId });
|
|
132
|
-
}
|
|
133
|
-
}
|
|
134
|
-
}
|
|
135
|
-
return result;
|
|
136
|
-
};
|
|
137
|
-
|
|
138
|
-
interface IEntryItem {
|
|
139
|
-
id: string;
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
const flattenEntryList = (entryList: IEntryRef[]): Array<IEntryItem> => {
|
|
143
|
-
const items: IEntryItem[] = [];
|
|
144
|
-
|
|
145
|
-
for (const entry of entryList) {
|
|
146
|
-
items.push({
|
|
147
|
-
id: entry.id,
|
|
148
|
-
});
|
|
149
|
-
|
|
150
|
-
if (entry.child?.length) {
|
|
151
|
-
for (const c of flattenEntryList(entry.child)) {
|
|
152
|
-
items.push({
|
|
153
|
-
id: c.id,
|
|
154
|
-
});
|
|
155
|
-
}
|
|
156
|
-
}
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
return items;
|
|
160
|
-
};
|
|
161
|
-
|
|
162
|
-
export const getEntries = (appDetail: IAppDetail): FormSelectItem[] => {
|
|
163
|
-
const { entryIdAliasMap, entryMap, entryList } = appDetail;
|
|
164
|
-
const whiteList = new Set(flattenEntryList(entryList).map((e) => e.id));
|
|
165
|
-
const aliasKeys = Object.keys(entryIdAliasMap).filter((k) => whiteList.has(k));
|
|
166
|
-
|
|
167
|
-
if (aliasKeys.length === 0) {
|
|
168
|
-
return [];
|
|
169
|
-
}
|
|
170
|
-
|
|
171
|
-
const entries = aliasKeys
|
|
172
|
-
.map((id) => {
|
|
173
|
-
return entryMap[id] as IEntryDetail;
|
|
174
|
-
})
|
|
175
|
-
.filter(Boolean);
|
|
176
|
-
|
|
177
|
-
return flattenFormEntries(entries);
|
|
178
|
-
};
|
|
179
|
-
|
|
180
|
-
export function filterTreeBySearch(nodes: EntryTreeItem[], searchQuery: string): EntryTreeItem[] {
|
|
181
|
-
const lowerQuery = searchQuery.toLowerCase().trim();
|
|
182
|
-
if (!lowerQuery) return nodes;
|
|
183
|
-
|
|
184
|
-
const result: EntryTreeItem[] = [];
|
|
185
|
-
for (const node of nodes) {
|
|
186
|
-
const nameMatch = node?.name.toLowerCase().includes(lowerQuery);
|
|
187
|
-
const filteredChildren = filterTreeBySearch(node.children, searchQuery);
|
|
188
|
-
|
|
189
|
-
if (!node.isSelectable) {
|
|
190
|
-
if (nameMatch || filteredChildren.length > 0) {
|
|
191
|
-
result.push({ ...node, children: filteredChildren });
|
|
192
|
-
}
|
|
193
|
-
} else {
|
|
194
|
-
if (nameMatch) {
|
|
195
|
-
result.push(node);
|
|
196
|
-
}
|
|
197
|
-
}
|
|
198
|
-
}
|
|
199
|
-
return result;
|
|
200
|
-
}
|
|
201
|
-
|
|
202
|
-
export function findSelected(
|
|
203
|
-
appDetails: Record<string, IAppDetail>,
|
|
204
|
-
entryId: string,
|
|
205
|
-
currentAppId?: string
|
|
206
|
-
): BsEntrySelectChangeResult | null {
|
|
207
|
-
for (const [appId, detail] of Object.entries(appDetails)) {
|
|
208
|
-
if (detail.entryMap[entryId]) {
|
|
209
|
-
return {
|
|
210
|
-
entry: detail.entryMap[entryId],
|
|
211
|
-
appId,
|
|
212
|
-
section: appId === currentAppId ? 'current' : 'other',
|
|
213
|
-
};
|
|
214
|
-
}
|
|
215
|
-
}
|
|
216
|
-
return null;
|
|
217
|
-
}
|
|
218
|
-
|
|
219
|
-
/** Create a virtual IEntryDetail for a flow center entry */
|
|
220
|
-
export function createFlowEntryDetail(entryId: string, name: string): IEntryDetail {
|
|
221
|
-
return {
|
|
222
|
-
_id: `${FLOW_CENTER_GROUP_ID}_${entryId}`,
|
|
223
|
-
entryId,
|
|
224
|
-
hasCoop: false,
|
|
225
|
-
hasFlow: true,
|
|
226
|
-
icon: 0,
|
|
227
|
-
isEvent: false,
|
|
228
|
-
isFavorite: false,
|
|
229
|
-
name,
|
|
230
|
-
parent: FLOW_CENTER_GROUP_ID,
|
|
231
|
-
seq: 0,
|
|
232
|
-
type: 'flow',
|
|
233
|
-
};
|
|
234
|
-
}
|
|
235
|
-
|
|
236
|
-
/** Build the synthetic "流程中心" group tree with 4 flow entries */
|
|
237
|
-
export function buildFlowCenterTree(): EntryTreeItem[] {
|
|
238
|
-
const children: EntryTreeItem[] = FLOW_CENTER_ENTRIES.map((item) => ({
|
|
239
|
-
// Use entryId directly as the node id so selected-state matching
|
|
240
|
-
// (selectedEntryId === node.id) works like real entries
|
|
241
|
-
id: item.entryId,
|
|
242
|
-
name: item.name,
|
|
243
|
-
icon: 0,
|
|
244
|
-
iconClass: `sdk-icon ${item.iconClass} text-[#0265ff]`,
|
|
245
|
-
type: 'flow',
|
|
246
|
-
children: [],
|
|
247
|
-
// depth 0: the group popover renders these as a flat list — no tree indent
|
|
248
|
-
depth: 0,
|
|
249
|
-
isSelectable: true,
|
|
250
|
-
entry: createFlowEntryDetail(item.entryId, item.name),
|
|
251
|
-
}));
|
|
252
|
-
|
|
253
|
-
const groupNode: EntryTreeItem = {
|
|
254
|
-
id: FLOW_CENTER_GROUP_ID,
|
|
255
|
-
name: '流程中心',
|
|
256
|
-
icon: 0,
|
|
257
|
-
type: 'group',
|
|
258
|
-
depth: 0,
|
|
259
|
-
isSelectable: false,
|
|
260
|
-
entry: null,
|
|
261
|
-
children,
|
|
262
|
-
};
|
|
263
|
-
|
|
264
|
-
return [groupNode];
|
|
265
|
-
}
|
|
1
|
+
import type { IAppDetail, IEntryAliasItem, IEntryDetail, IEntryRef } from '@baishuyun/types';
|
|
2
|
+
import type { EntryTreeItem, BsEntrySelectChangeResult } from './types';
|
|
3
|
+
import { FLOW_CENTER_GROUP_ID, FLOW_CENTER_ENTRIES } from './types';
|
|
4
|
+
import { FormSelectItem } from '../agent-helper/form-select';
|
|
5
|
+
|
|
6
|
+
export const DEPTH_PADDING: Record<number, string> = {
|
|
7
|
+
0: 'pl-[10px]',
|
|
8
|
+
1: 'pl-[32px]',
|
|
9
|
+
2: 'pl-[32px]',
|
|
10
|
+
3: 'pl-[54px]',
|
|
11
|
+
4: 'pl-[78px]',
|
|
12
|
+
5: 'pl-[102px]',
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
export function getDepthPadding(depth: number): string {
|
|
16
|
+
return DEPTH_PADDING[Math.min(depth, 5)] ?? DEPTH_PADDING[5];
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export function getEntryIconClass(entry: IEntryDetail): string {
|
|
20
|
+
const isNew = entry.icon >= 25;
|
|
21
|
+
const newStr = isNew ? '-new' : '';
|
|
22
|
+
return `node-icon icon-bsy-form${newStr} icon${newStr}-bsy-form-${entry.icon}`;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export function buildEntryTreeFromAliasMap(
|
|
26
|
+
appDetail: IAppDetail,
|
|
27
|
+
searchQuery: string
|
|
28
|
+
): EntryTreeItem[] {
|
|
29
|
+
const { entryIdAliasMap: originMap, entryMap, entryList } = appDetail;
|
|
30
|
+
|
|
31
|
+
const formIdWhiteList = new Set(flattenEntryList(entryList).map((e) => e.id));
|
|
32
|
+
|
|
33
|
+
const entryIdAliasMap: Record<string, IEntryAliasItem> = {
|
|
34
|
+
// ...originMap,
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
for (const [_, v] of Object.entries(originMap ?? {})) {
|
|
38
|
+
if (formIdWhiteList.has(v.formId)) {
|
|
39
|
+
entryIdAliasMap[v.formId as string] = v;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
const aliasKeys = Object.keys(entryIdAliasMap);
|
|
44
|
+
if (aliasKeys.length === 0) return [];
|
|
45
|
+
|
|
46
|
+
const childrenByParent = new Map<string, string[]>();
|
|
47
|
+
for (const id of aliasKeys) {
|
|
48
|
+
const aliasItem = entryIdAliasMap[id];
|
|
49
|
+
const parentKey = aliasItem.parent || '0';
|
|
50
|
+
if (!childrenByParent.has(parentKey)) {
|
|
51
|
+
childrenByParent.set(parentKey, []);
|
|
52
|
+
}
|
|
53
|
+
childrenByParent.get(parentKey)!.push(aliasItem.formId);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
// Root parents: any parent value that is not itself a key in entryIdAliasMap.
|
|
57
|
+
// Also include the sentinel '0' for entries with empty/falsy parent.
|
|
58
|
+
const allParentValues = new Set(childrenByParent.keys());
|
|
59
|
+
const rootParents = Array.from(allParentValues).filter((p) => p === '0' || !entryIdAliasMap[p]);
|
|
60
|
+
|
|
61
|
+
const lowerQuery = searchQuery.toLowerCase().trim();
|
|
62
|
+
|
|
63
|
+
function buildRecursive(parentId: string, depth: number): EntryTreeItem[] {
|
|
64
|
+
const childIds = childrenByParent.get(parentId) || [];
|
|
65
|
+
const nodes: EntryTreeItem[] = [];
|
|
66
|
+
|
|
67
|
+
for (const id of childIds) {
|
|
68
|
+
const aliasItem = entryIdAliasMap[id];
|
|
69
|
+
const entryDetail = entryMap[id] || null;
|
|
70
|
+
const name = entryDetail?.name || id;
|
|
71
|
+
const icon = entryDetail?.icon || 0;
|
|
72
|
+
const isGroup = aliasItem.type === 'group';
|
|
73
|
+
|
|
74
|
+
const children = buildRecursive(id, depth + 1);
|
|
75
|
+
const selfMatch = !lowerQuery || name?.toLowerCase().includes(lowerQuery);
|
|
76
|
+
|
|
77
|
+
if (isGroup) {
|
|
78
|
+
if (selfMatch || children.length > 0) {
|
|
79
|
+
nodes.push({
|
|
80
|
+
id,
|
|
81
|
+
name,
|
|
82
|
+
icon,
|
|
83
|
+
type: 'group',
|
|
84
|
+
children,
|
|
85
|
+
depth,
|
|
86
|
+
isSelectable: false,
|
|
87
|
+
entry: entryDetail,
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
} else {
|
|
91
|
+
if (selfMatch) {
|
|
92
|
+
nodes.push({
|
|
93
|
+
id,
|
|
94
|
+
name,
|
|
95
|
+
icon,
|
|
96
|
+
type: aliasItem.type,
|
|
97
|
+
children: [],
|
|
98
|
+
depth,
|
|
99
|
+
isSelectable: true,
|
|
100
|
+
entry: entryDetail,
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
return nodes;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
// Build from each root parent, all at depth 0
|
|
110
|
+
const result: EntryTreeItem[] = [];
|
|
111
|
+
for (const rootId of rootParents) {
|
|
112
|
+
result.push(...buildRecursive(rootId, 0));
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
return result;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
const flattenFormEntries = (entries: IEntryDetail[]): FormSelectItem[] => {
|
|
119
|
+
const result: FormSelectItem[] = [];
|
|
120
|
+
for (const entry of entries) {
|
|
121
|
+
result.push({
|
|
122
|
+
id: entry.entryId,
|
|
123
|
+
name: entry?.name || entry.entryId,
|
|
124
|
+
icon: entry?.icon || 0,
|
|
125
|
+
type: entry.type,
|
|
126
|
+
parent: entry.parent || undefined,
|
|
127
|
+
itemType: entry.type === 'group' ? 'group' : 'form',
|
|
128
|
+
});
|
|
129
|
+
if (entry.child?.length) {
|
|
130
|
+
for (const child of flattenFormEntries(entry.child)) {
|
|
131
|
+
result.push({ ...child, parent: entry.entryId });
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
return result;
|
|
136
|
+
};
|
|
137
|
+
|
|
138
|
+
interface IEntryItem {
|
|
139
|
+
id: string;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
const flattenEntryList = (entryList: IEntryRef[]): Array<IEntryItem> => {
|
|
143
|
+
const items: IEntryItem[] = [];
|
|
144
|
+
|
|
145
|
+
for (const entry of entryList) {
|
|
146
|
+
items.push({
|
|
147
|
+
id: entry.id,
|
|
148
|
+
});
|
|
149
|
+
|
|
150
|
+
if (entry.child?.length) {
|
|
151
|
+
for (const c of flattenEntryList(entry.child)) {
|
|
152
|
+
items.push({
|
|
153
|
+
id: c.id,
|
|
154
|
+
});
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
return items;
|
|
160
|
+
};
|
|
161
|
+
|
|
162
|
+
export const getEntries = (appDetail: IAppDetail): FormSelectItem[] => {
|
|
163
|
+
const { entryIdAliasMap, entryMap, entryList } = appDetail;
|
|
164
|
+
const whiteList = new Set(flattenEntryList(entryList).map((e) => e.id));
|
|
165
|
+
const aliasKeys = Object.keys(entryIdAliasMap).filter((k) => whiteList.has(k));
|
|
166
|
+
|
|
167
|
+
if (aliasKeys.length === 0) {
|
|
168
|
+
return [];
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
const entries = aliasKeys
|
|
172
|
+
.map((id) => {
|
|
173
|
+
return entryMap[id] as IEntryDetail;
|
|
174
|
+
})
|
|
175
|
+
.filter(Boolean);
|
|
176
|
+
|
|
177
|
+
return flattenFormEntries(entries);
|
|
178
|
+
};
|
|
179
|
+
|
|
180
|
+
export function filterTreeBySearch(nodes: EntryTreeItem[], searchQuery: string): EntryTreeItem[] {
|
|
181
|
+
const lowerQuery = searchQuery.toLowerCase().trim();
|
|
182
|
+
if (!lowerQuery) return nodes;
|
|
183
|
+
|
|
184
|
+
const result: EntryTreeItem[] = [];
|
|
185
|
+
for (const node of nodes) {
|
|
186
|
+
const nameMatch = node?.name.toLowerCase().includes(lowerQuery);
|
|
187
|
+
const filteredChildren = filterTreeBySearch(node.children, searchQuery);
|
|
188
|
+
|
|
189
|
+
if (!node.isSelectable) {
|
|
190
|
+
if (nameMatch || filteredChildren.length > 0) {
|
|
191
|
+
result.push({ ...node, children: filteredChildren });
|
|
192
|
+
}
|
|
193
|
+
} else {
|
|
194
|
+
if (nameMatch) {
|
|
195
|
+
result.push(node);
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
return result;
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
export function findSelected(
|
|
203
|
+
appDetails: Record<string, IAppDetail>,
|
|
204
|
+
entryId: string,
|
|
205
|
+
currentAppId?: string
|
|
206
|
+
): BsEntrySelectChangeResult | null {
|
|
207
|
+
for (const [appId, detail] of Object.entries(appDetails)) {
|
|
208
|
+
if (detail.entryMap[entryId]) {
|
|
209
|
+
return {
|
|
210
|
+
entry: detail.entryMap[entryId],
|
|
211
|
+
appId,
|
|
212
|
+
section: appId === currentAppId ? 'current' : 'other',
|
|
213
|
+
};
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
return null;
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
/** Create a virtual IEntryDetail for a flow center entry */
|
|
220
|
+
export function createFlowEntryDetail(entryId: string, name: string): IEntryDetail {
|
|
221
|
+
return {
|
|
222
|
+
_id: `${FLOW_CENTER_GROUP_ID}_${entryId}`,
|
|
223
|
+
entryId,
|
|
224
|
+
hasCoop: false,
|
|
225
|
+
hasFlow: true,
|
|
226
|
+
icon: 0,
|
|
227
|
+
isEvent: false,
|
|
228
|
+
isFavorite: false,
|
|
229
|
+
name,
|
|
230
|
+
parent: FLOW_CENTER_GROUP_ID,
|
|
231
|
+
seq: 0,
|
|
232
|
+
type: 'flow',
|
|
233
|
+
};
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
/** Build the synthetic "流程中心" group tree with 4 flow entries */
|
|
237
|
+
export function buildFlowCenterTree(): EntryTreeItem[] {
|
|
238
|
+
const children: EntryTreeItem[] = FLOW_CENTER_ENTRIES.map((item) => ({
|
|
239
|
+
// Use entryId directly as the node id so selected-state matching
|
|
240
|
+
// (selectedEntryId === node.id) works like real entries
|
|
241
|
+
id: item.entryId,
|
|
242
|
+
name: item.name,
|
|
243
|
+
icon: 0,
|
|
244
|
+
iconClass: `sdk-icon ${item.iconClass} text-[#0265ff]`,
|
|
245
|
+
type: 'flow',
|
|
246
|
+
children: [],
|
|
247
|
+
// depth 0: the group popover renders these as a flat list — no tree indent
|
|
248
|
+
depth: 0,
|
|
249
|
+
isSelectable: true,
|
|
250
|
+
entry: createFlowEntryDetail(item.entryId, item.name),
|
|
251
|
+
}));
|
|
252
|
+
|
|
253
|
+
const groupNode: EntryTreeItem = {
|
|
254
|
+
id: FLOW_CENTER_GROUP_ID,
|
|
255
|
+
name: '流程中心',
|
|
256
|
+
icon: 0,
|
|
257
|
+
type: 'group',
|
|
258
|
+
depth: 0,
|
|
259
|
+
isSelectable: false,
|
|
260
|
+
entry: null,
|
|
261
|
+
children,
|
|
262
|
+
};
|
|
263
|
+
|
|
264
|
+
return [groupNode];
|
|
265
|
+
}
|
|
@@ -1,45 +1,45 @@
|
|
|
1
|
-
import { cn } from '../../lib/utils';
|
|
2
|
-
import { transCls } from '../../const/ui';
|
|
3
|
-
import { getDepthPadding, getEntryIconClass } from './build-tree';
|
|
4
|
-
import type { EntryTreeItem } from './types';
|
|
5
|
-
|
|
6
|
-
export function EntryItem({
|
|
7
|
-
item,
|
|
8
|
-
depth,
|
|
9
|
-
isSelected,
|
|
10
|
-
onClick,
|
|
11
|
-
}: {
|
|
12
|
-
item: EntryTreeItem;
|
|
13
|
-
depth: number;
|
|
14
|
-
isSelected: boolean;
|
|
15
|
-
onClick: () => void;
|
|
16
|
-
}) {
|
|
17
|
-
return (
|
|
18
|
-
<div
|
|
19
|
-
className={cn(
|
|
20
|
-
'flex items-center justify-between h-[34px] px-[10px] cursor-pointer rounded-[4px] shrink-0',
|
|
21
|
-
getDepthPadding(depth),
|
|
22
|
-
'hover:bg-[#EFF0F6]',
|
|
23
|
-
isSelected && 'bg-[#EFF0F6]',
|
|
24
|
-
transCls,
|
|
25
|
-
)}
|
|
26
|
-
onClick={onClick}
|
|
27
|
-
>
|
|
28
|
-
<span className="flex items-center gap-[6px] min-w-0 flex-1">
|
|
29
|
-
<i
|
|
30
|
-
className={
|
|
31
|
-
item.iconClass
|
|
32
|
-
? item.iconClass
|
|
33
|
-
: item.entry
|
|
34
|
-
? getEntryIconClass(item.entry)
|
|
35
|
-
: 'node-icon icon-bsy-form icon-new-bsy-form-25'
|
|
36
|
-
}
|
|
37
|
-
style={{ fontSize: 16, lineHeight: 1 }}
|
|
38
|
-
/>
|
|
39
|
-
<span className="text-[14px] text-[#030303] truncate">
|
|
40
|
-
{item.name}
|
|
41
|
-
</span>
|
|
42
|
-
</span>
|
|
43
|
-
</div>
|
|
44
|
-
);
|
|
45
|
-
}
|
|
1
|
+
import { cn } from '../../lib/utils';
|
|
2
|
+
import { transCls } from '../../const/ui';
|
|
3
|
+
import { getDepthPadding, getEntryIconClass } from './build-tree';
|
|
4
|
+
import type { EntryTreeItem } from './types';
|
|
5
|
+
|
|
6
|
+
export function EntryItem({
|
|
7
|
+
item,
|
|
8
|
+
depth,
|
|
9
|
+
isSelected,
|
|
10
|
+
onClick,
|
|
11
|
+
}: {
|
|
12
|
+
item: EntryTreeItem;
|
|
13
|
+
depth: number;
|
|
14
|
+
isSelected: boolean;
|
|
15
|
+
onClick: () => void;
|
|
16
|
+
}) {
|
|
17
|
+
return (
|
|
18
|
+
<div
|
|
19
|
+
className={cn(
|
|
20
|
+
'flex items-center justify-between h-[34px] px-[10px] cursor-pointer rounded-[4px] shrink-0',
|
|
21
|
+
getDepthPadding(depth),
|
|
22
|
+
'hover:bg-[#EFF0F6]',
|
|
23
|
+
isSelected && 'bg-[#EFF0F6]',
|
|
24
|
+
transCls,
|
|
25
|
+
)}
|
|
26
|
+
onClick={onClick}
|
|
27
|
+
>
|
|
28
|
+
<span className="flex items-center gap-[6px] min-w-0 flex-1">
|
|
29
|
+
<i
|
|
30
|
+
className={
|
|
31
|
+
item.iconClass
|
|
32
|
+
? item.iconClass
|
|
33
|
+
: item.entry
|
|
34
|
+
? getEntryIconClass(item.entry)
|
|
35
|
+
: 'node-icon icon-bsy-form icon-new-bsy-form-25'
|
|
36
|
+
}
|
|
37
|
+
style={{ fontSize: 16, lineHeight: 1 }}
|
|
38
|
+
/>
|
|
39
|
+
<span className="text-[14px] text-[#030303] truncate">
|
|
40
|
+
{item.name}
|
|
41
|
+
</span>
|
|
42
|
+
</span>
|
|
43
|
+
</div>
|
|
44
|
+
);
|
|
45
|
+
}
|