@steedos/service-plugin-amis 2.4.0-beta.9 → 2.4.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.
@@ -6,23 +6,6 @@
6
6
 
7
7
  ; (function () {
8
8
 
9
- const loadCss = (href)=>{
10
- try {
11
- // 加载Amis css
12
- let amisStyle = document.createElement("link");
13
- amisStyle.setAttribute("rel", "stylesheet");
14
- amisStyle.setAttribute("type", "text/css");
15
- amisStyle.setAttribute("href", href);
16
- document.getElementsByTagName("head")[0].appendChild(amisStyle);
17
- } catch (error) {
18
- console.error(error)
19
- };
20
- }
21
- // loadCss(Steedos.absoluteUrl("/unpkg.com/amis/sdk/sdk.css"))
22
- loadCss(Steedos.absoluteUrl("/unpkg.com/amis/sdk/helper.css"))
23
- loadCss(Steedos.absoluteUrl("/unpkg.com/amis/sdk/iconfont.css"))
24
- loadCss(Steedos.absoluteUrl("/amis/amis.css"))
25
-
26
9
  try {
27
10
  window['attrAccept'] = function (file, acceptedFiles) {
28
11
  if (file && acceptedFiles) {
@@ -48,9 +31,9 @@
48
31
  }
49
32
 
50
33
  // 加载Amis SDK: 如果直接放到body中会导致 meteor 编译后的 cordova.js 加载报错
51
- let amisSDKScript = document.createElement("script");
52
- amisSDKScript.setAttribute("src", Steedos.absoluteUrl('/unpkg.com/amis/sdk/sdk.js'));
53
- document.getElementsByTagName("head")[0].appendChild(amisSDKScript);
34
+ // let amisSDKScript = document.createElement("script");
35
+ // amisSDKScript.setAttribute("src", Steedos.absoluteUrl('/unpkg.com/amis/sdk/sdk.js'));
36
+ // document.getElementsByTagName("head")[0].appendChild(amisSDKScript);
54
37
  } catch (error) {
55
38
  console.error(error)
56
39
  };
@@ -94,7 +77,7 @@
94
77
  if(comp.componentType === 'amisSchema'){
95
78
  let amisReact = amisRequire('react');
96
79
  AmisWrapper = function(props){
97
- const { body, render } = props
80
+ const { $schema, body, render } = props
98
81
  const [schema, setSchema] = amisReact.useState(null);
99
82
  amisReact.useEffect(()=>{
100
83
  const result = Component.class(props);
@@ -105,7 +88,24 @@
105
88
  }else{
106
89
  setSchema(result)
107
90
  }
108
- }, [])
91
+ }, [JSON.stringify($schema)])
92
+
93
+ if (!schema)
94
+ return render('body', {
95
+ "type": "wrapper",
96
+ "className": "h-full flex items-center justify-center",
97
+ "body": {
98
+ "type": "spinner",
99
+ "show": true
100
+ }
101
+ })
102
+
103
+ if (props.env.enableAMISDebug && schema) {
104
+ console.groupCollapsed(`[steedos render ${comp.amis?.render.type}]`);
105
+ console.trace('Component: ', props, 'Generated Amis Schema: ', schema);
106
+ console.groupEnd();
107
+ }
108
+
109
109
  return amisReact.createElement(amisReact.Fragment, null, amisReact.createElement(amisReact.Fragment, null, schema && render ? render('body', schema) : ''), amisReact.createElement(amisReact.Fragment, null, render ? render('body', body) : ''));
110
110
  }
111
111
  }
@@ -203,7 +203,7 @@
203
203
  console.error(`error`, error)
204
204
  }
205
205
  }
206
- const AmisEnv = {
206
+ AmisEnv = {
207
207
  // getModalContainer: (props)=>{
208
208
  // let div = document.querySelector("#amisModalContainer");
209
209
  // if(!div){
@@ -223,7 +223,7 @@
223
223
  to = normalizeLink(to);
224
224
 
225
225
  if (action && action.actionType === 'url') {
226
- action.blank === false ? (window.location.href = to) : window.open(to);
226
+ action.blank === true ? window.open(to): (window.location.href = to);
227
227
  return;
228
228
  }
229
229
 
@@ -248,10 +248,13 @@
248
248
  const schema = props.schema;
249
249
  const data = props.data;
250
250
  const name = props.name;
251
-
252
- if(SteedosUI.refs[schema.name]){
253
- if(SteedosUI.refs[schema.name].unmount){
254
- SteedosUI.refs[schema.name].unmount()
251
+ const refName = schema.name || schema.id;
252
+ if(SteedosUI.refs[refName]){
253
+ if(SteedosUI.refs[refName].unmount){
254
+ try {
255
+ SteedosUI.refs[refName].unmount()
256
+ } catch (Exception) {
257
+ }
255
258
  }else{
256
259
  console.log(`not find amis scope unmount`)
257
260
  }
@@ -279,19 +282,65 @@
279
282
  return scoped = ref
280
283
  }
281
284
 
282
- React.useEffect(()=>{
285
+
286
+ let amisReact = amisRequire('react');
287
+
288
+ amisReact.useEffect(()=>{
283
289
  const amisScope = amisRequire('amis/embed').embed(`.steedos-amis-render-scope-${name}`,schema, {data, name, locale: getAmisLng()}, Object.assign({}, AmisEnv, env))
284
- if(window.SteedosUI && schema.name){
285
- SteedosUI.refs[schema.name] = amisScope;
290
+ const refName = schema.name || schema.id;
291
+ if(window.SteedosUI && refName){
292
+ SteedosUI.refs[refName] = amisScope;
286
293
  }
287
294
  }, [])
288
- return React.createElement("div", {
295
+ return amisReact.createElement("div", {
289
296
  className: "amis-scope"
290
- }, React.createElement("div", {
297
+ }, amisReact.createElement("div", {
291
298
  className: `steedos-amis-render-scope-${name}`
292
299
  }));
293
300
  };
294
301
 
302
+ window.renderAmis = function (root, schema, data, env) {
303
+ const refName = schema.name || schema.id;
304
+ if(SteedosUI.refs[refName]){
305
+ if(SteedosUI.refs[refName].unmount){
306
+ try {
307
+ SteedosUI.refs[refName].unmount()
308
+ } catch (Exception) {
309
+ }
310
+ }else{
311
+ console.log(`not find amis scope unmount`)
312
+ }
313
+ }
314
+
315
+ // if(props.pageType === 'form'){
316
+ // env = Object.assign({
317
+ // getModalContainer: ()=>{
318
+ // return document.querySelector('.amis-scope');
319
+ // }
320
+ // }, env);
321
+ // }
322
+ schema.scopeRef = (ref) => {
323
+ try {
324
+ if(!window.amisScopes){
325
+ window.amisScopes = {};
326
+ }
327
+ if(name){
328
+ window.amisScopes[name] = ref;
329
+ }
330
+ } catch (error) {
331
+ console.error('error', error)
332
+ }
333
+
334
+ return scoped = ref
335
+ }
336
+
337
+
338
+ const amisScope = amisRequire('amis/embed').embed(root, schema, {data, name, locale: getAmisLng()}, Object.assign({}, AmisEnv, env))
339
+ if(window.SteedosUI && refName){
340
+ SteedosUI.refs[refName] = amisScope;
341
+ }
342
+ };
343
+
295
344
  const initMonaco = ()=>{
296
345
 
297
346
  // const { detect } = require('detect-browser');
@@ -0,0 +1,266 @@
1
+ {
2
+ "type": "page",
3
+ "body": [
4
+ {
5
+ "type": "service",
6
+ "className": "p-0",
7
+ "name": "page_edit_${recordId}",
8
+ "api": {
9
+ "method": "post",
10
+ "url": "${context.rootUrl}/graphql",
11
+ "adaptor": "\n if(payload.data.data){\n var data = payload.data.data[0];\n if(data){\n \n \n //初始化接口返回的字段移除字段值为null的字段\n for (key in data){\n if(data[key] === null){\n delete data[key];\n }\n }\n };\n payload.data = data;\n delete payload.extensions;\n }\n return payload;\n ",
12
+ "data": {
13
+ "query": "{data:action_field_updates(filters:[\"_id\", \"=\", \"${recordId}\"]){_id,name,label,object_name,target_object,field_name,operation,formula,literal_value,description,reevaluate_on_change,undirect,created,created_by,modified,modified_by,_display:_ui{object_name,target_object,field_name,operation,reevaluate_on_change,undirect,created,created_by,modified,modified_by}, \n recordPermissions: _permissions{\n allowCreate,\n allowCreateFiles,\n allowDelete,\n allowDeleteFiles,\n allowEdit,\n allowEditFiles,\n allowRead,\n allowReadFiles,\n disabled_actions,\n disabled_list_views,\n field_permissions,\n modifyAllFiles,\n modifyAllRecords,\n modifyAssignCompanysRecords,\n modifyCompanyRecords,\n uneditable_fields,\n unreadable_fields,\n unrelated_objects,\n viewAllFiles,\n viewAllRecords,\n viewAssignCompanysRecords,\n viewCompanyRecords,\n }\n }}"
14
+ },
15
+ "headers": {
16
+ "Authorization": "Bearer ${context.tenantId},${context.authToken}"
17
+ },
18
+ "sendOn": "!!this.recordId",
19
+ "cache": 100
20
+ },
21
+ "initFetch": null,
22
+ "body": [
23
+ {
24
+ "type": "form",
25
+ "title": "",
26
+ "body": [
27
+ {
28
+ "type": "fieldSet",
29
+ "id": "u:3ce1d050bcac",
30
+ "title": "通用",
31
+ "collapsable": true,
32
+ "body": [
33
+ {
34
+ "name": "name",
35
+ "label": "API 名称",
36
+ "required": true,
37
+ "type": "input-text",
38
+ "className": "m-1",
39
+ "labelClassName": "text-left",
40
+ "clearValueOnHidden": true,
41
+ "fieldName": "name",
42
+ "id": "u:8ebca359c714"
43
+ },
44
+ {
45
+ "name": "label",
46
+ "label": "显示名称",
47
+ "required": true,
48
+ "type": "input-text",
49
+ "className": "m-1",
50
+ "labelClassName": "text-left",
51
+ "clearValueOnHidden": true,
52
+ "fieldName": "label",
53
+ "id": "u:124c34a09c5c"
54
+ },
55
+ {
56
+ "name": "object_name",
57
+ "label": "对象",
58
+ "required": false,
59
+ "type": "select",
60
+ "joinValues": false,
61
+ "extractValue": true,
62
+ "searchable": true,
63
+ "source": {
64
+ "method": "post",
65
+ "url": "${context.rootUrl}/graphql",
66
+ "data": {
67
+ "orderBy": "${orderBy}",
68
+ "orderDir": "${orderDir}",
69
+ "pageNo": "${page}",
70
+ "pageSize": "${perPage}",
71
+ "query": "{options:objects(filters: {__filters}, top: {__top}, sort: \"{__sort}\"){_id label:label value:name},count:objects__count(filters:{__filters}),defaultValueOptions:objects(filters:{__options_filters}){_id label:label value:name}}",
72
+ "$term": "$term",
73
+ "$value": "$object_name",
74
+ "$": "$$",
75
+ "rfield": "${object_name}"
76
+ },
77
+ "headers": {
78
+ "Authorization": "Bearer ${context.tenantId},${context.authToken}"
79
+ },
80
+ "adaptor": "\n const data = payload.data;\n var defaultValueOptions = data.defaultValueOptions;\n // 字段值下拉选项合并到options中\n data.options = _.unionWith(defaultValueOptions, data.options, function(a,b){\n return a[\"value\"]=== b[\"value\"];\n });\n delete data.defaultValueOptions;\n payload.data.options = data.options;\n return payload;\n ",
81
+ "requestAdaptor": "\n var filters = [];\n var top = 10;\n if(api.data.$term){\n filters = [[\"label\", \"contains\", api.data.$term]];\n }\n // else if(api.data.$value){\n // filters = [[\"_id\", \"=\", api.data.$value]];\n // }\n\n var fieldFilters = undefined;\n if(fieldFilters && fieldFilters.length){\n filters.push(fieldFilters);\n }\n\n const filtersFunction = undefined;\n\n if(filtersFunction){\n const _filters = filtersFunction(filters, api.data.$);\n if(_filters && _filters.length > 0){\n filters.push(_filters);\n }\n }\n var sort = \"\";\n api.data.query = api.data.query.replace(/{__filters}/g, JSON.stringify(filters)).replace('{__top}', top).replace('{__sort}', sort.trim());\n\n var defaultValue = api.data.$value;\n var optionsFiltersOp = \"=\";\n var optionsFilters = [[\"name\", optionsFiltersOp, []]];\n if (defaultValue && !api.data.$term) { \n // 字段值单独请求,没值的时候在请求中返回空\n optionsFilters = [[\"name\", optionsFiltersOp, defaultValue]];\n }\n api.data.query = api.data.query.replace(/{__options_filters}/g, JSON.stringify(optionsFilters));\n return api;\n "
82
+ },
83
+ "className": "m-1",
84
+ "labelClassName": "text-left",
85
+ "clearValueOnHidden": true,
86
+ "fieldName": "object_name",
87
+ "id": "u:0f2e40f882e2"
88
+ },
89
+ {
90
+ "name": "target_object",
91
+ "label": "要更新的对象",
92
+ "required": false,
93
+ "type": "select",
94
+ "joinValues": false,
95
+ "extractValue": true,
96
+ "searchable": true,
97
+ "source": {
98
+ "method": "get",
99
+ "url": "${context.rootUrl}/service/api/action_field_updates/target_object/options?objectName=${object_name}"
100
+ },
101
+ "className": "m-1",
102
+ "labelClassName": "text-left",
103
+ "clearValueOnHidden": true,
104
+ "fieldName": "target_object",
105
+ "id": "u:dd1c95753238"
106
+ },
107
+ {
108
+ "name": "field_name",
109
+ "label": "要更新的字段",
110
+ "required": false,
111
+ "type": "select",
112
+ "joinValues": false,
113
+ "extractValue": true,
114
+ "searchable": true,
115
+ "source": {
116
+ "method": "get",
117
+ "url": "${context.rootUrl}/service/api/action_field_updates/field_name/options?objectName=${object_name}&targetObject=${target_object}"
118
+ },
119
+ "className": "m-1",
120
+ "labelClassName": "text-left",
121
+ "clearValueOnHidden": true,
122
+ "fieldName": "field_name",
123
+ "id": "u:204fadb7cef0"
124
+ },
125
+ {
126
+ "name": "operation",
127
+ "label": "新字段值类型",
128
+ "required": false,
129
+ "type": "select",
130
+ "joinValues": false,
131
+ "extractValue": true,
132
+ "source": {
133
+ "method": "get",
134
+ "url": "${context.rootUrl}/service/api/action_field_updates/operation/options?objectName=${object_name}&targetObject=${target_object}&fieldName=${field_name}"
135
+ },
136
+ "className": "m-1",
137
+ "labelClassName": "text-left",
138
+ "clearValueOnHidden": true,
139
+ "fieldName": "operation",
140
+ "id": "u:627e520855b5",
141
+ "multiple": false
142
+ },
143
+ {
144
+ "name": "formula",
145
+ "label": "公式",
146
+ "required": false,
147
+ "type": "textarea",
148
+ "tpl": "<b><%=data.formula%></b>",
149
+ "className": "col-span-2 m-1",
150
+ "labelClassName": "text-left",
151
+ "clearValueOnHidden": true,
152
+ "fieldName": "formula",
153
+ "id": "u:20766a86a9f4",
154
+ "hiddenOn": "this.operation != 'formula'"
155
+ },
156
+ {
157
+ "type": "service",
158
+ "id": "u:d201a629c160",
159
+ "body": [],
160
+ "messages": {},
161
+ "schemaApi": {
162
+ "method": "get",
163
+ "url": "${context.rootUrl}/service/api/action_field_updates/literal_value/options?objectName=${object_name}&targetObject=${target_object}&fieldName=${field_name}&operation=${operation}",
164
+ "data": {
165
+ "&": "$$"
166
+ }
167
+ }
168
+ },
169
+ {
170
+ "name": "description",
171
+ "label": "描述",
172
+ "required": false,
173
+ "type": "textarea",
174
+ "tpl": "<b><%=data.description%></b>",
175
+ "className": "col-span-2 m-1",
176
+ "labelClassName": "text-left",
177
+ "clearValueOnHidden": true,
178
+ "fieldName": "description",
179
+ "id": "u:16a7ebd835a6"
180
+ },
181
+ {
182
+ "name": "reevaluate_on_change",
183
+ "label": "字段更改后重新评估工作流规则",
184
+ "required": false,
185
+ "type": "checkbox",
186
+ "tpl": null,
187
+ "className": "m-1",
188
+ "labelClassName": "text-left",
189
+ "clearValueOnHidden": true,
190
+ "fieldName": "reevaluate_on_change",
191
+ "id": "u:b9baf683b6b0"
192
+ },
193
+ {
194
+ "name": "undirect",
195
+ "label": "触发对象触发器、工作流规则、字段验证规则",
196
+ "required": false,
197
+ "type": "checkbox",
198
+ "tpl": null,
199
+ "className": "m-1",
200
+ "labelClassName": "text-left",
201
+ "clearValueOnHidden": true,
202
+ "fieldName": "undirect",
203
+ "id": "u:b86f699bbe4f"
204
+ }
205
+ ]
206
+ }
207
+ ],
208
+ "id": "u:f57077c2a95f",
209
+ "mode": "horizontal",
210
+ "persistData": false,
211
+ "promptPageLeave": true,
212
+ "name": "form_edit_${recordId}",
213
+ "debug": false,
214
+ "submitText": "",
215
+ "api": {
216
+ "method": "post",
217
+ "url": "${context.rootUrl}/graphql",
218
+ "data": {
219
+ "objectName": "${objectName}",
220
+ "$": "$$",
221
+ "recordId": "${recordId}",
222
+ "modalName": "${modalName}"
223
+ },
224
+ "requestAdaptor": "\n \n const formData = api.data.$;\n for (key in formData){\n // image、select等字段清空值后保存的空字符串转换为null。\n if(formData[key] === ''){\n formData[key] = null;\n }\n }\n const objectName = api.data.objectName;\n const fieldsName = Object.keys(formData);\n delete formData.created;\n delete formData.created_by;\n delete formData.modified;\n delete formData.modified_by;\n delete formData._display;\n delete formData.created;\r\ndelete formData.created_by;\r\ndelete formData.modified;\r\ndelete formData.modified_by;\n \n \n let query = `mutation{record: ${objectName}__insert(doc: {__saveData}){_id}}`;\n if(formData.recordId && formData.recordId !='new'){\n query = `mutation{record: ${objectName}__update(id: \"${formData._id}\", doc: {__saveData}){_id}}`;\n };\n delete formData._id;\n let __saveData = JSON.stringify(JSON.stringify(formData));\n \n api.data = {query: query.replace('{__saveData}', __saveData)};\n return api;\n ",
225
+ "responseData": {
226
+ "recordId": "${record._id}"
227
+ },
228
+ "adaptor": "\n if(payload.errors){\n payload.status = 2;\n payload.msg = payload.errors[0].message;\n }\n return payload;\n ",
229
+ "headers": {
230
+ "Authorization": "Bearer ${context.tenantId},${context.authToken}"
231
+ }
232
+ },
233
+ "initFetch": true,
234
+ "panelClassName": "m-0 sm:rounded-lg shadow-none",
235
+ "bodyClassName": "p-0",
236
+ "className": "steedos-amis-form",
237
+ "onEvent": {
238
+ "submitSucc": {
239
+ "weight": 0,
240
+ "actions": [
241
+ {
242
+ "componentId": "listview_action_field_updates",
243
+ "actionType": "reload",
244
+ "expression": "!!listViewId"
245
+ },
246
+ {
247
+ "actionType": "custom",
248
+ "script": "\n const { recordId, listViewId } = context.props.data;\n const data = event.data;\n const appId = data.appId;\n const objectName = data.objectName;\n // 在记录详细界面时isRecordDetail为true\n // TODO: isRecordDetail这个判断需要优化\n const isRecordDetail = data._isRelated;\n if(recordId){\n // 编辑记录时,刷新主表单\n doAction({\n componentId: `detail_${recordId}`,\n actionType: \"reload\",\n expression: `!${listViewId}`\n });\n }\n else if(!isRecordDetail){\n // 在列表视图界面新建记录时跳转到详细页面\n const jumpTo = event.context.env && event.context.env.jumpTo;\n if(jumpTo){\n const newRecordId = data.result.data?.recordId;\n jumpTo(\"/app/\" + appId + \"/\" + objectName + \"/view/\" + newRecordId);\n }\n }\n "
249
+ }
250
+ ]
251
+ }
252
+ }
253
+ }
254
+ ],
255
+ "initApi": null
256
+ }
257
+ ],
258
+ "data": {
259
+ "objectName": "action_field_updates",
260
+ "context": {}
261
+ },
262
+ "regions": [
263
+ "body"
264
+ ],
265
+ "bodyClassName": ""
266
+ }
@@ -0,0 +1,12 @@
1
+ name: action_field_updates
2
+ is_active: true
3
+ label: 字段更新表单
4
+ object_name: action_field_updates
5
+ pageAssignments:
6
+ - desktop: true
7
+ mobile: true
8
+ page: action_field_updates
9
+ type: orgDefault
10
+ render_engine: amis
11
+ type: form
12
+ widgets: []
@@ -18,11 +18,11 @@
18
18
  "modalName": "${modalName}",
19
19
  "objectName": "${objectName}"
20
20
  },
21
- "requestAdaptor": "\nconst formData = api.data.$;\nfor (key in formData){\n // image、select等字段清空值后保存的空字符串转换为null。\n if(formData[key] === ''){\n formData[key] = null;\n }\n}\nconst objectName = api.data.objectName;\nconst fieldsName = Object.keys(formData);\ndelete formData.created;\ndelete formData.created_by;\ndelete formData.modified;\ndelete formData.modified_by;\ndelete formData._display;\ndelete formData.tabs_options;\ndelete formData.tab_groups_options;\n\n// 新加字段tab_items,值同步回传到老字段tabs中兼容老UI界面\nformData.tabs = [];\nif (formData.tab_items && formData.tab_items.length) { \n formData.tabs = formData.tab_items.map(function (item) { return item.tab_name; });\n}\n\n/*\ntab_items存储为:\ntab_items: {\n test1:{\n group:\"xxx\"\n },\n test3:{\n group:\"yyy\"\n }\n}\n而不是:\ntab_items: [\n {\n \"index\":1,\n \"group\":\"xxx\"\n },\n {\n \"index\":2,\n \"group\":\"yyy\"\n }\n]\n*/\nif (formData.tab_items) { \n formData.tab_items = _.keyBy(formData.tab_items, \"tab_name\")\n let tempIndex = 0;\n _.each(formData.tab_items, function (n, k) {\n tempIndex++;\n n.index = tempIndex;\n delete n.tab_name;\n });\n}\n\nlet query = `mutation{record: ${objectName}__insert(doc: {__saveData}){_id}}`;\nif(formData.recordId){\n query = `mutation{record: ${objectName}__update(id: \"${formData.recordId}\", doc: {__saveData}){_id}}`;\n};\ndelete formData._id;\nlet __saveData = JSON.stringify(JSON.stringify(formData));\n\napi.data = {query: query.replace('{__saveData}', __saveData)};\nreturn api;\n",
21
+ "requestAdaptor": "\nconst formData = api.data.$;\nconst recordId = formData.recordId;\nfor (key in formData){\n // image、select等字段清空值后保存的空字符串转换为null。\n if(formData[key] === ''){\n formData[key] = null;\n }\n}\nconst objectName = api.data.objectName;\nconst fieldsName = Object.keys(formData);\ndelete formData.created;\ndelete formData.created_by;\ndelete formData.modified;\ndelete formData.modified_by;\ndelete formData._display;\ndelete formData.tabs_options;\ndelete formData.tab_groups_options;\ndelete formData.sldsIconsOptions;\ndelete formData.recordId;\n\n// 新加字段tab_items,值同步回传到老字段tabs中兼容老UI界面\nformData.tabs = [];\nif (formData.tab_items && formData.tab_items.length) { \n formData.tabs = formData.tab_items.map(function (item) { return item.tab_name; });\n}\n\n/*\ntab_items存储为:\ntab_items: {\n test1:{\n group:\"xxx\"\n },\n test3:{\n group:\"yyy\"\n }\n}\n而不是:\ntab_items: [\n {\n \"index\":1,\n \"group\":\"xxx\"\n },\n {\n \"index\":2,\n \"group\":\"yyy\"\n }\n]\n*/\nif (formData.tab_items) { \n formData.tab_items = _.keyBy(formData.tab_items, \"tab_name\")\n let tempIndex = 0;\n _.each(formData.tab_items, function (n, k) {\n tempIndex++;\n n.index = tempIndex;\n delete n.tab_name;\n });\n}\n\nlet query = `mutation{record: ${objectName}__insert(doc: {__saveData}){_id}}`;\nif(recordId){\n query = `mutation{record: ${objectName}__update(id: \"${recordId}\", doc: {__saveData}){_id}}`;\n};\ndelete formData._id;\nlet __saveData = JSON.stringify(JSON.stringify(formData));\n\napi.data = {query: query.replace('{__saveData}', __saveData)};\nreturn api;\n",
22
22
  "responseData": {
23
23
  "recordId": "${record._id}"
24
24
  },
25
- "adaptor": "\nSteedosUI.router.go({objectName: api.body.objectName, recordId: payload.data.record._id, type: api.body.recordId ? 'edit': 'new'});\nreturn payload;\n ",
25
+ "adaptor": "\nif (payload.errors) {\n payload.status = 2;\n payload.msg = window.t ? window.t(payload.errors[0].message) : payload.errors[0].message;\n}\nreturn payload;",
26
26
  "headers": {
27
27
  "Authorization": "Bearer ${context.tenantId},${context.authToken}"
28
28
  }
@@ -33,7 +33,7 @@
33
33
  "sendOn": "!!this.recordId",
34
34
  "adaptor": "var data = payload.data.data[0];\nif(data){\n //初始化接口返回的字段移除字段值为null的字段\n for (key in data){\n if(data[key] === null){\n delete data[key];\n }\n }\n};\nif (data.tab_items && !_.isArray(data.tab_items)) {\n // 数据库中存储的是对象格式而不是数组,转换为数组用于界面显示\n let arrTabItems = [];\n _.each(data.tab_items, function (n, k) {\n n.tab_name = k;\n delete n.index;\n arrTabItems.push(n);\n });\n data.tab_items = arrTabItems;\n}\npayload.data = data;\ndelete payload.extensions;\nreturn payload;\n ",
35
35
  "data": {
36
- "query": "{data:apps(filters:[\"_id\", \"=\", \"${recordId}\"]){_id,name,code,icon_slds,visible,description,tabs,tab_items,tab_groups,objects,mobile_objects,is_creator,mobile,sort,url,is_use_ie,is_use_iframe,is_new_window,on_click,auth_name,secret,is_system,from_code_id,instance_state,created,created_by:created_by__expand{_id,name},modified,modified_by:modified_by__expand{_id,name},_display{visible,is_creator,mobile,is_use_ie,is_use_iframe,is_new_window,is_system,instance_state,created,modified}}}"
36
+ "query": "{data:apps(filters:[\"_id\", \"=\", \"${recordId}\"]){_id,name,code,icon_slds,visible, showSidebar, description,tabs,tab_items,tab_groups,objects,mobile_objects,is_creator,mobile,sort,url,is_use_ie,is_use_iframe,is_new_window,on_click,auth_name,secret,is_system,from_code_id,instance_state,created,created_by:created_by__expand{_id,name},modified,modified_by:modified_by__expand{_id,name},_display{visible,is_creator,mobile,is_use_ie,is_use_iframe,is_new_window,is_system,instance_state,created,modified}}}"
37
37
  },
38
38
  "headers": {
39
39
  "Authorization": "Bearer ${context.tenantId},${context.authToken}"
@@ -157,6 +157,15 @@
157
157
  "labelClassName": "text-left",
158
158
  "id": "u:07a8a4c5f875"
159
159
  },
160
+ {
161
+ "name": "showSidebar",
162
+ "label": "菜单显示在左侧",
163
+ "type": "checkbox",
164
+ "tpl": null,
165
+ "className": "m-0",
166
+ "labelClassName": "text-left",
167
+ "id": "u:07a8a4c5f877"
168
+ },
160
169
  {
161
170
  "name": "description",
162
171
  "label": "描述",
@@ -382,7 +391,7 @@
382
391
  {
383
392
  "name": "url",
384
393
  "label": "外部链接",
385
- "type": "input-url",
394
+ "type": "input-text",
386
395
  "className": "m-0",
387
396
  "labelClassName": "text-left",
388
397
  "id": "u:d7116a113670"
@@ -525,7 +534,21 @@
525
534
  "script": "const data = context.props.data;\nif (!data._id) { \n return;\n}\nif (data.tab_items) {\n return;\n}\n\nconst tabOptions = data.tabs_options || [];\nconst tabItems = [];\n// 把应用中原来tabs属性值添加到新的tab_items属性的默认值中\nif (data.tabs && data.tabs.length) {\n data.tabs.forEach(function (item) {\n tabItems.push({ tab_name: item });\n });\n}\nconst pushObjectsToTabItems = function (objects) {\n objects.forEach(function (item) {\n // 已经有绑定到指定对象的选项卡就不添加\n let existObjectItem = !!tabItems.find(function (tabItem) {\n return !!tabOptions.find(function (option) {\n return tabItem.tab_name === tabItem.value && option.object === item;\n });\n });\n if (existObjectItem) {\n return;\n }\n // 找到指向指定对象的选项卡\n let tempOption = tabOptions.find(function (option) {\n return option.type === \"object\" && option.object === item;\n });\n if (!tempOption) {\n return;\n }\n // 选项卡名称如果重复了就不添加\n let existTabItem = !!tabItems.find(function (tabItem) {\n return tabItem.tab_name === tempOption.value;\n });\n if (existTabItem) {\n return;\n }\n if (tempOption) {\n tabItems.push({ tab_name: tempOption.value });\n }\n });\n}\n// 把应用中原来objects属性值添加到新的tab_items属性的默认值中\nif (data.objects && data.objects.length) {\n pushObjectsToTabItems(data.objects);\n}\n// 把应用中原来mobile_objects属性值添加到新的tab_items属性的默认值中\nif (data.mobile_objects && data.mobile_objects.length) {\n pushObjectsToTabItems(data.mobile_objects);\n}\n\ndoAction({\n actionType: 'setValue',\n args: {\n \"value\": { tab_items: tabItems }\n }\n});"
526
535
  }
527
536
  ]
528
- }
537
+ },
538
+ "submitSucc": {
539
+ "weight": 0,
540
+ "actions": [
541
+ {
542
+ "actionType": "broadcast",
543
+ "args": {
544
+ "eventName": "@data.changed.apps"
545
+ },
546
+ "data": {
547
+ "objectName": "apps"
548
+ }
549
+ }
550
+ ]
551
+ }
529
552
  },
530
553
  "id": "apps-form"
531
554
  }
@@ -1,6 +1,4 @@
1
1
  name: apps_form
2
- __filename: >-
3
- /Users/yinlianghui/Documents/GitHub/steedos-platform2-3/services/service-plugin-amis/main/default/pages/apps_form.page.yml
4
2
  is_active: true
5
3
  label: 应用程序表单
6
4
  object_name: apps
@@ -20,7 +20,7 @@
20
20
  },
21
21
  "requestAdaptor": "const formData = api.data.$;\napi.data = { objects: formData.objects };\nreturn api;",
22
22
  "responseData": null,
23
- "adaptor": "\nif (api.body.objectName === \"tabs\") {\n // 在tabs列表操作”对象选项卡“按钮,保存后需要刷新主列表\n refreshGrid && refreshGrid();\n}\nreturn payload;\n ",
23
+ "adaptor": "\nif (api.body.objectName === \"tabs\") {\n // 在tabs列表操作”对象选项卡“按钮,保存后需要刷新主列表\n}\nreturn payload;\n ",
24
24
  "headers": {
25
25
  "Authorization": "Bearer ${context.tenantId},${context.authToken}"
26
26
  }
@@ -63,7 +63,7 @@
63
63
  "actions": [
64
64
  {
65
65
  "actionType": "custom",
66
- "script": "const result = event.data.result;\nconst doneCount = result.data && result.data.doneCount || 0;\nconst myMsg = '已成功生成' + doneCount.toString() + \"条选项卡!\";\ndoAction({\n actionType: 'toast',\n args: {\n msg: myMsg,\n msgType: \"success\"\n }\n});\nconst errors = result.data && result.data.errors || [];\nif (errors && errors.length) { \n console.warn(\"以下对象未能生成选项卡:\");\n console.warn(JSON.stringify(errors));\n}\nconst superData = event.data.__super;\nif (superData && superData.objectName === \"apps\") { \n // 在应用表单中生成选项卡后需要触发选项卡列表组件reload重新刷新列表\n doAction({\n actionType: 'reload',\n componentId: \"tabs-options-service\"\n });\n}"
66
+ "script": "const result = event.data.result;\nconst doneCount = result.data && result.data.doneCount || 0;\nconst myMsg = '已成功生成' + doneCount.toString() + \"条选项卡!\";\ndoAction({\n actionType: 'toast',\n args: {\n msg: myMsg,\n msgType: \"success\"\n }\n});\nconst errors = result.data && result.data.errors || [];\nif (errors && errors.length) { \n console.warn(\"以下对象未能生成选项卡:\");\n console.warn(JSON.stringify(errors));\n}\nconst objectName = event.data.objectName;\nif (objectName === \"apps\") {\n // 在应用表单中生成选项卡后需要触发选项卡列表组件reload重新刷新列表\n doAction({\n actionType: 'reload',\n componentId: \"tabs-options-service\"\n });\n}\nelse {\n // 刷新主列表\n doAction({\n actionType: 'reload',\n componentId: `listview_${objectName}`\n });\n}"
67
67
  }
68
68
  ]
69
69
  }
@@ -75,6 +75,7 @@
75
75
  ],
76
76
  "data": {
77
77
  "context": {
78
+ "rootUrl": "http://127.0.0.1:5800"
78
79
  }
79
80
  },
80
81
  "id": "u:3b0de7e88def",