@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.
Files changed (269) hide show
  1. package/.storybook/main.ts +31 -31
  2. package/.storybook/preview.ts +16 -16
  3. package/CHANGELOG.md +512 -492
  4. package/components.json +22 -22
  5. package/package.json +9 -6
  6. package/scripts/strip-layers.cjs +41 -41
  7. package/src/components/abs-fullscreen-gradient-bg.tsx +35 -35
  8. package/src/components/agent-helper/agent-category-select-menu/index.tsx +57 -57
  9. package/src/components/agent-helper/agent-entry-card/index.tsx +94 -94
  10. package/src/components/agent-helper/agent-helper-card/index.tsx +179 -179
  11. package/src/components/agent-helper/agent-helper-card-list/index.tsx +59 -59
  12. package/src/components/agent-helper/agent-helper-main-layout/index.tsx +60 -60
  13. package/src/components/agent-helper/agent-sort-select/index.tsx +89 -89
  14. package/src/components/agent-helper/agent-tag/index.tsx +29 -29
  15. package/src/components/agent-helper/app-select/index.tsx +559 -559
  16. package/src/components/agent-helper/condition-group/index.tsx +75 -75
  17. package/src/components/agent-helper/condition-input/index.tsx +233 -233
  18. package/src/components/agent-helper/condition-item/index.tsx +237 -237
  19. package/src/components/agent-helper/condition-quantifier-select/index.tsx +142 -142
  20. package/src/components/agent-helper/condition-trigger-description/index.tsx +49 -49
  21. package/src/components/agent-helper/date-picker/calendar-panel.tsx +164 -164
  22. package/src/components/agent-helper/date-picker/date-input.tsx +91 -91
  23. package/src/components/agent-helper/date-picker/date-picker.tsx +327 -327
  24. package/src/components/agent-helper/date-picker/footer-panel.tsx +44 -44
  25. package/src/components/agent-helper/date-picker/index.ts +3 -3
  26. package/src/components/agent-helper/date-picker/month-panel.tsx +82 -82
  27. package/src/components/agent-helper/date-picker/time-panel.tsx +146 -146
  28. package/src/components/agent-helper/date-picker/types.ts +37 -37
  29. package/src/components/agent-helper/date-picker/utils.ts +121 -121
  30. package/src/components/agent-helper/date-picker/year-panel.tsx +86 -86
  31. package/src/components/agent-helper/exec-log-filter/index.tsx +232 -232
  32. package/src/components/agent-helper/field-edit-preference-select/index.tsx +291 -291
  33. package/src/components/agent-helper/field-select/index.tsx +466 -466
  34. package/src/components/agent-helper/field-value-input/china-address-data.ts +4117 -4117
  35. package/src/components/agent-helper/field-value-input/display.tsx +71 -71
  36. package/src/components/agent-helper/field-value-input/icons.tsx +38 -38
  37. package/src/components/agent-helper/field-value-input/index.tsx +144 -144
  38. package/src/components/agent-helper/field-value-input/inputs.tsx +247 -247
  39. package/src/components/agent-helper/field-value-input/picker-inputs.tsx +1141 -1141
  40. package/src/components/agent-helper/flow-node-action-trigger-select/index.tsx +57 -57
  41. package/src/components/agent-helper/form-action-trigger-select/index.tsx +60 -60
  42. package/src/components/agent-helper/form-divider/index.tsx +44 -44
  43. package/src/components/agent-helper/form-select/index.tsx +732 -732
  44. package/src/components/agent-helper/monthdays-select/index.tsx +378 -378
  45. package/src/components/agent-helper/offset-preference-select/index.tsx +268 -268
  46. package/src/components/agent-helper/offset-type-select/index.tsx +66 -66
  47. package/src/components/agent-helper/offset-unit-select/index.tsx +54 -54
  48. package/src/components/agent-helper/placeholder-card/index.tsx +75 -75
  49. package/src/components/agent-helper/prompt-input/index.tsx +646 -640
  50. package/src/components/agent-helper/relational-operator-select/index.tsx +179 -179
  51. package/src/components/agent-helper/repeat-by-type-select/index.tsx +53 -53
  52. package/src/components/agent-helper/repeat-preference-select/index.tsx +162 -162
  53. package/src/components/agent-helper/repeat-preference-type-select/index.tsx +58 -58
  54. package/src/components/agent-helper/search-input/index.tsx +35 -35
  55. package/src/components/agent-helper/table/index.tsx +114 -114
  56. package/src/components/agent-helper/trigger-select/index.tsx +121 -121
  57. package/src/components/agent-helper/trigger-time-preference-select/index.tsx +189 -189
  58. package/src/components/agent-helper/trigger-time-source-type-select/index.tsx +53 -53
  59. package/src/components/agent-helper/weekdays-select/index.tsx +230 -230
  60. package/src/components/agent-scroll-selector.tsx +193 -193
  61. package/src/components/agent-select.tsx +154 -154
  62. package/src/components/attachment-part-group.tsx +35 -35
  63. package/src/components/attachment-part.tsx +296 -296
  64. package/src/components/attachments-previewer.tsx +272 -272
  65. package/src/components/base-button.tsx +49 -49
  66. package/src/components/border-animation.tsx +107 -107
  67. package/src/components/border-color-animation.tsx +66 -66
  68. package/src/components/bot-avatar-name.tsx +36 -36
  69. package/src/components/bot-icon.tsx +23 -23
  70. package/src/components/bs-entry-select/app-group-folder.tsx +61 -61
  71. package/src/components/bs-entry-select/bs-entry-select.tsx +296 -296
  72. package/src/components/bs-entry-select/build-tree.ts +265 -265
  73. package/src/components/bs-entry-select/entry-item.tsx +45 -45
  74. package/src/components/bs-entry-select/entry-popover.tsx +99 -99
  75. package/src/components/bs-entry-select/index.ts +7 -7
  76. package/src/components/bs-entry-select/other-app-section.tsx +96 -96
  77. package/src/components/bs-entry-select/scroll-slider.tsx +872 -872
  78. package/src/components/bs-entry-select/search-input.tsx +4 -4
  79. package/src/components/bs-entry-select/tree-item-node.tsx +84 -84
  80. package/src/components/bs-entry-select/types.ts +46 -46
  81. package/src/components/bs-icons.tsx +1362 -1362
  82. package/src/components/card-field.tsx +23 -23
  83. package/src/components/card.tsx +36 -36
  84. package/src/components/chat-area-header.tsx +65 -65
  85. package/src/components/check-card.tsx +77 -77
  86. package/src/components/circle-checker.tsx +66 -66
  87. package/src/components/collapsible-txt-msg.tsx +75 -75
  88. package/src/components/collapsible.tsx +9 -9
  89. package/src/components/confirm-dialog.tsx +139 -139
  90. package/src/components/date-range-picker.tsx +91 -91
  91. package/src/components/fake-bot-msg.tsx +51 -51
  92. package/src/components/field-checker-list-msg.tsx +146 -146
  93. package/src/components/field-checker.tsx +185 -185
  94. package/src/components/field-icon.tsx +13 -13
  95. package/src/components/field-value-checker.tsx +116 -116
  96. package/src/components/fields-design-info-table.tsx +160 -160
  97. package/src/components/fields-generating-indicator.tsx +95 -95
  98. package/src/components/fields-portal.tsx +18 -18
  99. package/src/components/fields-previewer.tsx +216 -216
  100. package/src/components/font-icon.tsx +65 -65
  101. package/src/components/form-info-editor.tsx +263 -263
  102. package/src/components/formula-tag.tsx +32 -32
  103. package/src/components/generate-animation.tsx +56 -56
  104. package/src/components/icon-btn.tsx +43 -43
  105. package/src/components/icon-card.tsx +67 -67
  106. package/src/components/icons/calendar-icon.tsx +5 -5
  107. package/src/components/icons/clear-all-icon.tsx +5 -5
  108. package/src/components/icons/empty-agent-icon.tsx +93 -93
  109. package/src/components/icons/empty-table-icon.tsx +104 -104
  110. package/src/components/icons/grids-icon.tsx +5 -5
  111. package/src/components/img-part.tsx +27 -27
  112. package/src/components/legacy-slot.tsx +110 -110
  113. package/src/components/line-checker.tsx +168 -168
  114. package/src/components/linear-gradient-border-btn.tsx +48 -48
  115. package/src/components/linear-gradient-color-bg-animation.tsx +103 -103
  116. package/src/components/memoized-markdown.tsx +32 -32
  117. package/src/components/message-content.tsx +21 -21
  118. package/src/components/number-part.tsx +46 -46
  119. package/src/components/office-container.tsx +289 -265
  120. package/src/components/option-item.tsx +27 -27
  121. package/src/components/output-config-editor.tsx +478 -478
  122. package/src/components/previewer-header.tsx +270 -270
  123. package/src/components/primary-confirm-btn.tsx +58 -58
  124. package/src/components/primary-entry-btn.tsx +48 -48
  125. package/src/components/radio-card.tsx +63 -63
  126. package/src/components/scroll-to-bottom-btn.tsx +28 -28
  127. package/src/components/split-line.tsx +9 -9
  128. package/src/components/square-checker.tsx +87 -87
  129. package/src/components/subform-fields-value-checker.tsx +184 -184
  130. package/src/components/tab-radio-group.tsx +83 -83
  131. package/src/components/tooltip.tsx +53 -53
  132. package/src/components/ui/button.tsx +51 -51
  133. package/src/components/ui/calendar.tsx +57 -57
  134. package/src/components/ui/dialog.tsx +104 -104
  135. package/src/components/ui/drawer.tsx +279 -279
  136. package/src/components/ui/form.tsx +202 -202
  137. package/src/components/ui/icons.tsx +1267 -1267
  138. package/src/components/ui/input.tsx +28 -28
  139. package/src/components/ui/label.tsx +30 -30
  140. package/src/components/ui/popover.tsx +85 -85
  141. package/src/components/ui/select.tsx +236 -236
  142. package/src/components/ui/spinner.tsx +17 -17
  143. package/src/components/ui/switch.tsx +33 -33
  144. package/src/components/ui/tabs.tsx +62 -62
  145. package/src/components/ui/textarea.tsx +28 -28
  146. package/src/components/ui/tooltip.tsx +53 -53
  147. package/src/components/user-txt-msg-bubble.tsx +47 -47
  148. package/src/components/warning-msg.tsx +27 -27
  149. package/src/const/ui.ts +119 -119
  150. package/src/css.d.ts +4 -4
  151. package/src/hooks/use-column-appear.ts +78 -78
  152. package/src/hooks/use-portal-container.ts +27 -27
  153. package/src/hooks/use-resizable-width.ts +129 -129
  154. package/src/hooks/use-select-popover-position.ts +74 -74
  155. package/src/hooks/use-shadow.ts +127 -127
  156. package/src/index.ts +226 -226
  157. package/src/lib/utils.ts +138 -138
  158. package/src/stories/AbsFullscreenGradientBg.stories.tsx +36 -36
  159. package/src/stories/AgentCategorySelectMenu.stories.tsx +33 -33
  160. package/src/stories/AgentEntryCard.stories.tsx +90 -90
  161. package/src/stories/AgentHelperCard.stories.tsx +105 -105
  162. package/src/stories/AgentHelperCardList.stories.tsx +120 -120
  163. package/src/stories/AgentHelperMainLayout.stories.tsx +71 -71
  164. package/src/stories/AgentScrollSelector.stories.tsx +95 -95
  165. package/src/stories/AgentSelect.stories.tsx +134 -134
  166. package/src/stories/AgentTag.stories.tsx +44 -44
  167. package/src/stories/AppSelect.stories.tsx +250 -250
  168. package/src/stories/AttachmentPart.stories.tsx +122 -122
  169. package/src/stories/AttachmentPartGroup.stories.tsx +152 -152
  170. package/src/stories/AttachmentsPreviewer.stories.tsx +306 -306
  171. package/src/stories/BaseButton.stories.tsx +33 -33
  172. package/src/stories/BorderAnimation.stories.tsx +116 -116
  173. package/src/stories/BorderColorAnimation.stories.tsx +63 -63
  174. package/src/stories/BotAvatarAndName.stories.ts +24 -24
  175. package/src/stories/BotIcon.stories.ts +22 -22
  176. package/src/stories/BsConditionInput.stories.tsx +460 -460
  177. package/src/stories/BsEntrySelect.stories.tsx +343 -343
  178. package/src/stories/BsTooltip.stories.tsx +32 -32
  179. package/src/stories/Card.stories.tsx +28 -28
  180. package/src/stories/CardField.stories.tsx +87 -87
  181. package/src/stories/ChatAreaHeader.stories.ts +26 -26
  182. package/src/stories/CheckCard.stories.tsx +114 -114
  183. package/src/stories/CircleChecker.stories.tsx +89 -89
  184. package/src/stories/CollapsibleTextMsg.stories.ts +44 -44
  185. package/src/stories/ConditionGroup.stories.tsx +216 -216
  186. package/src/stories/ConditionInput.stories.tsx +502 -502
  187. package/src/stories/ConditionItem.stories.tsx +163 -163
  188. package/src/stories/ConditonQuantifierSelect.stories.tsx +54 -54
  189. package/src/stories/ConditonTriggerDescription.stories.tsx +61 -61
  190. package/src/stories/ConfirmDialog.stories.tsx +123 -123
  191. package/src/stories/DataTable.stories.tsx +191 -191
  192. package/src/stories/DatePicker.stories.tsx +174 -174
  193. package/src/stories/ExecLogFilter.stories.tsx +145 -145
  194. package/src/stories/FakeBotMsg.stories.tsx +36 -36
  195. package/src/stories/FieldEditPreferenceSelect.stories.tsx +161 -161
  196. package/src/stories/FieldSelect.stories.tsx +228 -228
  197. package/src/stories/FieldValueInput.stories.tsx +442 -442
  198. package/src/stories/FlowNodeActionTriggerSelect.stories.tsx +80 -80
  199. package/src/stories/Form.stories.tsx +302 -302
  200. package/src/stories/FormActionTriggerSelect.stories.tsx +80 -80
  201. package/src/stories/FormDivider.stories.tsx +31 -31
  202. package/src/stories/FormInfoEditor.stories.tsx +173 -173
  203. package/src/stories/FormSelect.stories.tsx +222 -222
  204. package/src/stories/FormulaTag.stories.tsx +68 -68
  205. package/src/stories/GenerateAnimation.stories.ts +20 -20
  206. package/src/stories/IconBtn.stories.tsx +32 -32
  207. package/src/stories/IconCard.stories.tsx +35 -35
  208. package/src/stories/IconLib.tsx +45 -45
  209. package/src/stories/Icons.stories.ts +22 -22
  210. package/src/stories/ImgMsgPart.stories.tsx +42 -42
  211. package/src/stories/Input.stories.tsx +102 -102
  212. package/src/stories/Label.stories.tsx +66 -66
  213. package/src/stories/LegacySlot.stories.tsx +56 -56
  214. package/src/stories/LineChecker.stories.tsx +133 -133
  215. package/src/stories/LinearGradientBorderBtn.stories.tsx +86 -86
  216. package/src/stories/LinearGradientColorBgAnimation.stories.tsx +60 -60
  217. package/src/stories/MemoizedMarkdown.stories.tsx +102 -102
  218. package/src/stories/MessageContent.stories.tsx +36 -36
  219. package/src/stories/MonthdaysSelect.stories.tsx +78 -78
  220. package/src/stories/NumbersMsgPart.stories.tsx +42 -42
  221. package/src/stories/OfficeContainer.stories.tsx +287 -287
  222. package/src/stories/OffsetPreferenceSelect.stories.tsx +118 -118
  223. package/src/stories/OffsetTypeSelect.stories.tsx +75 -75
  224. package/src/stories/OffsetUnitSelect.stories.tsx +61 -61
  225. package/src/stories/OptionItem.stories.tsx +77 -77
  226. package/src/stories/OutputConfigEditor.stories.tsx +96 -96
  227. package/src/stories/PlaceholderCard.stories.tsx +35 -35
  228. package/src/stories/PreviewerHeader.stories.tsx +91 -91
  229. package/src/stories/PrimaryConfirmBtn.stories.tsx +60 -60
  230. package/src/stories/PrimaryEntryBtn.stories.tsx +74 -74
  231. package/src/stories/PromptInput.stories.tsx +228 -228
  232. package/src/stories/RadioCard.stories.tsx +103 -103
  233. package/src/stories/RelationalOperatorSelect.stories.tsx +61 -61
  234. package/src/stories/RepeatByTypeSelect.stories.tsx +58 -58
  235. package/src/stories/RepeatPreferenceSelect.stories.tsx +107 -107
  236. package/src/stories/RepeatPreferenceTypeSelect.stories.tsx +58 -58
  237. package/src/stories/ScrollToBottom.stories.tsx +24 -24
  238. package/src/stories/SearchInput.stories.tsx +50 -50
  239. package/src/stories/Select.stories.tsx +128 -128
  240. package/src/stories/SplitLine.stories.tsx +40 -40
  241. package/src/stories/SquareChecker.stories.tsx +96 -96
  242. package/src/stories/TabRadioGroup.stories.tsx +84 -84
  243. package/src/stories/Textarea.stories.tsx +67 -67
  244. package/src/stories/TriggerSelect.stories.tsx +48 -48
  245. package/src/stories/TriggerTimePreferenceSelect.stories.tsx +106 -106
  246. package/src/stories/TriggerTimeSourceTypeSelect.stories.tsx +68 -68
  247. package/src/stories/UserTextMsgBubble.stories.ts +24 -24
  248. package/src/stories/WarningMessage.stories.tsx +23 -23
  249. package/src/stories/WeekdaysSelect.stories.tsx +66 -66
  250. package/src/stories/assets/demo.css +539 -539
  251. package/src/stories/assets/demo_index.html +7988 -7988
  252. package/src/stories/assets/iconfont.css +1377 -1377
  253. package/src/stories/assets/iconfont.json +2382 -2382
  254. package/src/stories/assets/iconfont.svg +697 -697
  255. package/src/stories/collapsible.stories.tsx +47 -47
  256. package/src/stories/drawer.stories.tsx +196 -196
  257. package/src/stories/field-checker-list-msg.stories.tsx +95 -95
  258. package/src/stories/field-checker.stories.tsx +117 -117
  259. package/src/stories/field-icon.stories.tsx +70 -70
  260. package/src/stories/field-value-checker.stories.tsx +113 -113
  261. package/src/stories/fields-design-info-table.stories.tsx +203 -203
  262. package/src/stories/fields-generating.stories.tsx +41 -41
  263. package/src/stories/fields-previewer.stories.tsx +77 -77
  264. package/src/stories/subform-fields-value-checker.stories.tsx +98 -98
  265. package/src/style.css +226 -226
  266. package/src/types.ts +8 -8
  267. package/style.css +3652 -3652
  268. package/tsconfig.json +13 -13
  269. package/vite.config.ts +44 -44
@@ -1,237 +1,237 @@
1
- import { useState, useCallback, useRef, useMemo } from 'react';
2
- import type { IField, IConditionItem, relationalOperator, IFieldValueService } from '@baishuyun/types';
3
- import { getAvailableOperators, getDefaultOperator } from '@baishuyun/ai-feat-utils';
4
- import { cn } from '../../../lib/utils';
5
- import { transCls } from '../../../const/ui';
6
- import { FieldSelect } from '../field-select';
7
- import { RelationalOperatorSelect } from '../relational-operator-select';
8
- import { FieldValueInput } from '../field-value-input';
9
- import { TrashIcon } from '../../bs-icons';
10
-
11
- // ── Helpers ──────────────────────────────────────────────────────────
12
-
13
- function findFieldKey(_: IField[], targetField: IField): string | undefined {
14
- return targetField.widget?.widgetName;
15
-
16
- // for (let i = 0; i < fields.length; i++) {
17
- // if (fields[i] === targetField) return targetField.widget?.widgetName || String(i);
18
- // }
19
- // return undefined;
20
- }
21
-
22
- function generateId(): string {
23
- return `cond-${Date.now()}-${Math.random().toString(36).slice(2, 9)}`;
24
- }
25
-
26
- // ── Props ────────────────────────────────────────────────────────────
27
-
28
- export interface ConditionItemProps {
29
- fields: IField[];
30
- value?: IConditionItem;
31
- defaultValue?: IConditionItem;
32
- onChange?: (item: IConditionItem) => void;
33
- onRemoveClick?: () => void;
34
- service?: IFieldValueService;
35
- disabled?: boolean;
36
- className?: string;
37
- }
38
-
39
- // ── Component ────────────────────────────────────────────────────────
40
-
41
- export const ConditionItem = ({
42
- fields,
43
- value: controlledValue,
44
- defaultValue,
45
- onChange,
46
- onRemoveClick,
47
- service,
48
- disabled = false,
49
- className,
50
- }: ConditionItemProps) => {
51
- const idRef = useRef<string>(controlledValue?.id || defaultValue?.id || generateId());
52
-
53
- const [internalField, setInternalField] = useState<IField | undefined>(
54
- defaultValue?.field,
55
- );
56
- const [internalKey, setInternalKey] = useState<string | undefined>(() =>
57
- defaultValue?.field ? findFieldKey(fields, defaultValue.field) : undefined,
58
- );
59
- const [internalOperator, setInternalOperator] = useState<relationalOperator>(
60
- defaultValue?.operator ||
61
- getDefaultOperator(defaultValue?.field?.widget?.type),
62
- );
63
- const [internalValue, setInternalValue] = useState<unknown>(
64
- defaultValue?.value,
65
- );
66
-
67
- const isControlled = controlledValue !== undefined;
68
-
69
- const currentField = isControlled ? controlledValue.field : internalField;
70
- const currentKey = useMemo(() => {
71
- if (isControlled && controlledValue.field) {
72
- return findFieldKey(fields, controlledValue.field);
73
- }
74
- return internalKey;
75
- }, [isControlled, controlledValue?.field, fields, internalKey]);
76
- const currentOperator = isControlled
77
- ? controlledValue.operator
78
- : internalOperator;
79
- const currentValue = isControlled ? controlledValue.value : internalValue;
80
-
81
- const fieldType = currentField?.widget?.type;
82
- const availableOperators = useMemo(
83
- () => getAvailableOperators(fieldType),
84
- [fieldType],
85
- );
86
-
87
- const emitChange = useCallback(
88
- (field: IField, operator: relationalOperator, value: unknown) => {
89
- onChange?.({
90
- id: idRef.current,
91
- field,
92
- operator,
93
- value,
94
- });
95
- },
96
- [onChange],
97
- );
98
-
99
- // ── Handlers ──────────────────────────────────────────────────
100
-
101
- const handleFieldChange = useCallback(
102
- (field: IField, nodeKey: string) => {
103
- const newOperator = getDefaultOperator(field.widget?.type);
104
-
105
- if (!isControlled) {
106
- setInternalField(field);
107
- setInternalKey(nodeKey);
108
- setInternalOperator(newOperator);
109
- setInternalValue(undefined);
110
- }
111
-
112
- emitChange(field, newOperator, undefined);
113
- },
114
- [isControlled, emitChange],
115
- );
116
-
117
- const handleOperatorChange = useCallback(
118
- (operator: relationalOperator) => {
119
- const isEmptyOp = operator === 'empty' || operator === 'not_empty';
120
- const isRangeOp = operator === 'range';
121
- const isMultiOp = operator === 'in' || operator === 'nin' || operator === 'all';
122
-
123
- let newValue: unknown;
124
- if (isEmptyOp) {
125
- newValue = undefined;
126
- } else if (isRangeOp) {
127
- newValue = { min: undefined, max: undefined };
128
- } else if (isMultiOp) {
129
- newValue = [];
130
- } else if (
131
- typeof currentValue === 'object' &&
132
- currentValue !== null &&
133
- !Array.isArray(currentValue)
134
- ) {
135
- newValue = undefined;
136
- } else {
137
- newValue = currentValue;
138
- }
139
-
140
- if (!isControlled) {
141
- setInternalOperator(operator);
142
- if (isEmptyOp || isRangeOp || isMultiOp) setInternalValue(newValue);
143
- }
144
-
145
- if (currentField) {
146
- emitChange(currentField, operator, newValue);
147
- }
148
- },
149
- [isControlled, currentField, currentValue, emitChange],
150
- );
151
-
152
- const handleValueChange = useCallback(
153
- (value: unknown) => {
154
- if (!isControlled) {
155
- setInternalValue(value);
156
- }
157
-
158
- if (currentField) {
159
- emitChange(currentField, currentOperator, value);
160
- }
161
- },
162
- [isControlled, currentField, currentOperator, emitChange],
163
- );
164
-
165
- const hideValueInput =
166
- currentField != null &&
167
- (currentOperator === 'empty' || currentOperator === 'not_empty');
168
-
169
- return (
170
- <div className={cn('flex items-center gap-[10px]', className)}>
171
- <FieldSelect
172
- fields={fields}
173
- value={currentKey}
174
- onChange={handleFieldChange}
175
- placeholder="请选择字段"
176
- searchPlaceholder="输入字段名称来搜索"
177
- disabled={disabled}
178
- showTypeBadge
179
- className="w-[200px] shrink-0"
180
- />
181
-
182
- <RelationalOperatorSelect
183
- value={currentOperator}
184
- onChange={handleOperatorChange}
185
- operators={availableOperators}
186
- borderless
187
- disabled={disabled}
188
- className="w-[120px] shrink-0"
189
- />
190
-
191
- {hideValueInput ? (
192
- <div className="flex-1 min-w-0 h-[34px]" />
193
- ) : currentField ? (
194
- <div className="flex-1 min-w-0">
195
- <FieldValueInput
196
- field={currentField}
197
- value={currentValue}
198
- onChange={handleValueChange}
199
- operator={currentOperator}
200
- service={service}
201
- disabled={disabled}
202
- />
203
- </div>
204
- ) : (
205
- <div
206
- className={cn(
207
- 'flex-1 min-w-0 flex items-center',
208
- 'bg-white border border-[#E0E0E0] rounded-[4px]',
209
- 'h-[34px] px-[10px] py-[7px]',
210
- )}
211
- >
212
- <span className="text-[14px] leading-[normal] text-[#999] truncate">
213
- 请选择
214
- </span>
215
- </div>
216
- )}
217
-
218
- {onRemoveClick && (
219
- <button
220
- type="button"
221
- onClick={onRemoveClick}
222
- disabled={disabled}
223
- className={cn(
224
- 'shrink-0 flex items-center justify-center size-[16px]',
225
- 'text-[#999] hover:text-[#FF5631]',
226
- disabled && 'opacity-50 cursor-not-allowed',
227
- transCls,
228
- )}
229
- >
230
- <TrashIcon />
231
- </button>
232
- )}
233
- </div>
234
- );
235
- };
236
-
237
- ConditionItem.displayName = 'ConditionItem';
1
+ import { useState, useCallback, useRef, useMemo } from 'react';
2
+ import type { IField, IConditionItem, relationalOperator, IFieldValueService } from '@baishuyun/types';
3
+ import { getAvailableOperators, getDefaultOperator } from '@baishuyun/ai-feat-utils';
4
+ import { cn } from '../../../lib/utils';
5
+ import { transCls } from '../../../const/ui';
6
+ import { FieldSelect } from '../field-select';
7
+ import { RelationalOperatorSelect } from '../relational-operator-select';
8
+ import { FieldValueInput } from '../field-value-input';
9
+ import { TrashIcon } from '../../bs-icons';
10
+
11
+ // ── Helpers ──────────────────────────────────────────────────────────
12
+
13
+ function findFieldKey(_: IField[], targetField: IField): string | undefined {
14
+ return targetField.widget?.widgetName;
15
+
16
+ // for (let i = 0; i < fields.length; i++) {
17
+ // if (fields[i] === targetField) return targetField.widget?.widgetName || String(i);
18
+ // }
19
+ // return undefined;
20
+ }
21
+
22
+ function generateId(): string {
23
+ return `cond-${Date.now()}-${Math.random().toString(36).slice(2, 9)}`;
24
+ }
25
+
26
+ // ── Props ────────────────────────────────────────────────────────────
27
+
28
+ export interface ConditionItemProps {
29
+ fields: IField[];
30
+ value?: IConditionItem;
31
+ defaultValue?: IConditionItem;
32
+ onChange?: (item: IConditionItem) => void;
33
+ onRemoveClick?: () => void;
34
+ service?: IFieldValueService;
35
+ disabled?: boolean;
36
+ className?: string;
37
+ }
38
+
39
+ // ── Component ────────────────────────────────────────────────────────
40
+
41
+ export const ConditionItem = ({
42
+ fields,
43
+ value: controlledValue,
44
+ defaultValue,
45
+ onChange,
46
+ onRemoveClick,
47
+ service,
48
+ disabled = false,
49
+ className,
50
+ }: ConditionItemProps) => {
51
+ const idRef = useRef<string>(controlledValue?.id || defaultValue?.id || generateId());
52
+
53
+ const [internalField, setInternalField] = useState<IField | undefined>(
54
+ defaultValue?.field,
55
+ );
56
+ const [internalKey, setInternalKey] = useState<string | undefined>(() =>
57
+ defaultValue?.field ? findFieldKey(fields, defaultValue.field) : undefined,
58
+ );
59
+ const [internalOperator, setInternalOperator] = useState<relationalOperator>(
60
+ defaultValue?.operator ||
61
+ getDefaultOperator(defaultValue?.field?.widget?.type),
62
+ );
63
+ const [internalValue, setInternalValue] = useState<unknown>(
64
+ defaultValue?.value,
65
+ );
66
+
67
+ const isControlled = controlledValue !== undefined;
68
+
69
+ const currentField = isControlled ? controlledValue.field : internalField;
70
+ const currentKey = useMemo(() => {
71
+ if (isControlled && controlledValue.field) {
72
+ return findFieldKey(fields, controlledValue.field);
73
+ }
74
+ return internalKey;
75
+ }, [isControlled, controlledValue?.field, fields, internalKey]);
76
+ const currentOperator = isControlled
77
+ ? controlledValue.operator
78
+ : internalOperator;
79
+ const currentValue = isControlled ? controlledValue.value : internalValue;
80
+
81
+ const fieldType = currentField?.widget?.type;
82
+ const availableOperators = useMemo(
83
+ () => getAvailableOperators(fieldType),
84
+ [fieldType],
85
+ );
86
+
87
+ const emitChange = useCallback(
88
+ (field: IField, operator: relationalOperator, value: unknown) => {
89
+ onChange?.({
90
+ id: idRef.current,
91
+ field,
92
+ operator,
93
+ value,
94
+ });
95
+ },
96
+ [onChange],
97
+ );
98
+
99
+ // ── Handlers ──────────────────────────────────────────────────
100
+
101
+ const handleFieldChange = useCallback(
102
+ (field: IField, nodeKey: string) => {
103
+ const newOperator = getDefaultOperator(field.widget?.type);
104
+
105
+ if (!isControlled) {
106
+ setInternalField(field);
107
+ setInternalKey(nodeKey);
108
+ setInternalOperator(newOperator);
109
+ setInternalValue(undefined);
110
+ }
111
+
112
+ emitChange(field, newOperator, undefined);
113
+ },
114
+ [isControlled, emitChange],
115
+ );
116
+
117
+ const handleOperatorChange = useCallback(
118
+ (operator: relationalOperator) => {
119
+ const isEmptyOp = operator === 'empty' || operator === 'not_empty';
120
+ const isRangeOp = operator === 'range';
121
+ const isMultiOp = operator === 'in' || operator === 'nin' || operator === 'all';
122
+
123
+ let newValue: unknown;
124
+ if (isEmptyOp) {
125
+ newValue = undefined;
126
+ } else if (isRangeOp) {
127
+ newValue = { min: undefined, max: undefined };
128
+ } else if (isMultiOp) {
129
+ newValue = [];
130
+ } else if (
131
+ typeof currentValue === 'object' &&
132
+ currentValue !== null &&
133
+ !Array.isArray(currentValue)
134
+ ) {
135
+ newValue = undefined;
136
+ } else {
137
+ newValue = currentValue;
138
+ }
139
+
140
+ if (!isControlled) {
141
+ setInternalOperator(operator);
142
+ if (isEmptyOp || isRangeOp || isMultiOp) setInternalValue(newValue);
143
+ }
144
+
145
+ if (currentField) {
146
+ emitChange(currentField, operator, newValue);
147
+ }
148
+ },
149
+ [isControlled, currentField, currentValue, emitChange],
150
+ );
151
+
152
+ const handleValueChange = useCallback(
153
+ (value: unknown) => {
154
+ if (!isControlled) {
155
+ setInternalValue(value);
156
+ }
157
+
158
+ if (currentField) {
159
+ emitChange(currentField, currentOperator, value);
160
+ }
161
+ },
162
+ [isControlled, currentField, currentOperator, emitChange],
163
+ );
164
+
165
+ const hideValueInput =
166
+ currentField != null &&
167
+ (currentOperator === 'empty' || currentOperator === 'not_empty');
168
+
169
+ return (
170
+ <div className={cn('flex items-center gap-[10px]', className)}>
171
+ <FieldSelect
172
+ fields={fields}
173
+ value={currentKey}
174
+ onChange={handleFieldChange}
175
+ placeholder="请选择字段"
176
+ searchPlaceholder="输入字段名称来搜索"
177
+ disabled={disabled}
178
+ showTypeBadge
179
+ className="w-[200px] shrink-0"
180
+ />
181
+
182
+ <RelationalOperatorSelect
183
+ value={currentOperator}
184
+ onChange={handleOperatorChange}
185
+ operators={availableOperators}
186
+ borderless
187
+ disabled={disabled}
188
+ className="w-[120px] shrink-0"
189
+ />
190
+
191
+ {hideValueInput ? (
192
+ <div className="flex-1 min-w-0 h-[34px]" />
193
+ ) : currentField ? (
194
+ <div className="flex-1 min-w-0">
195
+ <FieldValueInput
196
+ field={currentField}
197
+ value={currentValue}
198
+ onChange={handleValueChange}
199
+ operator={currentOperator}
200
+ service={service}
201
+ disabled={disabled}
202
+ />
203
+ </div>
204
+ ) : (
205
+ <div
206
+ className={cn(
207
+ 'flex-1 min-w-0 flex items-center',
208
+ 'bg-white border border-[#E0E0E0] rounded-[4px]',
209
+ 'h-[34px] px-[10px] py-[7px]',
210
+ )}
211
+ >
212
+ <span className="text-[14px] leading-[normal] text-[#999] truncate">
213
+ 请选择
214
+ </span>
215
+ </div>
216
+ )}
217
+
218
+ {onRemoveClick && (
219
+ <button
220
+ type="button"
221
+ onClick={onRemoveClick}
222
+ disabled={disabled}
223
+ className={cn(
224
+ 'shrink-0 flex items-center justify-center size-[16px]',
225
+ 'text-[#999] hover:text-[#FF5631]',
226
+ disabled && 'opacity-50 cursor-not-allowed',
227
+ transCls,
228
+ )}
229
+ >
230
+ <TrashIcon />
231
+ </button>
232
+ )}
233
+ </div>
234
+ );
235
+ };
236
+
237
+ ConditionItem.displayName = 'ConditionItem';