bi-sdk-react 0.0.51 → 0.0.53
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 +103 -38
- package/dist/types/components/context/PageContext.d.ts +12 -0
- package/dist/types/components/hooks/event.d.ts +4 -0
- package/dist/types/components/hooks/method.d.ts +4 -0
- package/dist/types/components/panel/EventPanel.d.ts +2 -0
- package/dist/types/components/plugins/@antd/items/EchartsRender.d.ts +2 -2
- package/dist/types/components/typing.d.ts +13 -1
- package/dist/umd/js/bi-sdk.umd.min.js +104 -39
- package/package.json +1 -1
- package/src/components/PageDesigner.tsx +57 -41
- package/src/components/context/PageContext.tsx +54 -1
- package/src/components/dnd/DropContainer.tsx +0 -1
- package/src/components/hooks/event.ts +68 -0
- package/src/components/hooks/method.ts +13 -0
- package/src/components/icon/IconFont.tsx +1 -1
- package/src/components/panel/EventPanel.tsx +186 -0
- package/src/components/panel/ScriptPanel.tsx +1 -1
- package/src/components/plugins/@antd/index.ts +9 -1
- package/src/components/plugins/@antd/item-props/DrawerProps.tsx +18 -1
- package/src/components/plugins/@antd/item-props/ModalProps.tsx +18 -1
- package/src/components/plugins/@antd/items/ButtonRender.tsx +3 -0
- package/src/components/plugins/@antd/items/DrawerRender.tsx +15 -6
- package/src/components/plugins/@antd/items/EchartsRender.tsx +30 -3
- package/src/components/plugins/@antd/items/HtmlRender.tsx +1 -1
- package/src/components/plugins/@antd/items/ModalRender.tsx +14 -2
- package/src/components/typing.ts +13 -1
- package/src/example.tsx +1 -1
- package/dist/types/components/context/DesignerContext.d.ts +0 -18
- package/dist/types/components/context/EnvContext.d.ts +0 -16
package/package.json
CHANGED
|
@@ -44,6 +44,7 @@ import {
|
|
|
44
44
|
SchemaItemType,
|
|
45
45
|
} from "./typing";
|
|
46
46
|
import { uuid } from "./utils";
|
|
47
|
+
import { EventPanel } from "./panel/EventPanel";
|
|
47
48
|
|
|
48
49
|
export type PageDesignerProps = {
|
|
49
50
|
pageId: string;
|
|
@@ -267,7 +268,7 @@ export const PageDesigner = React.forwardRef<any, PageDesignerProps>(
|
|
|
267
268
|
| "dataset"
|
|
268
269
|
>("component");
|
|
269
270
|
const [rightPanelActiveKey, setRightPanelActiveKey] = useState<
|
|
270
|
-
"ai" | "props" | "cascade"
|
|
271
|
+
"ai" | "props" | "cascade" | "events"
|
|
271
272
|
>(fetch?.ai ? "ai" : "props");
|
|
272
273
|
const [showLeft, setShowLeft] = useState(true);
|
|
273
274
|
const [showRight, setShowRight] = useState(true);
|
|
@@ -467,6 +468,11 @@ export const PageDesigner = React.forwardRef<any, PageDesignerProps>(
|
|
|
467
468
|
return rightPanelActiveKey;
|
|
468
469
|
}, [selectedItem, rightPanelActiveKey]);
|
|
469
470
|
|
|
471
|
+
|
|
472
|
+
const selectedPlugin: PluginType | undefined = useMemo(() => {
|
|
473
|
+
return (plugins || []).find((p) => p.key === selectedItem?.type);
|
|
474
|
+
}, [plugins, selectedItem?.type]);
|
|
475
|
+
|
|
470
476
|
return (
|
|
471
477
|
<PageProvider
|
|
472
478
|
pageId={pageId}
|
|
@@ -593,47 +599,47 @@ export const PageDesigner = React.forwardRef<any, PageDesignerProps>(
|
|
|
593
599
|
}}
|
|
594
600
|
className="left-pane-tabs"
|
|
595
601
|
>
|
|
596
|
-
<
|
|
597
|
-
<
|
|
602
|
+
<Tooltip title="组件" placement="right">
|
|
603
|
+
<Radio.Button value="component">
|
|
598
604
|
<IconFont type="icon-puzzle" />
|
|
599
|
-
</
|
|
600
|
-
</
|
|
601
|
-
<
|
|
602
|
-
<
|
|
605
|
+
</Radio.Button>
|
|
606
|
+
</Tooltip>
|
|
607
|
+
<Tooltip title="图层" placement="right">
|
|
608
|
+
<Radio.Button value="layer">
|
|
603
609
|
<IconFont type="icon-outline" />
|
|
604
|
-
</
|
|
605
|
-
</
|
|
610
|
+
</Radio.Button>
|
|
611
|
+
</Tooltip>
|
|
606
612
|
{!!datasetPanel && (
|
|
607
|
-
<
|
|
608
|
-
<
|
|
613
|
+
<Tooltip title="数据集" placement="right">
|
|
614
|
+
<Radio.Button value="dataset">
|
|
609
615
|
<IconFont type="icon-dataset" />
|
|
610
|
-
</
|
|
611
|
-
</
|
|
616
|
+
</Radio.Button>
|
|
617
|
+
</Tooltip>
|
|
612
618
|
)}
|
|
613
619
|
{datasourceEnable && (
|
|
614
|
-
<
|
|
615
|
-
<
|
|
620
|
+
<Tooltip title="数据源" placement="right">
|
|
621
|
+
<Radio.Button value="datasource" title="数据源">
|
|
616
622
|
<IconFont type="icon-datasource" />
|
|
617
|
-
</
|
|
618
|
-
</
|
|
623
|
+
</Radio.Button>
|
|
624
|
+
</Tooltip>
|
|
619
625
|
)}
|
|
620
626
|
{scriptEnable && (
|
|
621
|
-
<
|
|
622
|
-
<
|
|
627
|
+
<Tooltip title="脚本" placement="right">
|
|
628
|
+
<Radio.Button value="script">
|
|
623
629
|
<IconFont type="icon-js" />
|
|
624
|
-
</
|
|
625
|
-
</
|
|
630
|
+
</Radio.Button>
|
|
631
|
+
</Tooltip>
|
|
626
632
|
)}
|
|
627
|
-
<
|
|
628
|
-
<
|
|
633
|
+
<Tooltip title="环境变量" placement="right">
|
|
634
|
+
<Radio.Button value="env">
|
|
629
635
|
<IconFont type="icon-variable" />
|
|
630
|
-
</
|
|
631
|
-
</
|
|
632
|
-
<
|
|
633
|
-
<
|
|
636
|
+
</Radio.Button>
|
|
637
|
+
</Tooltip>
|
|
638
|
+
<Tooltip title="源码" placement="right">
|
|
639
|
+
<Radio.Button value="code">
|
|
634
640
|
<IconFont type="icon-json" />
|
|
635
|
-
</
|
|
636
|
-
</
|
|
641
|
+
</Radio.Button>
|
|
642
|
+
</Tooltip>
|
|
637
643
|
</Radio.Group>
|
|
638
644
|
</div>
|
|
639
645
|
<div
|
|
@@ -733,6 +739,9 @@ export const PageDesigner = React.forwardRef<any, PageDesignerProps>(
|
|
|
733
739
|
{rightActiveKey === "cascade" && selectedItem?.cascadeIds && (
|
|
734
740
|
<CascadePanel />
|
|
735
741
|
)}
|
|
742
|
+
{rightActiveKey === "events" && selectedPlugin?.events && (
|
|
743
|
+
<EventPanel />
|
|
744
|
+
)}
|
|
736
745
|
</div>
|
|
737
746
|
<div
|
|
738
747
|
style={{
|
|
@@ -757,23 +766,30 @@ export const PageDesigner = React.forwardRef<any, PageDesignerProps>(
|
|
|
757
766
|
className="right-pane-tabs"
|
|
758
767
|
>
|
|
759
768
|
{fetch?.ai && (
|
|
760
|
-
<
|
|
761
|
-
<
|
|
769
|
+
<Tooltip title="智能助理" placement="right">
|
|
770
|
+
<Radio.Button value="ai">
|
|
762
771
|
<IconFont type="icon-assistant" />
|
|
763
|
-
</
|
|
764
|
-
</
|
|
772
|
+
</Radio.Button>
|
|
773
|
+
</Tooltip>
|
|
765
774
|
)}
|
|
766
|
-
<
|
|
767
|
-
<
|
|
775
|
+
<Tooltip title="属性" placement="right">
|
|
776
|
+
<Radio.Button value="props">
|
|
768
777
|
<IconFont type="icon-info" />
|
|
769
|
-
</
|
|
770
|
-
</
|
|
778
|
+
</Radio.Button>
|
|
779
|
+
</Tooltip>
|
|
771
780
|
{selectedItem?.cascadeIds && (
|
|
772
|
-
<
|
|
773
|
-
<
|
|
781
|
+
<Tooltip title="联动" placement="right">
|
|
782
|
+
<Radio.Button value="cascade">
|
|
774
783
|
<IconFont type="icon-cascade" />
|
|
775
|
-
</
|
|
776
|
-
</
|
|
784
|
+
</Radio.Button>
|
|
785
|
+
</Tooltip>
|
|
786
|
+
)}
|
|
787
|
+
{selectedPlugin?.events && (
|
|
788
|
+
<Tooltip title="事件" placement="right">
|
|
789
|
+
<Radio.Button value="events">
|
|
790
|
+
<IconFont type="icon-thunderbolt" />
|
|
791
|
+
</Radio.Button>
|
|
792
|
+
</Tooltip>
|
|
777
793
|
)}
|
|
778
794
|
</Radio.Group>
|
|
779
795
|
{/* <Popover
|
|
@@ -16,6 +16,9 @@ type InitCallbackParams = {
|
|
|
16
16
|
callback: CallbackType;
|
|
17
17
|
};
|
|
18
18
|
|
|
19
|
+
type MethodParams = { sourceId: string; arg?: any };
|
|
20
|
+
type MethodType = Record<string, (params?: MethodParams) => any>;
|
|
21
|
+
|
|
19
22
|
type PageContextType = {
|
|
20
23
|
pageId: string;
|
|
21
24
|
designable: boolean;
|
|
@@ -42,8 +45,23 @@ type PageContextType = {
|
|
|
42
45
|
refresh?: boolean,
|
|
43
46
|
consume?: (item: Omit<SchemaItemType, "children">, data: any) => void,
|
|
44
47
|
) => void;
|
|
48
|
+
initMethod: ({
|
|
49
|
+
id,
|
|
50
|
+
method,
|
|
51
|
+
}: {
|
|
52
|
+
id: string;
|
|
53
|
+
method: MethodType;
|
|
54
|
+
}) => any;
|
|
55
|
+
handleMethod: (
|
|
56
|
+
item: SchemaItemType,
|
|
57
|
+
targetId: string,
|
|
58
|
+
methodName: string,
|
|
59
|
+
arg?: any,
|
|
60
|
+
) => any;
|
|
45
61
|
getVars: (id: string) => Record<string, any>;
|
|
46
62
|
setVar: (item: SchemaItemType, key: string, value: any) => void;
|
|
63
|
+
getGlobalVar: (key: string) => string | undefined | null;
|
|
64
|
+
setGlobalVar: (key: string, value: any) => void;
|
|
47
65
|
setItemData?: (id: string, data: any) => void;
|
|
48
66
|
};
|
|
49
67
|
|
|
@@ -75,8 +93,12 @@ export const PageContext = createContext<PageContextType>({
|
|
|
75
93
|
setDeviceWidth: () => {},
|
|
76
94
|
initCallback: () => {},
|
|
77
95
|
handleCallback: () => {},
|
|
96
|
+
initMethod: () => {},
|
|
97
|
+
handleMethod: () => {},
|
|
78
98
|
getVars: () => ({}),
|
|
79
99
|
setVar: () => {},
|
|
100
|
+
getGlobalVar: () => undefined,
|
|
101
|
+
setGlobalVar: () => {},
|
|
80
102
|
setItemData: () => {},
|
|
81
103
|
});
|
|
82
104
|
|
|
@@ -129,6 +151,30 @@ export const PageProvider: React.FC<PageProviderProps> = ({
|
|
|
129
151
|
|
|
130
152
|
const [env, setEnv] = useState<EnvType>({ global: {}, local: {} });
|
|
131
153
|
const [callbacks, setCallbacks] = useState<CallbacksType>({});
|
|
154
|
+
const [methods, setMethods] = useState<Record<string, MethodType>>({});
|
|
155
|
+
|
|
156
|
+
const initMethod = ({
|
|
157
|
+
id,
|
|
158
|
+
method,
|
|
159
|
+
}: {
|
|
160
|
+
id: string;
|
|
161
|
+
method: MethodType;
|
|
162
|
+
}) => {
|
|
163
|
+
setMethods((c) => ({ ...c, [id]: method }));
|
|
164
|
+
};
|
|
165
|
+
|
|
166
|
+
const handleMethod = (
|
|
167
|
+
item: SchemaItemType,
|
|
168
|
+
targetId: string,
|
|
169
|
+
methodName: string,
|
|
170
|
+
arg?: any,
|
|
171
|
+
) => {
|
|
172
|
+
const method = methods[targetId][methodName];
|
|
173
|
+
if (typeof method === "function") {
|
|
174
|
+
return method({ sourceId: item.id!, arg });
|
|
175
|
+
}
|
|
176
|
+
return null;
|
|
177
|
+
};
|
|
132
178
|
|
|
133
179
|
const initCallback = ({
|
|
134
180
|
id,
|
|
@@ -172,7 +218,10 @@ export const PageProvider: React.FC<PageProviderProps> = ({
|
|
|
172
218
|
next.local[id][key] = value;
|
|
173
219
|
});
|
|
174
220
|
};
|
|
175
|
-
|
|
221
|
+
const getGlobalVar = (key: string) => env.global[key];
|
|
222
|
+
const setGlobalVar = (key: string, value: any) => {
|
|
223
|
+
setEnv((e: EnvType) => ({ ...e, global: { ...e.global, [key]: value } }));
|
|
224
|
+
};
|
|
176
225
|
|
|
177
226
|
useEffect(() => {
|
|
178
227
|
const nextGlobal: Record<string, any> = {};
|
|
@@ -207,8 +256,12 @@ export const PageProvider: React.FC<PageProviderProps> = ({
|
|
|
207
256
|
setDeviceWidth: setDeviceWidth || (() => {}),
|
|
208
257
|
initCallback,
|
|
209
258
|
handleCallback,
|
|
259
|
+
initMethod,
|
|
260
|
+
handleMethod,
|
|
210
261
|
getVars,
|
|
211
262
|
setVar,
|
|
263
|
+
getGlobalVar,
|
|
264
|
+
setGlobalVar,
|
|
212
265
|
setItemData,
|
|
213
266
|
}}
|
|
214
267
|
>
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { SchemaItemType } from "../typing";
|
|
2
|
+
import { useMethods } from "./method";
|
|
3
|
+
|
|
4
|
+
export const useEvent = (item: SchemaItemType) => {
|
|
5
|
+
const events = (item.events || []).reduce(
|
|
6
|
+
(acc, cur) => {
|
|
7
|
+
acc[cur.name] = cur.script;
|
|
8
|
+
return acc;
|
|
9
|
+
},
|
|
10
|
+
{} as Record<string, string>,
|
|
11
|
+
);
|
|
12
|
+
|
|
13
|
+
const { callMethod } = useMethods(item);
|
|
14
|
+
|
|
15
|
+
const handleEvent = (eventName: string, arg?: any) => {
|
|
16
|
+
const script = events[eventName];
|
|
17
|
+
if (script) {
|
|
18
|
+
if (script) {
|
|
19
|
+
try {
|
|
20
|
+
const safeEval = new Function(
|
|
21
|
+
"console",
|
|
22
|
+
"Math",
|
|
23
|
+
"Date",
|
|
24
|
+
"Array",
|
|
25
|
+
"Object",
|
|
26
|
+
"String",
|
|
27
|
+
"Number",
|
|
28
|
+
"Boolean",
|
|
29
|
+
"callMethod",
|
|
30
|
+
"param",
|
|
31
|
+
`
|
|
32
|
+
"use strict";
|
|
33
|
+
const window = undefined;
|
|
34
|
+
const document = undefined;
|
|
35
|
+
const global = undefined;
|
|
36
|
+
const process = undefined;
|
|
37
|
+
const require = undefined;
|
|
38
|
+
const module = undefined;
|
|
39
|
+
const exports = undefined;
|
|
40
|
+
${script}
|
|
41
|
+
`,
|
|
42
|
+
);
|
|
43
|
+
return (safeEval as any)(
|
|
44
|
+
console,
|
|
45
|
+
Math,
|
|
46
|
+
Date,
|
|
47
|
+
Array,
|
|
48
|
+
Object,
|
|
49
|
+
String,
|
|
50
|
+
Number,
|
|
51
|
+
Boolean,
|
|
52
|
+
callMethod,
|
|
53
|
+
{
|
|
54
|
+
item,
|
|
55
|
+
sourceId: item.id,
|
|
56
|
+
arg,
|
|
57
|
+
},
|
|
58
|
+
);
|
|
59
|
+
} catch (evalError) {
|
|
60
|
+
console.error("点击事件脚本执行失败:", evalError);
|
|
61
|
+
return null;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
return { handleEvent };
|
|
68
|
+
};
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { useContext } from "react";
|
|
2
|
+
import { PageContext } from "../context/PageContext";
|
|
3
|
+
import { SchemaItemType } from "../typing";
|
|
4
|
+
|
|
5
|
+
export const useMethods = (item: SchemaItemType) => {
|
|
6
|
+
const { handleMethod } = useContext(PageContext);
|
|
7
|
+
|
|
8
|
+
const callMethod = (targetId: string, methodName: string, arg?: any) => {
|
|
9
|
+
return handleMethod(item, targetId, methodName, arg);
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
return { callMethod };
|
|
13
|
+
};
|
|
@@ -2,7 +2,7 @@ import React from "react";
|
|
|
2
2
|
import { createFromIconfontCN } from "@ant-design/icons";
|
|
3
3
|
|
|
4
4
|
const IconFontCN = createFromIconfontCN({
|
|
5
|
-
scriptUrl: "https://at.alicdn.com/t/c/
|
|
5
|
+
scriptUrl: "https://at.alicdn.com/t/c/font_5072483_8ex0em5yn29.js",
|
|
6
6
|
});
|
|
7
7
|
|
|
8
8
|
export type IconFontProps = {
|
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
import { CaretDownOutlined, PlusOutlined } from "@ant-design/icons";
|
|
2
|
+
import { Divider, Dropdown, Empty, Space } from "antd";
|
|
3
|
+
import React, { useContext, useMemo } from "react";
|
|
4
|
+
import styled from "styled-components";
|
|
5
|
+
import { PageContext } from "../context/PageContext";
|
|
6
|
+
import { PluginType } from "../typing";
|
|
7
|
+
import { PaneHeader } from "./PaneHeader";
|
|
8
|
+
import { Editor } from "@monaco-editor/react";
|
|
9
|
+
import { IconFont } from "../icon/IconFont";
|
|
10
|
+
|
|
11
|
+
const Root = styled.div`
|
|
12
|
+
display: flex;
|
|
13
|
+
flex-direction: column;
|
|
14
|
+
height: 100%;
|
|
15
|
+
.body {
|
|
16
|
+
flex: 1 1 auto;
|
|
17
|
+
display: flex;
|
|
18
|
+
flex-direction: column;
|
|
19
|
+
gap: 12px;
|
|
20
|
+
padding: 12px;
|
|
21
|
+
overflow-y: auto;
|
|
22
|
+
overflow-x: hidden;
|
|
23
|
+
|
|
24
|
+
.ant-divider {
|
|
25
|
+
margin: 0;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
ul {
|
|
29
|
+
list-style: none;
|
|
30
|
+
padding: 0;
|
|
31
|
+
margin: 0;
|
|
32
|
+
|
|
33
|
+
li {
|
|
34
|
+
list-style: none;
|
|
35
|
+
padding: 0;
|
|
36
|
+
margin: 0;
|
|
37
|
+
display: flex;
|
|
38
|
+
flex-direction: column;
|
|
39
|
+
border-bottom: 1px dotted #d9d9d9;
|
|
40
|
+
padding-bottom: 8px;
|
|
41
|
+
|
|
42
|
+
& > div:first-child {
|
|
43
|
+
font-size: 14px;
|
|
44
|
+
color: var(--ant-color-text-label);
|
|
45
|
+
padding: 6px 0;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
&:last-child {
|
|
49
|
+
border-bottom: none;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
ul.tips {
|
|
54
|
+
padding-left: 20px;
|
|
55
|
+
li {
|
|
56
|
+
display: list-item;
|
|
57
|
+
list-style: disc;
|
|
58
|
+
border-bottom: none;
|
|
59
|
+
color: var(--ant-color-text-secondary);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
a.toolbar {
|
|
63
|
+
font-size: 16px;
|
|
64
|
+
color: var(--ant-color-text-secondary);
|
|
65
|
+
}
|
|
66
|
+
`;
|
|
67
|
+
|
|
68
|
+
export const EventPanel: React.FC = ({}) => {
|
|
69
|
+
const { selectedItem, setSelectedItem, plugins, forceUpdate } =
|
|
70
|
+
useContext(PageContext);
|
|
71
|
+
const selectedPlugin: PluginType | undefined = useMemo(() => {
|
|
72
|
+
return (plugins || []).find((p) => p.key === selectedItem?.type);
|
|
73
|
+
}, [plugins, selectedItem?.type]);
|
|
74
|
+
|
|
75
|
+
const events = selectedPlugin?.events || [];
|
|
76
|
+
const eventMap = events.reduce((prev: Record<string, string>, cur) => {
|
|
77
|
+
prev[cur.handler] = cur.name;
|
|
78
|
+
return prev;
|
|
79
|
+
}, {});
|
|
80
|
+
|
|
81
|
+
const onChange = (events: { name: string; script: string }[]) => {
|
|
82
|
+
if (!selectedItem) return;
|
|
83
|
+
setSelectedItem(Object.assign(selectedItem, { events }));
|
|
84
|
+
forceUpdate();
|
|
85
|
+
};
|
|
86
|
+
|
|
87
|
+
return (
|
|
88
|
+
<Root className="cascade-panel">
|
|
89
|
+
<PaneHeader
|
|
90
|
+
title="事件"
|
|
91
|
+
extra={
|
|
92
|
+
selectedPlugin?.events ? (
|
|
93
|
+
<Space>
|
|
94
|
+
<Dropdown
|
|
95
|
+
menu={{
|
|
96
|
+
onClick: ({ key }) => {
|
|
97
|
+
const nextEvents = [...(selectedItem?.events || [])];
|
|
98
|
+
nextEvents.push({ name: key, script: "" });
|
|
99
|
+
onChange && onChange(nextEvents);
|
|
100
|
+
},
|
|
101
|
+
items: events
|
|
102
|
+
.filter(
|
|
103
|
+
(e) =>
|
|
104
|
+
!(selectedItem?.events || [])?.some((i) => i.name === e.handler),
|
|
105
|
+
)
|
|
106
|
+
.map((it) => ({
|
|
107
|
+
key: it.handler,
|
|
108
|
+
label: `${it.name}(${it.handler})`,
|
|
109
|
+
})),
|
|
110
|
+
}}
|
|
111
|
+
placement="bottomRight"
|
|
112
|
+
trigger={["click"]}
|
|
113
|
+
>
|
|
114
|
+
<a className="toolbar">
|
|
115
|
+
<PlusOutlined />
|
|
116
|
+
<CaretDownOutlined
|
|
117
|
+
style={{ fontSize: 8, verticalAlign: "sub" }}
|
|
118
|
+
/>
|
|
119
|
+
</a>
|
|
120
|
+
</Dropdown>
|
|
121
|
+
</Space>
|
|
122
|
+
) : null
|
|
123
|
+
}
|
|
124
|
+
/>
|
|
125
|
+
<div className="body beautified_scrollbar">
|
|
126
|
+
<Divider>事件列表</Divider>
|
|
127
|
+
{!!selectedItem?.events?.length ? (
|
|
128
|
+
<ul>
|
|
129
|
+
{(selectedItem.events || []).map(
|
|
130
|
+
({ name, script }, index: number) => (
|
|
131
|
+
<li key={name}>
|
|
132
|
+
<div>
|
|
133
|
+
<IconFont type="icon-thunderbolt" /> {eventMap[name]}(
|
|
134
|
+
{name})
|
|
135
|
+
</div>
|
|
136
|
+
<div
|
|
137
|
+
style={{
|
|
138
|
+
border: "solid 1px var(--ant-color-border)",
|
|
139
|
+
borderRadius: "var(--ant-border-radius-sm)",
|
|
140
|
+
}}
|
|
141
|
+
>
|
|
142
|
+
<Editor
|
|
143
|
+
height="200px"
|
|
144
|
+
defaultLanguage="javascript"
|
|
145
|
+
value={script || ""}
|
|
146
|
+
onChange={(v) => {
|
|
147
|
+
const nextEvents = [...(selectedItem?.events || [])];
|
|
148
|
+
nextEvents[index].script = v || "";
|
|
149
|
+
onChange && onChange(nextEvents);
|
|
150
|
+
}}
|
|
151
|
+
options={{
|
|
152
|
+
minimap: { enabled: false },
|
|
153
|
+
scrollBeyondLastLine: false,
|
|
154
|
+
tabSize: 2,
|
|
155
|
+
}}
|
|
156
|
+
/>
|
|
157
|
+
</div>
|
|
158
|
+
</li>
|
|
159
|
+
),
|
|
160
|
+
)}
|
|
161
|
+
</ul>
|
|
162
|
+
) : (
|
|
163
|
+
<Empty description="暂无事件" image={Empty.PRESENTED_IMAGE_SIMPLE} />
|
|
164
|
+
)}
|
|
165
|
+
<Divider>脚本说明</Divider>
|
|
166
|
+
<div>
|
|
167
|
+
<ul className="tips">
|
|
168
|
+
<li>
|
|
169
|
+
内置参数:param(类型:Object)
|
|
170
|
+
<ul style={{ margin: "8px 0 0 20px" }}>
|
|
171
|
+
<li>param.item: 当前事件触发的组件。</li>
|
|
172
|
+
<li>param.sourceId: 当前事件触发的组件ID。</li>
|
|
173
|
+
<li>param.arg: 事件触发时传递的参数。</li>
|
|
174
|
+
</ul>
|
|
175
|
+
</li>
|
|
176
|
+
<li>
|
|
177
|
+
脚本禁止使用以下 API:window, document, global, process, require,
|
|
178
|
+
module, exports, cookie, localStorage, sessionStorage。
|
|
179
|
+
</li>
|
|
180
|
+
<li>组件方法调用:callMethod(targetId, methodName, arg)。</li>
|
|
181
|
+
</ul>
|
|
182
|
+
</div>
|
|
183
|
+
</div>
|
|
184
|
+
</Root>
|
|
185
|
+
);
|
|
186
|
+
};
|
|
@@ -152,7 +152,7 @@ export const ScriptPanel: React.FC = () => {
|
|
|
152
152
|
name="script"
|
|
153
153
|
rules={[{ required: true, message: "请输入脚本语句" }]}
|
|
154
154
|
>
|
|
155
|
-
<div style={{ border: "1px solid #d9d9d9"
|
|
155
|
+
<div style={{ border: "1px solid #d9d9d9" }}>
|
|
156
156
|
<div className="function-wrapper">function fixed(data) {"{"}</div>
|
|
157
157
|
<Editor
|
|
158
158
|
height="200px"
|
|
@@ -109,7 +109,9 @@ export const ButtonPlugin: PluginType = {
|
|
|
109
109
|
icon: "",
|
|
110
110
|
},
|
|
111
111
|
cascadeIds: [],
|
|
112
|
+
events: [],
|
|
112
113
|
},
|
|
114
|
+
events: [{ name: "点击", handler: "click" }],
|
|
113
115
|
};
|
|
114
116
|
|
|
115
117
|
export const PageHeaderPlugin: PluginType = {
|
|
@@ -221,7 +223,13 @@ return {
|
|
|
221
223
|
}
|
|
222
224
|
`,
|
|
223
225
|
},
|
|
226
|
+
events: [],
|
|
224
227
|
},
|
|
228
|
+
events: [
|
|
229
|
+
{ name: "点击", handler: "click" },
|
|
230
|
+
{ name: "双击点击", handler: "dblclick" },
|
|
231
|
+
{ name: "选中变化", handler: "selectchanged" },
|
|
232
|
+
],
|
|
225
233
|
};
|
|
226
234
|
|
|
227
235
|
export const InputPlugin: PluginType = {
|
|
@@ -294,7 +302,7 @@ export const SelectPlugin: PluginType = {
|
|
|
294
302
|
export const CapsulePlugin: PluginType = {
|
|
295
303
|
group: "表单组件",
|
|
296
304
|
key: "b-capsule",
|
|
297
|
-
label: "
|
|
305
|
+
label: "胶囊选择器",
|
|
298
306
|
icon: "icon-form-capsule",
|
|
299
307
|
component: CapsuleRender,
|
|
300
308
|
formComponent: CapsuleProps,
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { InfoCircleOutlined } from "@ant-design/icons";
|
|
2
|
-
import { Form, Input, InputNumber, Radio, Switch, Tooltip } from "antd";
|
|
2
|
+
import { Descriptions, Divider, Form, Input, InputNumber, Radio, Switch, Tooltip } from "antd";
|
|
3
3
|
import React from "react";
|
|
4
4
|
import styled from "styled-components";
|
|
5
5
|
import type { PropEditorProps } from "./types";
|
|
@@ -152,6 +152,23 @@ export const DrawerProps: React.FC<PropEditorProps<DrawerModel>> = ({
|
|
|
152
152
|
onChange={(v) => trigger("footer", v)}
|
|
153
153
|
/>
|
|
154
154
|
</Form.Item> */}
|
|
155
|
+
<Divider>组件方法</Divider>
|
|
156
|
+
<Descriptions
|
|
157
|
+
size="small"
|
|
158
|
+
column={1}
|
|
159
|
+
items={[
|
|
160
|
+
{
|
|
161
|
+
key: "open",
|
|
162
|
+
label: "open",
|
|
163
|
+
children: "打开抽屉",
|
|
164
|
+
},
|
|
165
|
+
{
|
|
166
|
+
key: "close",
|
|
167
|
+
label: "close",
|
|
168
|
+
children: "关闭抽屉",
|
|
169
|
+
},
|
|
170
|
+
]}
|
|
171
|
+
/>
|
|
155
172
|
</Form>
|
|
156
173
|
);
|
|
157
174
|
};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { InfoCircleOutlined } from "@ant-design/icons";
|
|
2
|
-
import { Form, Input, InputNumber, Radio, Switch, Tooltip } from "antd";
|
|
2
|
+
import { Descriptions, Divider, Form, Input, InputNumber, Radio, Switch, Tooltip } from "antd";
|
|
3
3
|
import React from "react";
|
|
4
4
|
import styled from "styled-components";
|
|
5
5
|
import type { PropEditorProps } from "./types";
|
|
@@ -131,6 +131,23 @@ export const ModalProps: React.FC<PropEditorProps<ModalModel>> = ({
|
|
|
131
131
|
onChange={(v) => trigger("footer", v)}
|
|
132
132
|
/>
|
|
133
133
|
</Form.Item> */}
|
|
134
|
+
<Divider>组件方法</Divider>
|
|
135
|
+
<Descriptions
|
|
136
|
+
size="small"
|
|
137
|
+
column={1}
|
|
138
|
+
items={[
|
|
139
|
+
{
|
|
140
|
+
key: "open",
|
|
141
|
+
label: "open",
|
|
142
|
+
children: "打开模态框",
|
|
143
|
+
},
|
|
144
|
+
{
|
|
145
|
+
key: "close",
|
|
146
|
+
label: "close",
|
|
147
|
+
children: "关闭模态框",
|
|
148
|
+
},
|
|
149
|
+
]}
|
|
150
|
+
/>
|
|
134
151
|
</Form>
|
|
135
152
|
);
|
|
136
153
|
};
|