@baishuyun/chat-sdk 0.0.15 → 0.0.17
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/CHANGELOG.md +14 -0
- package/dist/chat-sdk.js +16307 -15780
- package/dist/chat-sdk.js.map +1 -1
- package/dist/chat-sdk.umd.cjs +149 -149
- package/dist/chat-sdk.umd.cjs.map +1 -1
- package/dist/index.css +1 -1
- package/package.json +4 -4
- package/src/chat.tsx +15 -1
- package/src/components/biz-comp/FieldChecker.tsx +49 -7
- package/src/components/biz-comp/FieldCheckerListMsg.tsx +101 -22
- package/src/components/biz-comp/chat-client.tsx +7 -2
- package/src/components/biz-comp/error-msg.tsx +10 -0
- package/src/components/biz-comp/messages.tsx +10 -0
- package/src/components/biz-comp/multi-modal-input/clear-btn.tsx +3 -1
- package/src/components/biz-comp/multi-modal-input/index.tsx +58 -38
- package/src/components/biz-comp/multi-modal-input/prompt-input.tsx +13 -10
- package/src/components/biz-comp/preview-message-wrapper.tsx +4 -4
- package/src/components/biz-comp/preview-message.tsx +3 -1
- package/src/components/biz-comp/suggestions.tsx +5 -1
- package/src/components/bs-ui/attachments-previewer.tsx +4 -1
- package/src/components/bs-ui/base-button.tsx +7 -2
- package/src/components/bs-ui/bs-icons.tsx +29 -0
- package/src/components/bs-ui/card.tsx +4 -3
- package/src/components/bs-ui/chat-area-header.tsx +7 -3
- package/src/components/bs-ui/fields-design-info-table.tsx +160 -0
- package/src/components/bs-ui/fields-previewer.tsx +2 -0
- package/src/components/bs-ui/form-info-editor.tsx +2 -42
- package/src/components/bs-ui/generate-animation.tsx +7 -5
- package/src/components/bs-ui/img-part.tsx +1 -1
- package/src/components/bs-ui/line-checker.tsx +19 -5
- package/src/components/bs-ui/previewer-header.tsx +31 -3
- package/src/components/bs-ui/square-checker.tsx +30 -5
- package/src/components/bs-ui/tooltip.tsx +1 -1
- package/src/components/ui/dialog.tsx +1 -1
- package/src/components/ui/tooltip.tsx +1 -1
- package/src/const/ui.ts +42 -0
- package/src/hooks/use-frame-mode.ts +15 -0
- package/src/lib/parse-design-doc.ts +60 -0
- package/src/lib/utils.ts +19 -0
- package/src/plugins/form-builder-base-plugin/const.ts +3 -0
- package/src/plugins/form-builder-plugin/components/create-form-confirm.tsx +14 -1
- package/src/plugins/form-builder-plugin/components/design-info.tsx +47 -0
- package/src/plugins/form-builder-plugin/components/entry-btn.tsx +10 -2
- package/src/plugins/form-builder-plugin/components/follow-up.tsx +21 -6
- package/src/plugins/form-builder-plugin/components/msg-part.tsx +29 -9
- package/src/plugins/form-builder-plugin/components/opening-lines.tsx +11 -6
- package/src/plugins/form-builder-plugin/index.ts +73 -5
- package/src/plugins/form-builder-plugin/types.ts +3 -0
- package/src/plugins/form-builder-plugin/utils/index.ts +33 -6
- package/src/plugins/form-filling-plugin/components/batch-generator-action.tsx +44 -34
- package/src/plugins/form-filling-plugin/components/first-batch-generating-animation.tsx +21 -0
- package/src/plugins/form-filling-plugin/components/generated-data-counter.tsx +17 -0
- package/src/plugins/form-filling-plugin/components/non-first-batch-generating-animation.tsx +28 -0
- package/src/plugins/form-filling-plugin/index.ts +14 -0
- package/src/plugins/form-filling-plugin/types.ts +2 -0
- package/src/plugins/report-query-plugin/components/query-msg-part.tsx +16 -18
- package/src/plugins/report-query-plugin/components/result-cards/CreatedSourceMsg.tsx +36 -0
- package/src/plugins/report-query-plugin/components/result-cards/DataTableCard.tsx +15 -2
- package/src/plugins/report-query-plugin/const.ts +22 -0
- package/src/plugins/report-query-plugin/index.ts +30 -3
- package/src/plugins/report-query-plugin/types.ts +6 -0
- package/src/sdk.impl.tsx +4 -0
- package/src/store/index.ts +11 -0
- package/src/stories/FormInfoEditor.stories.tsx +19 -28
- package/src/stories/PreviewerHeader.stories.tsx +14 -0
- package/src/stories/fields-design-info-table.stories.tsx +203 -0
|
@@ -44,14 +44,18 @@ export const ChatAreaHeader = ({
|
|
|
44
44
|
|
|
45
45
|
<div className="actions flex items-center gap-2.5 text-[#666]">
|
|
46
46
|
<IconBtn
|
|
47
|
+
onMouseDown={(e) => {
|
|
48
|
+
// 阻止事件冒泡,避免触发拖拽
|
|
49
|
+
e.stopPropagation();
|
|
50
|
+
}}
|
|
47
51
|
tooltip={isDocked ? '悬浮' : '右侧打开'}
|
|
48
|
-
className="hover:!bg-[#ffffff]"
|
|
52
|
+
// className="hover:!bg-[#ffffff]"
|
|
49
53
|
icon={isDocked ? <FloatIcon /> : <DockIcon />}
|
|
50
54
|
onClick={onDockClick}
|
|
51
55
|
/>
|
|
52
56
|
<IconBtn
|
|
53
|
-
tooltip="关闭"
|
|
54
|
-
className="hover:!bg-[#ffffff]"
|
|
57
|
+
// tooltip="关闭"
|
|
58
|
+
// className="hover:!bg-[#ffffff]"
|
|
55
59
|
icon={<CloseIcon />}
|
|
56
60
|
onClick={onCloseClick}
|
|
57
61
|
/>
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
import { useState, useCallback, useMemo } from 'react';
|
|
2
|
+
import { IFieldDesignInfo } from '@baishuyun/types';
|
|
3
|
+
import { cn } from '@/lib/utils';
|
|
4
|
+
import { ChevronIcon } from './bs-icons';
|
|
5
|
+
|
|
6
|
+
interface FieldsDesignInfoTableProps {
|
|
7
|
+
fields: IFieldDesignInfo[];
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
/** Group fields into top-level items and subform groups */
|
|
11
|
+
function groupFields(fields: IFieldDesignInfo[]) {
|
|
12
|
+
const groups: Array<
|
|
13
|
+
| { kind: 'field'; field: IFieldDesignInfo }
|
|
14
|
+
| { kind: 'subform'; parent: IFieldDesignInfo; children: IFieldDesignInfo[] }
|
|
15
|
+
> = [];
|
|
16
|
+
|
|
17
|
+
let i = 0;
|
|
18
|
+
while (i < fields.length) {
|
|
19
|
+
const f = fields[i];
|
|
20
|
+
if (f.isSubForm) {
|
|
21
|
+
const children: IFieldDesignInfo[] = [];
|
|
22
|
+
let j = i + 1;
|
|
23
|
+
while (
|
|
24
|
+
j < fields.length &&
|
|
25
|
+
fields[j].isFieldInSubForm &&
|
|
26
|
+
fields[j].parentFormName === f.fieldName
|
|
27
|
+
) {
|
|
28
|
+
children.push(fields[j]);
|
|
29
|
+
j++;
|
|
30
|
+
}
|
|
31
|
+
groups.push({ kind: 'subform', parent: f, children });
|
|
32
|
+
i = j;
|
|
33
|
+
} else {
|
|
34
|
+
groups.push({ kind: 'field', field: f });
|
|
35
|
+
i++;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
return groups;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
const cellCls = 'flex items-center px-1.5 py-2.5 text-xs leading-normal';
|
|
42
|
+
|
|
43
|
+
function FieldRow({
|
|
44
|
+
field,
|
|
45
|
+
isSubFormChild = false,
|
|
46
|
+
}: {
|
|
47
|
+
field: IFieldDesignInfo;
|
|
48
|
+
isSubFormChild?: boolean;
|
|
49
|
+
}) {
|
|
50
|
+
return (
|
|
51
|
+
<div className="flex items-center w-full">
|
|
52
|
+
{/* 名称 */}
|
|
53
|
+
<div className={cn(cellCls, 'w-20 shrink-0 min-h-[34px] whitespace-nowrap')}>
|
|
54
|
+
{isSubFormChild && (
|
|
55
|
+
<span className="inline-flex items-center justify-center shrink-0 w-5 h-5 opacity-0">
|
|
56
|
+
<ChevronIcon />
|
|
57
|
+
</span>
|
|
58
|
+
)}
|
|
59
|
+
<span>{field.fieldName}</span>
|
|
60
|
+
</div>
|
|
61
|
+
{/* 类型 */}
|
|
62
|
+
<div className={cn(cellCls, 'w-[72px] shrink-0 min-h-[34px] whitespace-nowrap')}>
|
|
63
|
+
{field.type}
|
|
64
|
+
</div>
|
|
65
|
+
{/* 必填 */}
|
|
66
|
+
<div className={cn(cellCls, 'w-9 shrink-0 min-h-[34px] whitespace-nowrap')}>
|
|
67
|
+
{field.required ? '是' : '否'}
|
|
68
|
+
</div>
|
|
69
|
+
{/* 说明 */}
|
|
70
|
+
<div className={cn(cellCls, 'flex-1 min-w-0 min-h-[34px]')}>
|
|
71
|
+
<span className="break-words min-w-0">{field.description}</span>
|
|
72
|
+
</div>
|
|
73
|
+
</div>
|
|
74
|
+
);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
function SubFormGroup({
|
|
78
|
+
parent,
|
|
79
|
+
children,
|
|
80
|
+
}: {
|
|
81
|
+
parent: IFieldDesignInfo;
|
|
82
|
+
children: IFieldDesignInfo[];
|
|
83
|
+
}) {
|
|
84
|
+
const [isOpen, setIsOpen] = useState(true);
|
|
85
|
+
const toggle = useCallback(() => setIsOpen((v) => !v), []);
|
|
86
|
+
|
|
87
|
+
return (
|
|
88
|
+
<>
|
|
89
|
+
{/* 子表单 parent row */}
|
|
90
|
+
<div className="flex items-center w-full">
|
|
91
|
+
{/* 名称 */}
|
|
92
|
+
<div className={cn(cellCls, 'w-20 shrink-0 min-h-[34px]')}>
|
|
93
|
+
<button
|
|
94
|
+
type="button"
|
|
95
|
+
onClick={toggle}
|
|
96
|
+
className="inline-flex items-center justify-center shrink-0 w-5 h-5 rounded cursor-pointer text-[#666] relative -left-[2px]"
|
|
97
|
+
>
|
|
98
|
+
<ChevronIcon isOpen={isOpen} />
|
|
99
|
+
</button>
|
|
100
|
+
<span>{parent.fieldName}</span>
|
|
101
|
+
</div>
|
|
102
|
+
{/* 类型 */}
|
|
103
|
+
<div className={cn(cellCls, 'w-[72px] shrink-0 min-h-[34px] whitespace-nowrap')}>
|
|
104
|
+
{parent.type}
|
|
105
|
+
</div>
|
|
106
|
+
{/* 必填 */}
|
|
107
|
+
<div className={cn(cellCls, 'w-9 shrink-0 min-h-[34px] whitespace-nowrap')}>
|
|
108
|
+
{parent.required ? '是' : '否'}
|
|
109
|
+
</div>
|
|
110
|
+
{/* 说明 */}
|
|
111
|
+
<div className={cn(cellCls, 'flex-1 min-w-0 min-h-[34px]')}>
|
|
112
|
+
<span className="break-words min-w-0">{parent.description}</span>
|
|
113
|
+
</div>
|
|
114
|
+
</div>
|
|
115
|
+
|
|
116
|
+
{/* 子表单 children */}
|
|
117
|
+
{isOpen && children.map((child, idx) => <FieldRow key={idx} field={child} isSubFormChild />)}
|
|
118
|
+
</>
|
|
119
|
+
);
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
export function FieldsDesignInfoTable({ fields }: FieldsDesignInfoTableProps) {
|
|
123
|
+
const groups = useMemo(() => groupFields(fields), [fields]);
|
|
124
|
+
|
|
125
|
+
return (
|
|
126
|
+
<div className="flex flex-col items-start w-full bg-white rounded-[10px] overflow-hidden text-black my-[10px] border border-[#E0E0E0]">
|
|
127
|
+
{/* 表头 */}
|
|
128
|
+
<div className="flex items-center w-full shrink-0 bg-[#E5E6EB] rounded-t-[10px] border-b border-[#E0E0E0]">
|
|
129
|
+
<div className={cn(cellCls, 'w-20 shrink-0 h-[34px] font-bold whitespace-nowrap')}>
|
|
130
|
+
名称
|
|
131
|
+
</div>
|
|
132
|
+
<div className={cn(cellCls, 'w-[72px] shrink-0 h-[34px] font-bold whitespace-nowrap')}>
|
|
133
|
+
类型
|
|
134
|
+
</div>
|
|
135
|
+
<div
|
|
136
|
+
className={cn(
|
|
137
|
+
cellCls,
|
|
138
|
+
'w-9 shrink-0 h-[34px] font-bold whitespace-nowrap justify-center'
|
|
139
|
+
)}
|
|
140
|
+
>
|
|
141
|
+
必填
|
|
142
|
+
</div>
|
|
143
|
+
<div className={cn(cellCls, 'flex-1 min-w-0 h-[34px] font-bold whitespace-nowrap')}>
|
|
144
|
+
说明
|
|
145
|
+
</div>
|
|
146
|
+
</div>
|
|
147
|
+
|
|
148
|
+
{/* 表体 */}
|
|
149
|
+
<div className="flex flex-col items-start w-full">
|
|
150
|
+
{groups.map((g, idx) =>
|
|
151
|
+
g.kind === 'field' ? (
|
|
152
|
+
<FieldRow key={idx} field={g.field} />
|
|
153
|
+
) : (
|
|
154
|
+
<SubFormGroup key={idx} parent={g.parent} children={g.children} />
|
|
155
|
+
)
|
|
156
|
+
)}
|
|
157
|
+
</div>
|
|
158
|
+
</div>
|
|
159
|
+
);
|
|
160
|
+
}
|
|
@@ -76,6 +76,7 @@ export const FieldsPreviewer = forwardRef<HTMLDivElement, FieldsPreviewerProps>(
|
|
|
76
76
|
|
|
77
77
|
closeBtnLabel,
|
|
78
78
|
disableOperation,
|
|
79
|
+
disableConfirm,
|
|
79
80
|
}: FieldsPreviewerProps) => {
|
|
80
81
|
const p = fullscreen ? 0 : padding;
|
|
81
82
|
const pr = fullscreen ? 0 : rightSpaceWidth;
|
|
@@ -137,6 +138,7 @@ export const FieldsPreviewer = forwardRef<HTMLDivElement, FieldsPreviewerProps>(
|
|
|
137
138
|
confirmContent={confirmContent}
|
|
138
139
|
closeBtnLabel={closeBtnLabel}
|
|
139
140
|
disableOperation={disableOperation}
|
|
141
|
+
disableConfirm={disableConfirm}
|
|
140
142
|
/>
|
|
141
143
|
<div className={contentCls} style={fullContentStyle}>
|
|
142
144
|
{empty && isFields ? <PlaceholderDashedBox /> : children}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { cn } from '@/lib/utils';
|
|
2
|
-
import { transCls } from '@/const/ui';
|
|
2
|
+
import { FORM_ICON_OPTIONS, transCls } from '@/const/ui';
|
|
3
3
|
import { useState, memo, useEffect } from 'react';
|
|
4
4
|
import { ChevronDownIcon } from '../ui/icons';
|
|
5
5
|
import { PrimaryConfirmBtn } from './primary-confirm-btn';
|
|
@@ -15,46 +15,6 @@ export interface FormIconOption {
|
|
|
15
15
|
value: number;
|
|
16
16
|
}
|
|
17
17
|
|
|
18
|
-
// Form icon data from iconfont.json (icons with name starting with "表单")
|
|
19
|
-
export const FORM_ICON_OPTIONS: FormIconOption[] = [
|
|
20
|
-
{ id: 'biaodan1', code: '', label: '表单1', value: 25 },
|
|
21
|
-
{ id: 'biaodan2', code: '', label: '表单2', value: 26 },
|
|
22
|
-
{ id: 'biaodan3', code: '', label: '表单3', value: 27 },
|
|
23
|
-
{ id: 'biaodan4', code: '', label: '表单4', value: 28 },
|
|
24
|
-
{ id: 'biaodan5', code: '', label: '表单5', value: 29 },
|
|
25
|
-
{ id: 'biaodan6', code: '', label: '表单6', value: 30 },
|
|
26
|
-
{ id: 'biaodan7', code: '', label: '表单7', value: 31 },
|
|
27
|
-
{ id: 'biaodan8', code: '', label: '表单8', value: 32 },
|
|
28
|
-
{ id: 'biaodan9', code: '', label: '表单9', value: 33 },
|
|
29
|
-
{ id: 'biaodan10', code: '', label: '表单10', value: 34 },
|
|
30
|
-
{ id: 'biaodan11', code: '', label: '表单11', value: 35 },
|
|
31
|
-
{ id: 'biaodan12', code: '', label: '表单12', value: 36 },
|
|
32
|
-
{ id: 'biaodan13', code: '', label: '表单13', value: 37 },
|
|
33
|
-
{ id: 'biaodan14', code: '', label: '表单14', value: 38 },
|
|
34
|
-
{ id: 'biaodan15', code: '', label: '表单15', value: 39 },
|
|
35
|
-
{ id: 'biaodan16', code: '', label: '表单16', value: 40 },
|
|
36
|
-
{ id: 'biaodan17', code: '', label: '表单17', value: 41 },
|
|
37
|
-
{ id: 'biaodan18', code: '', label: '表单18', value: 42 },
|
|
38
|
-
{ id: 'biaodan19', code: '', label: '表单19', value: 43 },
|
|
39
|
-
{ id: 'biaodan20', code: '', label: '表单20', value: 44 },
|
|
40
|
-
{ id: 'biaodan21', code: '', label: '表单21', value: 45 },
|
|
41
|
-
{ id: 'biaodan22', code: '', label: '表单22', value: 46 },
|
|
42
|
-
{ id: 'biaodan23', code: '', label: '表单23', value: 47 },
|
|
43
|
-
{ id: 'biaodan24', code: '', label: '表单24', value: 48 },
|
|
44
|
-
{ id: 'biaodan25', code: '', label: '表单25', value: 49 },
|
|
45
|
-
{ id: 'biaodan26', code: '', label: '表单26', value: 50 },
|
|
46
|
-
{ id: 'biaodan27', code: '', label: '表单27', value: 51 },
|
|
47
|
-
{ id: 'biaodan28', code: '', label: '表单28', value: 52 },
|
|
48
|
-
{ id: 'biaodan29', code: '', label: '表单29', value: 53 },
|
|
49
|
-
{ id: 'biaodan30', code: '', label: '表单30', value: 54 },
|
|
50
|
-
{ id: 'biaodan31', code: '', label: '表单31', value: 55 },
|
|
51
|
-
{ id: 'biaodan32', code: '', label: '表单32', value: 56 },
|
|
52
|
-
{ id: 'biaodan33', code: '', label: '表单33', value: 57 },
|
|
53
|
-
{ id: 'biaodan34', code: '', label: '表单34', value: 58 },
|
|
54
|
-
{ id: 'biaodan35', code: '', label: '表单35', value: 59 },
|
|
55
|
-
{ id: 'biaodan36', code: '', label: '表单36', value: 60 },
|
|
56
|
-
];
|
|
57
|
-
|
|
58
18
|
// Form icon component with blue background - dynamically shows selected icon
|
|
59
19
|
const FormIcon = ({
|
|
60
20
|
size = 36,
|
|
@@ -116,7 +76,7 @@ export const FormInfoEditor = memo(
|
|
|
116
76
|
name,
|
|
117
77
|
onNameChange,
|
|
118
78
|
onMount,
|
|
119
|
-
selectedIcon,
|
|
79
|
+
selectedIcon = FORM_ICON_OPTIONS[0],
|
|
120
80
|
iconOptions = [],
|
|
121
81
|
onIconChange,
|
|
122
82
|
readonly,
|
|
@@ -1,11 +1,13 @@
|
|
|
1
|
-
|
|
1
|
+
import classNames from "classnames";
|
|
2
|
+
|
|
3
|
+
export const GenerateAnimation = (props: { children?: React.ReactNode, className?: string }) => {
|
|
2
4
|
return (
|
|
3
|
-
<div className="flex items-center gap-[6px]">
|
|
5
|
+
<div className={classNames("flex items-center gap-[6px]", props.className)}>
|
|
4
6
|
<div className="flex gap-[2px] flex-shrink-0" style={{ marginRight: '6px' }}>
|
|
5
7
|
<div
|
|
6
8
|
className="w-[5px] h-[5px] rounded-full bg-[#999] flex-shrink-0"
|
|
7
9
|
style={{
|
|
8
|
-
animation: 'pulse 1.
|
|
10
|
+
animation: 'pulse 1.0s ease-in-out infinite',
|
|
9
11
|
animationDelay: '0s',
|
|
10
12
|
width: '5px',
|
|
11
13
|
height: '5px',
|
|
@@ -16,7 +18,7 @@ export const GenerateAnimation = (props: { children?: React.ReactNode }) => {
|
|
|
16
18
|
<div
|
|
17
19
|
className="w-[5px] h-[5px] rounded-full bg-[#999] flex-shrink-0"
|
|
18
20
|
style={{
|
|
19
|
-
animation: 'pulse 1.
|
|
21
|
+
animation: 'pulse 1.0s ease-in-out infinite',
|
|
20
22
|
width: '5px',
|
|
21
23
|
height: '5px',
|
|
22
24
|
background: '#999',
|
|
@@ -27,7 +29,7 @@ export const GenerateAnimation = (props: { children?: React.ReactNode }) => {
|
|
|
27
29
|
<div
|
|
28
30
|
className="w-[5px] h-[5px] rounded-full bg-[#999] flex-shrink-0"
|
|
29
31
|
style={{
|
|
30
|
-
animation: 'pulse 1.
|
|
32
|
+
animation: 'pulse 1.0s ease-in-out infinite',
|
|
31
33
|
width: '5px',
|
|
32
34
|
height: '5px',
|
|
33
35
|
marginRight: '3px',
|
|
@@ -11,7 +11,7 @@ export interface ImgMsgPartProps {
|
|
|
11
11
|
export const ImgMsgPart = ({ url, alt = '', className, size = 102 }: ImgMsgPartProps) => {
|
|
12
12
|
return (
|
|
13
13
|
<div
|
|
14
|
-
className={cn('relative overflow-hidden rounded-[10px]', className)}
|
|
14
|
+
className={cn('relative overflow-hidden rounded-[10px] border border-[#e0e0e0]', className)}
|
|
15
15
|
style={{ width: size, height: size }}
|
|
16
16
|
>
|
|
17
17
|
<img
|
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import React, { CSSProperties, useState } from 'react';
|
|
2
|
-
import { Checkbox } from '@/components/ui/checkbox';
|
|
1
|
+
import React, { CSSProperties, useEffect, useState } from 'react';
|
|
3
2
|
import classNames from 'classnames';
|
|
4
3
|
import { cn } from '@/lib/utils';
|
|
5
4
|
import { CheckerIcon } from './bs-icons';
|
|
@@ -7,6 +6,7 @@ import { SquareChecker } from './square-checker';
|
|
|
7
6
|
|
|
8
7
|
export interface LineCheckerProps {
|
|
9
8
|
defaultChecked?: boolean;
|
|
9
|
+
checked?: boolean;
|
|
10
10
|
disabled?: boolean;
|
|
11
11
|
onCheckedChange?: (checked: boolean) => void;
|
|
12
12
|
|
|
@@ -24,6 +24,7 @@ export interface LineCheckerProps {
|
|
|
24
24
|
|
|
25
25
|
export const LineChecker: React.FC<LineCheckerProps> = ({
|
|
26
26
|
defaultChecked = false,
|
|
27
|
+
checked: checkedProp,
|
|
27
28
|
disabled = false,
|
|
28
29
|
onCheckedChange,
|
|
29
30
|
icon,
|
|
@@ -38,6 +39,12 @@ export const LineChecker: React.FC<LineCheckerProps> = ({
|
|
|
38
39
|
}) => {
|
|
39
40
|
const [checked, setChecked] = useState(defaultChecked);
|
|
40
41
|
|
|
42
|
+
useEffect(() => {
|
|
43
|
+
if (checkedProp !== undefined) {
|
|
44
|
+
setChecked(checkedProp);
|
|
45
|
+
}
|
|
46
|
+
}, [checkedProp]);
|
|
47
|
+
|
|
41
48
|
const handleClick = () => {
|
|
42
49
|
if (streaming || disabled) return;
|
|
43
50
|
|
|
@@ -111,7 +118,7 @@ export const LineChecker: React.FC<LineCheckerProps> = ({
|
|
|
111
118
|
|
|
112
119
|
{/* Title - truncates */}
|
|
113
120
|
<p
|
|
114
|
-
className={classNames(' min-w-0 text-sm text-[#121111] truncate', {
|
|
121
|
+
className={classNames(' min-w-0 text-sm text-[#121111] truncate text-[12px]', {
|
|
115
122
|
'flex-1': !!icon,
|
|
116
123
|
'flex-grow-1 flex-shrink-0': !icon,
|
|
117
124
|
'!text-[#666]': readonly,
|
|
@@ -123,7 +130,7 @@ export const LineChecker: React.FC<LineCheckerProps> = ({
|
|
|
123
130
|
|
|
124
131
|
{shortDesc && (
|
|
125
132
|
<p
|
|
126
|
-
className={classNames('text-sm text-[#666]', {
|
|
133
|
+
className={classNames('text-sm text-[#666] text-[12px]', {
|
|
127
134
|
'whitespace-nowrap flex-shrink-0': !!icon,
|
|
128
135
|
anywhere: !icon,
|
|
129
136
|
'!text-[#121111]': readonly,
|
|
@@ -134,7 +141,14 @@ export const LineChecker: React.FC<LineCheckerProps> = ({
|
|
|
134
141
|
)}
|
|
135
142
|
</div>
|
|
136
143
|
{hasExtra ? (
|
|
137
|
-
<div
|
|
144
|
+
<div
|
|
145
|
+
className={cn(
|
|
146
|
+
'overflow-x-auto whitespace-nowrap no-scrollbar flex items-center gap-2',
|
|
147
|
+
{
|
|
148
|
+
'!overflow-x-hidden': disabled || readonly || confirmed,
|
|
149
|
+
}
|
|
150
|
+
)}
|
|
151
|
+
>
|
|
138
152
|
{extra}
|
|
139
153
|
</div>
|
|
140
154
|
) : null}
|
|
@@ -4,6 +4,7 @@ import { IconBtn } from './icon-btn';
|
|
|
4
4
|
import { BackIcon, InfoIcon } from './bs-icons';
|
|
5
5
|
import { LinearGradientColorBgAnimation } from './linear-gradient-color-bg-animation';
|
|
6
6
|
import { ConfirmDialog } from './confirm-dialog';
|
|
7
|
+
import { Spinner } from '../ui/spinner';
|
|
7
8
|
|
|
8
9
|
export interface PreviewerHeaderProps {
|
|
9
10
|
title: string;
|
|
@@ -11,7 +12,7 @@ export interface PreviewerHeaderProps {
|
|
|
11
12
|
active?: boolean;
|
|
12
13
|
className?: string;
|
|
13
14
|
onBackClick?: () => void;
|
|
14
|
-
onSave?: () => void;
|
|
15
|
+
onSave?: (isConfirm?: boolean) => void;
|
|
15
16
|
onCancel?: () => void;
|
|
16
17
|
style?: React.CSSProperties;
|
|
17
18
|
|
|
@@ -21,6 +22,8 @@ export interface PreviewerHeaderProps {
|
|
|
21
22
|
variant?: 'fields-previewer' | 'data-previewer';
|
|
22
23
|
closeBtnLabel?: string;
|
|
23
24
|
|
|
25
|
+
disableConfirm?: boolean;
|
|
26
|
+
|
|
24
27
|
disableOperation?: boolean;
|
|
25
28
|
}
|
|
26
29
|
|
|
@@ -38,6 +41,7 @@ export const PreviewerHeader = ({
|
|
|
38
41
|
onCancel,
|
|
39
42
|
variant = 'fields-previewer',
|
|
40
43
|
dialogContainer,
|
|
44
|
+
disableConfirm,
|
|
41
45
|
disableOperation,
|
|
42
46
|
}: PreviewerHeaderProps) => {
|
|
43
47
|
const [showConfirmDialog, setShowConfirmDialog] = useState(false);
|
|
@@ -62,7 +66,19 @@ export const PreviewerHeader = ({
|
|
|
62
66
|
{isData ? null : (
|
|
63
67
|
<IconBtn
|
|
64
68
|
icon={<BackIcon />}
|
|
65
|
-
onClick={() =>
|
|
69
|
+
onClick={() => {
|
|
70
|
+
if (disableOperation) {
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
if (disableConfirm) {
|
|
75
|
+
onCancel?.();
|
|
76
|
+
onBackClick?.();
|
|
77
|
+
return;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
setShowConfirmDialog(true);
|
|
81
|
+
}}
|
|
66
82
|
className="text-[#0265FF] hover:text-[#0265FF]"
|
|
67
83
|
/>
|
|
68
84
|
)}
|
|
@@ -89,6 +105,7 @@ export const PreviewerHeader = ({
|
|
|
89
105
|
}}
|
|
90
106
|
className={classNames(
|
|
91
107
|
btnResetStyle,
|
|
108
|
+
'flex items-center gap-[6px]',
|
|
92
109
|
'bg-[#0265FF] hover:opacity-90 text-white text-[14px]',
|
|
93
110
|
{
|
|
94
111
|
'w-[115px]': isData,
|
|
@@ -96,12 +113,23 @@ export const PreviewerHeader = ({
|
|
|
96
113
|
}
|
|
97
114
|
)}
|
|
98
115
|
>
|
|
116
|
+
{loading ? <Spinner /> : null}
|
|
99
117
|
{isFields ? '保存' : '添加到表单'}
|
|
100
118
|
</button>
|
|
101
119
|
)}
|
|
102
120
|
{onCancel && (
|
|
103
121
|
<button
|
|
104
122
|
onClick={() => {
|
|
123
|
+
if (disableOperation) {
|
|
124
|
+
return;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
if (disableConfirm) {
|
|
128
|
+
onCancel?.();
|
|
129
|
+
onBackClick?.();
|
|
130
|
+
return;
|
|
131
|
+
}
|
|
132
|
+
|
|
105
133
|
setShowConfirmDialog(true);
|
|
106
134
|
}}
|
|
107
135
|
className={classNames(
|
|
@@ -132,7 +160,7 @@ export const PreviewerHeader = ({
|
|
|
132
160
|
setShowConfirmDialog(false);
|
|
133
161
|
setLoading(true);
|
|
134
162
|
try {
|
|
135
|
-
await onSave?.();
|
|
163
|
+
await onSave?.(true);
|
|
136
164
|
} catch (error) {
|
|
137
165
|
console.error('Save failed:', error);
|
|
138
166
|
} finally {
|
|
@@ -3,15 +3,32 @@ import * as CheckboxPrimitive from '@radix-ui/react-checkbox';
|
|
|
3
3
|
import { cn } from '@/lib/utils';
|
|
4
4
|
import { CheckerInBoxIcon } from './bs-icons';
|
|
5
5
|
|
|
6
|
+
const SquareInBoxIcon = () => {
|
|
7
|
+
// size 8, border 1px svg
|
|
8
|
+
return (
|
|
9
|
+
<svg
|
|
10
|
+
width="8"
|
|
11
|
+
height="8"
|
|
12
|
+
viewBox="0 0 8 8"
|
|
13
|
+
// fill="currentColor"
|
|
14
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
15
|
+
>
|
|
16
|
+
<rect x="0.5" y="0.5" width="7" height="7" rx="1" fill="#0265ff" />
|
|
17
|
+
</svg>
|
|
18
|
+
);
|
|
19
|
+
};
|
|
20
|
+
|
|
6
21
|
export type SquareCheckerProps = React.ComponentPropsWithoutRef<typeof CheckboxPrimitive.Root> & {
|
|
7
22
|
/** Optional label rendered beside the checkbox */
|
|
8
23
|
children?: React.ReactNode;
|
|
24
|
+
readonly?: boolean;
|
|
25
|
+
intermediate?: boolean;
|
|
9
26
|
};
|
|
10
27
|
|
|
11
28
|
export const SquareChecker = React.forwardRef<
|
|
12
29
|
React.ElementRef<typeof CheckboxPrimitive.Root>,
|
|
13
30
|
SquareCheckerProps
|
|
14
|
-
>(({ className, children, id, disabled, ...props }, ref) => {
|
|
31
|
+
>(({ className, children, id, readonly, disabled, intermediate, ...props }, ref) => {
|
|
15
32
|
const generatedId = React.useId();
|
|
16
33
|
const checkboxId = id ?? generatedId;
|
|
17
34
|
|
|
@@ -20,7 +37,10 @@ export const SquareChecker = React.forwardRef<
|
|
|
20
37
|
htmlFor={checkboxId}
|
|
21
38
|
className={cn(
|
|
22
39
|
'inline-flex items-center gap-[6px] select-none text-[#121111] text-[14px]',
|
|
23
|
-
disabled ? 'cursor-not-allowed' : 'cursor-pointer'
|
|
40
|
+
disabled ? 'cursor-not-allowed' : 'cursor-pointer',
|
|
41
|
+
{
|
|
42
|
+
'pointer-events-none': readonly,
|
|
43
|
+
}
|
|
24
44
|
)}
|
|
25
45
|
>
|
|
26
46
|
<CheckboxPrimitive.Root
|
|
@@ -43,12 +63,17 @@ export const SquareChecker = React.forwardRef<
|
|
|
43
63
|
'disabled:cursor-not-allowed disabled:bg-[#F0F0F0] disabled:border-[#C2C2C2]',
|
|
44
64
|
// disabled checked: use muted gray fill
|
|
45
65
|
'disabled:data-[state=checked]:bg-[#C2C2C2] disabled:data-[state=checked]:border-[#C2C2C2]',
|
|
46
|
-
|
|
66
|
+
// indeterminate: blue fill
|
|
67
|
+
intermediate && 'bg-white border-[#0265FF] text-[#0265FF]',
|
|
68
|
+
className,
|
|
69
|
+
{
|
|
70
|
+
'opacity-50': readonly,
|
|
71
|
+
}
|
|
47
72
|
)}
|
|
48
73
|
{...props}
|
|
49
74
|
>
|
|
50
|
-
<CheckboxPrimitive.Indicator className="text-white">
|
|
51
|
-
<CheckerInBoxIcon />
|
|
75
|
+
<CheckboxPrimitive.Indicator className="text-white" forceMount={intermediate || undefined}>
|
|
76
|
+
{intermediate ? <SquareInBoxIcon /> : <CheckerInBoxIcon />}
|
|
52
77
|
</CheckboxPrimitive.Indicator>
|
|
53
78
|
</CheckboxPrimitive.Root>
|
|
54
79
|
|
|
@@ -44,7 +44,7 @@ export const BsTooltip = ({
|
|
|
44
44
|
</TooltipTrigger>
|
|
45
45
|
<TooltipContent
|
|
46
46
|
portalContainer={portalContainer}
|
|
47
|
-
className="rounded-[4px] bg-[#525867] px-[12px] !py-[7px] text-[12px] text-white leading-normal max-w-[288px]"
|
|
47
|
+
className="rounded-[4px] bg-[#525867] px-[12px] !py-[7px] text-[12px] text-white leading-normal max-w-[288px] animate-in fade-in-0 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 duration-200"
|
|
48
48
|
>
|
|
49
49
|
{content}
|
|
50
50
|
</TooltipContent>
|
|
@@ -40,7 +40,7 @@ const DialogContent = React.forwardRef<
|
|
|
40
40
|
style={{ padding: 0 }}
|
|
41
41
|
ref={ref}
|
|
42
42
|
className={cn(
|
|
43
|
-
'left-[50%] top-[50%] z-50 grid w-full max-w-lg translate-x-[-50%] translate-y-[-50%] gap-4 border bg-background p-6 shadow-lg duration-200 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95
|
|
43
|
+
'left-[50%] top-[50%] z-50 grid w-full max-w-lg translate-x-[-50%] translate-y-[-50%] gap-4 border bg-background p-6 shadow-lg duration-200 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 sm:rounded-lg',
|
|
44
44
|
container ? 'absolute' : 'fixed',
|
|
45
45
|
className
|
|
46
46
|
)}
|
|
@@ -42,7 +42,7 @@ const TooltipContent = React.forwardRef<
|
|
|
42
42
|
{...props}
|
|
43
43
|
>
|
|
44
44
|
{props.children}
|
|
45
|
-
<TooltipPrimitive.Arrow className="fill-[#525867]" />
|
|
45
|
+
<TooltipPrimitive.Arrow className="fill-[#525867] stroke-[#525867] stroke-[2px] stroke-linejoin-round [paint-order:stroke_fill]" />
|
|
46
46
|
</TooltipPrimitive.Content>
|
|
47
47
|
</TooltipPrimitive.Portal>
|
|
48
48
|
);
|
package/src/const/ui.ts
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { FormIconOption } from '@/components/bs-ui/form-info-editor';
|
|
2
|
+
|
|
1
3
|
export const BotImgUrl = `
|
|
2
4
|
url(data:image/png;base64,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)
|
|
3
5
|
`;
|
|
@@ -8,3 +10,43 @@ url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAPAAAACaCAMAAACg5DWcAAAC/VBMVE
|
|
|
8
10
|
export const ChatHeaderBgImgUrl = `url(data:image/png;base64,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)`;
|
|
9
11
|
|
|
10
12
|
export const transCls = 'transition-all duration-200 ease-out';
|
|
13
|
+
// Form icon data from iconfont.json (icons with name starting with "表单")
|
|
14
|
+
|
|
15
|
+
export const FORM_ICON_OPTIONS: FormIconOption[] = [
|
|
16
|
+
{ id: 'biaodan1', code: '', label: '表单1', value: 25 },
|
|
17
|
+
{ id: 'biaodan2', code: '', label: '表单2', value: 26 },
|
|
18
|
+
{ id: 'biaodan3', code: '', label: '表单3', value: 27 },
|
|
19
|
+
{ id: 'biaodan4', code: '', label: '表单4', value: 28 },
|
|
20
|
+
{ id: 'biaodan5', code: '', label: '表单5', value: 29 },
|
|
21
|
+
{ id: 'biaodan6', code: '', label: '表单6', value: 30 },
|
|
22
|
+
{ id: 'biaodan7', code: '', label: '表单7', value: 31 },
|
|
23
|
+
{ id: 'biaodan8', code: '', label: '表单8', value: 32 },
|
|
24
|
+
{ id: 'biaodan9', code: '', label: '表单9', value: 33 },
|
|
25
|
+
{ id: 'biaodan10', code: '', label: '表单10', value: 34 },
|
|
26
|
+
{ id: 'biaodan11', code: '', label: '表单11', value: 35 },
|
|
27
|
+
{ id: 'biaodan12', code: '', label: '表单12', value: 36 },
|
|
28
|
+
{ id: 'biaodan13', code: '', label: '表单13', value: 37 },
|
|
29
|
+
{ id: 'biaodan14', code: '', label: '表单14', value: 38 },
|
|
30
|
+
{ id: 'biaodan15', code: '', label: '表单15', value: 39 },
|
|
31
|
+
{ id: 'biaodan16', code: '', label: '表单16', value: 40 },
|
|
32
|
+
{ id: 'biaodan17', code: '', label: '表单17', value: 41 },
|
|
33
|
+
{ id: 'biaodan18', code: '', label: '表单18', value: 42 },
|
|
34
|
+
{ id: 'biaodan19', code: '', label: '表单19', value: 43 },
|
|
35
|
+
{ id: 'biaodan20', code: '', label: '表单20', value: 44 },
|
|
36
|
+
{ id: 'biaodan21', code: '', label: '表单21', value: 45 },
|
|
37
|
+
{ id: 'biaodan22', code: '', label: '表单22', value: 46 },
|
|
38
|
+
{ id: 'biaodan23', code: '', label: '表单23', value: 47 },
|
|
39
|
+
{ id: 'biaodan24', code: '', label: '表单24', value: 48 },
|
|
40
|
+
{ id: 'biaodan25', code: '', label: '表单25', value: 49 },
|
|
41
|
+
{ id: 'biaodan26', code: '', label: '表单26', value: 50 },
|
|
42
|
+
{ id: 'biaodan27', code: '', label: '表单27', value: 51 },
|
|
43
|
+
{ id: 'biaodan28', code: '', label: '表单28', value: 52 },
|
|
44
|
+
{ id: 'biaodan29', code: '', label: '表单29', value: 53 },
|
|
45
|
+
{ id: 'biaodan30', code: '', label: '表单30', value: 54 },
|
|
46
|
+
{ id: 'biaodan31', code: '', label: '表单31', value: 55 },
|
|
47
|
+
{ id: 'biaodan32', code: '', label: '表单32', value: 56 },
|
|
48
|
+
{ id: 'biaodan33', code: '', label: '表单33', value: 57 },
|
|
49
|
+
{ id: 'biaodan34', code: '', label: '表单34', value: 58 },
|
|
50
|
+
{ id: 'biaodan35', code: '', label: '表单35', value: 59 },
|
|
51
|
+
{ id: 'biaodan36', code: '', label: '表单36', value: 60 },
|
|
52
|
+
];
|
|
@@ -17,6 +17,21 @@ export const useChatStatus = () => {
|
|
|
17
17
|
};
|
|
18
18
|
};
|
|
19
19
|
|
|
20
|
+
export const useFakeGlobalLoadingMessage = () => {
|
|
21
|
+
const { globalFakeLoadingMessage, setGlobalFakeLoadingMessage, clearGlobalFakeLoadingMessage } =
|
|
22
|
+
useChatStore((store) => ({
|
|
23
|
+
globalFakeLoadingMessage: store.globalFakeLoadingMessage,
|
|
24
|
+
setGlobalFakeLoadingMessage: store.setGlobalFakeLoadingMessage,
|
|
25
|
+
clearGlobalFakeLoadingMessage: store.clearGlobalFakeLoadingMessage,
|
|
26
|
+
}));
|
|
27
|
+
|
|
28
|
+
return {
|
|
29
|
+
globalFakeLoadingMessage,
|
|
30
|
+
setGlobalFakeLoadingMessage,
|
|
31
|
+
clearGlobalFakeLoadingMessage,
|
|
32
|
+
};
|
|
33
|
+
};
|
|
34
|
+
|
|
20
35
|
/** @deprecated Use useChatStatus instead */
|
|
21
36
|
export const useFrameMode = () => {
|
|
22
37
|
const { status, setStatus } = useChatStatus();
|