bi-sdk-react 0.0.3 → 0.0.4
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/dist/es/js/bi-sdk.es.js +53 -32
- package/dist/types/components/PageDesigner.d.ts +1 -1
- package/dist/types/components/panel/ChatInput.d.ts +1 -1
- package/dist/types/components/plugins/@antd/item-props/CheckboxProps.d.ts +3 -3
- package/dist/types/components/plugins/@antd/item-props/ColProps.d.ts +2 -2
- package/dist/umd/js/bi-sdk.umd.min.js +43 -22
- package/package.json +1 -1
- package/src/components/PageDesigner.tsx +69 -4
- package/src/components/panel/ChatInput.tsx +76 -46
- package/src/components/panel/PropertiesPanel.tsx +2 -2
- package/src/components/plugins/@antd/index.ts +0 -1
- package/src/components/plugins/@antd/item-props/CapsuleProps.tsx +1 -1
- package/src/components/plugins/@antd/item-props/CheckboxProps.tsx +90 -42
- package/src/components/plugins/@antd/item-props/ColProps.tsx +139 -25
- package/src/components/plugins/@antd/item-props/SelectProps.tsx +1 -1
- package/src/components/plugins/@antd/item-props/TextProps.tsx +1 -2
package/package.json
CHANGED
|
@@ -2,6 +2,7 @@ import {
|
|
|
2
2
|
DesktopOutlined,
|
|
3
3
|
EyeInvisibleOutlined,
|
|
4
4
|
EyeOutlined,
|
|
5
|
+
ImportOutlined,
|
|
5
6
|
MobileOutlined,
|
|
6
7
|
RedoOutlined,
|
|
7
8
|
SaveOutlined,
|
|
@@ -10,13 +11,12 @@ import {
|
|
|
10
11
|
ZoomInOutlined,
|
|
11
12
|
ZoomOutOutlined,
|
|
12
13
|
} from "@ant-design/icons";
|
|
13
|
-
import { Button, Divider, Radio, Space, Tooltip } from "antd";
|
|
14
|
+
import { Button, Divider, Modal, Radio, Space, Tooltip } from "antd";
|
|
14
15
|
import React, {
|
|
15
|
-
useEffect,
|
|
16
16
|
useImperativeHandle,
|
|
17
17
|
useMemo,
|
|
18
18
|
useRef,
|
|
19
|
-
useState
|
|
19
|
+
useState
|
|
20
20
|
} from "react";
|
|
21
21
|
import styled from "styled-components";
|
|
22
22
|
import { IconFont } from "./icon/IconFont";
|
|
@@ -32,10 +32,11 @@ import { PropertiesPanel } from "./panel/PropertiesPanel";
|
|
|
32
32
|
import { ScriptPanel } from "./panel/ScriptPanel";
|
|
33
33
|
import { VariablesPanel } from "./panel/VariablesPanel";
|
|
34
34
|
|
|
35
|
-
import {
|
|
35
|
+
import { Editor } from "@monaco-editor/react";
|
|
36
36
|
import { DesignerProvider } from "./context/DesignerContext";
|
|
37
37
|
import { useDeepCompareEffect } from "./hooks/useDeepCompareEffect";
|
|
38
38
|
import "./styles.css";
|
|
39
|
+
import { PageSchema, PluginType } from "./typing";
|
|
39
40
|
|
|
40
41
|
export type PageDesignerProps = {
|
|
41
42
|
agentList?: any[];
|
|
@@ -135,6 +136,46 @@ const Container = styled.div`
|
|
|
135
136
|
}
|
|
136
137
|
`;
|
|
137
138
|
|
|
139
|
+
const ImportModal: React.FC<{
|
|
140
|
+
open?: boolean;
|
|
141
|
+
onCancel?: () => void;
|
|
142
|
+
onOk?: (schema: PageSchema) => void;
|
|
143
|
+
}> = ({ open, onCancel, onOk }) => {
|
|
144
|
+
const [importSchema, setImportSchema] = useState<string>(
|
|
145
|
+
JSON.stringify({
|
|
146
|
+
info: {},
|
|
147
|
+
datasources: [],
|
|
148
|
+
scripts: [],
|
|
149
|
+
variables: [],
|
|
150
|
+
items: [],
|
|
151
|
+
})
|
|
152
|
+
);
|
|
153
|
+
return (
|
|
154
|
+
<Modal
|
|
155
|
+
title="导入页面"
|
|
156
|
+
open={open}
|
|
157
|
+
width={800}
|
|
158
|
+
onCancel={onCancel}
|
|
159
|
+
onOk={() => onOk?.(JSON.parse(importSchema))}
|
|
160
|
+
okText="导入"
|
|
161
|
+
cancelText="取消"
|
|
162
|
+
styles={{ body: { height: "calc(100vh - 250px)", overflow: "auto" } }}
|
|
163
|
+
>
|
|
164
|
+
<div className="body" style={{ flex: "1 1 auto", display: "flex", height: "100%" }}>
|
|
165
|
+
<Editor
|
|
166
|
+
height="100%"
|
|
167
|
+
defaultLanguage="json"
|
|
168
|
+
value={importSchema}
|
|
169
|
+
options={{
|
|
170
|
+
minimap: { enabled: false },
|
|
171
|
+
}}
|
|
172
|
+
onChange={(v) => setImportSchema(v || "")}
|
|
173
|
+
/>
|
|
174
|
+
</div>
|
|
175
|
+
</Modal>
|
|
176
|
+
);
|
|
177
|
+
};
|
|
178
|
+
|
|
138
179
|
export const PageDesigner = React.forwardRef<any, PageDesignerProps>(
|
|
139
180
|
({ agentList = [], plugins = [], headerExtra }, ref) => {
|
|
140
181
|
const pageCanvasRef = useRef<any>(null);
|
|
@@ -162,6 +203,7 @@ export const PageDesigner = React.forwardRef<any, PageDesignerProps>(
|
|
|
162
203
|
items: [],
|
|
163
204
|
});
|
|
164
205
|
const [designable, setDesignable] = useState(true);
|
|
206
|
+
const [importModalOpen, setImportModalOpen] = useState(false);
|
|
165
207
|
const containerStyle = useMemo(() => {
|
|
166
208
|
const left = showLeft ? "250px" : "";
|
|
167
209
|
const right = showRight ? "400px" : "";
|
|
@@ -252,6 +294,15 @@ export const PageDesigner = React.forwardRef<any, PageDesignerProps>(
|
|
|
252
294
|
setTimeout(() => pageCanvasRef.current?.handleResize?.(), 0);
|
|
253
295
|
};
|
|
254
296
|
|
|
297
|
+
const handleImportClick = () => {
|
|
298
|
+
setImportModalOpen(true);
|
|
299
|
+
};
|
|
300
|
+
|
|
301
|
+
const handleImportOk = (s: PageSchema) => {
|
|
302
|
+
setImportModalOpen(false);
|
|
303
|
+
setSchema(s);
|
|
304
|
+
};
|
|
305
|
+
|
|
255
306
|
return (
|
|
256
307
|
<DesignerProvider
|
|
257
308
|
designable={designable}
|
|
@@ -300,6 +351,15 @@ export const PageDesigner = React.forwardRef<any, PageDesignerProps>(
|
|
|
300
351
|
<RedoOutlined />
|
|
301
352
|
</a>
|
|
302
353
|
</Tooltip>
|
|
354
|
+
<Divider orientation="vertical" />
|
|
355
|
+
<Tooltip title="导入JSON">
|
|
356
|
+
<a
|
|
357
|
+
className={`toolbar ${future.length > 0 ? "active" : ""}`}
|
|
358
|
+
onClick={handleImportClick}
|
|
359
|
+
>
|
|
360
|
+
<ImportOutlined />
|
|
361
|
+
</a>
|
|
362
|
+
</Tooltip>
|
|
303
363
|
</Space>
|
|
304
364
|
<Space>
|
|
305
365
|
<Tooltip title="缩小">
|
|
@@ -501,6 +561,11 @@ export const PageDesigner = React.forwardRef<any, PageDesignerProps>(
|
|
|
501
561
|
</div>
|
|
502
562
|
</Container>
|
|
503
563
|
</div>
|
|
564
|
+
<ImportModal
|
|
565
|
+
open={importModalOpen}
|
|
566
|
+
onOk={handleImportOk}
|
|
567
|
+
onCancel={() => setImportModalOpen(false)}
|
|
568
|
+
/>
|
|
504
569
|
</DesignerProvider>
|
|
505
570
|
);
|
|
506
571
|
}
|
|
@@ -1,3 +1,17 @@
|
|
|
1
|
+
import {
|
|
2
|
+
DeleteOutlined,
|
|
3
|
+
PaperClipOutlined,
|
|
4
|
+
SendOutlined,
|
|
5
|
+
} from "@ant-design/icons";
|
|
6
|
+
import {
|
|
7
|
+
Button,
|
|
8
|
+
Dropdown,
|
|
9
|
+
Input,
|
|
10
|
+
Switch,
|
|
11
|
+
Tooltip,
|
|
12
|
+
Typography,
|
|
13
|
+
Upload,
|
|
14
|
+
} from "antd";
|
|
1
15
|
import React, {
|
|
2
16
|
useEffect,
|
|
3
17
|
useImperativeHandle,
|
|
@@ -6,9 +20,8 @@ import React, {
|
|
|
6
20
|
useState,
|
|
7
21
|
} from "react";
|
|
8
22
|
import styled from "styled-components";
|
|
9
|
-
import { Input, Button, Space, Tooltip, Dropdown, Switch, Upload } from "antd";
|
|
10
|
-
import { PaperClipOutlined, SendOutlined } from "@ant-design/icons";
|
|
11
23
|
import * as XLSX from "xlsx";
|
|
24
|
+
import { IconFont } from "../icon/IconFont";
|
|
12
25
|
|
|
13
26
|
export type ChatInputProps = {
|
|
14
27
|
value?: string;
|
|
@@ -24,7 +37,7 @@ export type ChatInputProps = {
|
|
|
24
37
|
onSubmit?: (data: {
|
|
25
38
|
demand: string;
|
|
26
39
|
title: string;
|
|
27
|
-
|
|
40
|
+
agentIds?: (string | number)[];
|
|
28
41
|
csvData: Record<string, string>;
|
|
29
42
|
}) => void;
|
|
30
43
|
onUpdateTitle?: (title: string) => void;
|
|
@@ -93,6 +106,11 @@ const Wrapper = styled.div`
|
|
|
93
106
|
background-color: #fafafa;
|
|
94
107
|
font-size: 12px;
|
|
95
108
|
position: relative;
|
|
109
|
+
|
|
110
|
+
.anticon {
|
|
111
|
+
font-size: 36px;
|
|
112
|
+
color: var(--ant-green-8);
|
|
113
|
+
}
|
|
96
114
|
}
|
|
97
115
|
.attachment-card .name {
|
|
98
116
|
max-width: 80px;
|
|
@@ -108,9 +126,19 @@ const Wrapper = styled.div`
|
|
|
108
126
|
position: absolute;
|
|
109
127
|
top: 4px;
|
|
110
128
|
right: 2px;
|
|
129
|
+
|
|
130
|
+
.anticon {
|
|
131
|
+
font-size: 12px;
|
|
132
|
+
color: var(--ant-color-text-tertiary);
|
|
133
|
+
}
|
|
111
134
|
}
|
|
112
135
|
.attachment-card .remove:hover {
|
|
113
136
|
color: #666;
|
|
137
|
+
|
|
138
|
+
.anticon {
|
|
139
|
+
font-size: 12px;
|
|
140
|
+
color: var(--ant-color-text-secondary);
|
|
141
|
+
}
|
|
114
142
|
}
|
|
115
143
|
.agent-info {
|
|
116
144
|
box-sizing: border-box;
|
|
@@ -120,11 +148,17 @@ const Wrapper = styled.div`
|
|
|
120
148
|
border-bottom: none;
|
|
121
149
|
background-color: #eff1f9;
|
|
122
150
|
font-size: 14px;
|
|
123
|
-
color:
|
|
151
|
+
color: var(--ant-color-text-label);
|
|
124
152
|
display: flex;
|
|
125
153
|
align-items: center;
|
|
126
|
-
|
|
154
|
+
flex-wrap: wrap;
|
|
127
155
|
user-select: none;
|
|
156
|
+
gap: 8px;
|
|
157
|
+
|
|
158
|
+
a {
|
|
159
|
+
color: var(--ant-color-text-disabled);
|
|
160
|
+
margin-left: 4px;
|
|
161
|
+
}
|
|
128
162
|
}
|
|
129
163
|
.attachment-bar + .agent-info {
|
|
130
164
|
border-radius: 0;
|
|
@@ -249,7 +283,7 @@ const Wrapper = styled.div`
|
|
|
249
283
|
width: 50px;
|
|
250
284
|
height: 26px;
|
|
251
285
|
color: #fff;
|
|
252
|
-
font-size:
|
|
286
|
+
font-size: 14px;
|
|
253
287
|
background-color: rgb(184, 184, 191);
|
|
254
288
|
border: unset;
|
|
255
289
|
border-radius: 14px;
|
|
@@ -257,7 +291,7 @@ const Wrapper = styled.div`
|
|
|
257
291
|
cursor: pointer;
|
|
258
292
|
}
|
|
259
293
|
.send-btn.send-btn-active {
|
|
260
|
-
background-color: var(--
|
|
294
|
+
background-color: var(--ant-color-primary);
|
|
261
295
|
}
|
|
262
296
|
`;
|
|
263
297
|
|
|
@@ -289,13 +323,12 @@ export const ChatInput = React.forwardRef<
|
|
|
289
323
|
) => {
|
|
290
324
|
const inputRef = useRef<any>(null);
|
|
291
325
|
const [localTitle, setLocalTitle] = useState(title || "");
|
|
292
|
-
const [
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
} | null>(null);
|
|
326
|
+
const [selectedAgent, setSelectedAgent] = useState<
|
|
327
|
+
{
|
|
328
|
+
id: string | number;
|
|
329
|
+
name: string;
|
|
330
|
+
}[]
|
|
331
|
+
>([]);
|
|
299
332
|
const [localValue, setLocalValue] = useState(value || "");
|
|
300
333
|
const [lastSubmitAt, setLastSubmitAt] = useState(0);
|
|
301
334
|
const minIntervalMs = 400;
|
|
@@ -316,21 +349,17 @@ export const ChatInput = React.forwardRef<
|
|
|
316
349
|
onInput && onInput(localValue);
|
|
317
350
|
}, [localValue]);
|
|
318
351
|
useEffect(() => setLocalTitle(title || ""), [title]);
|
|
319
|
-
useEffect(() => {
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
}, [agentId, agentList]);
|
|
352
|
+
// useEffect(() => {
|
|
353
|
+
// setSelectedAgent(
|
|
354
|
+
// agentId ? agentList.find((s) => s.id === agentId) || [] : []
|
|
355
|
+
// );
|
|
356
|
+
// }, [agentId, agentList]);
|
|
325
357
|
useEffect(
|
|
326
358
|
() => setLocalAttachments(Array.isArray(attachments) ? attachments : []),
|
|
327
359
|
[attachments]
|
|
328
360
|
);
|
|
329
361
|
const canSubmit = !!(localValue && localValue.trim());
|
|
330
|
-
|
|
331
|
-
if (!localAgentId) return null;
|
|
332
|
-
return agentList.find((it) => it.id === localAgentId) || null;
|
|
333
|
-
}, [localAgentId, agentList]);
|
|
362
|
+
|
|
334
363
|
const onTitleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
|
|
335
364
|
const v = e.target.value;
|
|
336
365
|
setLocalTitle(v);
|
|
@@ -338,14 +367,12 @@ export const ChatInput = React.forwardRef<
|
|
|
338
367
|
};
|
|
339
368
|
const onAgentSelect = (item: { id: string | number; name: string }) => {
|
|
340
369
|
const id = item.id || null;
|
|
341
|
-
setLocalAgentId(id);
|
|
342
370
|
onUpdateAgentId && onUpdateAgentId(id);
|
|
343
|
-
setSelectedAgent(item);
|
|
371
|
+
setSelectedAgent((prev) => [...prev, item]);
|
|
344
372
|
};
|
|
345
|
-
const
|
|
346
|
-
setLocalAgentId(null);
|
|
373
|
+
const onRemoveAgent = (index: number) => {
|
|
347
374
|
onUpdateAgentId && onUpdateAgentId(null);
|
|
348
|
-
setSelectedAgent(
|
|
375
|
+
setSelectedAgent((prev) => prev.filter((_, i) => i !== index));
|
|
349
376
|
};
|
|
350
377
|
const onKeydown = (e: React.KeyboardEvent<HTMLTextAreaElement>) => {
|
|
351
378
|
if (e.key === "Enter") {
|
|
@@ -415,7 +442,7 @@ export const ChatInput = React.forwardRef<
|
|
|
415
442
|
const data = {
|
|
416
443
|
demand: text,
|
|
417
444
|
title: showTitle ? localTitle : "",
|
|
418
|
-
|
|
445
|
+
agentIds: selectedAgent.map((it) => it.id),
|
|
419
446
|
csvData: localAttachments.reduce(
|
|
420
447
|
(acc, a) => ({ ...acc, [a.name]: a.csvBySheet }),
|
|
421
448
|
{}
|
|
@@ -442,31 +469,34 @@ export const ChatInput = React.forwardRef<
|
|
|
442
469
|
{localAttachments.length > 0 && (
|
|
443
470
|
<div className="attachment-bar">
|
|
444
471
|
{localAttachments.map((a) => (
|
|
445
|
-
<
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
</
|
|
453
|
-
<span className="name">{a.name}</span>
|
|
472
|
+
<div className="attachment-card">
|
|
473
|
+
<IconFont type="icon-excel" />
|
|
474
|
+
<Typography.Text
|
|
475
|
+
className="name"
|
|
476
|
+
ellipsis={{ tooltip: a.name }}
|
|
477
|
+
>
|
|
478
|
+
{a.name}
|
|
479
|
+
</Typography.Text>
|
|
454
480
|
<a
|
|
455
481
|
className="remove"
|
|
456
482
|
onClick={() => removeAttachment(a.uid)}
|
|
457
483
|
>
|
|
458
|
-
|
|
484
|
+
<DeleteOutlined />
|
|
459
485
|
</a>
|
|
460
|
-
</
|
|
486
|
+
</div>
|
|
461
487
|
))}
|
|
462
488
|
</div>
|
|
463
489
|
)}
|
|
464
|
-
{selectedAgent && (
|
|
490
|
+
{selectedAgent.length > 0 && (
|
|
465
491
|
<div className="agent-info">
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
492
|
+
{selectedAgent.map((item, index) => (
|
|
493
|
+
<div key={String(item.id)}>
|
|
494
|
+
<span className="name">@ {item.name}</span>
|
|
495
|
+
<a className="remove" onClick={() => onRemoveAgent(index)}>
|
|
496
|
+
×
|
|
497
|
+
</a>
|
|
498
|
+
</div>
|
|
499
|
+
))}
|
|
470
500
|
</div>
|
|
471
501
|
)}
|
|
472
502
|
{showTitle && (
|
|
@@ -197,8 +197,8 @@ export const PropertiesPanel: React.FC = () => {
|
|
|
197
197
|
<Form labelCol={{ span: 24 }} wrapperCol={{ span: 24 }}>
|
|
198
198
|
<Form.Item
|
|
199
199
|
label="组件标识"
|
|
200
|
-
labelCol={{ span:
|
|
201
|
-
wrapperCol={{ span:
|
|
200
|
+
labelCol={{ span: 5 }}
|
|
201
|
+
wrapperCol={{ span: 19 }}
|
|
202
202
|
>
|
|
203
203
|
{selectedItem?.id || ""}
|
|
204
204
|
</Form.Item>
|
|
@@ -84,7 +84,7 @@ export const CapsuleProps: React.FC<PropEditorProps<CapsuleModel>> = ({
|
|
|
84
84
|
<Radio.Button value="large">大</Radio.Button>
|
|
85
85
|
</Radio.Group>
|
|
86
86
|
</Form.Item>
|
|
87
|
-
<Form.Item>
|
|
87
|
+
<Form.Item labelCol={{ span: 24 }} wrapperCol={{ span: 24 }}>
|
|
88
88
|
<Table
|
|
89
89
|
size="small"
|
|
90
90
|
dataSource={model.options}
|
|
@@ -1,75 +1,123 @@
|
|
|
1
|
-
import React from
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
|
|
1
|
+
import React from "react";
|
|
2
|
+
import {
|
|
3
|
+
Form,
|
|
4
|
+
Input,
|
|
5
|
+
Radio,
|
|
6
|
+
InputNumber,
|
|
7
|
+
Table,
|
|
8
|
+
Button,
|
|
9
|
+
Space,
|
|
10
|
+
Switch,
|
|
11
|
+
} from "antd";
|
|
12
|
+
import type { PropEditorProps } from "./types";
|
|
13
|
+
import { DeleteOutlined } from "@ant-design/icons";
|
|
5
14
|
|
|
6
|
-
export type CheckboxOption = { label: string; value: any }
|
|
15
|
+
export type CheckboxOption = { label: string; value: any };
|
|
7
16
|
export type CheckboxModel = {
|
|
8
|
-
var?: string
|
|
9
|
-
layout?:
|
|
10
|
-
lineNumber?: number
|
|
11
|
-
options: CheckboxOption[]
|
|
12
|
-
}
|
|
17
|
+
var?: string;
|
|
18
|
+
layout?: "horizontal" | "vertical" | "grid";
|
|
19
|
+
lineNumber?: number;
|
|
20
|
+
options: CheckboxOption[];
|
|
21
|
+
};
|
|
13
22
|
|
|
14
|
-
export const CheckboxProps: React.FC<PropEditorProps<CheckboxModel>> = ({
|
|
15
|
-
|
|
23
|
+
export const CheckboxProps: React.FC<PropEditorProps<CheckboxModel>> = ({
|
|
24
|
+
model,
|
|
25
|
+
onChange,
|
|
26
|
+
}) => {
|
|
27
|
+
const trigger = (key: keyof CheckboxModel, value: any) =>
|
|
28
|
+
onChange && onChange({ ...model, [key]: value });
|
|
16
29
|
const setOption = (index: number, key: keyof CheckboxOption, value: any) => {
|
|
17
|
-
const options = [...(model.options || [])]
|
|
18
|
-
options[index] = { ...options[index], [key]: value }
|
|
19
|
-
trigger(
|
|
20
|
-
}
|
|
30
|
+
const options = [...(model.options || [])];
|
|
31
|
+
options[index] = { ...options[index], [key]: value };
|
|
32
|
+
trigger("options", options);
|
|
33
|
+
};
|
|
21
34
|
const removeOption = (index: number) => {
|
|
22
|
-
const options = [...(model.options || [])]
|
|
23
|
-
options.splice(index, 1)
|
|
24
|
-
trigger(
|
|
25
|
-
}
|
|
35
|
+
const options = [...(model.options || [])];
|
|
36
|
+
options.splice(index, 1);
|
|
37
|
+
trigger("options", options);
|
|
38
|
+
};
|
|
26
39
|
const addOption = () => {
|
|
27
|
-
trigger(
|
|
28
|
-
}
|
|
40
|
+
trigger("options", [...(model.options || []), { label: "", value: "" }]);
|
|
41
|
+
};
|
|
29
42
|
const columns = [
|
|
30
43
|
{
|
|
31
|
-
title:
|
|
32
|
-
dataIndex:
|
|
33
|
-
render: (_: any, r: CheckboxOption, i: number) =>
|
|
44
|
+
title: "选项标签",
|
|
45
|
+
dataIndex: "label",
|
|
46
|
+
render: (_: any, r: CheckboxOption, i: number) => (
|
|
47
|
+
<Input
|
|
48
|
+
size="small"
|
|
49
|
+
value={r.label}
|
|
50
|
+
onChange={(e) => setOption(i, "label", e.target.value)}
|
|
51
|
+
/>
|
|
52
|
+
),
|
|
34
53
|
},
|
|
35
54
|
{
|
|
36
|
-
title:
|
|
37
|
-
dataIndex:
|
|
38
|
-
render: (_: any, r: CheckboxOption, i: number) =>
|
|
55
|
+
title: "选项值",
|
|
56
|
+
dataIndex: "value",
|
|
57
|
+
render: (_: any, r: CheckboxOption, i: number) => (
|
|
58
|
+
<Input
|
|
59
|
+
size="small"
|
|
60
|
+
value={r.value}
|
|
61
|
+
onChange={(e) => setOption(i, "value", e.target.value)}
|
|
62
|
+
/>
|
|
63
|
+
),
|
|
39
64
|
},
|
|
40
65
|
{
|
|
41
|
-
title:
|
|
66
|
+
title: "操作",
|
|
42
67
|
render: (_: any, r: CheckboxOption, i: number) => (
|
|
43
68
|
<Space>
|
|
44
69
|
<Button danger size="small" onClick={() => removeOption(i)}>
|
|
45
70
|
<DeleteOutlined />
|
|
46
71
|
</Button>
|
|
47
72
|
</Space>
|
|
48
|
-
)
|
|
49
|
-
}
|
|
50
|
-
]
|
|
73
|
+
),
|
|
74
|
+
},
|
|
75
|
+
];
|
|
51
76
|
return (
|
|
52
77
|
<Form labelCol={{ span: 6 }} wrapperCol={{ span: 18 }}>
|
|
53
78
|
<Form.Item label="变量名">
|
|
54
|
-
<Input
|
|
79
|
+
<Input
|
|
80
|
+
size="small"
|
|
81
|
+
value={model.var}
|
|
82
|
+
onChange={(e) => trigger("var", e.target.value)}
|
|
83
|
+
placeholder="请输入变量名"
|
|
84
|
+
/>
|
|
55
85
|
</Form.Item>
|
|
56
86
|
<Form.Item label="布局">
|
|
57
|
-
<Radio.Group
|
|
87
|
+
<Radio.Group
|
|
88
|
+
size="small"
|
|
89
|
+
value={model.layout}
|
|
90
|
+
onChange={(e) => trigger("layout", e.target.value)}
|
|
91
|
+
>
|
|
58
92
|
<Radio.Button value="horizontal">水平</Radio.Button>
|
|
59
93
|
<Radio.Button value="vertical">垂直</Radio.Button>
|
|
60
94
|
<Radio.Button value="grid">网格</Radio.Button>
|
|
61
95
|
</Radio.Group>
|
|
62
96
|
</Form.Item>
|
|
63
|
-
{model.layout ===
|
|
97
|
+
{model.layout === "grid" && (
|
|
64
98
|
<Form.Item label="网格行数">
|
|
65
|
-
<InputNumber
|
|
99
|
+
<InputNumber
|
|
100
|
+
size="small"
|
|
101
|
+
value={model.lineNumber}
|
|
102
|
+
onChange={(v) => trigger("lineNumber", v)}
|
|
103
|
+
min={1}
|
|
104
|
+
max={10}
|
|
105
|
+
/>
|
|
66
106
|
</Form.Item>
|
|
67
107
|
)}
|
|
68
|
-
<Form.Item>
|
|
69
|
-
<Table
|
|
70
|
-
|
|
108
|
+
<Form.Item labelCol={{ span: 24 }} wrapperCol={{ span: 24 }}>
|
|
109
|
+
<Table
|
|
110
|
+
size="small"
|
|
111
|
+
dataSource={model.options}
|
|
112
|
+
columns={columns as any}
|
|
113
|
+
pagination={false}
|
|
114
|
+
rowKey={(_, i) => String(i)}
|
|
115
|
+
bordered
|
|
116
|
+
/>
|
|
117
|
+
<Button size="small" block onClick={addOption}>
|
|
118
|
+
添加选项
|
|
119
|
+
</Button>
|
|
71
120
|
</Form.Item>
|
|
72
121
|
</Form>
|
|
73
|
-
)
|
|
74
|
-
}
|
|
75
|
-
|
|
122
|
+
);
|
|
123
|
+
};
|