amis 1.6.0 → 1.6.1-beta.0
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/README.md +1 -0
- package/lib/RootRenderer.d.ts +2 -0
- package/lib/RootRenderer.js +19 -1
- package/lib/RootRenderer.js.map +2 -2
- package/lib/SchemaRenderer.js +52 -1
- package/lib/SchemaRenderer.js.map +2 -2
- package/lib/Scoped.d.ts +2 -0
- package/lib/Scoped.js +27 -1
- package/lib/Scoped.js.map +2 -2
- package/lib/actions/Action.d.ts +33 -0
- package/lib/actions/Action.js +100 -0
- package/lib/actions/Action.js.map +13 -0
- package/lib/actions/AjaxAction.d.ts +14 -0
- package/lib/actions/AjaxAction.js +68 -0
- package/lib/actions/AjaxAction.js.map +13 -0
- package/lib/actions/BreakAction.d.ts +12 -0
- package/lib/actions/BreakAction.js +28 -0
- package/lib/actions/BreakAction.js.map +13 -0
- package/lib/actions/BroadcastAction.d.ts +12 -0
- package/lib/actions/BroadcastAction.js +40 -0
- package/lib/actions/BroadcastAction.js.map +13 -0
- package/lib/actions/CmptAction.d.ts +12 -0
- package/lib/actions/CmptAction.js +40 -0
- package/lib/actions/CmptAction.js.map +13 -0
- package/lib/actions/ContinueAction.d.ts +12 -0
- package/lib/actions/ContinueAction.js +28 -0
- package/lib/actions/ContinueAction.js.map +13 -0
- package/lib/actions/CopyAction.d.ts +12 -0
- package/lib/actions/CopyAction.js +35 -0
- package/lib/actions/CopyAction.js.map +13 -0
- package/lib/actions/CustomAction.d.ts +12 -0
- package/lib/actions/CustomAction.js +43 -0
- package/lib/actions/CustomAction.js.map +13 -0
- package/lib/actions/DialogAction.d.ts +12 -0
- package/lib/actions/DialogAction.js +31 -0
- package/lib/actions/DialogAction.js.map +13 -0
- package/lib/actions/DrawerAction.d.ts +12 -0
- package/lib/actions/DrawerAction.js +31 -0
- package/lib/actions/DrawerAction.js.map +13 -0
- package/lib/actions/EmailAction.d.ts +12 -0
- package/lib/actions/EmailAction.js +37 -0
- package/lib/actions/EmailAction.js.map +13 -0
- package/lib/actions/LoopAction.d.ts +12 -0
- package/lib/actions/LoopAction.js +93 -0
- package/lib/actions/LoopAction.js.map +13 -0
- package/lib/actions/OpenPageAction.d.ts +12 -0
- package/lib/actions/OpenPageAction.js +33 -0
- package/lib/actions/OpenPageAction.js.map +13 -0
- package/lib/actions/ParallelAction.d.ts +5 -0
- package/lib/actions/ParallelAction.js +33 -0
- package/lib/actions/ParallelAction.js.map +13 -0
- package/lib/actions/SwitchAction.d.ts +8 -0
- package/lib/actions/SwitchAction.js +45 -0
- package/lib/actions/SwitchAction.js.map +13 -0
- package/lib/actions/index.d.ts +18 -0
- package/lib/actions/index.js +22 -0
- package/lib/actions/index.js.map +13 -0
- package/lib/components/AnchorNav.d.ts +20 -20
- package/lib/components/Button.d.ts +20 -20
- package/lib/components/CalendarMobile.d.ts +112 -86
- package/lib/components/CalendarMobile.js +85 -31
- package/lib/components/CalendarMobile.js.map +2 -2
- package/lib/components/Collapse.d.ts +20 -20
- package/lib/components/DatePicker.js +9 -3
- package/lib/components/DatePicker.js.map +2 -2
- package/lib/components/DateRangePicker.js +1 -0
- package/lib/components/DateRangePicker.js.map +2 -2
- package/lib/components/InputBox.d.ts +21 -21
- package/lib/components/ListGroup.d.ts +21 -21
- package/lib/components/ListMenu.d.ts +84 -84
- package/lib/components/MonthRangePicker.js +2 -1
- package/lib/components/MonthRangePicker.js.map +2 -2
- package/lib/components/Radios.d.ts +21 -21
- package/lib/components/Rating.d.ts +21 -21
- package/lib/components/ResultBox.d.ts +84 -84
- package/lib/components/Select.d.ts +238 -238
- package/lib/components/Select.js +4 -3
- package/lib/components/Select.js.map +2 -2
- package/lib/components/Timeline.js +1 -1
- package/lib/components/Timeline.js.map +2 -2
- package/lib/components/TimelineItem.d.ts +3 -2
- package/lib/components/TimelineItem.js +8 -9
- package/lib/components/TimelineItem.js.map +2 -2
- package/lib/components/Tree.d.ts +84 -84
- package/lib/components/formula/plugin.js +0 -1
- package/lib/components/formula/plugin.js.map +2 -2
- package/lib/env.d.ts +4 -0
- package/lib/env.js.map +2 -2
- package/lib/factory.d.ts +2 -1
- package/lib/factory.js +78 -0
- package/lib/factory.js.map +2 -2
- package/lib/helper.css.map +1 -1
- package/lib/index.d.ts +2 -0
- package/lib/index.js +3 -1
- package/lib/index.js.map +2 -2
- package/lib/renderers/Action.d.ts +1 -1
- package/lib/renderers/Action.js +26 -10
- package/lib/renderers/Action.js.map +2 -2
- package/lib/renderers/Custom.d.ts +1 -1
- package/lib/renderers/Custom.js +1 -1
- package/lib/renderers/Custom.js.map +1 -1
- package/lib/renderers/Form/DiffEditor.d.ts +6 -0
- package/lib/renderers/Form/Editor.d.ts +6 -0
- package/lib/renderers/Form/Options.js +9 -7
- package/lib/renderers/Form/Options.js.map +2 -2
- package/lib/renderers/Form/Select.js +3 -3
- package/lib/renderers/Form/Select.js.map +2 -2
- package/lib/renderers/Form/index.js +8 -1
- package/lib/renderers/Form/index.js.map +2 -2
- package/lib/renderers/Link.d.ts +1 -1
- package/lib/renderers/Link.js +27 -6
- package/lib/renderers/Link.js.map +2 -2
- package/lib/renderers/Nav.d.ts +21 -21
- package/lib/renderers/Remark.d.ts +1 -1
- package/lib/store/formItem.js +1 -1
- package/lib/store/formItem.js.map +2 -2
- package/lib/themes/ang-ie11.css +180 -1
- package/lib/themes/ang.css +180 -1
- package/lib/themes/ang.css.map +1 -1
- package/lib/themes/antd-ie11.css +184 -2
- package/lib/themes/antd.css +184 -2
- package/lib/themes/antd.css.map +1 -1
- package/lib/themes/cxd-ie11.css +182 -8
- package/lib/themes/cxd.css +182 -8
- package/lib/themes/cxd.css.map +1 -1
- package/lib/themes/dark-ie11.css +182 -1
- package/lib/themes/dark.css +182 -1
- package/lib/themes/dark.css.map +1 -1
- package/lib/themes/default.css +182 -8
- package/lib/themes/default.css.map +1 -1
- package/lib/utils/api.js +14 -3
- package/lib/utils/api.js.map +2 -2
- package/lib/utils/debug.d.ts +26 -0
- package/lib/utils/debug.js +351 -0
- package/lib/utils/debug.js.map +13 -0
- package/lib/utils/renderer-event.d.ts +38 -0
- package/lib/utils/renderer-event.js +28 -0
- package/lib/utils/renderer-event.js.map +13 -0
- package/package.json +1 -1
- package/scss/_properties.scss +2 -0
- package/scss/_variables.scss +1 -0
- package/scss/components/_calendar.scss +4 -0
- package/scss/components/_debug.scss +167 -0
- package/scss/components/_popup.scss +1 -1
- package/scss/components/form/_date-range.scss +33 -0
- package/scss/components/form/_form.scss +2 -0
- package/scss/themes/_antd-variables.scss +4 -1
- package/scss/themes/_common.scss +2 -0
- package/scss/themes/_cxd-variables.scss +2 -0
- package/scss/themes/_dark-variables.scss +3 -0
- package/scss/themes/cxd.scss +0 -7
- package/sdk/ang-ie11.css +211 -1
- package/sdk/ang.css +213 -1
- package/sdk/antd-ie11.css +213 -2
- package/sdk/antd.css +217 -2
- package/sdk/charts.js +16 -16
- package/sdk/codemirror.js +7 -7
- package/sdk/color-picker.js +65 -65
- package/sdk/cropperjs.js +2 -2
- package/sdk/cxd-ie11.css +211 -8
- package/sdk/cxd.css +215 -8
- package/sdk/dark-ie11.css +211 -1
- package/sdk/dark.css +215 -1
- package/sdk/exceljs.js +1 -1
- package/sdk/helper.css.map +1 -1
- package/sdk/markdown.js +69 -69
- package/sdk/papaparse.js +1 -1
- package/sdk/renderers/Form/CityDB.js +1 -1
- package/sdk/rest.js +18 -18
- package/sdk/rich-text.js +62 -62
- package/sdk/sdk-ie11.css +211 -8
- package/sdk/sdk.css +215 -8
- package/sdk/sdk.js +1293 -1257
- package/sdk/thirds/hls.js/hls.js +1 -1
- package/sdk/thirds/mpegts.js/mpegts.js +1 -1
- package/sdk/tinymce.js +57 -57
- package/src/RootRenderer.tsx +27 -1
- package/src/SchemaRenderer.tsx +70 -4
- package/src/Scoped.tsx +46 -4
- package/src/actions/Action.ts +138 -0
- package/src/actions/AjaxAction.ts +58 -0
- package/src/actions/BreakAction.ts +27 -0
- package/src/actions/BroadcastAction.ts +41 -0
- package/src/actions/CmptAction.ts +36 -0
- package/src/actions/ContinueAction.ts +27 -0
- package/src/actions/CopyAction.ts +41 -0
- package/src/actions/CustomAction.ts +46 -0
- package/src/actions/DialogAction.ts +28 -0
- package/src/actions/DrawerAction.ts +28 -0
- package/src/actions/EmailAction.ts +38 -0
- package/src/actions/LoopAction.ts +77 -0
- package/src/actions/OpenPageAction.ts +39 -0
- package/src/actions/ParallelAction.ts +26 -0
- package/src/actions/SwitchAction.ts +35 -0
- package/src/actions/index.ts +20 -0
- package/src/components/CalendarMobile.tsx +127 -32
- package/src/components/DatePicker.tsx +32 -2
- package/src/components/DateRangePicker.tsx +2 -1
- package/src/components/MonthRangePicker.tsx +2 -1
- package/src/components/Select.tsx +4 -3
- package/src/components/Timeline.tsx +9 -4
- package/src/components/TimelineItem.tsx +62 -29
- package/src/components/formula/plugin.ts +0 -2
- package/src/env.tsx +22 -0
- package/src/factory.tsx +87 -1
- package/src/index.tsx +4 -0
- package/src/renderers/Action.tsx +11 -2
- package/src/renderers/Custom.tsx +1 -1
- package/src/renderers/Form/Options.tsx +15 -7
- package/src/renderers/Form/Select.tsx +7 -3
- package/src/renderers/Form/index.tsx +7 -1
- package/src/renderers/Link.tsx +18 -3
- package/src/store/formItem.ts +1 -1
- package/src/utils/api.ts +15 -2
- package/src/utils/debug.tsx +438 -0
- package/src/utils/renderer-event.ts +75 -0
package/src/RootRenderer.tsx
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
import {observer} from 'mobx-react';
|
2
|
+
import {getEnv} from 'mobx-state-tree';
|
2
3
|
import React from 'react';
|
3
4
|
import Alert from './components/Alert2';
|
4
5
|
import Spinner from './components/Spinner';
|
@@ -39,10 +40,18 @@ export class RootRenderer extends React.Component<RootRendererProps> {
|
|
39
40
|
'handleDialogConfirm',
|
40
41
|
'handleDialogClose',
|
41
42
|
'handleDrawerConfirm',
|
42
|
-
'handleDrawerClose'
|
43
|
+
'handleDrawerClose',
|
44
|
+
'handlePageVisibilityChange'
|
43
45
|
]);
|
44
46
|
}
|
45
47
|
|
48
|
+
componentDidMount() {
|
49
|
+
document.addEventListener(
|
50
|
+
'visibilitychange',
|
51
|
+
this.handlePageVisibilityChange
|
52
|
+
);
|
53
|
+
}
|
54
|
+
|
46
55
|
componentDidUpdate(prevProps: RootRendererProps) {
|
47
56
|
const props = this.props;
|
48
57
|
|
@@ -61,6 +70,23 @@ export class RootRenderer extends React.Component<RootRendererProps> {
|
|
61
70
|
|
62
71
|
componentWillUnmount() {
|
63
72
|
this.props.rootStore.removeStore(this.store);
|
73
|
+
document.removeEventListener(
|
74
|
+
'visibilitychange',
|
75
|
+
this.handlePageVisibilityChange
|
76
|
+
);
|
77
|
+
}
|
78
|
+
|
79
|
+
handlePageVisibilityChange() {
|
80
|
+
const env = this.props.env;
|
81
|
+
if (document.visibilityState === 'hidden') {
|
82
|
+
env?.tracker({
|
83
|
+
eventType: 'pageHidden'
|
84
|
+
});
|
85
|
+
} else if (document.visibilityState === 'visible') {
|
86
|
+
env?.tracker({
|
87
|
+
eventType: 'pageVisible'
|
88
|
+
});
|
89
|
+
}
|
64
90
|
}
|
65
91
|
|
66
92
|
handleAction(
|
package/src/SchemaRenderer.tsx
CHANGED
@@ -5,6 +5,7 @@ import LazyComponent from './components/LazyComponent';
|
|
5
5
|
import {
|
6
6
|
filterSchema,
|
7
7
|
loadRenderer,
|
8
|
+
RendererComponent,
|
8
9
|
RendererConfig,
|
9
10
|
RendererEnv,
|
10
11
|
RendererProps,
|
@@ -12,9 +13,12 @@ import {
|
|
12
13
|
} from './factory';
|
13
14
|
import {asFormItem} from './renderers/Form/Item';
|
14
15
|
import {renderChild, renderChildren} from './Root';
|
16
|
+
import {IScopedContext, ScopedContext} from './Scoped';
|
15
17
|
import {Schema, SchemaNode} from './types';
|
18
|
+
import {DebugWrapper, enableAMISDebug} from './utils/debug';
|
16
19
|
import getExprProperties from './utils/filter-schema';
|
17
|
-
import {anyChanged, chainEvents} from './utils/helper';
|
20
|
+
import {anyChanged, chainEvents, autobind} from './utils/helper';
|
21
|
+
import {RendererEvent} from './utils/renderer-event';
|
18
22
|
import {SimpleMap} from './utils/SimpleMap';
|
19
23
|
|
20
24
|
interface SchemaRendererProps extends Partial<RendererProps> {
|
@@ -23,6 +27,10 @@ interface SchemaRendererProps extends Partial<RendererProps> {
|
|
23
27
|
env: RendererEnv;
|
24
28
|
}
|
25
29
|
|
30
|
+
interface BroadcastCmptProps extends RendererProps {
|
31
|
+
component: RendererComponent;
|
32
|
+
}
|
33
|
+
|
26
34
|
const defaultOmitList = [
|
27
35
|
'type',
|
28
36
|
'name',
|
@@ -50,6 +58,58 @@ const defaultOmitList = [
|
|
50
58
|
|
51
59
|
const componentCache: SimpleMap = new SimpleMap();
|
52
60
|
|
61
|
+
class BroadcastCmpt extends React.Component<BroadcastCmptProps> {
|
62
|
+
ref: any;
|
63
|
+
unbindEvent: (() => void) | undefined = undefined;
|
64
|
+
static contextType = ScopedContext;
|
65
|
+
|
66
|
+
constructor(props: BroadcastCmptProps, context: IScopedContext) {
|
67
|
+
super(props);
|
68
|
+
this.triggerEvent = this.triggerEvent.bind(this);
|
69
|
+
}
|
70
|
+
|
71
|
+
componentDidMount() {
|
72
|
+
const {env} = this.props;
|
73
|
+
this.unbindEvent = env.bindEvent(this.ref);
|
74
|
+
}
|
75
|
+
|
76
|
+
componentWillUnmount() {
|
77
|
+
this.unbindEvent?.();
|
78
|
+
}
|
79
|
+
|
80
|
+
getWrappedInstance() {
|
81
|
+
return this.ref;
|
82
|
+
}
|
83
|
+
|
84
|
+
async triggerEvent(
|
85
|
+
e: React.MouseEvent<any>,
|
86
|
+
data: any
|
87
|
+
): Promise<RendererEvent<any> | undefined> {
|
88
|
+
return await this.props.env.dispatchEvent(e, this.ref, data);
|
89
|
+
}
|
90
|
+
|
91
|
+
@autobind
|
92
|
+
childRef(ref: any) {
|
93
|
+
while (ref && ref.getWrappedInstance) {
|
94
|
+
ref = ref.getWrappedInstance();
|
95
|
+
}
|
96
|
+
|
97
|
+
this.ref = ref;
|
98
|
+
}
|
99
|
+
|
100
|
+
render() {
|
101
|
+
const {component: Component, ...rest} = this.props;
|
102
|
+
return (
|
103
|
+
<Component
|
104
|
+
ref={this.childRef}
|
105
|
+
{...rest}
|
106
|
+
scoped={this.context}
|
107
|
+
dispatchEvent={this.triggerEvent}
|
108
|
+
/>
|
109
|
+
);
|
110
|
+
}
|
111
|
+
}
|
112
|
+
|
53
113
|
export class SchemaRenderer extends React.Component<SchemaRendererProps, any> {
|
54
114
|
static displayName: string = 'Renderer';
|
55
115
|
|
@@ -300,7 +360,6 @@ export class SchemaRenderer extends React.Component<SchemaRendererProps, any> {
|
|
300
360
|
...restSchema
|
301
361
|
} = schema;
|
302
362
|
const Component = renderer.component;
|
303
|
-
|
304
363
|
// 原来表单项的 visible: false 和 hidden: true 表单项的值和验证是有效的
|
305
364
|
// 而 visibleOn 和 hiddenOn 是无效的,
|
306
365
|
// 这个本来就是个bug,但是已经被广泛使用了
|
@@ -315,8 +374,8 @@ export class SchemaRenderer extends React.Component<SchemaRendererProps, any> {
|
|
315
374
|
return null;
|
316
375
|
}
|
317
376
|
|
318
|
-
|
319
|
-
<
|
377
|
+
const component = (
|
378
|
+
<BroadcastCmpt
|
320
379
|
{...theme.getRendererConfig(renderer.name)}
|
321
380
|
{...restSchema}
|
322
381
|
{...chainEvents(rest, restSchema)}
|
@@ -329,8 +388,15 @@ export class SchemaRenderer extends React.Component<SchemaRendererProps, any> {
|
|
329
388
|
$schema={{...schema, ...exprProps}}
|
330
389
|
ref={this.refFn}
|
331
390
|
render={this.renderChild}
|
391
|
+
component={Component}
|
332
392
|
/>
|
333
393
|
);
|
394
|
+
|
395
|
+
return enableAMISDebug ? (
|
396
|
+
<DebugWrapper renderer={renderer}>{component}</DebugWrapper>
|
397
|
+
) : (
|
398
|
+
component
|
399
|
+
);
|
334
400
|
}
|
335
401
|
}
|
336
402
|
|
package/src/Scoped.tsx
CHANGED
@@ -8,7 +8,15 @@ import find from 'lodash/find';
|
|
8
8
|
import hoistNonReactStatic from 'hoist-non-react-statics';
|
9
9
|
import {dataMapping} from './utils/tpl-builtin';
|
10
10
|
import {RendererEnv, RendererProps} from './factory';
|
11
|
-
import {
|
11
|
+
import {
|
12
|
+
noop,
|
13
|
+
autobind,
|
14
|
+
qsstringify,
|
15
|
+
qsparse,
|
16
|
+
createObject,
|
17
|
+
findTree,
|
18
|
+
TreeItem
|
19
|
+
} from './utils/helper';
|
12
20
|
import {RendererData, Action} from './types';
|
13
21
|
|
14
22
|
export interface ScopedComponentType extends React.Component<RendererProps> {
|
@@ -29,9 +37,11 @@ export interface ScopedComponentType extends React.Component<RendererProps> {
|
|
29
37
|
|
30
38
|
export interface IScopedContext {
|
31
39
|
parent?: AliasIScopedContext;
|
40
|
+
children?: AliasIScopedContext[];
|
32
41
|
registerComponent: (component: ScopedComponentType) => void;
|
33
42
|
unRegisterComponent: (component: ScopedComponentType) => void;
|
34
43
|
getComponentByName: (name: string) => ScopedComponentType;
|
44
|
+
getComponentById: (id: string) => ScopedComponentType | undefined;
|
35
45
|
getComponents: () => Array<ScopedComponentType>;
|
36
46
|
reload: (target: string, ctx: RendererData) => void;
|
37
47
|
send: (target: string, ctx: RendererData) => void;
|
@@ -46,8 +56,7 @@ function createScopedTools(
|
|
46
56
|
env?: RendererEnv
|
47
57
|
): IScopedContext {
|
48
58
|
const components: Array<ScopedComponentType> = [];
|
49
|
-
|
50
|
-
return {
|
59
|
+
const self = {
|
51
60
|
parent,
|
52
61
|
registerComponent(component: ScopedComponentType) {
|
53
62
|
// 不要把自己注册在自己的 Scoped 上,自己的 Scoped 是给子节点们注册的。
|
@@ -80,7 +89,7 @@ function createScopedTools(
|
|
80
89
|
|
81
90
|
return paths.reduce((scope, name, idx) => {
|
82
91
|
if (scope && scope.getComponentByName) {
|
83
|
-
const result = scope.getComponentByName(name);
|
92
|
+
const result: ScopedComponentType = scope.getComponentByName(name);
|
84
93
|
return result && idx < len - 1 ? result.context : result;
|
85
94
|
}
|
86
95
|
|
@@ -96,6 +105,27 @@ function createScopedTools(
|
|
96
105
|
return resolved || (parent && parent.getComponentByName(name));
|
97
106
|
},
|
98
107
|
|
108
|
+
getComponentById(id: string) {
|
109
|
+
let root: AliasIScopedContext = this;
|
110
|
+
// 找到顶端scoped
|
111
|
+
while (root.parent) {
|
112
|
+
root = root.parent;
|
113
|
+
}
|
114
|
+
|
115
|
+
// 向下查找
|
116
|
+
let component = undefined;
|
117
|
+
findTree([root], (item: TreeItem) =>
|
118
|
+
item.getComponents().find((cmpt: ScopedComponentType) => {
|
119
|
+
if (cmpt.props.id === id) {
|
120
|
+
component = cmpt;
|
121
|
+
return true;
|
122
|
+
}
|
123
|
+
return false;
|
124
|
+
})
|
125
|
+
) as ScopedComponentType | undefined;
|
126
|
+
return component;
|
127
|
+
},
|
128
|
+
|
99
129
|
getComponents() {
|
100
130
|
return components.concat();
|
101
131
|
},
|
@@ -208,6 +238,17 @@ function createScopedTools(
|
|
208
238
|
}
|
209
239
|
}
|
210
240
|
};
|
241
|
+
|
242
|
+
if (!parent) {
|
243
|
+
return self;
|
244
|
+
}
|
245
|
+
|
246
|
+
!parent.children && (parent.children = []);
|
247
|
+
|
248
|
+
// 把孩子带上
|
249
|
+
parent.children!.push(self);
|
250
|
+
|
251
|
+
return self;
|
211
252
|
}
|
212
253
|
|
213
254
|
function closeDialog(component: ScopedComponentType) {
|
@@ -257,6 +298,7 @@ export function HocScoped<
|
|
257
298
|
context,
|
258
299
|
this.props.env
|
259
300
|
);
|
301
|
+
|
260
302
|
const scopeRef = props.scopeRef;
|
261
303
|
scopeRef && scopeRef(this.scoped);
|
262
304
|
}
|
@@ -0,0 +1,138 @@
|
|
1
|
+
import {extendObject} from '../utils/helper';
|
2
|
+
import {RendererEvent} from '../utils/renderer-event';
|
3
|
+
import {evalExpression} from '../utils/tpl';
|
4
|
+
import {dataMapping} from '../utils/tpl-builtin';
|
5
|
+
|
6
|
+
// 逻辑动作类型,支持并行、排他(switch)、循环(支持continue和break)
|
7
|
+
type LogicActionType = 'parallel' | 'switch' | 'loop' | 'continue' | 'break';
|
8
|
+
|
9
|
+
// 循环动作执行状态
|
10
|
+
export enum LoopStatus {
|
11
|
+
NORMAL,
|
12
|
+
BREAK,
|
13
|
+
CONTINUE
|
14
|
+
}
|
15
|
+
|
16
|
+
// 监听器动作定义
|
17
|
+
export interface ListenerAction {
|
18
|
+
actionType: 'broadcast' | LogicActionType | 'custom' | string; // 动作类型 逻辑动作|自定义(脚本支撑)|reload|url|ajax|dialog|drawer 其他扩充的组件动作
|
19
|
+
eventName?: string; // 事件名称,actionType: broadcast
|
20
|
+
description?: string; // 事件描述,actionType: broadcast
|
21
|
+
componentId?: string; // 组件ID,用于直接执行指定组件的动作
|
22
|
+
args?: any; // 参数,可以配置数据映射
|
23
|
+
preventDefault?: boolean; // 阻止原有组件的动作行为
|
24
|
+
stopPropagation?: boolean; // 阻止后续的事件处理器执行
|
25
|
+
execOn?: string; // 执行条件
|
26
|
+
script?: string; // 自定义JS,actionType: custom
|
27
|
+
[propName: string]: any; // 扩展各种Action
|
28
|
+
}
|
29
|
+
|
30
|
+
export interface LogicAction extends ListenerAction {
|
31
|
+
children?: ListenerAction[]; // 子动作
|
32
|
+
}
|
33
|
+
|
34
|
+
export interface ListenerContext {
|
35
|
+
[propName: string]: any;
|
36
|
+
}
|
37
|
+
|
38
|
+
// Action 基础接口
|
39
|
+
export interface Action {
|
40
|
+
// 运行这个 Action,每个类型的 Action 都只有一个实例,run 函数是个可重入的函数
|
41
|
+
run: (
|
42
|
+
action: ListenerAction,
|
43
|
+
renderer: ListenerContext,
|
44
|
+
event: RendererEvent<any>,
|
45
|
+
mergeData?: any // 有些Action内部需要通过上下文数据处理专有逻辑,这里的数据是事件数据+渲染器数据
|
46
|
+
) => Promise<void>;
|
47
|
+
}
|
48
|
+
|
49
|
+
// 存储 Action 和类型的映射关系,用于后续查找
|
50
|
+
const ActionTypeMap: {[key: string]: Action} = {};
|
51
|
+
|
52
|
+
// 注册 Action
|
53
|
+
export const registerAction = (type: string, action: Action) => {
|
54
|
+
ActionTypeMap[type] = action;
|
55
|
+
};
|
56
|
+
|
57
|
+
// 通过类型获取 Action 实例
|
58
|
+
export const getActionByType = (type: string) => {
|
59
|
+
return ActionTypeMap[type];
|
60
|
+
};
|
61
|
+
|
62
|
+
export const runActions = async (
|
63
|
+
actions: ListenerAction | ListenerAction[],
|
64
|
+
renderer: ListenerContext,
|
65
|
+
event: any
|
66
|
+
) => {
|
67
|
+
if (!Array.isArray(actions)) {
|
68
|
+
actions = [actions];
|
69
|
+
}
|
70
|
+
|
71
|
+
for (const actionConfig of actions) {
|
72
|
+
let actionInstrance = getActionByType(actionConfig.actionType);
|
73
|
+
|
74
|
+
// 如果存在指定组件ID,说明是组件专有动作
|
75
|
+
if (actionConfig.componentId) {
|
76
|
+
actionInstrance = getActionByType('component');
|
77
|
+
} else if (
|
78
|
+
actionConfig.actionType === 'url' ||
|
79
|
+
actionConfig.actionType === 'link' ||
|
80
|
+
actionConfig.actionType === 'jump'
|
81
|
+
) {
|
82
|
+
// 打开页面动作
|
83
|
+
actionInstrance = getActionByType('openpage');
|
84
|
+
}
|
85
|
+
|
86
|
+
// 找不到就通过组件专有动作完成
|
87
|
+
if (!actionInstrance) {
|
88
|
+
actionInstrance = getActionByType('component');
|
89
|
+
}
|
90
|
+
|
91
|
+
// 这些节点的子节点运行逻辑由节点内部实现
|
92
|
+
await runAction(actionInstrance, actionConfig, renderer, event);
|
93
|
+
|
94
|
+
if (event.stoped) {
|
95
|
+
break;
|
96
|
+
}
|
97
|
+
}
|
98
|
+
};
|
99
|
+
|
100
|
+
// 执行动作,与原有动作处理打通
|
101
|
+
export const runAction = async (
|
102
|
+
actionInstrance: Action,
|
103
|
+
actionConfig: ListenerAction,
|
104
|
+
renderer: ListenerContext,
|
105
|
+
event: any
|
106
|
+
) => {
|
107
|
+
// 用户可能,需要用到事件数据和当前域的数据,因此merge事件数据和当前渲染器数据
|
108
|
+
// 需要保持渲染器数据链完整
|
109
|
+
const mergeData = extendObject(renderer.props.data, {
|
110
|
+
event
|
111
|
+
});
|
112
|
+
|
113
|
+
if (actionConfig.execOn && !evalExpression(actionConfig.execOn, mergeData)) {
|
114
|
+
return;
|
115
|
+
}
|
116
|
+
|
117
|
+
// 修正参数,处理数据映射
|
118
|
+
let args = event.data;
|
119
|
+
|
120
|
+
if (actionConfig.args) {
|
121
|
+
args = dataMapping(actionConfig.args, mergeData);
|
122
|
+
}
|
123
|
+
|
124
|
+
await actionInstrance.run(
|
125
|
+
{
|
126
|
+
...actionConfig,
|
127
|
+
args
|
128
|
+
},
|
129
|
+
renderer,
|
130
|
+
event,
|
131
|
+
mergeData
|
132
|
+
);
|
133
|
+
|
134
|
+
// 阻止原有动作执行
|
135
|
+
actionConfig.preventDefault && event.preventDefault();
|
136
|
+
// 阻止后续动作执行
|
137
|
+
actionConfig.stopPropagation && event.stopPropagation();
|
138
|
+
};
|
@@ -0,0 +1,58 @@
|
|
1
|
+
import {IRootStore} from '../store/root';
|
2
|
+
import {isVisible} from '../utils/helper';
|
3
|
+
import {RendererEvent} from '../utils/renderer-event';
|
4
|
+
import {filter} from '../utils/tpl';
|
5
|
+
import {
|
6
|
+
Action,
|
7
|
+
ListenerAction,
|
8
|
+
ListenerContext,
|
9
|
+
registerAction
|
10
|
+
} from './Action';
|
11
|
+
|
12
|
+
/**
|
13
|
+
* 发送请求动作
|
14
|
+
*
|
15
|
+
* @export
|
16
|
+
* @class AjaxAction
|
17
|
+
* @implements {Action}
|
18
|
+
*/
|
19
|
+
export class AjaxAction implements Action {
|
20
|
+
async run(
|
21
|
+
action: ListenerAction,
|
22
|
+
renderer: ListenerContext,
|
23
|
+
event: RendererEvent<any>
|
24
|
+
) {
|
25
|
+
const store = renderer.props.store;
|
26
|
+
|
27
|
+
store.setCurrentAction(action);
|
28
|
+
store
|
29
|
+
.saveRemote(action.api as string, action.args, {
|
30
|
+
successMessage: action.messages && action.messages.success,
|
31
|
+
errorMessage: action.messages && action.messages.failed
|
32
|
+
})
|
33
|
+
.then(async () => {
|
34
|
+
if (action.feedback && isVisible(action.feedback, store.data)) {
|
35
|
+
await this.openFeedback(action.feedback, store);
|
36
|
+
}
|
37
|
+
|
38
|
+
const redirect = action.redirect && filter(action.redirect, store.data);
|
39
|
+
redirect && renderer.env.jumpTo(redirect, action);
|
40
|
+
})
|
41
|
+
.catch(() => {});
|
42
|
+
}
|
43
|
+
|
44
|
+
openFeedback(dialog: any, store: IRootStore) {
|
45
|
+
return new Promise(resolve => {
|
46
|
+
store.setCurrentAction({
|
47
|
+
type: 'button',
|
48
|
+
actionType: 'dialog',
|
49
|
+
dialog: dialog
|
50
|
+
});
|
51
|
+
store.openDialog(store.data, undefined, confirmed => {
|
52
|
+
resolve(confirmed);
|
53
|
+
});
|
54
|
+
});
|
55
|
+
}
|
56
|
+
}
|
57
|
+
|
58
|
+
registerAction('ajax', new AjaxAction());
|
@@ -0,0 +1,27 @@
|
|
1
|
+
import {RendererEvent} from '../utils/renderer-event';
|
2
|
+
import {
|
3
|
+
Action,
|
4
|
+
ListenerAction,
|
5
|
+
ListenerContext,
|
6
|
+
LoopStatus,
|
7
|
+
registerAction
|
8
|
+
} from './Action';
|
9
|
+
|
10
|
+
/**
|
11
|
+
* breach
|
12
|
+
*
|
13
|
+
* @export
|
14
|
+
* @class BreakAction
|
15
|
+
* @implements {Action}
|
16
|
+
*/
|
17
|
+
export class BreakAction implements Action {
|
18
|
+
async run(
|
19
|
+
action: ListenerAction,
|
20
|
+
renderer: ListenerContext,
|
21
|
+
event: RendererEvent<any>
|
22
|
+
) {
|
23
|
+
renderer.loopStatus = LoopStatus.BREAK;
|
24
|
+
}
|
25
|
+
}
|
26
|
+
|
27
|
+
registerAction('break', new BreakAction());
|
@@ -0,0 +1,41 @@
|
|
1
|
+
import {createObject} from '../utils/helper';
|
2
|
+
import {RendererEvent} from '../utils/renderer-event';
|
3
|
+
import {
|
4
|
+
Action,
|
5
|
+
ListenerAction,
|
6
|
+
ListenerContext,
|
7
|
+
registerAction
|
8
|
+
} from './Action';
|
9
|
+
|
10
|
+
/**
|
11
|
+
* broadcast
|
12
|
+
*
|
13
|
+
* @export
|
14
|
+
* @class BroadcastAction
|
15
|
+
* @implements {Action}
|
16
|
+
*/
|
17
|
+
export class BroadcastAction implements Action {
|
18
|
+
async run(
|
19
|
+
action: ListenerAction,
|
20
|
+
renderer: ListenerContext,
|
21
|
+
event: RendererEvent<any>
|
22
|
+
) {
|
23
|
+
if (!action.eventName) {
|
24
|
+
console.warn('eventName 未定义,请定义事件名称');
|
25
|
+
return;
|
26
|
+
}
|
27
|
+
|
28
|
+
// 作为一个新的事件,需要把广播动作的args参数追加到事件数据中
|
29
|
+
event.setData(createObject(event.data, action.args));
|
30
|
+
|
31
|
+
// 直接触发对应的动作
|
32
|
+
return await event.context.env.dispatchEvent(
|
33
|
+
action.eventName,
|
34
|
+
renderer,
|
35
|
+
action.args,
|
36
|
+
event
|
37
|
+
);
|
38
|
+
}
|
39
|
+
}
|
40
|
+
|
41
|
+
registerAction('broadcast', new BroadcastAction());
|
@@ -0,0 +1,36 @@
|
|
1
|
+
import {RendererEvent} from '../utils/renderer-event';
|
2
|
+
import {dataMapping} from '../utils/tpl-builtin';
|
3
|
+
import {
|
4
|
+
Action,
|
5
|
+
ListenerAction,
|
6
|
+
ListenerContext,
|
7
|
+
LoopStatus,
|
8
|
+
registerAction
|
9
|
+
} from './Action';
|
10
|
+
|
11
|
+
/**
|
12
|
+
* 组件动作
|
13
|
+
*
|
14
|
+
* @export
|
15
|
+
* @class CmptAction
|
16
|
+
* @implements {Action}
|
17
|
+
*/
|
18
|
+
export class CmptAction implements Action {
|
19
|
+
async run(
|
20
|
+
action: ListenerAction,
|
21
|
+
renderer: ListenerContext,
|
22
|
+
event: RendererEvent<any>
|
23
|
+
) {
|
24
|
+
// 根据唯一ID查找指定组件
|
25
|
+
const component =
|
26
|
+
renderer.props.$schema.id !== action.componentId
|
27
|
+
? renderer.props.scoped?.getComponentById(action.componentId)
|
28
|
+
: renderer;
|
29
|
+
|
30
|
+
// 执行组件动作
|
31
|
+
(await component.props.onAction?.(event, action, action.args)) ||
|
32
|
+
component.doAction?.(action, action.args);
|
33
|
+
}
|
34
|
+
}
|
35
|
+
|
36
|
+
registerAction('component', new CmptAction());
|
@@ -0,0 +1,27 @@
|
|
1
|
+
import {RendererEvent} from '../utils/renderer-event';
|
2
|
+
import {
|
3
|
+
Action,
|
4
|
+
ListenerAction,
|
5
|
+
ListenerContext,
|
6
|
+
LoopStatus,
|
7
|
+
registerAction
|
8
|
+
} from './Action';
|
9
|
+
|
10
|
+
/**
|
11
|
+
* continue
|
12
|
+
*
|
13
|
+
* @export
|
14
|
+
* @class ContinueAction
|
15
|
+
* @implements {Action}
|
16
|
+
*/
|
17
|
+
export class ContinueAction implements Action {
|
18
|
+
async run(
|
19
|
+
action: ListenerAction,
|
20
|
+
renderer: ListenerContext,
|
21
|
+
event: RendererEvent<any>
|
22
|
+
) {
|
23
|
+
renderer.loopStatus = LoopStatus.CONTINUE;
|
24
|
+
}
|
25
|
+
}
|
26
|
+
|
27
|
+
registerAction('continue', new ContinueAction());
|
@@ -0,0 +1,41 @@
|
|
1
|
+
import {RendererEvent} from '../utils/renderer-event';
|
2
|
+
import {dataMapping} from '../utils/tpl-builtin';
|
3
|
+
import {filter} from '../utils/tpl';
|
4
|
+
import pick from 'lodash/pick';
|
5
|
+
import mapValues from 'lodash/mapValues';
|
6
|
+
import qs from 'qs';
|
7
|
+
import {
|
8
|
+
Action,
|
9
|
+
ListenerAction,
|
10
|
+
ListenerContext,
|
11
|
+
LoopStatus,
|
12
|
+
registerAction
|
13
|
+
} from './Action';
|
14
|
+
import {isVisible} from '../utils/helper';
|
15
|
+
|
16
|
+
/**
|
17
|
+
* 复制动作
|
18
|
+
*
|
19
|
+
* @export
|
20
|
+
* @class CopyAction
|
21
|
+
* @implements {Action}
|
22
|
+
*/
|
23
|
+
export class CopyAction implements Action {
|
24
|
+
async run(
|
25
|
+
action: ListenerAction,
|
26
|
+
renderer: ListenerContext,
|
27
|
+
event: RendererEvent<any>
|
28
|
+
) {
|
29
|
+
debugger;
|
30
|
+
if (action.content || action.copy) {
|
31
|
+
renderer.props.env.copy?.(
|
32
|
+
filter(action.content || action.copy, action.args, '| raw'),
|
33
|
+
{
|
34
|
+
format: action.copyFormat
|
35
|
+
}
|
36
|
+
);
|
37
|
+
}
|
38
|
+
}
|
39
|
+
}
|
40
|
+
|
41
|
+
registerAction('copy', new CopyAction());
|
@@ -0,0 +1,46 @@
|
|
1
|
+
import {RendererEvent} from '../utils/renderer-event';
|
2
|
+
import {
|
3
|
+
Action,
|
4
|
+
ListenerAction,
|
5
|
+
ListenerContext,
|
6
|
+
LoopStatus,
|
7
|
+
registerAction
|
8
|
+
} from './Action';
|
9
|
+
|
10
|
+
/**
|
11
|
+
* 自定义动作,JS脚本
|
12
|
+
*
|
13
|
+
* @export
|
14
|
+
* @class CustomAction
|
15
|
+
* @implements {Action}
|
16
|
+
*/
|
17
|
+
export class CustomAction implements Action {
|
18
|
+
async run(
|
19
|
+
action: ListenerAction,
|
20
|
+
renderer: ListenerContext,
|
21
|
+
event: RendererEvent<any>
|
22
|
+
) {
|
23
|
+
// 执行自定义编排脚本
|
24
|
+
let scriptFunc = action.script;
|
25
|
+
|
26
|
+
if (typeof scriptFunc === 'string') {
|
27
|
+
scriptFunc = new Function(
|
28
|
+
'context',
|
29
|
+
'doAction',
|
30
|
+
'event',
|
31
|
+
scriptFunc
|
32
|
+
) as any;
|
33
|
+
}
|
34
|
+
|
35
|
+
// 外部可以直接调用doAction来完成动作调用
|
36
|
+
// 可以通过上下文直接编排动作调用,通过event来进行动作干预
|
37
|
+
await (scriptFunc as any)?.call(
|
38
|
+
null,
|
39
|
+
renderer,
|
40
|
+
renderer.doAction.bind(renderer),
|
41
|
+
event
|
42
|
+
);
|
43
|
+
}
|
44
|
+
}
|
45
|
+
|
46
|
+
registerAction('custom', new CustomAction());
|