bi-sdk-react 0.0.3 → 0.0.5
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/css/bi-sdk.css +1 -1
- package/dist/es/js/bi-sdk.es.js +295 -67
- package/dist/types/components/PageDesigner.d.ts +9 -1
- package/dist/types/components/context/DesignerContext.d.ts +5 -2
- package/dist/types/components/context/EnvContext.d.ts +2 -1
- package/dist/types/components/icon/IconFont.d.ts +2 -1
- package/dist/types/components/layout/PageCanvas.d.ts +2 -0
- package/dist/types/components/panel/AiPanel.d.ts +4 -0
- package/dist/types/components/panel/ChatInput.d.ts +13 -6
- package/dist/types/components/panel/DatasetPanel.d.ts +11 -0
- package/dist/types/components/panel/PaneHeader.d.ts +1 -0
- package/dist/types/components/panel/PropertiesPanel.d.ts +3 -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/types/components/plugins/@antd/item-props/EchartsProps.d.ts +2 -2
- package/dist/types/components/plugins/@antd/item-props/TextProps.d.ts +1 -0
- package/dist/types/components/plugins/@antd/items/TableRender.d.ts +1 -0
- package/dist/types/components/plugins/@antd/items/TextRender.d.ts +1 -0
- package/dist/types/components/typing.d.ts +97 -2
- package/dist/types/components/utils.d.ts +1 -0
- package/dist/umd/css/bi-sdk.css +1 -1
- package/dist/umd/js/bi-sdk.umd.min.js +299 -71
- package/package.json +1 -1
- package/src/components/PageDesigner.tsx +293 -35
- package/src/components/context/DesignerContext.tsx +15 -3
- package/src/components/context/EnvContext.tsx +4 -1
- package/src/components/icon/IconFont.tsx +15 -11
- package/src/components/layout/PageCanvas.tsx +4 -2
- package/src/components/layout/PageItem.tsx +1 -1
- package/src/components/panel/AiPanel.tsx +609 -43
- package/src/components/panel/ChatInput.tsx +322 -180
- package/src/components/panel/DatasetPanel.tsx +65 -0
- package/src/components/panel/PaneHeader.tsx +3 -2
- package/src/components/panel/PropertiesPanel.tsx +334 -127
- package/src/components/plugins/@antd/index.ts +12 -9
- 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/EchartsProps.tsx +52 -22
- package/src/components/plugins/@antd/item-props/HtmlProps.tsx +8 -9
- package/src/components/plugins/@antd/item-props/SelectProps.tsx +1 -1
- package/src/components/plugins/@antd/item-props/TextProps.tsx +14 -3
- package/src/components/plugins/@antd/items/EchartsRender.tsx +9 -1
- package/src/components/plugins/@antd/items/HtmlRender.tsx +13 -1
- package/src/components/plugins/@antd/items/ListRender.tsx +18 -1
- package/src/components/plugins/@antd/items/TableRender.tsx +16 -1
- package/src/components/plugins/@antd/items/TextRender.tsx +3 -1
- package/src/components/styles.css +20 -0
- package/src/components/typing.ts +111 -2
- package/src/components/utils.ts +40 -0
- package/src/example.tsx +314 -13
package/package.json
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import {
|
|
2
|
+
CloseOutlined,
|
|
2
3
|
DesktopOutlined,
|
|
3
4
|
EyeInvisibleOutlined,
|
|
4
5
|
EyeOutlined,
|
|
6
|
+
ImportOutlined,
|
|
5
7
|
MobileOutlined,
|
|
6
8
|
RedoOutlined,
|
|
7
9
|
SaveOutlined,
|
|
@@ -10,9 +12,18 @@ import {
|
|
|
10
12
|
ZoomInOutlined,
|
|
11
13
|
ZoomOutOutlined,
|
|
12
14
|
} from "@ant-design/icons";
|
|
13
|
-
import {
|
|
15
|
+
import {
|
|
16
|
+
Button,
|
|
17
|
+
Divider,
|
|
18
|
+
Drawer,
|
|
19
|
+
Modal,
|
|
20
|
+
Popover,
|
|
21
|
+
Radio,
|
|
22
|
+
Space,
|
|
23
|
+
Tooltip,
|
|
24
|
+
} from "antd";
|
|
14
25
|
import React, {
|
|
15
|
-
|
|
26
|
+
ReactNode,
|
|
16
27
|
useImperativeHandle,
|
|
17
28
|
useMemo,
|
|
18
29
|
useRef,
|
|
@@ -32,15 +43,35 @@ import { PropertiesPanel } from "./panel/PropertiesPanel";
|
|
|
32
43
|
import { ScriptPanel } from "./panel/ScriptPanel";
|
|
33
44
|
import { VariablesPanel } from "./panel/VariablesPanel";
|
|
34
45
|
|
|
35
|
-
import {
|
|
46
|
+
import { Editor } from "@monaco-editor/react";
|
|
36
47
|
import { DesignerProvider } from "./context/DesignerContext";
|
|
37
48
|
import { useDeepCompareEffect } from "./hooks/useDeepCompareEffect";
|
|
38
49
|
import "./styles.css";
|
|
50
|
+
import {
|
|
51
|
+
ChatResponseAnswerEffectType,
|
|
52
|
+
DatasetSelectorFunction,
|
|
53
|
+
FetchType,
|
|
54
|
+
PageSchema,
|
|
55
|
+
PluginType,
|
|
56
|
+
SchemaItemType,
|
|
57
|
+
} from "./typing";
|
|
58
|
+
import { DatasetPanel } from "./panel/DatasetPanel";
|
|
39
59
|
|
|
40
60
|
export type PageDesignerProps = {
|
|
61
|
+
pageId: string;
|
|
41
62
|
agentList?: any[];
|
|
42
63
|
plugins?: PluginType[];
|
|
43
64
|
headerExtra?: React.ReactNode;
|
|
65
|
+
datasourceEnable?: boolean;
|
|
66
|
+
scriptEnable?: boolean;
|
|
67
|
+
datasetPanel?: React.ForwardRefExoticComponent<
|
|
68
|
+
Omit<any, "ref"> &
|
|
69
|
+
React.RefAttributes<{
|
|
70
|
+
handleAdd: () => void;
|
|
71
|
+
}>
|
|
72
|
+
>;
|
|
73
|
+
datasetSelector?: DatasetSelectorFunction;
|
|
74
|
+
fetch?: FetchType;
|
|
44
75
|
};
|
|
45
76
|
|
|
46
77
|
const Container = styled.div`
|
|
@@ -111,6 +142,7 @@ const Container = styled.div`
|
|
|
111
142
|
flex-direction: column;
|
|
112
143
|
gap: 12px;
|
|
113
144
|
padding: 12px;
|
|
145
|
+
height: calc(100% - 40px);
|
|
114
146
|
}
|
|
115
147
|
.left-pane-tabs > label,
|
|
116
148
|
.right-pane-tabs > label {
|
|
@@ -135,9 +167,66 @@ const Container = styled.div`
|
|
|
135
167
|
}
|
|
136
168
|
`;
|
|
137
169
|
|
|
170
|
+
const ImportModal: React.FC<{
|
|
171
|
+
open?: boolean;
|
|
172
|
+
onCancel?: () => void;
|
|
173
|
+
onOk?: (schema: PageSchema) => void;
|
|
174
|
+
}> = ({ open, onCancel, onOk }) => {
|
|
175
|
+
const [importSchema, setImportSchema] = useState<string>(
|
|
176
|
+
JSON.stringify({
|
|
177
|
+
info: {},
|
|
178
|
+
datasources: [],
|
|
179
|
+
scripts: [],
|
|
180
|
+
variables: [],
|
|
181
|
+
items: [],
|
|
182
|
+
})
|
|
183
|
+
);
|
|
184
|
+
return (
|
|
185
|
+
<Modal
|
|
186
|
+
title="导入页面"
|
|
187
|
+
open={open}
|
|
188
|
+
width={800}
|
|
189
|
+
onCancel={onCancel}
|
|
190
|
+
onOk={() => onOk?.(JSON.parse(importSchema))}
|
|
191
|
+
okText="导入"
|
|
192
|
+
cancelText="取消"
|
|
193
|
+
styles={{ body: { height: "calc(100vh - 250px)", overflow: "auto" } }}
|
|
194
|
+
>
|
|
195
|
+
<div
|
|
196
|
+
className="body"
|
|
197
|
+
style={{ flex: "1 1 auto", display: "flex", height: "100%" }}
|
|
198
|
+
>
|
|
199
|
+
<Editor
|
|
200
|
+
height="100%"
|
|
201
|
+
defaultLanguage="json"
|
|
202
|
+
value={importSchema}
|
|
203
|
+
options={{
|
|
204
|
+
minimap: { enabled: false },
|
|
205
|
+
}}
|
|
206
|
+
onChange={(v) => setImportSchema(v || "")}
|
|
207
|
+
/>
|
|
208
|
+
</div>
|
|
209
|
+
</Modal>
|
|
210
|
+
);
|
|
211
|
+
};
|
|
212
|
+
|
|
138
213
|
export const PageDesigner = React.forwardRef<any, PageDesignerProps>(
|
|
139
|
-
(
|
|
214
|
+
(
|
|
215
|
+
{
|
|
216
|
+
pageId,
|
|
217
|
+
agentList = [],
|
|
218
|
+
plugins = [],
|
|
219
|
+
headerExtra,
|
|
220
|
+
datasourceEnable = true,
|
|
221
|
+
scriptEnable = true,
|
|
222
|
+
datasetPanel,
|
|
223
|
+
datasetSelector,
|
|
224
|
+
fetch,
|
|
225
|
+
},
|
|
226
|
+
ref
|
|
227
|
+
) => {
|
|
140
228
|
const pageCanvasRef = useRef<any>(null);
|
|
229
|
+
const datasetPanelRef = useRef<any>(null);
|
|
141
230
|
const [zoom, setZoom] = useState(1);
|
|
142
231
|
const [history, setHistory] = useState<any[]>([]);
|
|
143
232
|
const [future, setFuture] = useState<any[]>([]);
|
|
@@ -146,14 +235,22 @@ export const PageDesigner = React.forwardRef<any, PageDesignerProps>(
|
|
|
146
235
|
"desktop" | "mobile" | "tablet"
|
|
147
236
|
>("desktop");
|
|
148
237
|
const [leftPanelActiveKey, setLeftPanelActiveKey] = useState<
|
|
149
|
-
|
|
238
|
+
| "component"
|
|
239
|
+
| "layer"
|
|
240
|
+
| "datasource"
|
|
241
|
+
| "script"
|
|
242
|
+
| "env"
|
|
243
|
+
| "code"
|
|
244
|
+
| "dataset"
|
|
150
245
|
>("component");
|
|
151
246
|
const [rightPanelActiveKey, setRightPanelActiveKey] = useState<
|
|
152
247
|
"ai" | "props" | "cascade"
|
|
153
|
-
>("ai");
|
|
248
|
+
>(fetch?.ai ? "ai" : "props");
|
|
154
249
|
const [showLeft, setShowLeft] = useState(true);
|
|
155
250
|
const [showRight, setShowRight] = useState(true);
|
|
156
|
-
const [selectedItem, setSelectedItem] = useState<
|
|
251
|
+
const [selectedItem, setSelectedItem] = useState<SchemaItemType | null>(
|
|
252
|
+
null
|
|
253
|
+
);
|
|
157
254
|
const [schema, setSchema] = useState<PageSchema>({
|
|
158
255
|
info: {},
|
|
159
256
|
datasources: [],
|
|
@@ -162,6 +259,8 @@ export const PageDesigner = React.forwardRef<any, PageDesignerProps>(
|
|
|
162
259
|
items: [],
|
|
163
260
|
});
|
|
164
261
|
const [designable, setDesignable] = useState(true);
|
|
262
|
+
const [importModalOpen, setImportModalOpen] = useState(false);
|
|
263
|
+
const [aiPaneOpen, setAiPaneOpen] = useState(false);
|
|
165
264
|
const containerStyle = useMemo(() => {
|
|
166
265
|
const left = showLeft ? "250px" : "";
|
|
167
266
|
const right = showRight ? "400px" : "";
|
|
@@ -252,14 +351,69 @@ export const PageDesigner = React.forwardRef<any, PageDesignerProps>(
|
|
|
252
351
|
setTimeout(() => pageCanvasRef.current?.handleResize?.(), 0);
|
|
253
352
|
};
|
|
254
353
|
|
|
354
|
+
const handleImportClick = () => {
|
|
355
|
+
setImportModalOpen(true);
|
|
356
|
+
};
|
|
357
|
+
|
|
358
|
+
const handleImportOk = (s: PageSchema) => {
|
|
359
|
+
setImportModalOpen(false);
|
|
360
|
+
setSchema(s);
|
|
361
|
+
};
|
|
362
|
+
|
|
363
|
+
/**
|
|
364
|
+
* 处理效果
|
|
365
|
+
*/
|
|
366
|
+
const handleAiEffect = (effect: ChatResponseAnswerEffectType) => {
|
|
367
|
+
if (effect.datasets?.length && datasetPanelRef?.current?.reload) {
|
|
368
|
+
datasetPanelRef.current.reload();
|
|
369
|
+
}
|
|
370
|
+
if (effect.schema) {
|
|
371
|
+
setSchema(effect.schema);
|
|
372
|
+
} else if (effect.pageItems?.length) {
|
|
373
|
+
const effectItemMap = new Map(effect.pageItems.map((item) => [item.id, item]));
|
|
374
|
+
const cloneSchema = JSON.parse(JSON.stringify(schema));
|
|
375
|
+
const loop = (list: any[] = []) => {
|
|
376
|
+
list.forEach((item) => {
|
|
377
|
+
if (effectItemMap.has(item.id)) {
|
|
378
|
+
Object.keys(item).forEach((k) => {
|
|
379
|
+
if (k !== "id") {
|
|
380
|
+
delete item[k];
|
|
381
|
+
}
|
|
382
|
+
});
|
|
383
|
+
Object.assign(item, effectItemMap.get(item.id)!);
|
|
384
|
+
}
|
|
385
|
+
if (Array.isArray(item.children)) {
|
|
386
|
+
loop(item.children);
|
|
387
|
+
} else if (typeof item.children === "object" && item.children) {
|
|
388
|
+
Object.keys(item.children).forEach((k) => {
|
|
389
|
+
if (Array.isArray(item.children[k])) {
|
|
390
|
+
loop(item.children[k]);
|
|
391
|
+
}
|
|
392
|
+
});
|
|
393
|
+
}
|
|
394
|
+
});
|
|
395
|
+
};
|
|
396
|
+
loop(cloneSchema.items);
|
|
397
|
+
setSchema(cloneSchema);
|
|
398
|
+
}
|
|
399
|
+
};
|
|
400
|
+
|
|
401
|
+
const rightActiveKey = useMemo(() => {
|
|
402
|
+
if (rightPanelActiveKey === "cascade" && !selectedItem?.cascadeIds) return "props";
|
|
403
|
+
return rightPanelActiveKey;
|
|
404
|
+
}, [selectedItem, rightPanelActiveKey]);
|
|
405
|
+
|
|
255
406
|
return (
|
|
256
407
|
<DesignerProvider
|
|
408
|
+
pageId={pageId}
|
|
257
409
|
designable={designable}
|
|
258
410
|
plugins={plugins}
|
|
259
411
|
schema={schema}
|
|
260
412
|
selectedItem={selectedItem}
|
|
261
413
|
setSchema={setSchema}
|
|
262
414
|
setSelectedItem={setSelectedItem}
|
|
415
|
+
datasetSelector={datasetSelector}
|
|
416
|
+
fetch={fetch}
|
|
263
417
|
>
|
|
264
418
|
<div
|
|
265
419
|
style={{ display: "flex", flexDirection: "column", height: "100%" }}
|
|
@@ -300,6 +454,15 @@ export const PageDesigner = React.forwardRef<any, PageDesignerProps>(
|
|
|
300
454
|
<RedoOutlined />
|
|
301
455
|
</a>
|
|
302
456
|
</Tooltip>
|
|
457
|
+
<Divider orientation="vertical" />
|
|
458
|
+
<Tooltip title="导入JSON">
|
|
459
|
+
<a
|
|
460
|
+
className={`toolbar ${future.length > 0 ? "active" : ""}`}
|
|
461
|
+
onClick={handleImportClick}
|
|
462
|
+
>
|
|
463
|
+
<ImportOutlined />
|
|
464
|
+
</a>
|
|
465
|
+
</Tooltip>
|
|
303
466
|
</Space>
|
|
304
467
|
<Space>
|
|
305
468
|
<Tooltip title="缩小">
|
|
@@ -370,16 +533,27 @@ export const PageDesigner = React.forwardRef<any, PageDesignerProps>(
|
|
|
370
533
|
<IconFont type="icon-outline" />
|
|
371
534
|
</Tooltip>
|
|
372
535
|
</Radio.Button>
|
|
373
|
-
|
|
374
|
-
<
|
|
375
|
-
<
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
536
|
+
{!!datasetPanel && (
|
|
537
|
+
<Radio.Button value="dataset">
|
|
538
|
+
<Tooltip title="数据集" placement="right">
|
|
539
|
+
<IconFont type="icon-dataset" />
|
|
540
|
+
</Tooltip>
|
|
541
|
+
</Radio.Button>
|
|
542
|
+
)}
|
|
543
|
+
{datasourceEnable && (
|
|
544
|
+
<Radio.Button value="datasource" title="数据源">
|
|
545
|
+
<Tooltip title="数据源" placement="right">
|
|
546
|
+
<IconFont type="icon-datasource" />
|
|
547
|
+
</Tooltip>
|
|
548
|
+
</Radio.Button>
|
|
549
|
+
)}
|
|
550
|
+
{scriptEnable && (
|
|
551
|
+
<Radio.Button value="script">
|
|
552
|
+
<Tooltip title="脚本" placement="right">
|
|
553
|
+
<IconFont type="icon-js" />
|
|
554
|
+
</Tooltip>
|
|
555
|
+
</Radio.Button>
|
|
556
|
+
)}
|
|
383
557
|
<Radio.Button value="env">
|
|
384
558
|
<Tooltip title="环境变量" placement="right">
|
|
385
559
|
<IconFont type="icon-variable" />
|
|
@@ -402,10 +576,17 @@ export const PageDesigner = React.forwardRef<any, PageDesignerProps>(
|
|
|
402
576
|
>
|
|
403
577
|
{leftPanelActiveKey === "component" && <ComponentPanel />}
|
|
404
578
|
{leftPanelActiveKey === "layer" && <LayerPanel />}
|
|
405
|
-
{leftPanelActiveKey === "datasource" &&
|
|
406
|
-
|
|
579
|
+
{datasourceEnable && leftPanelActiveKey === "datasource" && (
|
|
580
|
+
<DatasourcePanel />
|
|
581
|
+
)}
|
|
582
|
+
{scriptEnable && leftPanelActiveKey === "script" && (
|
|
583
|
+
<ScriptPanel />
|
|
584
|
+
)}
|
|
407
585
|
{leftPanelActiveKey === "env" && <VariablesPanel />}
|
|
408
586
|
{leftPanelActiveKey === "code" && <CodePanel />}
|
|
587
|
+
{!!datasetPanel && leftPanelActiveKey === "dataset" && (
|
|
588
|
+
<DatasetPanel ref={datasetPanelRef} renderNode={datasetPanel} />
|
|
589
|
+
)}
|
|
409
590
|
</div>
|
|
410
591
|
</div>
|
|
411
592
|
<div className="center" style={{ flex: "1 1 auto" }}>
|
|
@@ -447,7 +628,11 @@ export const PageDesigner = React.forwardRef<any, PageDesignerProps>(
|
|
|
447
628
|
transformOrigin: "top center",
|
|
448
629
|
}}
|
|
449
630
|
>
|
|
450
|
-
<PageCanvas
|
|
631
|
+
<PageCanvas
|
|
632
|
+
ref={pageCanvasRef}
|
|
633
|
+
device={deviceType}
|
|
634
|
+
fetch={fetch}
|
|
635
|
+
/>
|
|
451
636
|
</div>
|
|
452
637
|
</div>
|
|
453
638
|
</div>
|
|
@@ -460,17 +645,27 @@ export const PageDesigner = React.forwardRef<any, PageDesignerProps>(
|
|
|
460
645
|
width: "calc(100% - 47px)",
|
|
461
646
|
}}
|
|
462
647
|
>
|
|
463
|
-
{
|
|
648
|
+
{rightActiveKey === "ai" && fetch?.ai && (
|
|
464
649
|
<AiPanel agentList={agentList} />
|
|
465
650
|
)}
|
|
466
|
-
{
|
|
467
|
-
|
|
651
|
+
{rightActiveKey === "props" && (
|
|
652
|
+
<PropertiesPanel datasourceEnable={datasourceEnable} />
|
|
653
|
+
)}
|
|
654
|
+
{rightActiveKey === "cascade" &&
|
|
655
|
+
selectedItem?.cascadeIds && <CascadePanel />}
|
|
468
656
|
</div>
|
|
469
657
|
<div
|
|
470
|
-
style={{
|
|
658
|
+
style={{
|
|
659
|
+
padding: "22px 0",
|
|
660
|
+
borderLeft: "solid 1px #e8e8e8",
|
|
661
|
+
display: "flex",
|
|
662
|
+
flexDirection: "column",
|
|
663
|
+
justifyContent: "space-between",
|
|
664
|
+
alignItems: "center",
|
|
665
|
+
}}
|
|
471
666
|
>
|
|
472
667
|
<Radio.Group
|
|
473
|
-
value={
|
|
668
|
+
value={rightActiveKey}
|
|
474
669
|
onChange={(e) => setRightPanelActiveKey(e.target.value)}
|
|
475
670
|
buttonStyle="outline"
|
|
476
671
|
style={{
|
|
@@ -481,26 +676,89 @@ export const PageDesigner = React.forwardRef<any, PageDesignerProps>(
|
|
|
481
676
|
}}
|
|
482
677
|
className="right-pane-tabs"
|
|
483
678
|
>
|
|
484
|
-
|
|
485
|
-
<
|
|
486
|
-
<
|
|
487
|
-
|
|
488
|
-
|
|
679
|
+
{fetch?.ai && (
|
|
680
|
+
<Radio.Button value="ai">
|
|
681
|
+
<Tooltip title="智能助理" placement="right">
|
|
682
|
+
<IconFont type="icon-assistant" />
|
|
683
|
+
</Tooltip>
|
|
684
|
+
</Radio.Button>
|
|
685
|
+
)}
|
|
489
686
|
<Radio.Button value="props">
|
|
490
687
|
<Tooltip title="属性" placement="right">
|
|
491
688
|
<IconFont type="icon-info" />
|
|
492
689
|
</Tooltip>
|
|
493
690
|
</Radio.Button>
|
|
494
|
-
|
|
495
|
-
<
|
|
496
|
-
<
|
|
497
|
-
|
|
498
|
-
|
|
691
|
+
{selectedItem?.cascadeIds && (
|
|
692
|
+
<Radio.Button value="cascade">
|
|
693
|
+
<Tooltip title="联动" placement="right">
|
|
694
|
+
<IconFont type="icon-cascade" />
|
|
695
|
+
</Tooltip>
|
|
696
|
+
</Radio.Button>
|
|
697
|
+
)}
|
|
499
698
|
</Radio.Group>
|
|
699
|
+
{/* <Popover
|
|
700
|
+
content={
|
|
701
|
+
<AiPanel
|
|
702
|
+
agentList={agentList}
|
|
703
|
+
style={{ width: 400, height: "85vh" }}
|
|
704
|
+
/>
|
|
705
|
+
}
|
|
706
|
+
trigger="click"
|
|
707
|
+
placement="bottomLeft"
|
|
708
|
+
styles={{
|
|
709
|
+
root: {
|
|
710
|
+
right: 15,
|
|
711
|
+
},
|
|
712
|
+
container: {
|
|
713
|
+
boxShadow: "0 0 10px 1px #0000008a",
|
|
714
|
+
padding: 0,
|
|
715
|
+
},
|
|
716
|
+
}}
|
|
717
|
+
> */}
|
|
718
|
+
{/* <Tooltip title="智能助理" placement="left">
|
|
719
|
+
<Button
|
|
720
|
+
type="link"
|
|
721
|
+
style={{ fontSize: 20 }}
|
|
722
|
+
onClick={() => setAiPaneOpen(true)}
|
|
723
|
+
>
|
|
724
|
+
<IconFont type="icon-assistant" />
|
|
725
|
+
</Button>
|
|
726
|
+
</Tooltip> */}
|
|
727
|
+
{/* </Popover> */}
|
|
500
728
|
</div>
|
|
501
729
|
</div>
|
|
502
730
|
</Container>
|
|
503
731
|
</div>
|
|
732
|
+
<ImportModal
|
|
733
|
+
open={importModalOpen}
|
|
734
|
+
onOk={handleImportOk}
|
|
735
|
+
onCancel={() => setImportModalOpen(false)}
|
|
736
|
+
/>
|
|
737
|
+
<Drawer
|
|
738
|
+
open={aiPaneOpen}
|
|
739
|
+
size={400}
|
|
740
|
+
mask={false}
|
|
741
|
+
title={null}
|
|
742
|
+
closable={false}
|
|
743
|
+
styles={{
|
|
744
|
+
body: {
|
|
745
|
+
padding: 0,
|
|
746
|
+
},
|
|
747
|
+
}}
|
|
748
|
+
onClose={() => setAiPaneOpen(false)}
|
|
749
|
+
>
|
|
750
|
+
<AiPanel
|
|
751
|
+
agentList={agentList}
|
|
752
|
+
headExtra={
|
|
753
|
+
<Button
|
|
754
|
+
type="link"
|
|
755
|
+
icon={<CloseOutlined />}
|
|
756
|
+
onClick={() => setAiPaneOpen(false)}
|
|
757
|
+
/>
|
|
758
|
+
}
|
|
759
|
+
onEffect={handleAiEffect}
|
|
760
|
+
/>
|
|
761
|
+
</Drawer>
|
|
504
762
|
</DesignerProvider>
|
|
505
763
|
);
|
|
506
764
|
}
|
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import { createContext } from "react";
|
|
2
|
-
import { PageSchema, PluginType, SchemaItemType } from "../typing";
|
|
1
|
+
import { createContext, ReactNode } from "react";
|
|
2
|
+
import { DatasetSelectorFunction, FetchType, PageSchema, PluginType, SchemaItemType } from "../typing";
|
|
3
3
|
|
|
4
4
|
type DesignerContextType = {
|
|
5
|
+
pageId: string;
|
|
5
6
|
designable: boolean;
|
|
6
7
|
plugins: PluginType[];
|
|
7
8
|
schema: PageSchema;
|
|
@@ -10,9 +11,12 @@ type DesignerContextType = {
|
|
|
10
11
|
setSelectedItem: React.Dispatch<React.SetStateAction<SchemaItemType | null>>;
|
|
11
12
|
updateSelectedItem: (selectedItem?: Partial<SchemaItemType> | null) => void;
|
|
12
13
|
forceUpdate: () => void;
|
|
14
|
+
datasetSelector?: DatasetSelectorFunction;
|
|
15
|
+
fetch?: FetchType;
|
|
13
16
|
};
|
|
14
17
|
|
|
15
18
|
export const DesignerContext = createContext<DesignerContextType>({
|
|
19
|
+
pageId: "",
|
|
16
20
|
designable: false,
|
|
17
21
|
plugins: [],
|
|
18
22
|
schema: {
|
|
@@ -27,6 +31,8 @@ export const DesignerContext = createContext<DesignerContextType>({
|
|
|
27
31
|
setSelectedItem: () => {},
|
|
28
32
|
updateSelectedItem: () => {},
|
|
29
33
|
forceUpdate: () => {},
|
|
34
|
+
datasetSelector: undefined,
|
|
35
|
+
fetch: undefined,
|
|
30
36
|
});
|
|
31
37
|
|
|
32
38
|
type DesignerProviderProps = React.PropsWithChildren<
|
|
@@ -34,16 +40,19 @@ type DesignerProviderProps = React.PropsWithChildren<
|
|
|
34
40
|
Partial<DesignerContextType>,
|
|
35
41
|
"updateSelectedItem" | "schema" | "forceUpdate"
|
|
36
42
|
> &
|
|
37
|
-
Pick<DesignerContextType, "schema">
|
|
43
|
+
Pick<DesignerContextType, "schema" | "pageId">
|
|
38
44
|
>;
|
|
39
45
|
|
|
40
46
|
export const DesignerProvider: React.FC<DesignerProviderProps> = ({
|
|
47
|
+
pageId,
|
|
41
48
|
designable,
|
|
42
49
|
plugins,
|
|
43
50
|
schema,
|
|
44
51
|
selectedItem,
|
|
45
52
|
setSchema,
|
|
46
53
|
setSelectedItem,
|
|
54
|
+
datasetSelector,
|
|
55
|
+
fetch,
|
|
47
56
|
children,
|
|
48
57
|
}) => {
|
|
49
58
|
const updateSelectedItem = (props?: Partial<SchemaItemType> | null) => {
|
|
@@ -53,6 +62,7 @@ export const DesignerProvider: React.FC<DesignerProviderProps> = ({
|
|
|
53
62
|
return (
|
|
54
63
|
<DesignerContext.Provider
|
|
55
64
|
value={{
|
|
65
|
+
pageId,
|
|
56
66
|
designable: !!designable,
|
|
57
67
|
plugins: plugins || [],
|
|
58
68
|
schema,
|
|
@@ -60,6 +70,8 @@ export const DesignerProvider: React.FC<DesignerProviderProps> = ({
|
|
|
60
70
|
setSchema: setSchema || (() => {}),
|
|
61
71
|
setSelectedItem: setSelectedItem || (() => {}),
|
|
62
72
|
updateSelectedItem,
|
|
73
|
+
datasetSelector,
|
|
74
|
+
fetch,
|
|
63
75
|
forceUpdate: () => {
|
|
64
76
|
setSchema?.({ ...schema });
|
|
65
77
|
},
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { createContext, FC, PropsWithChildren } from "react";
|
|
2
|
-
import { CallbacksType, EnvType } from "../typing";
|
|
2
|
+
import { CallbacksType, EnvType, FetchType } from "../typing";
|
|
3
3
|
|
|
4
4
|
type InitCallbackParams = {
|
|
5
5
|
id: string;
|
|
@@ -9,6 +9,7 @@ type InitCallbackParams = {
|
|
|
9
9
|
type EnvContextType = {
|
|
10
10
|
deviceWidth: number;
|
|
11
11
|
env: EnvType;
|
|
12
|
+
fetch?: FetchType;
|
|
12
13
|
callbacks: CallbacksType;
|
|
13
14
|
initCallback: ({ id, callback }: InitCallbackParams) => void;
|
|
14
15
|
};
|
|
@@ -23,6 +24,7 @@ export const EnvContext = createContext<EnvContextType>({
|
|
|
23
24
|
export const EnvProvider: FC<PropsWithChildren<EnvContextType>> = ({
|
|
24
25
|
deviceWidth,
|
|
25
26
|
env,
|
|
27
|
+
fetch,
|
|
26
28
|
callbacks,
|
|
27
29
|
initCallback,
|
|
28
30
|
children,
|
|
@@ -32,6 +34,7 @@ export const EnvProvider: FC<PropsWithChildren<EnvContextType>> = ({
|
|
|
32
34
|
value={{
|
|
33
35
|
deviceWidth,
|
|
34
36
|
env,
|
|
37
|
+
fetch,
|
|
35
38
|
callbacks,
|
|
36
39
|
initCallback,
|
|
37
40
|
}}
|
|
@@ -1,16 +1,20 @@
|
|
|
1
|
-
import React from
|
|
2
|
-
import { createFromIconfontCN } from
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { createFromIconfontCN } from "@ant-design/icons";
|
|
3
3
|
|
|
4
4
|
const IconFontCN = createFromIconfontCN({
|
|
5
|
-
scriptUrl:
|
|
6
|
-
})
|
|
5
|
+
scriptUrl: "https://at.alicdn.com/t/c/font_5072483_zvtcct793i.js",
|
|
6
|
+
});
|
|
7
7
|
|
|
8
8
|
export type IconFontProps = {
|
|
9
|
-
type: string
|
|
10
|
-
className?: string
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
export const IconFont: React.FC<IconFontProps> = ({ type, className = '' }) => {
|
|
14
|
-
return <IconFontCN type={type} className={className} />
|
|
15
|
-
}
|
|
9
|
+
type: string;
|
|
10
|
+
className?: string;
|
|
11
|
+
style?: React.CSSProperties;
|
|
12
|
+
};
|
|
16
13
|
|
|
14
|
+
export const IconFont: React.FC<IconFontProps> = ({
|
|
15
|
+
type,
|
|
16
|
+
className = "",
|
|
17
|
+
style = {},
|
|
18
|
+
}) => {
|
|
19
|
+
return <IconFontCN type={type} className={className} style={style} />;
|
|
20
|
+
};
|
|
@@ -8,12 +8,13 @@ import React, {
|
|
|
8
8
|
} from "react";
|
|
9
9
|
import styled from "styled-components";
|
|
10
10
|
import { DropContainer } from "../dnd/DropContainer";
|
|
11
|
-
import { CallbacksType, EnvType } from "../typing";
|
|
11
|
+
import { CallbacksType, EnvType, FetchType } from "../typing";
|
|
12
12
|
import { DesignerContext } from "../context/DesignerContext";
|
|
13
13
|
import { EnvProvider } from "../context/EnvContext";
|
|
14
14
|
|
|
15
15
|
export type PageCanvasProps = {
|
|
16
16
|
device?: "desktop" | "mobile" | "tablet";
|
|
17
|
+
fetch?: FetchType;
|
|
17
18
|
};
|
|
18
19
|
|
|
19
20
|
const Wrapper = styled.div`
|
|
@@ -53,7 +54,7 @@ const Wrapper = styled.div`
|
|
|
53
54
|
`;
|
|
54
55
|
|
|
55
56
|
export const PageCanvas = React.forwardRef<any, PageCanvasProps>(
|
|
56
|
-
|
|
57
|
+
({ device = "desktop", fetch }, ref) => {
|
|
57
58
|
const { schema, forceUpdate } = useContext(DesignerContext);
|
|
58
59
|
const rootRef = useRef<HTMLDivElement | null>(null);
|
|
59
60
|
const [canvasWidth, setCanvasWidth] = useState(0);
|
|
@@ -129,6 +130,7 @@ export const PageCanvas = React.forwardRef<any, PageCanvasProps>(
|
|
|
129
130
|
env={env}
|
|
130
131
|
callbacks={callbacks}
|
|
131
132
|
initCallback={initCallback}
|
|
133
|
+
fetch={fetch}
|
|
132
134
|
>
|
|
133
135
|
<Wrapper ref={rootRef}>
|
|
134
136
|
<DropContainer
|
|
@@ -90,7 +90,7 @@ export const PageItem: React.FC<PageItemProps> = ({
|
|
|
90
90
|
if (selectedItem && selectedItem === item && designable) {
|
|
91
91
|
const div = document.createElement("div");
|
|
92
92
|
div.style.position = "absolute";
|
|
93
|
-
div.style.zIndex = "
|
|
93
|
+
div.style.zIndex = "1000";
|
|
94
94
|
div.style.display = "flex";
|
|
95
95
|
div.style.gap = "4px";
|
|
96
96
|
const text = document.createElement("span");
|