bi-sdk-react 0.0.51 → 0.0.52
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 +10 -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 +44 -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/panel/EventPanel.tsx +186 -0
- 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/ModalRender.tsx +14 -2
- package/src/components/typing.ts +13 -1
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,6 +45,19 @@ 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;
|
|
47
63
|
setItemData?: (id: string, data: any) => void;
|
|
@@ -75,6 +91,8 @@ export const PageContext = createContext<PageContextType>({
|
|
|
75
91
|
setDeviceWidth: () => {},
|
|
76
92
|
initCallback: () => {},
|
|
77
93
|
handleCallback: () => {},
|
|
94
|
+
initMethod: () => {},
|
|
95
|
+
handleMethod: () => {},
|
|
78
96
|
getVars: () => ({}),
|
|
79
97
|
setVar: () => {},
|
|
80
98
|
setItemData: () => {},
|
|
@@ -129,6 +147,30 @@ export const PageProvider: React.FC<PageProviderProps> = ({
|
|
|
129
147
|
|
|
130
148
|
const [env, setEnv] = useState<EnvType>({ global: {}, local: {} });
|
|
131
149
|
const [callbacks, setCallbacks] = useState<CallbacksType>({});
|
|
150
|
+
const [methods, setMethods] = useState<Record<string, MethodType>>({});
|
|
151
|
+
|
|
152
|
+
const initMethod = ({
|
|
153
|
+
id,
|
|
154
|
+
method,
|
|
155
|
+
}: {
|
|
156
|
+
id: string;
|
|
157
|
+
method: MethodType;
|
|
158
|
+
}) => {
|
|
159
|
+
setMethods((c) => ({ ...c, [id]: method }));
|
|
160
|
+
};
|
|
161
|
+
|
|
162
|
+
const handleMethod = (
|
|
163
|
+
item: SchemaItemType,
|
|
164
|
+
targetId: string,
|
|
165
|
+
methodName: string,
|
|
166
|
+
arg?: any,
|
|
167
|
+
) => {
|
|
168
|
+
const method = methods[targetId][methodName];
|
|
169
|
+
if (typeof method === "function") {
|
|
170
|
+
return method({ sourceId: item.id!, arg });
|
|
171
|
+
}
|
|
172
|
+
return null;
|
|
173
|
+
};
|
|
132
174
|
|
|
133
175
|
const initCallback = ({
|
|
134
176
|
id,
|
|
@@ -173,7 +215,6 @@ export const PageProvider: React.FC<PageProviderProps> = ({
|
|
|
173
215
|
});
|
|
174
216
|
};
|
|
175
217
|
|
|
176
|
-
|
|
177
218
|
useEffect(() => {
|
|
178
219
|
const nextGlobal: Record<string, any> = {};
|
|
179
220
|
(schema.variables || []).forEach((item) => {
|
|
@@ -207,6 +248,8 @@ export const PageProvider: React.FC<PageProviderProps> = ({
|
|
|
207
248
|
setDeviceWidth: setDeviceWidth || (() => {}),
|
|
208
249
|
initCallback,
|
|
209
250
|
handleCallback,
|
|
251
|
+
initMethod,
|
|
252
|
+
handleMethod,
|
|
210
253
|
getVars,
|
|
211
254
|
setVar,
|
|
212
255
|
setItemData,
|
|
@@ -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
|
+
};
|
|
@@ -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
|
+
};
|
|
@@ -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
|
};
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { Button, type ButtonProps } from "antd";
|
|
2
2
|
import React, { MouseEventHandler, useContext } from "react";
|
|
3
3
|
import { PageContext } from "../../../context/PageContext";
|
|
4
|
+
import { useEvent } from "../../../hooks/event";
|
|
4
5
|
import { IconFont } from "../../../icon/IconFont";
|
|
5
6
|
import { HtmlBaseProps, SchemaItemType } from "../../../typing";
|
|
6
7
|
|
|
@@ -29,12 +30,14 @@ export const ButtonRender: React.FC<ButtonRenderProps> = ({
|
|
|
29
30
|
className,
|
|
30
31
|
}) => {
|
|
31
32
|
const { handleCallback } = useContext(PageContext);
|
|
33
|
+
const { handleEvent } = useEvent(item);
|
|
32
34
|
const danger = type === "danger";
|
|
33
35
|
const realType = danger ? "default" : type;
|
|
34
36
|
const click: MouseEventHandler = () => {
|
|
35
37
|
handleCallback(item, false, (target, data) => {
|
|
36
38
|
console.log("点击回调:", { target, data });
|
|
37
39
|
});
|
|
40
|
+
handleEvent("click");
|
|
38
41
|
};
|
|
39
42
|
const iconNode =
|
|
40
43
|
typeof icon === "string" ? (
|