@cloudbase/framework-plugin-low-code 0.7.0 → 0.7.1

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.
@@ -1,17 +1,117 @@
1
1
  import * as React from 'react';
2
- import { useRef } from 'react';
3
2
  import * as _ from 'lodash';
4
- import { CompRenderer, ForContext } from './FieldMiddleware/renderer';
3
+ import { ForContext, getComponentRenderList } from './FieldMiddleware/renderer';
5
4
  import { isScopeSlot } from '../utils/index';
5
+ import { observer } from 'mobx-react-lite';
6
6
 
7
- function getComponentChildren(component) {
7
+ export function getComponentChildren(component, context = {}) {
8
8
  const { properties } = component;
9
9
  if (!properties) {
10
10
  return [];
11
11
  }
12
- return Object.values(properties).sort(
12
+ const list = Object.values(properties).sort(
13
13
  (a, b) => (a['x-index'] || 0) - (b['x-index'] || 0)
14
14
  );
15
+ const {
16
+ virtualFields,
17
+ codeContext,
18
+ scopeContext,
19
+ forContext,
20
+ injectContext = {},
21
+ dataContext,
22
+ updateContext,
23
+ } = context;
24
+
25
+ return list.map((schema) => {
26
+ return getRenderList({
27
+ key: schema.key,
28
+ componentSchema: schema,
29
+ rootNode: false,
30
+ renderSlot: false,
31
+ virtualFields,
32
+ codeContext,
33
+ scopeContext,
34
+ forContext,
35
+ injectContext,
36
+ context: dataContext,
37
+ updateContext,
38
+ });
39
+ });
40
+ }
41
+
42
+ function getRenderList(props) {
43
+ const {
44
+ key = '',
45
+ className,
46
+ virtualFields,
47
+ componentSchema,
48
+ renderSlot,
49
+ rootNode = true,
50
+ codeContext,
51
+ scopeContext = {},
52
+ context = {},
53
+ updateContext,
54
+ forContext = {},
55
+ } = props;
56
+
57
+ const { 'x-props': xProps, properties = {} } = componentSchema;
58
+
59
+ // 判断是否为 slot
60
+ const isSlot = !xProps;
61
+ if (isSlot && !(renderSlot || rootNode)) {
62
+ return null;
63
+ }
64
+
65
+ // const preClassName = useRef();
66
+
67
+ // wrapperClass
68
+ const containerEl = Object.values(properties)[0];
69
+ if (containerEl && containerEl['x-props'] && className) {
70
+ let { classNameList = [] } = containerEl['x-props'];
71
+
72
+ // 先替换掉先前计算出来的className部分
73
+ // if (preClassName.current) {
74
+ // if (preClassName.current !== className) {
75
+ // classNameList = classNameList.filter(
76
+ // (clsName) => clsName !== preClassName.current
77
+ // );
78
+ // preClassName.current = className;
79
+ // }
80
+ // } else {
81
+ // preClassName.current = className;
82
+ // }
83
+
84
+ containerEl['x-props'].classNameList = Array.from(
85
+ new Set([className, ...classNameList])
86
+ );
87
+ }
88
+
89
+ if (xProps && xProps.sourceKey) {
90
+ const { sourceKey } = xProps;
91
+ const Field = virtualFields[sourceKey];
92
+ if (!Field) {
93
+ return (
94
+ <div style={{ color: 'red' }}>
95
+ 组件<em>{sourceKey}</em>未找到
96
+ </div>
97
+ );
98
+ }
99
+ }
100
+
101
+ return getComponentRenderList({
102
+ key,
103
+ componentSchema,
104
+ id: componentSchema.key,
105
+ xProps,
106
+ emitEvents: componentSchema.emitEvents || [],
107
+ virtualFields,
108
+ renderSlot,
109
+ codeContext,
110
+ scopeContext,
111
+ forContext,
112
+ context,
113
+ updateContext,
114
+ });
15
115
  }
16
116
 
17
117
  export function generateSlotMetaMap(componentSchema, context, options = {}) {
@@ -36,14 +136,10 @@ export function generateSlotMetaMap(componentSchema, context, options = {}) {
36
136
  node: isHOC
37
137
  ? (props) => {
38
138
  let clonedScopeContext = _.cloneDeep(scopeContext);
39
- _.set(
40
- clonedScopeContext,
41
- `${componentSchema.key}.${child.key}`,
42
- props
43
- );
139
+ _.set(clonedScopeContext, `${componentSchema.key}.${key}`, props);
44
140
  return (
45
141
  <AppRender
46
- key={child.key}
142
+ key={key}
47
143
  componentSchema={child}
48
144
  renderSlot={options?.renderSlot}
49
145
  virtualFields={virtualFields}
@@ -58,7 +154,7 @@ export function generateSlotMetaMap(componentSchema, context, options = {}) {
58
154
  return (
59
155
  <ForContext.Provider value={forContext}>
60
156
  <AppRender
61
- key={child.key}
157
+ key={key}
62
158
  componentSchema={child}
63
159
  renderSlot={options?.renderSlot}
64
160
  virtualFields={virtualFields}
@@ -76,89 +172,10 @@ export function generateSlotMetaMap(componentSchema, context, options = {}) {
76
172
  return slots;
77
173
  }
78
174
 
79
- export function AppRender(props) {
80
- const {
81
- className,
82
- virtualFields,
83
- componentSchema,
84
- renderSlot,
85
- rootNode = true,
86
- codeContext,
87
- scopeContext = {},
88
- context = {},
89
- updateContext,
90
- } = props;
91
-
92
- const { 'x-props': xProps, properties = {} } = componentSchema;
93
-
94
- // 判断是否为 slot
95
- const isSlot = !xProps;
96
- if (isSlot && !(renderSlot || rootNode)) {
97
- return null;
98
- }
99
-
100
- const preClassName = useRef();
101
-
102
- // wrapperClass
103
- const containerEl = Object.values(properties)[0];
104
- if (containerEl && containerEl['x-props'] && className) {
105
- let { classNameList = [] } = containerEl['x-props'];
106
-
107
- // 先替换掉先前计算出来的className部分
108
- if (preClassName.current) {
109
- if (preClassName.current !== className) {
110
- classNameList = classNameList.filter(
111
- (clsName) => clsName !== preClassName.current
112
- );
113
- preClassName.current = className;
114
- }
115
- } else {
116
- preClassName.current = className;
117
- }
118
-
119
- containerEl['x-props'].classNameList = [className, ...classNameList];
120
- }
121
-
122
- if (xProps && xProps.sourceKey) {
123
- const { sourceKey } = xProps;
124
- const Field = virtualFields[sourceKey];
125
- if (!Field) {
126
- return (
127
- <div style={{ color: 'red' }}>
128
- 组件<em>{sourceKey}</em>未找到
129
- </div>
130
- );
131
- }
132
- }
133
-
134
- const children = getComponentChildren(componentSchema);
135
-
136
- return (
137
- <CompRenderer
138
- id={componentSchema.key}
139
- xProps={xProps}
140
- emitEvents={componentSchema.emitEvents || []}
141
- componentSchema={componentSchema}
142
- virtualFields={virtualFields}
143
- renderSlot={renderSlot}
144
- codeContext={codeContext}
145
- scopeContext={scopeContext}
146
- context={context}
147
- updateContext={updateContext}
148
- >
149
- {children.map((comp) => (
150
- <AppRender
151
- key={comp.key}
152
- componentSchema={comp}
153
- rootNode={false}
154
- renderSlot={false}
155
- virtualFields={virtualFields}
156
- codeContext={codeContext}
157
- scopeContext={scopeContext}
158
- context={context}
159
- updateContext={updateContext}
160
- />
161
- ))}
162
- </CompRenderer>
163
- );
164
- }
175
+ export const AppRender = observer(function (props) {
176
+ return getRenderList({
177
+ ...props,
178
+ forContext: React.useContext(ForContext),
179
+ injectContext: {},
180
+ });
181
+ });
@@ -84,7 +84,7 @@ export function resolveComponentProps(props, isPlainProps) {
84
84
  ...props,
85
85
  };
86
86
  }
87
- const { data = {}, events = [], ...restProps } = props;
87
+ const { data = {}, events = [], $node, ...restProps } = props;
88
88
  const customProps = { ...data };
89
89
  const builtinProps = [
90
90
  // react 保留字
@@ -78,37 +78,19 @@ initLifeCycle({
78
78
  export default function App() {
79
79
  // 检查权限
80
80
  const [weDaHasLogin, setWeDaHasLogin] = React.useState(false);
81
- const context = React.useRef(observable({})).current;
81
+ const dataContextRef = React.useRef(observable({}))
82
+ const context = dataContextRef.current;
82
83
  const containerRef = React.useRef(null);
83
84
  const microApp = React.useRef(null);
84
85
  const pureSrc = '<%= pageSource %>';
85
86
  const isPure = !!pureSrc;
86
87
 
87
- /**
88
- * 更新数据容器的上下文的方法
89
- * 会传递到事件emit的地方,将从组件获取到的数据data赋值给上下文
90
- * 当组件卸载时,传过来的data为undefined即可
91
- * {
92
- * id1: [{...}],
93
- * id2: {...},
94
- * id3: undefined,
95
- * id4: null,
96
- * ...
97
- * }
98
- * @param id
99
- * @param data
100
- */
101
- const updateContext = (id, data) => {
102
- if (id) {
103
- context[id] = { data };
104
- }
105
- }
106
-
107
88
  React.useEffect(() => {
108
89
  Object.assign($page, {
109
90
  id: '<%= pageName %>',
110
91
  state: observable(initPageState),
111
92
  computed: createComputed(computed),
93
+ // _context: context,
112
94
  handler,
113
95
  });
114
96
 
@@ -134,10 +116,10 @@ export default function App() {
134
116
  }, []);
135
117
 
136
118
  React.useEffect(() => {
137
- $page.widgets = createWidgets(widgetsContext, dataBinds, {}, context);
119
+ $page.widgets = createWidgets(widgetsContext, dataBinds, {}, dataContextRef.current);
138
120
  // widgets 内的 dataBinds 可能需要关联 widgets,需要重新执行 dataBinds
139
121
  retryDataBinds();
140
- }, [context]);
122
+ }, [dataContextRef.current]);
141
123
 
142
124
  // Web 环境页面级别生命周期
143
125
  if (!process.env.isMiniprogram) {
@@ -179,8 +161,27 @@ export default function App() {
179
161
  <AppRender pageListenerInstances={pageListenerInstances}
180
162
  virtualFields={virtualFields}
181
163
  componentSchema={componentSchema}
182
- context={context}
183
- updateContext={updateContext}
164
+ context={dataContextRef.current}
165
+ /**
166
+ * 更新数据容器的上下文的方法
167
+ * 会传递到事件emit的地方,将从组件获取到的数据data赋值给上下文
168
+ * 当组件卸载时,传过来的data为undefined即可
169
+ * {
170
+ * id1: [{...}],
171
+ * id2: {...},
172
+ * id3: undefined,
173
+ * id4: null,
174
+ * ...
175
+ * }
176
+ * @param id
177
+ * @param data
178
+ */
179
+ updateContext={(id, data) => {
180
+ if (id) {
181
+ dataContextRef.current[id] = { data };
182
+ // console.log('111', context[id])
183
+ }
184
+ }}
184
185
  />
185
186
  )}
186
187
  </div>
@@ -0,0 +1,42 @@
1
+ import { observable } from 'mobx';
2
+ let loading = {};
3
+ export let enumOptions = observable({});
4
+ export function formatEnum(path, optionname) {
5
+ // 判断是单选还是多选
6
+ let isSingle = Array.isArray(path);
7
+ // 获取到options
8
+ let parseOptions = getEnumOptions(optionname);
9
+ if (parseOptions === '') {
10
+ return !isSingle ? path : path.join(',');
11
+ }
12
+ let multiTmp = [];
13
+ let value = !isSingle
14
+ ? JSON.parse(parseOptions)?.find((item) => item?.key === path)?.value
15
+ : JSON.parse(parseOptions)
16
+ ?.filter((item) => path.some((pathValue) => item?.key === pathValue))
17
+ .map((item) => multiTmp.push(item?.value));
18
+ // 对多选或者单选有不同处理
19
+ return !isSingle ? value : multiTmp?.join(',');
20
+ }
21
+ function getEnumOptions(optionName) {
22
+ if (enumOptions[optionName]) {
23
+ return enumOptions[optionName];
24
+ }
25
+ if (!loading[optionName]) {
26
+ loading[optionName] = true;
27
+ getGeneralOptions(optionName).then((data) => {
28
+ enumOptions[optionName] = data?.Items[0]?.Config;
29
+ });
30
+ }
31
+ return '';
32
+ }
33
+ export async function getGeneralOptions(optionName) {
34
+ return app.cloud.callWedaApi({
35
+ action: 'DescribeGeneralOptionsDetailList',
36
+ data: {
37
+ PageSize: 1,
38
+ PageIndex: 1,
39
+ LikeNameOrTitle: optionName,
40
+ },
41
+ });
42
+ }