@steedos/service-metadata-apps 3.0.0-beta.58 → 3.0.0-beta.59

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,81 +1,109 @@
1
1
  import { getServiceAppConfig, METADATA_TYPE, refreshApp } from ".";
2
2
  import _ = require("lodash");
3
- import { translationApp, translationObjectLabel, translationTabLabel } from '@steedos/i18n';
4
- import { getAssignedApps, getObject as _getObject, absoluteUrl } from "@steedos/objectql";
5
- import { getNotLicensedTabNames } from "./getNotLicensedTabNames"
3
+ import {
4
+ translationApp,
5
+ translationObjectLabel,
6
+ translationTabLabel,
7
+ } from "@steedos/i18n";
8
+ import {
9
+ getAssignedApps,
10
+ getObject as _getObject,
11
+ absoluteUrl,
12
+ } from "@steedos/objectql";
13
+ import { getNotLicensedTabNames } from "./getNotLicensedTabNames";
6
14
 
7
15
  function cacherKey(appApiName: string): string {
8
- return `$steedos.#${METADATA_TYPE}.${appApiName}`
16
+ return `$steedos.#${METADATA_TYPE}.${appApiName}`;
9
17
  }
10
18
 
11
19
  async function registerApp(ctx, appApiName, data, meta) {
12
- return await ctx.broker.call('metadata.add', { key: cacherKey(appApiName), data: data }, { meta: meta });
20
+ return await ctx.broker.call(
21
+ "metadata.add",
22
+ { key: cacherKey(appApiName), data: data },
23
+ { meta: meta },
24
+ );
13
25
  }
14
26
 
15
27
  async function getSpaceApp(ctx: any, appApiName: string) {
16
- const allApps = await getAllApps(ctx);
17
- const userSession = ctx.meta.user;
18
- const spaceId = userSession.spaceId;
19
- const userApps = _.filter(allApps, function (metadataConfig) {
28
+ const allApps = await getAllApps(ctx);
29
+ const userSession = ctx.meta.user;
30
+ const spaceId = userSession.spaceId;
31
+ const userApps = _.filter(allApps, function (metadataConfig) {
32
+ const config = metadataConfig.metadata;
33
+ //只判断是否启用
34
+ if (!config.visible) {
35
+ return false;
36
+ }
37
+ if (_.has(config, "space") && config.space) {
38
+ return config.space === spaceId;
39
+ }
40
+ if (
41
+ !_.isEmpty(config.tabs) ||
42
+ !_.isEmpty(config.objects) ||
43
+ !_.isEmpty(config.mobile_objects)
44
+ ) {
45
+ return true;
46
+ }
47
+ return true;
48
+ });
49
+
50
+ return _.find(userApps, function (metadataConfig) {
51
+ const config = metadataConfig.metadata;
52
+ return config.space && config.code === appApiName;
53
+ });
54
+ }
55
+
56
+ async function get(ctx: any) {
57
+ const spaceAppMetadataConfig = await getSpaceApp(ctx, ctx.params.appApiName);
58
+ if (spaceAppMetadataConfig) {
59
+ return spaceAppMetadataConfig;
60
+ } else {
61
+ const metadataConfig = await ctx.broker.call(
62
+ "metadata.get",
63
+ { key: cacherKey(ctx.params.appApiName) },
64
+ { meta: ctx.meta },
65
+ );
66
+ if (metadataConfig) {
67
+ return metadataConfig;
68
+ } else {
69
+ const allApps = await getAllApps(ctx);
70
+ const userSession = ctx.meta.user;
71
+ const spaceId = userSession.spaceId;
72
+ const userApps = _.filter(allApps, function (metadataConfig) {
20
73
  const config = metadataConfig.metadata;
21
74
  //只判断是否启用
22
75
  if (!config.visible) {
23
- return false;
76
+ return false;
24
77
  }
25
- if (_.has(config, 'space') && config.space) {
26
- return config.space === spaceId;
78
+ if (_.has(config, "space") && config.space) {
79
+ return config.space === spaceId;
27
80
  }
28
- if (!_.isEmpty(config.tabs) || !_.isEmpty(config.objects) || !_.isEmpty(config.mobile_objects)) {
29
- return true;
81
+ if (
82
+ !_.isEmpty(config.tabs) ||
83
+ !_.isEmpty(config.objects) ||
84
+ !_.isEmpty(config.mobile_objects)
85
+ ) {
86
+ return true;
30
87
  }
31
88
  return true;
32
- });
33
-
34
- return _.find(userApps, function (metadataConfig) {
35
- const config = metadataConfig.metadata;
36
- return config.space && config.code === appApiName
37
- })
38
- }
39
-
40
- async function get(ctx: any) {
41
- const spaceAppMetadataConfig = await getSpaceApp(ctx, ctx.params.appApiName)
42
- if (spaceAppMetadataConfig) {
43
- return spaceAppMetadataConfig;
44
- } else {
45
- const metadataConfig = await ctx.broker.call('metadata.get', { key: cacherKey(ctx.params.appApiName) }, { meta: ctx.meta });
46
- if (metadataConfig) {
47
- return metadataConfig;
48
- } else {
49
- const allApps = await getAllApps(ctx);
50
- const userSession = ctx.meta.user;
51
- const spaceId = userSession.spaceId;
52
- const userApps = _.filter(allApps, function (metadataConfig) {
53
- const config = metadataConfig.metadata;
54
- //只判断是否启用
55
- if (!config.visible) {
56
- return false;
57
- }
58
- if (_.has(config, 'space') && config.space) {
59
- return config.space === spaceId;
60
- }
61
- if (!_.isEmpty(config.tabs) || !_.isEmpty(config.objects) || !_.isEmpty(config.mobile_objects)) {
62
- return true;
63
- }
64
- return true;
65
- })
66
- if (ctx.params.appApiName === '-') {
67
- return _.first(_.sortBy(userApps, ['metadata.sort']));
68
- }
69
- return _.find(userApps, function (metadataConfig) {
70
- const app = metadataConfig.metadata;
71
- return app.code === ctx.params.appApiName
72
- })
73
- }
89
+ });
90
+ if (ctx.params.appApiName === "-") {
91
+ return _.first(_.sortBy(userApps, ["metadata.sort"]));
92
+ }
93
+ return _.find(userApps, function (metadataConfig) {
94
+ const app = metadataConfig.metadata;
95
+ return app.code === ctx.params.appApiName;
96
+ });
74
97
  }
98
+ }
75
99
  }
76
100
 
77
101
  async function getAllApps(ctx: any) {
78
- return await ctx.broker.call('metadata.filter', { key: cacherKey("*") }, { meta: ctx.meta })
102
+ return await ctx.broker.call(
103
+ "metadata.filter",
104
+ { key: cacherKey("*") },
105
+ { meta: ctx.meta },
106
+ );
79
107
  }
80
108
 
81
109
  // async function getObject(ctx: any, objectApiName: string){
@@ -83,32 +111,32 @@ async function getAllApps(ctx: any) {
83
111
  // }
84
112
 
85
113
  async function getAllTabs(ctx: any) {
86
- return await ctx.broker.call('tabs.getAll');
114
+ return await ctx.broker.call("tabs.getAll");
87
115
  }
88
116
 
89
117
  async function getContext(ctx: any) {
90
- const userSession = ctx.meta.user;
91
- const allTabs = await getAllTabs(ctx);
92
- if(userSession.is_space_admin){
93
- return {
94
- tabs: allTabs,
95
- hiddenTabNames: []
96
- }
97
- }
98
- // const allObject = await getSteedosSchema().getAllObject()
99
- let hiddenTabNames = await getHiddenTabNames(ctx, allTabs)
100
- const notLicensedTabNames = await getNotLicensedTabNames(ctx, allTabs)
101
- hiddenTabNames = hiddenTabNames.concat(notLicensedTabNames)
118
+ const userSession = ctx.meta.user;
119
+ const allTabs = await getAllTabs(ctx);
120
+ if (userSession.is_space_admin) {
102
121
  return {
103
- tabs: allTabs,
104
- // objects: allObject,
105
- hiddenTabNames: hiddenTabNames
106
- }
122
+ tabs: allTabs,
123
+ hiddenTabNames: [],
124
+ };
125
+ }
126
+ // const allObject = await getSteedosSchema().getAllObject()
127
+ let hiddenTabNames = await getHiddenTabNames(ctx, allTabs);
128
+ const notLicensedTabNames = await getNotLicensedTabNames(ctx, allTabs);
129
+ hiddenTabNames = hiddenTabNames.concat(notLicensedTabNames);
130
+ return {
131
+ tabs: allTabs,
132
+ // objects: allObject,
133
+ hiddenTabNames: hiddenTabNames,
134
+ };
107
135
  }
108
136
 
109
137
  async function getTab(ctx: any, tabApiName: string) {
110
- const metadataConfig = await ctx.broker.call('tabs.get', { tabApiName });
111
- return metadataConfig?.metadata;
138
+ const metadataConfig = await ctx.broker.call("tabs.get", { tabApiName });
139
+ return metadataConfig?.metadata;
112
140
  }
113
141
 
114
142
  // async function getChildren(ctx: any, tabApiName: string){
@@ -116,470 +144,600 @@ async function getTab(ctx: any, tabApiName: string) {
116
144
  // }
117
145
 
118
146
  function getTabChildren(context: any, tabApiName: string) {
119
- if (context) {
120
- const { tabs } = context;
121
- return _.filter(tabs, function (tab) {
122
- return tab?.metadata.parent === tabApiName
123
- })
124
- }
147
+ if (context) {
148
+ const { tabs } = context;
149
+ return _.filter(tabs, function (tab) {
150
+ return tab?.metadata.parent === tabApiName;
151
+ });
152
+ }
125
153
  }
126
154
 
127
155
  /**
128
156
  * 判断tab是否符合mobile配置
129
- * @param tab
157
+ * @param tab
130
158
  * @param mobile 是否是在移动设备上显示tab
131
- * @returns
159
+ * @returns
132
160
  */
133
161
  function checkTabMobile(tab, mobile) {
134
- let isChecked = false;
135
- if (mobile === true || mobile === "true") {
136
- isChecked = tab.mobile !== false;
137
- }
138
- else {
139
- isChecked = tab.desktop !== false;
140
- }
141
- return isChecked;
162
+ let isChecked = false;
163
+ if (mobile === true || mobile === "true") {
164
+ isChecked = tab.mobile !== false;
165
+ } else {
166
+ isChecked = tab.desktop !== false;
167
+ }
168
+ return isChecked;
142
169
  }
143
170
  function checkAppMobile(app, mobile) {
144
- let isChecked = false;
145
- // 手机端访问
146
- if (mobile === true || mobile === "true") {
147
- isChecked = app.mobile === true;
148
- }
149
- else {
150
- // 桌面端访问
151
- isChecked = app.is_creator === true
152
- }
153
- return isChecked;
171
+ let isChecked = false;
172
+ // 手机端访问
173
+ if (mobile === true || mobile === "true") {
174
+ isChecked = app.mobile === true;
175
+ } else {
176
+ // 桌面端访问
177
+ isChecked = app.is_creator === true;
178
+ }
179
+ return isChecked;
154
180
  }
155
181
 
156
182
  /**
157
183
  * 根据选项卡权限的配置决定选项卡是否可见,默认可见,关闭的和隐藏的选项卡不可见
158
- * @param ctx
184
+ * @param ctx
159
185
  * @return ['tabName', ...]
160
186
  */
161
187
  async function getHiddenTabNames(ctx, allTabs) {
162
- const userSession = ctx.meta.user
163
- if (!userSession) {
164
- throw new Error('no permission.')
165
- }
166
- const hiddenTabNames = []
167
- const permissionTabs = await getPermissionTabs(ctx, userSession)
168
- const showTabNames = [] // 同一个选项卡在不同权限集中的权限叠加,如有一个是默认打开的则选项卡默认打开
169
- for (const permissionTab of permissionTabs) {
170
- if (permissionTab.permission === 'on') {
171
- showTabNames.push(permissionTab.tab)
172
- }
188
+ const userSession = ctx.meta.user;
189
+ if (!userSession) {
190
+ throw new Error("no permission.");
191
+ }
192
+ const hiddenTabNames = [];
193
+ const permissionTabs = await getPermissionTabs(ctx, userSession);
194
+ const showTabNames = []; // 同一个选项卡在不同权限集中的权限叠加,如有一个是默认打开的则选项卡默认打开
195
+ for (const permissionTab of permissionTabs) {
196
+ if (permissionTab.permission === "on") {
197
+ showTabNames.push(permissionTab.tab);
173
198
  }
174
- for (const permissionTab of permissionTabs) {
175
- if ((permissionTab.permission === 'off' || permissionTab.permission === 'hidden') && !showTabNames.includes(permissionTab.tab)) {
176
- hiddenTabNames.push(permissionTab.tab)
177
- }
199
+ }
200
+ for (const permissionTab of permissionTabs) {
201
+ if (
202
+ (permissionTab.permission === "off" ||
203
+ permissionTab.permission === "hidden") &&
204
+ !showTabNames.includes(permissionTab.tab)
205
+ ) {
206
+ hiddenTabNames.push(permissionTab.tab);
178
207
  }
208
+ }
179
209
 
180
- // .tab.yml中配置了hidden:true
181
- for (const config of allTabs) {
182
- if (config.metadata && config.metadata.hidden) {
183
- hiddenTabNames.push(config.metadata.name)
184
- }
210
+ // .tab.yml中配置了hidden:true
211
+ for (const config of allTabs) {
212
+ if (config.metadata && config.metadata.hidden) {
213
+ hiddenTabNames.push(config.metadata.name);
185
214
  }
215
+ }
186
216
 
187
- return hiddenTabNames
217
+ return hiddenTabNames;
188
218
  }
189
219
 
190
- async function getPermissionTabs(ctx, userSession): Promise<any[]>{
191
- const { roles, spaceId } = userSession
192
- const permissionTabs = []
193
- for (const role of roles) {
194
- const pattern = `${role}_*`
195
- const filterResult = await ctx.broker.call('permission_tabs.filter', {
196
- pattern: pattern,
197
- }, {
198
- user: { spaceId: spaceId }
199
- });
200
- for (const ptConfig of filterResult) {
201
- if (ptConfig.metadata.permission_set === role && (!_.has(ptConfig.metadata, 'space') || ptConfig.metadata.space === spaceId)) {
202
- permissionTabs.push(ptConfig.metadata)
203
- }
204
- }
220
+ async function getPermissionTabs(ctx, userSession): Promise<any[]> {
221
+ const { roles, spaceId } = userSession;
222
+ const permissionTabs = [];
223
+ for (const role of roles) {
224
+ const pattern = `${role}_*`;
225
+ const filterResult = await ctx.broker.call(
226
+ "permission_tabs.filter",
227
+ {
228
+ pattern: pattern,
229
+ },
230
+ {
231
+ user: { spaceId: spaceId },
232
+ },
233
+ );
234
+ for (const ptConfig of filterResult) {
235
+ if (
236
+ ptConfig.metadata.permission_set === role &&
237
+ (!_.has(ptConfig.metadata, "space") ||
238
+ ptConfig.metadata.space === spaceId)
239
+ ) {
240
+ permissionTabs.push(ptConfig.metadata);
241
+ }
205
242
  }
206
- return permissionTabs
243
+ }
244
+ return permissionTabs;
207
245
  }
208
246
 
247
+ async function tabMenus(
248
+ ctx: any,
249
+ appPath,
250
+ tabApiName,
251
+ menu,
252
+ mobile,
253
+ userSession,
254
+ context,
255
+ props: any = {},
256
+ ) {
257
+ try {
258
+ // const objectsConfigs = context.objects;
259
+ const tab = await getTab(ctx, tabApiName);
260
+ if (props.group) {
261
+ props.group =
262
+ _.find(menu.tab_groups, { id: props.group })?.group_name || props.group;
263
+ }
209
264
 
210
- async function tabMenus(ctx: any, appPath, tabApiName, menu, mobile, userSession, context, props:any = {}) {
211
- try {
212
- // const objectsConfigs = context.objects;
213
- const tab = await getTab(ctx, tabApiName);
214
- if(props.group){
215
- props.group = _.find(menu.tab_groups, { id: props.group })?.group_name || props.group;
216
- }
265
+ if (tabApiName) {
266
+ props.tabApiName = tabApiName;
267
+ }
217
268
 
218
- if(tabApiName){
219
- props.tabApiName = tabApiName;
269
+ if (tab) {
270
+ const isMobileChecked = checkTabMobile(tab, mobile);
271
+ if (!isMobileChecked) {
272
+ return;
273
+ }
274
+ const tabChildren = getTabChildren(context, tabApiName);
275
+
276
+ if (tabChildren && tabChildren.length > 0) {
277
+ const tabMenu = {
278
+ id: tab.name,
279
+ icon: tab.icon,
280
+ name: `${tab.label}`,
281
+ children: [],
282
+ ...props,
283
+ };
284
+ for (const { metadata: tabChild } of tabChildren) {
285
+ if (tabChild && tabChild.apiName) {
286
+ await tabMenus(
287
+ ctx,
288
+ appPath,
289
+ tabChild.apiName,
290
+ tabMenu,
291
+ mobile,
292
+ userSession,
293
+ context,
294
+ );
295
+ }
220
296
  }
221
-
222
- if (tab) {
223
- const isMobileChecked = checkTabMobile(tab, mobile)
224
- if (!isMobileChecked) {
225
- return;
226
- }
227
- const tabChildren = getTabChildren(context, tabApiName);
228
-
229
- if (tabChildren && tabChildren.length > 0) {
230
- const tabMenu = {
231
- id: tab.name,
232
- icon: tab.icon,
233
- name: `${tab.label}`,
234
- children: [],
235
- ...props
236
- };
237
- for (const { metadata: tabChild } of tabChildren) {
238
- if (tabChild && tabChild.apiName) {
239
- await tabMenus(ctx, appPath, tabChild.apiName, tabMenu, mobile, userSession, context);
240
- }
241
- }
242
- menu.children.push(tabMenu);
243
- } else {
244
- if (tab.type === 'object') {
245
- const allowRead = await objectAllowRead(tab.object, userSession);
246
- if (!allowRead) {
247
- return;
248
- }
249
- // const objectMetadata = await getObject(ctx, tab.object);
250
- // const objectMetadata = _.find(objectsConfigs, (config) => {
251
- // return config && config.metadata.name === tab.object
252
- // });
253
- const objectConfig = await _getObject(tab.object).getConfig()
254
- if (objectConfig) {
255
- // const objectConfig = objectMetadata.metadata;
256
- const objectLabel = translationObjectLabel(userSession.language, objectConfig.name, objectConfig.label || objectConfig.name)
257
- menu.children.push(
258
- {
259
- id: objectConfig.name,
260
- type: tab.type,
261
- icon: objectConfig.icon,
262
- path: `${appPath}/${objectConfig.name}`,
263
- name: `${objectLabel}`,
264
- ...props
265
- }
266
- )
267
- }
268
- }
269
- if (tab.type === 'url') {
270
- tab.label = translationTabLabel(userSession.language, tab.name, tab.label || tab.name);
271
- let urlMenu: any = {
272
- id: `${tab.name}`,
273
- type: tab.type,
274
- icon: tab.icon,
275
- path: `${tab.url}`,
276
- name: `${tab.label}`,
277
- ...props
278
- };
279
- if (tab.is_new_window) {
280
- urlMenu.target = '_blank'
281
- }else if(tab.is_use_iframe){
282
- urlMenu.is_use_iframe = true;
283
- urlMenu.path = `${appPath}/tab_iframe/${tab.name}/?url=${tab.url}`
284
- }
285
- menu.children.push(
286
- urlMenu
287
- )
288
- }
289
- if (tab.type === 'page') {
290
- tab.label = translationTabLabel(userSession.language, tab.name, tab.label || tab.name);
291
- menu.children.push(
292
- {
293
- id: `${tab.name}`,
294
- icon: tab.icon,
295
- type: tab.type,
296
- page: tab.page,
297
- path: `${appPath}/${tab.type}/${tab.page}`,
298
- name: `${tab.label}`,
299
- ...props
300
- }
301
- )
302
- }
303
- }
297
+ menu.children.push(tabMenu);
298
+ } else {
299
+ if (tab.type === "object") {
300
+ const allowRead = await objectAllowRead(tab.object, userSession);
301
+ if (!allowRead) {
302
+ return;
303
+ }
304
+ // const objectMetadata = await getObject(ctx, tab.object);
305
+ // const objectMetadata = _.find(objectsConfigs, (config) => {
306
+ // return config && config.metadata.name === tab.object
307
+ // });
308
+ const objectConfig = await _getObject(tab.object).getConfig();
309
+ if (objectConfig) {
310
+ // const objectConfig = objectMetadata.metadata;
311
+ const objectLabel = translationObjectLabel(
312
+ userSession.language,
313
+ objectConfig.name,
314
+ objectConfig.label || objectConfig.name,
315
+ );
316
+ menu.children.push({
317
+ id: objectConfig.name,
318
+ type: tab.type,
319
+ icon: objectConfig.icon,
320
+ path: `${appPath}/${objectConfig.name}`,
321
+ name: `${objectLabel}`,
322
+ ...props,
323
+ });
324
+ }
304
325
  }
305
- } catch (error) {
306
- ctx.broker.logger.info(error.message);
326
+ if (tab.type === "url") {
327
+ tab.label = translationTabLabel(
328
+ userSession.language,
329
+ tab.name,
330
+ tab.label || tab.name,
331
+ );
332
+ let urlMenu: any = {
333
+ id: `${tab.name}`,
334
+ type: tab.type,
335
+ icon: tab.icon,
336
+ path: `${encodeURIComponent(tab.url)}`,
337
+ name: `${tab.label}`,
338
+ ...props,
339
+ };
340
+ if (tab.is_new_window) {
341
+ urlMenu.target = "_blank";
342
+ } else if (tab.is_use_iframe) {
343
+ urlMenu.is_use_iframe = true;
344
+ urlMenu.path = `${appPath}/tab_iframe/${tab.name}/?url=${encodeURIComponent(tab.url)}`;
345
+ }
346
+ menu.children.push(urlMenu);
347
+ }
348
+ if (tab.type === "page") {
349
+ tab.label = translationTabLabel(
350
+ userSession.language,
351
+ tab.name,
352
+ tab.label || tab.name,
353
+ );
354
+ menu.children.push({
355
+ id: `${tab.name}`,
356
+ icon: tab.icon,
357
+ type: tab.type,
358
+ page: tab.page,
359
+ path: `${appPath}/${tab.type}/${tab.page}`,
360
+ name: `${tab.label}`,
361
+ ...props,
362
+ });
363
+ }
364
+ }
307
365
  }
366
+ } catch (error) {
367
+ ctx.broker.logger.info(error.message);
368
+ }
308
369
  }
309
370
  async function objectAllowRead(objectApiName: string, userSession) {
310
- return await _getObject(objectApiName).allowRead(userSession);
371
+ return await _getObject(objectApiName).allowRead(userSession);
311
372
  }
312
373
 
313
374
  async function transformAppToMenus(ctx, app, mobile, userSession, context) {
314
- if (!app.code && !app._id) {
315
- return;
316
- }
317
-
318
- const isAppShow = checkAppMobile(app, mobile);
319
- if (!isAppShow) {
320
- return;
321
- }
322
-
323
- if (!app.code) {
324
- app.code = app._id;
375
+ if (!app.code && !app._id) {
376
+ return;
377
+ }
378
+
379
+ const isAppShow = checkAppMobile(app, mobile);
380
+ if (!isAppShow) {
381
+ return;
382
+ }
383
+
384
+ if (!app.code) {
385
+ app.code = app._id;
386
+ }
387
+ translationApp(userSession.language, app.code, app);
388
+ var appPath = `/app/${app.code}`;
389
+ if (app.url) {
390
+ if (/^http(s?):\/\//.test(app.url)) {
391
+ if (app.secret) {
392
+ appPath = absoluteUrl("/api/external/app/" + (app._id || app.code));
393
+ } else {
394
+ appPath = app.url;
395
+ }
396
+ } else {
397
+ appPath = app.url;
325
398
  }
326
- translationApp(userSession.language, app.code, app);
327
- var appPath = `/app/${app.code}`
328
- if(app.url){
329
- if(/^http(s?):\/\//.test(app.url)){
330
- if(app.secret){
331
- appPath = absoluteUrl("/api/external/app/" + (app._id || app.code))
332
- }else{
333
- appPath = app.url
334
- }
335
- }else{
336
- appPath = app.url
399
+ }
400
+ const menu: any = {
401
+ id: app.code,
402
+ path: appPath,
403
+ name: `${app.label || app.name}`,
404
+ icon: app.icon_slds,
405
+ showSidebar: app.showSidebar,
406
+ description: app.description,
407
+ children: [],
408
+ blank: app.is_new_window,
409
+ on_click: app.on_click,
410
+ isExternalUrl: !!app.url,
411
+ tab_groups: app.tab_groups,
412
+ is_hide_mobile_menu: app.is_hide_mobile_menu,
413
+ visible_on: app.visible_on || "${true}",
414
+ };
415
+ if (app.enable_nav_schema && app.nav_schema && !mobile) {
416
+ menu.nav_schema = _.isString(app.nav_schema)
417
+ ? JSON.parse(app.nav_schema)
418
+ : app.nav_schema;
419
+ }
420
+
421
+ const hiddenTabNames = context.hiddenTabNames || [];
422
+ if (app.tab_items) {
423
+ // app.tab_items is array
424
+ if (_.isArray(app.tab_items)) {
425
+ for (const item of app.tab_items) {
426
+ try {
427
+ if (hiddenTabNames.includes(item.tab_name)) continue;
428
+ await tabMenus(
429
+ ctx,
430
+ appPath,
431
+ item.tab_name,
432
+ menu,
433
+ mobile,
434
+ userSession,
435
+ context,
436
+ item,
437
+ );
438
+ } catch (error) {
439
+ ctx.broker.logger.info(error.message);
440
+ }
441
+ }
442
+ } else {
443
+ for (const tabApiName in app.tab_items) {
444
+ try {
445
+ if (hiddenTabNames.includes(tabApiName)) continue;
446
+ const props = app.tab_items[tabApiName];
447
+ await tabMenus(
448
+ ctx,
449
+ appPath,
450
+ tabApiName,
451
+ menu,
452
+ mobile,
453
+ userSession,
454
+ context,
455
+ props,
456
+ );
457
+ } catch (error) {
458
+ ctx.broker.logger.info(error.message);
337
459
  }
460
+ }
338
461
  }
339
- const menu: any = {
340
- id: app.code,
341
- path: appPath,
342
- name: `${app.label || app.name}`,
343
- icon: app.icon_slds,
344
- showSidebar: app.showSidebar,
345
- description: app.description,
346
- children: [],
347
- blank: app.is_new_window,
348
- on_click: app.on_click,
349
- isExternalUrl: !!app.url,
350
- tab_groups: app.tab_groups,
351
- is_hide_mobile_menu: app.is_hide_mobile_menu,
352
- visible_on: app.visible_on || "${true}"
462
+ } else if (_.isArray(app.tabs)) {
463
+ for (const tabApiName of app.tabs) {
464
+ try {
465
+ if (hiddenTabNames.includes(tabApiName)) continue;
466
+ await tabMenus(
467
+ ctx,
468
+ appPath,
469
+ tabApiName,
470
+ menu,
471
+ mobile,
472
+ userSession,
473
+ context,
474
+ );
475
+ } catch (error) {
476
+ ctx.broker.logger.info(error.message);
477
+ }
353
478
  }
354
- if(app.enable_nav_schema && app.nav_schema && !mobile){
355
- menu.nav_schema = _.isString(app.nav_schema) ? JSON.parse(app.nav_schema) : app.nav_schema
479
+ }
480
+ const objects = mobile ? app.mobile_objects : app.objects;
481
+ // const objectsConfigs = context.objects;
482
+ if (_.isArray(objects)) {
483
+ const getChildrenPromises = [];
484
+ for (const objectApiName of objects) {
485
+ getChildrenPromises.push(
486
+ getMenuChildren({
487
+ objectApiName,
488
+ userSession,
489
+ ctx,
490
+ appPath,
491
+ app,
492
+ }),
493
+ );
356
494
  }
357
-
358
- const hiddenTabNames = context.hiddenTabNames || []
359
- if (app.tab_items) {
360
- // app.tab_items is array
361
- if (_.isArray(app.tab_items)) {
362
- for (const item of app.tab_items) {
363
- try {
364
- if (hiddenTabNames.includes(item.tab_name)) continue;
365
- await tabMenus(ctx, appPath, item.tab_name, menu, mobile, userSession, context, item)
366
- } catch (error) {
367
- ctx.broker.logger.info(error.message);
368
- }
369
- }
370
- } else {
371
- for (const tabApiName in app.tab_items) {
372
- try {
373
- if (hiddenTabNames.includes(tabApiName)) continue;
374
- const props = app.tab_items[tabApiName]
375
- await tabMenus(ctx, appPath, tabApiName, menu, mobile, userSession, context, props)
376
- } catch (error) {
377
- ctx.broker.logger.info(error.message);
378
- }
379
- }
380
- }
381
- } else if (_.isArray(app.tabs)) {
382
- for (const tabApiName of app.tabs) {
383
- try {
384
- if (hiddenTabNames.includes(tabApiName)) continue;
385
- await tabMenus(ctx, appPath, tabApiName, menu, mobile, userSession, context)
386
- } catch (error) {
387
- ctx.broker.logger.info(error.message);
388
- }
389
- }
495
+ const children = await Promise.all(getChildrenPromises);
496
+ for (const child of children) {
497
+ if (child) {
498
+ menu.children.push(child);
499
+ }
390
500
  }
391
- const objects = mobile ? app.mobile_objects : app.objects
392
- // const objectsConfigs = context.objects;
393
- if (_.isArray(objects)) {
394
- const getChildrenPromises = []
395
- for (const objectApiName of objects) {
396
- getChildrenPromises.push(getMenuChildren({
397
- objectApiName, userSession, ctx, appPath, app
398
- }))
399
- }
400
- const children = await Promise.all(getChildrenPromises)
401
- for (const child of children) {
402
- if (child) {
403
- menu.children.push(child)
404
- }
405
- }
406
- }
407
-
408
- return menu;
501
+ }
502
+
503
+ return menu;
409
504
  }
410
505
 
411
- async function getMenuChildren({ objectApiName, userSession, ctx, appPath, app }) {
412
- try {
413
- const objectConfig = await _getObject(objectApiName).getConfig()
414
- if (!objectConfig) {
415
- ctx.broker.logger.error(`${objectApiName} is not found in the objects of app ${app.code} `)
416
- return
417
- }
418
- const allowRead = await objectAllowRead(objectApiName, userSession);
419
- if (!allowRead) {
420
- return
421
- }
422
- if (objectConfig) {
423
- // const objectConfig = objectMetadata.metadata;
424
- const objectLabel = translationObjectLabel(userSession.language, objectConfig.name, objectConfig.label || objectConfig.name)
425
- return {
426
- id: objectConfig.name,
427
- icon: objectConfig.icon,
428
- path: `${appPath}/${objectConfig.name}`,
429
- name: `${objectLabel}`
430
- }
431
- }
432
- } catch (error) {
433
- ctx.broker.logger.error(error);
506
+ async function getMenuChildren({
507
+ objectApiName,
508
+ userSession,
509
+ ctx,
510
+ appPath,
511
+ app,
512
+ }) {
513
+ try {
514
+ const objectConfig = await _getObject(objectApiName).getConfig();
515
+ if (!objectConfig) {
516
+ ctx.broker.logger.error(
517
+ `${objectApiName} is not found in the objects of app ${app.code} `,
518
+ );
519
+ return;
434
520
  }
521
+ const allowRead = await objectAllowRead(objectApiName, userSession);
522
+ if (!allowRead) {
523
+ return;
524
+ }
525
+ if (objectConfig) {
526
+ // const objectConfig = objectMetadata.metadata;
527
+ const objectLabel = translationObjectLabel(
528
+ userSession.language,
529
+ objectConfig.name,
530
+ objectConfig.label || objectConfig.name,
531
+ );
532
+ return {
533
+ id: objectConfig.name,
534
+ icon: objectConfig.icon,
535
+ path: `${appPath}/${objectConfig.name}`,
536
+ name: `${objectLabel}`,
537
+ };
538
+ }
539
+ } catch (error) {
540
+ ctx.broker.logger.error(error);
541
+ }
435
542
  }
436
543
 
437
544
  async function getAppsMenus(ctx) {
438
- const userSession = ctx.meta.user;
439
- if (!userSession) {
440
- throw new Error('no permission.')
441
- }
442
- let assigned_apps = await getAssignedApps(userSession);
443
- let mobile = ctx.params.mobile;
444
- if (typeof mobile !== 'boolean') {
445
- mobile = mobile === "true" ? true : false;
446
- }
447
- const spaceId = userSession.spaceId;
448
- const metadataApps = await getAllApps(ctx);
449
- const context = await getContext(ctx)
450
- const allApps = _.map(metadataApps, 'metadata');
451
- if (assigned_apps && assigned_apps.length) {
452
- assigned_apps = _.filter(allApps, (item) => { return assigned_apps.includes(item.code) });
453
- } else {
454
- assigned_apps = allApps;
545
+ const userSession = ctx.meta.user;
546
+ if (!userSession) {
547
+ throw new Error("no permission.");
548
+ }
549
+ let assigned_apps = await getAssignedApps(userSession);
550
+ let mobile = ctx.params.mobile;
551
+ if (typeof mobile !== "boolean") {
552
+ mobile = mobile === "true" ? true : false;
553
+ }
554
+ const spaceId = userSession.spaceId;
555
+ const metadataApps = await getAllApps(ctx);
556
+ const context = await getContext(ctx);
557
+ const allApps = _.map(metadataApps, "metadata");
558
+ if (assigned_apps && assigned_apps.length) {
559
+ assigned_apps = _.filter(allApps, (item) => {
560
+ return assigned_apps.includes(item.code);
561
+ });
562
+ } else {
563
+ assigned_apps = allApps;
564
+ }
565
+ const _userApps = _.filter(assigned_apps, function (config) {
566
+ if (!config.visible) {
567
+ return false;
455
568
  }
456
- const _userApps = _.filter(assigned_apps, function (config) {
457
- if (!config.visible) {
458
- return false;
459
- }
460
569
 
461
- if (config._id === config.code) {
462
- let dbApp = _.find(assigned_apps, (item) => {
463
- return item.code === config.code && item._id != item.code && item.space === spaceId;
464
- });
465
- if (dbApp) {
466
- return dbApp.visible
467
- }
468
- }
570
+ if (config._id === config.code) {
571
+ let dbApp = _.find(assigned_apps, (item) => {
572
+ return (
573
+ item.code === config.code &&
574
+ item._id != item.code &&
575
+ item.space === spaceId
576
+ );
577
+ });
578
+ if (dbApp) {
579
+ return dbApp.visible;
580
+ }
581
+ }
469
582
 
470
- if (_.has(config, 'space') && config.space) {
471
- return config.space === spaceId;
472
- }
473
- return true;
474
- })
475
- const menus = [];
583
+ if (_.has(config, "space") && config.space) {
584
+ return config.space === spaceId;
585
+ }
586
+ return true;
587
+ });
588
+ const menus = [];
476
589
 
477
- let userApps = [];
478
- _.each(_.sortBy(_userApps, ['sort']), function (app) {
479
- if (!app.code) {
480
- app.code = app._id;
481
- }
482
- const _appIndex = _.findIndex(userApps, function (item) { return item.code === app.code });
483
- if (_appIndex < 0) {
484
- userApps.push(app)
485
- } else {
486
- const _app = userApps[_appIndex];
487
- if (!_app.space && app.space) {
488
- userApps[_appIndex] = app;
489
- }
490
- }
491
- })
492
- for (const app of _.sortBy(userApps, ['sort'])) {
493
- const menu = await transformAppToMenus(ctx, app, mobile, userSession, context);
494
- if (menu) {
495
- menus.push(menu);
496
- }
590
+ let userApps = [];
591
+ _.each(_.sortBy(_userApps, ["sort"]), function (app) {
592
+ if (!app.code) {
593
+ app.code = app._id;
497
594
  }
498
- // if (!mobile) {
499
- // const setupApp = {
500
- // code: 'admin',
501
- // name: '设置',
502
- // icon_slds: 'settings',
503
- // description: '管理员设置公司、人员、权限等。',
504
- // children: [],
505
- // mobile: true,
506
- // is_creator: true,
507
- // }
508
- // const menu = await transformAppToMenus(ctx, setupApp, mobile, userSession, context);
509
- // menus.push(menu);
510
- // }
511
- return menus;
595
+ const _appIndex = _.findIndex(userApps, function (item) {
596
+ return item.code === app.code;
597
+ });
598
+ if (_appIndex < 0) {
599
+ userApps.push(app);
600
+ } else {
601
+ const _app = userApps[_appIndex];
602
+ if (!_app.space && app.space) {
603
+ userApps[_appIndex] = app;
604
+ }
605
+ }
606
+ });
607
+ for (const app of _.sortBy(userApps, ["sort"])) {
608
+ const menu = await transformAppToMenus(
609
+ ctx,
610
+ app,
611
+ mobile,
612
+ userSession,
613
+ context,
614
+ );
615
+ if (menu) {
616
+ menus.push(menu);
617
+ }
618
+ }
619
+ // if (!mobile) {
620
+ // const setupApp = {
621
+ // code: 'admin',
622
+ // name: '设置',
623
+ // icon_slds: 'settings',
624
+ // description: '管理员设置公司、人员、权限等。',
625
+ // children: [],
626
+ // mobile: true,
627
+ // is_creator: true,
628
+ // }
629
+ // const menu = await transformAppToMenus(ctx, setupApp, mobile, userSession, context);
630
+ // menus.push(menu);
631
+ // }
632
+ return menus;
512
633
  }
513
634
 
514
635
  async function getAppMenus(ctx) {
515
- const userSession = ctx.meta.user;
516
- const { mobile } = ctx.params;
517
- if (!userSession) {
518
- throw new Error('no permission.')
636
+ const userSession = ctx.meta.user;
637
+ const { mobile } = ctx.params;
638
+ if (!userSession) {
639
+ throw new Error("no permission.");
640
+ }
641
+ const spaceId = userSession.spaceId;
642
+ const metadataConf = await get(ctx);
643
+ if (metadataConf) {
644
+ const appConfig = metadataConf.metadata;
645
+ if (
646
+ _.has(appConfig, "space") &&
647
+ appConfig.space &&
648
+ appConfig.space != spaceId
649
+ ) {
650
+ return;
519
651
  }
520
- const spaceId = userSession.spaceId;
521
- const metadataConf = await get(ctx);
522
- if (metadataConf) {
523
- const appConfig = metadataConf.metadata;
524
- if (_.has(appConfig, 'space') && appConfig.space && appConfig.space != spaceId) {
525
- return;
526
- }
527
- const context = await getContext(ctx)
528
- const appMenus = await transformAppToMenus(ctx, appConfig, mobile, userSession, context);
529
-
530
- if (userSession.is_space_admin && appConfig._id && appConfig.code && appConfig._id != appConfig.code) {
531
- appMenus.allowEditApp = true;
532
- }
533
-
534
- return appMenus;
652
+ const context = await getContext(ctx);
653
+ const appMenus = await transformAppToMenus(
654
+ ctx,
655
+ appConfig,
656
+ mobile,
657
+ userSession,
658
+ context,
659
+ );
660
+
661
+ if (
662
+ userSession.is_space_admin &&
663
+ appConfig._id &&
664
+ appConfig.code &&
665
+ appConfig._id != appConfig.code
666
+ ) {
667
+ appMenus.allowEditApp = true;
535
668
  }
536
669
 
670
+ return appMenus;
671
+ }
537
672
  }
538
673
 
539
674
  export const ActionHandlers = {
540
- async get(ctx: any): Promise<any> {
541
- return await ctx.broker.call('metadata.get', { key: cacherKey(ctx.params.appApiName) }, { meta: ctx.meta })
542
- },
543
- async getAll(ctx: any): Promise<any> {
544
- return await getAllApps(ctx);
545
- },
546
- async getMenus(ctx: any): Promise<any> {
547
- const menus = await getAppsMenus(ctx);
548
- return menus;
549
- },
550
- async getAppMenus(ctx: any): Promise<any> {
551
- return await getAppMenus(ctx);
552
- },
553
- async add(ctx: any): Promise<boolean> {
554
- let config = ctx.params.data;
555
- const serviceName = ctx.meta.metadataServiceName
556
- const metadataApiName = ctx.params.appApiName;
557
- const metadataConfig = await getServiceAppConfig(ctx, serviceName, metadataApiName)
558
- if (metadataConfig && metadataConfig.metadata) {
559
- config = _.defaultsDeep(config, metadataConfig.metadata);
560
- }
561
- await ctx.broker.call('metadata.addServiceMetadata', { key: cacherKey(metadataApiName), data: config }, { meta: Object.assign({}, ctx.meta, { metadataType: METADATA_TYPE, metadataApiName: metadataApiName }) })
675
+ async get(ctx: any): Promise<any> {
676
+ return await ctx.broker.call(
677
+ "metadata.get",
678
+ { key: cacherKey(ctx.params.appApiName) },
679
+ { meta: ctx.meta },
680
+ );
681
+ },
682
+ async getAll(ctx: any): Promise<any> {
683
+ return await getAllApps(ctx);
684
+ },
685
+ async getMenus(ctx: any): Promise<any> {
686
+ const menus = await getAppsMenus(ctx);
687
+ return menus;
688
+ },
689
+ async getAppMenus(ctx: any): Promise<any> {
690
+ return await getAppMenus(ctx);
691
+ },
692
+ async add(ctx: any): Promise<boolean> {
693
+ let config = ctx.params.data;
694
+ const serviceName = ctx.meta.metadataServiceName;
695
+ const metadataApiName = ctx.params.appApiName;
696
+ const metadataConfig = await getServiceAppConfig(
697
+ ctx,
698
+ serviceName,
699
+ metadataApiName,
700
+ );
701
+ if (metadataConfig && metadataConfig.metadata) {
702
+ config = _.defaultsDeep(config, metadataConfig.metadata);
703
+ }
704
+ await ctx.broker.call(
705
+ "metadata.addServiceMetadata",
706
+ { key: cacherKey(metadataApiName), data: config },
707
+ {
708
+ meta: Object.assign({}, ctx.meta, {
709
+ metadataType: METADATA_TYPE,
710
+ metadataApiName: metadataApiName,
711
+ }),
712
+ },
713
+ );
714
+ const appConfig = await refreshApp(ctx, metadataApiName);
715
+ return await registerApp(ctx, metadataApiName, appConfig, ctx.meta);
716
+ },
717
+ async delete(ctx: any): Promise<boolean> {
718
+ return await ctx.broker.call(
719
+ "metadata.delete",
720
+ { key: cacherKey(ctx.params.appApiName) },
721
+ { meta: ctx.meta },
722
+ );
723
+ },
724
+ async verify(ctx: any): Promise<boolean> {
725
+ console.log("verify");
726
+ return true;
727
+ },
728
+ async refresh(ctx) {
729
+ const { isClear, metadataApiNames } = ctx.params;
730
+ if (isClear) {
731
+ for (const metadataApiName of metadataApiNames) {
562
732
  const appConfig = await refreshApp(ctx, metadataApiName);
563
- return await registerApp(ctx, metadataApiName, appConfig, ctx.meta)
564
- },
565
- async delete(ctx: any): Promise<boolean> {
566
- return await ctx.broker.call('metadata.delete', { key: cacherKey(ctx.params.appApiName) }, { meta: ctx.meta })
567
- },
568
- async verify(ctx: any): Promise<boolean> {
569
- console.log("verify");
570
- return true;
571
- },
572
- async refresh(ctx) {
573
- const { isClear, metadataApiNames } = ctx.params
574
- if (isClear) {
575
- for (const metadataApiName of metadataApiNames) {
576
- const appConfig = await refreshApp(ctx, metadataApiName);
577
- if (!appConfig) {
578
- await ctx.broker.call('metadata.delete', { key: cacherKey(metadataApiName) })
579
- } else {
580
- await registerApp(ctx, metadataApiName, appConfig, {});
581
- }
582
- }
733
+ if (!appConfig) {
734
+ await ctx.broker.call("metadata.delete", {
735
+ key: cacherKey(metadataApiName),
736
+ });
737
+ } else {
738
+ await registerApp(ctx, metadataApiName, appConfig, {});
583
739
  }
740
+ }
584
741
  }
585
- }
742
+ },
743
+ };