@steedos/service-ui 2.2.41
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/LICENSE.txt +25 -0
- package/main/default/objects/.gitkeep +0 -0
- package/main/default/permissionsets/.gitkeep +0 -0
- package/main/default/profiles/.gitkeep +0 -0
- package/main/default/routes/apps.router.js +27 -0
- package/main/default/routes/bootstrap.router.js +457 -0
- package/main/default/routes/objects.router.js +114 -0
- package/main/default/routes/objects.router.todo.js +22 -0
- package/main/default/tabs/.gitkeep +0 -0
- package/main/default/triggers/.gitkeep +0 -0
- package/package.json +23 -0
- package/package.service.js +69 -0
- package/src/routes/apps.router.ts +23 -0
- package/src/routes/bootstrap.router.ts +466 -0
- package/src/routes/declare.d.ts +7 -0
- package/src/routes/objects.router.ts +99 -0
- package/tsconfig.json +37 -0
package/package.json
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@steedos/service-ui",
|
|
3
|
+
"version": "2.2.41",
|
|
4
|
+
"keywords": [
|
|
5
|
+
"steedos"
|
|
6
|
+
],
|
|
7
|
+
"scripts": {
|
|
8
|
+
"compile": "tsc",
|
|
9
|
+
"prepare": "tsc"
|
|
10
|
+
},
|
|
11
|
+
"description": "steedos package",
|
|
12
|
+
"repository": {},
|
|
13
|
+
"dependencies": {
|
|
14
|
+
"@steedos/core": "2.2.41",
|
|
15
|
+
"@steedos/objectql": "2.2.41"
|
|
16
|
+
},
|
|
17
|
+
"license": "MIT",
|
|
18
|
+
"private": false,
|
|
19
|
+
"publishConfig": {
|
|
20
|
+
"access": "public"
|
|
21
|
+
},
|
|
22
|
+
"gitHead": "ded6a9013bea822bc4cf81c98e60a3d829bed858"
|
|
23
|
+
}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
const project = require('./package.json');
|
|
3
|
+
const packageName = project.name;
|
|
4
|
+
const packageLoader = require('@steedos/service-package-loader');
|
|
5
|
+
/**
|
|
6
|
+
* @typedef {import('moleculer').Context} Context Moleculer's Context
|
|
7
|
+
* 软件包服务启动后也需要抛出事件。
|
|
8
|
+
*/
|
|
9
|
+
module.exports = {
|
|
10
|
+
name: packageName,
|
|
11
|
+
namespace: "steedos",
|
|
12
|
+
mixins: [packageLoader],
|
|
13
|
+
/**
|
|
14
|
+
* Settings
|
|
15
|
+
*/
|
|
16
|
+
settings: {
|
|
17
|
+
packageInfo: {
|
|
18
|
+
path: __dirname,
|
|
19
|
+
name: packageName
|
|
20
|
+
}
|
|
21
|
+
},
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Dependencies
|
|
25
|
+
*/
|
|
26
|
+
dependencies: [],
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Actions
|
|
30
|
+
*/
|
|
31
|
+
actions: {
|
|
32
|
+
|
|
33
|
+
},
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Events
|
|
37
|
+
*/
|
|
38
|
+
events: {
|
|
39
|
+
|
|
40
|
+
},
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Methods
|
|
44
|
+
*/
|
|
45
|
+
methods: {
|
|
46
|
+
|
|
47
|
+
},
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Service created lifecycle event handler
|
|
51
|
+
*/
|
|
52
|
+
async created() {
|
|
53
|
+
|
|
54
|
+
},
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Service started lifecycle event handler
|
|
58
|
+
*/
|
|
59
|
+
async started() {
|
|
60
|
+
|
|
61
|
+
},
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Service stopped lifecycle event handler
|
|
65
|
+
*/
|
|
66
|
+
async stopped() {
|
|
67
|
+
|
|
68
|
+
}
|
|
69
|
+
};
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* @Author: baozhoutao@steedos.com
|
|
3
|
+
* @Date: 2022-06-08 23:28:39
|
|
4
|
+
* @LastEditors: baozhoutao@steedos.com
|
|
5
|
+
* @LastEditTime: 2022-06-09 10:21:45
|
|
6
|
+
* @Description:
|
|
7
|
+
*/
|
|
8
|
+
import * as express from 'express';
|
|
9
|
+
import { requireAuthentication } from '@steedos/core';
|
|
10
|
+
import { getSteedosSchema } from '@steedos/objectql';
|
|
11
|
+
|
|
12
|
+
const router = express.Router();
|
|
13
|
+
|
|
14
|
+
router.get('/service/api/apps/menus', requireAuthentication, async function (req: any, res: any) {
|
|
15
|
+
const userSession = req.user;
|
|
16
|
+
try {
|
|
17
|
+
const result = await getSteedosSchema().broker.call('apps.getMenus', {}, {meta: {user: userSession}});
|
|
18
|
+
res.status(200).send(result);
|
|
19
|
+
} catch (error) {
|
|
20
|
+
res.status(500).send(error.message);
|
|
21
|
+
}
|
|
22
|
+
});
|
|
23
|
+
exports.default = router;
|
|
@@ -0,0 +1,466 @@
|
|
|
1
|
+
import steedosI18n = require("@steedos/i18n");
|
|
2
|
+
import { getPlugins, requireAuthentication } from '@steedos/core';
|
|
3
|
+
import { getObject, getObjectLayouts, getLayout, getAppConfigs, getAssignedMenus, getAssignedApps, getAllRelationsInfo, FieldPermission } from '@steedos/objectql'
|
|
4
|
+
//
|
|
5
|
+
require("@steedos/license");
|
|
6
|
+
const Fiber = require('fibers')
|
|
7
|
+
const clone = require("clone");
|
|
8
|
+
const _ = require('underscore');
|
|
9
|
+
|
|
10
|
+
var express = require('express');
|
|
11
|
+
const bootStrapExpress = express.Router();
|
|
12
|
+
|
|
13
|
+
async function getUserProfileObjectsLayout(userId, spaceId, objectName?) {
|
|
14
|
+
let spaceUser;
|
|
15
|
+
let spaceUsers = await getObject("space_users").directFind({filters: [['space', '=', spaceId], ['user', '=', userId]]});
|
|
16
|
+
if(spaceUsers.length > 0){
|
|
17
|
+
spaceUser = spaceUsers[0];
|
|
18
|
+
}
|
|
19
|
+
if (spaceUser && spaceUser.profile) {
|
|
20
|
+
// let filters = [['space', '=', spaceId],['profiles', '=', spaceUser.profile]];
|
|
21
|
+
// if(objectName){
|
|
22
|
+
// filters.push(['object_name', '=', objectName])
|
|
23
|
+
// }
|
|
24
|
+
// return await getObject("object_layouts").directFind({filters: filters})
|
|
25
|
+
return await getObjectLayouts(spaceUser.profile, spaceId, objectName)
|
|
26
|
+
}
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
async function getUserObjects(userId, spaceId, objects){
|
|
30
|
+
const objectsLayout = await getUserProfileObjectsLayout(userId, spaceId);
|
|
31
|
+
for (const objectName in objects) {
|
|
32
|
+
// objects[objectName].list_views = await getUserObjectListViews(userId, spaceId, objectName)
|
|
33
|
+
let userObjectLayout = null;
|
|
34
|
+
if(objectsLayout){
|
|
35
|
+
userObjectLayout = _.find(objectsLayout, function(objectLayout){
|
|
36
|
+
return objectLayout.object_name === objectName
|
|
37
|
+
})
|
|
38
|
+
}
|
|
39
|
+
if(!userObjectLayout && false){
|
|
40
|
+
userObjectLayout = getLayout(objectName, 'default');
|
|
41
|
+
}
|
|
42
|
+
if(userObjectLayout){
|
|
43
|
+
objects[userObjectLayout.object_name] = await getUserObject(userId, spaceId, objects[userObjectLayout.object_name], userObjectLayout)
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
async function getUserObject(userId, spaceId, object, layout?){
|
|
49
|
+
if(!layout){
|
|
50
|
+
const layouts = await getUserProfileObjectsLayout(userId, spaceId, object.name);
|
|
51
|
+
if(layouts && layouts.length > 0){
|
|
52
|
+
layout = layouts[0];
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
let _object = clone(object);
|
|
56
|
+
if(_object && layout){
|
|
57
|
+
_.each(_object.actions, (action, key) => {
|
|
58
|
+
if (!_.has(action, 'name')) {
|
|
59
|
+
action.name = key;
|
|
60
|
+
}
|
|
61
|
+
});
|
|
62
|
+
let _fields = {};
|
|
63
|
+
let sort_no = 1;
|
|
64
|
+
_.each(layout.fields, function(_item){
|
|
65
|
+
_fields[_item.field_name] = _object.fields[_item.field_name]
|
|
66
|
+
if(_fields[_item.field_name]){
|
|
67
|
+
if(_.has(_item, 'group')){
|
|
68
|
+
_fields[_item.field_name].group = _item.group
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
if(_item.is_required){
|
|
72
|
+
_fields[_item.field_name].readonly = false
|
|
73
|
+
_fields[_item.field_name].disabled = false
|
|
74
|
+
_fields[_item.field_name].required = true
|
|
75
|
+
}else if(_item.is_readonly){
|
|
76
|
+
_fields[_item.field_name].readonly = true
|
|
77
|
+
_fields[_item.field_name].disabled = true
|
|
78
|
+
_fields[_item.field_name].required = false
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
if(_item.visible_on){
|
|
82
|
+
_fields[_item.field_name].visible_on = _item.visible_on
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
if(['created','created_by','modified','modified_by'].indexOf(_item.field_name) < 0){
|
|
86
|
+
_fields[_item.field_name].omit = false;
|
|
87
|
+
_fields[_item.field_name].hidden = false;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
_fields[_item.field_name].sort_no = sort_no;
|
|
91
|
+
sort_no++;
|
|
92
|
+
}
|
|
93
|
+
})
|
|
94
|
+
|
|
95
|
+
const layoutFieldKeys = _.keys(_fields);
|
|
96
|
+
const objectFieldKeys = _.keys(_object.fields);
|
|
97
|
+
|
|
98
|
+
const difference = _.difference(objectFieldKeys, layoutFieldKeys);
|
|
99
|
+
|
|
100
|
+
_.each(layoutFieldKeys, function(fieldApiName){
|
|
101
|
+
_object.fields[fieldApiName] = _fields[fieldApiName];
|
|
102
|
+
})
|
|
103
|
+
|
|
104
|
+
_.each(difference, function(fieldApiName){
|
|
105
|
+
_object.fields[fieldApiName].hidden = true;
|
|
106
|
+
_object.fields[fieldApiName].sort_no = 99999;
|
|
107
|
+
})
|
|
108
|
+
|
|
109
|
+
// let _buttons = {};
|
|
110
|
+
_.each(layout.buttons, function(button){
|
|
111
|
+
const action = _object.actions[button.button_name];
|
|
112
|
+
if(action){
|
|
113
|
+
if(button.visible_on){
|
|
114
|
+
action._visible = button.visible_on;
|
|
115
|
+
}
|
|
116
|
+
// _buttons[button.button_name] = action
|
|
117
|
+
}
|
|
118
|
+
})
|
|
119
|
+
|
|
120
|
+
const layoutButtonsName = _.pluck(layout.buttons,'button_name');
|
|
121
|
+
_.each(_object.actions, function(action){
|
|
122
|
+
if(!_.include(layoutButtonsName, action.name)){
|
|
123
|
+
action.visible = false
|
|
124
|
+
action._visible = function(){return false}.toString()
|
|
125
|
+
}
|
|
126
|
+
})
|
|
127
|
+
|
|
128
|
+
// _object.actions = _buttons;
|
|
129
|
+
// _object.allow_customActions = userObjectLayout.custom_actions || []
|
|
130
|
+
// _object.exclude_actions = userObjectLayout.exclude_actions || []
|
|
131
|
+
_object.related_lists = layout.related_lists || []
|
|
132
|
+
_.each(_object.related_lists, (related_list)=>{
|
|
133
|
+
if(related_list.sort_field_name && _.isArray(related_list.sort_field_name) && related_list.sort_field_name.length > 0){
|
|
134
|
+
related_list.sort = [];
|
|
135
|
+
_.each(related_list.sort_field_name, (fName)=>{
|
|
136
|
+
related_list.sort.push({field_name: fName, order: related_list.sort_order || 'asc'})
|
|
137
|
+
})
|
|
138
|
+
}
|
|
139
|
+
})
|
|
140
|
+
}
|
|
141
|
+
return _object;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
|
|
145
|
+
export async function getSpaceBootStrap(req, res) {
|
|
146
|
+
return Fiber(async function () {
|
|
147
|
+
let userSession = req.user;
|
|
148
|
+
|
|
149
|
+
if (!userSession) {
|
|
150
|
+
return res.status(500).send();
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
let urlParams = req.params;
|
|
154
|
+
const { userId, language: lng} = userSession;
|
|
155
|
+
|
|
156
|
+
let spaceId = req.headers['x-space-id'] || urlParams.spaceId
|
|
157
|
+
let space = await getObject("spaces").findOne(spaceId, { fields: ['name'] })
|
|
158
|
+
//TODO 无需再从getAllPermissions中获取用户的对象权限
|
|
159
|
+
let result = Creator.getAllPermissions(spaceId, userId);
|
|
160
|
+
steedosI18n.translationObjects(lng, result.objects);
|
|
161
|
+
result.user = userSession
|
|
162
|
+
|
|
163
|
+
result.space = space
|
|
164
|
+
|
|
165
|
+
result.dashboards = clone(Creator.Dashboards)
|
|
166
|
+
result.object_workflows = Meteor.call('object_workflows.get', spaceId, userId)
|
|
167
|
+
result.object_listviews = await getUserObjectsListViews(userId, spaceId)
|
|
168
|
+
// result.apps = clone(Creator.Apps)
|
|
169
|
+
result.apps = await getAppConfigs(spaceId);
|
|
170
|
+
result.assigned_apps = await getAssignedApps(userSession);
|
|
171
|
+
let datasources = Creator.steedosSchema.getDataSources();
|
|
172
|
+
// for (const datasourceName in datasources) {
|
|
173
|
+
// if(datasourceName != 'default'){
|
|
174
|
+
// let datasource = datasources[datasourceName];
|
|
175
|
+
// const datasourceObjects = datasource.getObjects();
|
|
176
|
+
// for (const objectName in datasourceObjects) {
|
|
177
|
+
// const object = datasourceObjects[objectName];
|
|
178
|
+
// const _obj = Creator.convertObject(clone(object.toConfig()), spaceId)
|
|
179
|
+
// _obj.name = objectName
|
|
180
|
+
// _obj.database_name = datasourceName
|
|
181
|
+
// _obj.permissions = await object.getUserObjectPermission(userSession)
|
|
182
|
+
// result.objects[_obj.name] = _obj
|
|
183
|
+
// }
|
|
184
|
+
// }
|
|
185
|
+
// }
|
|
186
|
+
const spaceProcessDefinition = await getObject("process_definition").find({ filters: [['space', '=', spaceId], ['active', '=', true]] })
|
|
187
|
+
const spaceObjectsProcessDefinition = _.groupBy(spaceProcessDefinition, 'object_name');
|
|
188
|
+
|
|
189
|
+
const dbListViews = await getObject("object_listviews").directFind({ filters: [['space', '=', userSession.spaceId], [['owner', '=', userSession.userId], 'or', ['shared', '=', true]]] })
|
|
190
|
+
const dbObjectsListViews = _.groupBy(dbListViews, 'object_name');
|
|
191
|
+
|
|
192
|
+
const layouts = await getObjectLayouts(userSession.profile, spaceId)
|
|
193
|
+
const objectsLayouts = _.groupBy(layouts, 'object_name');
|
|
194
|
+
const objectsFieldsPermissionGroupRole = await FieldPermission.getObjectsFieldsPermissionGroupRole();
|
|
195
|
+
|
|
196
|
+
const allRelationsInfo = await getAllRelationsInfo();
|
|
197
|
+
|
|
198
|
+
for (const datasourceName in datasources) {
|
|
199
|
+
let datasource = datasources[datasourceName];
|
|
200
|
+
const datasourceObjects = await datasource.getObjects();
|
|
201
|
+
for (const object of datasourceObjects) {
|
|
202
|
+
const objectConfig = object.metadata;
|
|
203
|
+
if (!result.objects[objectConfig.name] || objectConfig.name.endsWith("__c")) {
|
|
204
|
+
try {
|
|
205
|
+
const userObjectConfig = await getObject(objectConfig.name).getRecordView(userSession, {
|
|
206
|
+
objectConfig: objectConfig,
|
|
207
|
+
layouts: objectsLayouts[objectConfig.name] || [],
|
|
208
|
+
spaceProcessDefinition: spaceObjectsProcessDefinition[objectConfig.name] || [],
|
|
209
|
+
dbListViews: dbObjectsListViews[objectConfig.name] || [],
|
|
210
|
+
rolesFieldsPermission: objectsFieldsPermissionGroupRole[objectConfig.name] || [],
|
|
211
|
+
relationsInfo: {
|
|
212
|
+
details: _.map(_.filter(allRelationsInfo.details, {objectName: objectConfig.name}), 'key'),
|
|
213
|
+
masters: _.map(_.filter(allRelationsInfo.masters, {objectName: objectConfig.name}), 'key'),
|
|
214
|
+
lookup_details: _.map(_.filter(allRelationsInfo.lookup_details, {objectName: objectConfig.name}))
|
|
215
|
+
}
|
|
216
|
+
});
|
|
217
|
+
let _objectConfig = null;
|
|
218
|
+
if (userObjectConfig) {
|
|
219
|
+
_objectConfig = userObjectConfig
|
|
220
|
+
} else {
|
|
221
|
+
_objectConfig = clone(objectConfig)
|
|
222
|
+
}
|
|
223
|
+
const _obj = Creator.convertObject(_objectConfig, spaceId)
|
|
224
|
+
_obj.name = objectConfig.name
|
|
225
|
+
_obj.database_name = datasourceName
|
|
226
|
+
if (userObjectConfig) {
|
|
227
|
+
_obj.permission = userObjectConfig.permissions
|
|
228
|
+
} else {
|
|
229
|
+
_obj.permissions = await getObject(objectConfig.name).getUserObjectPermission(userSession)
|
|
230
|
+
steedosI18n.translationObject(lng, _obj.name, _obj);
|
|
231
|
+
}
|
|
232
|
+
result.objects[_obj.name] = _obj
|
|
233
|
+
} catch (error) {
|
|
234
|
+
console.error(error.message)
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
var _dbApps = await getObject("apps").directFind({filters: [['space', '=', spaceId],['is_creator', '=', true]]});
|
|
241
|
+
let dbApps = {};
|
|
242
|
+
_.each(_dbApps, function(dbApp){
|
|
243
|
+
if(dbApp.visible){
|
|
244
|
+
return dbApps[dbApp._id] = dbApp;
|
|
245
|
+
}
|
|
246
|
+
})
|
|
247
|
+
|
|
248
|
+
result.apps = _.extend( result.apps || {}, dbApps);
|
|
249
|
+
|
|
250
|
+
var _dbDashboards = await getObject("dashboard").directFind({filters: [['space', '=', spaceId]]});
|
|
251
|
+
let dbDashboards = {};
|
|
252
|
+
_.each(_dbDashboards, function(dashboard){
|
|
253
|
+
dbDashboards[dashboard._id] = dashboard;
|
|
254
|
+
})
|
|
255
|
+
result.dashboards = _.extend( result.dashboards || {}, dbDashboards)
|
|
256
|
+
|
|
257
|
+
let _Apps = {}
|
|
258
|
+
_.each(result.apps, function(app, key){
|
|
259
|
+
if(!app._id){
|
|
260
|
+
app._id = key
|
|
261
|
+
}
|
|
262
|
+
if(app.code){
|
|
263
|
+
app._dbid = app._id
|
|
264
|
+
app._id = app.code
|
|
265
|
+
}
|
|
266
|
+
_Apps[app._id] = app
|
|
267
|
+
});
|
|
268
|
+
|
|
269
|
+
_.each(_dbApps, function(dbApp){
|
|
270
|
+
if(dbApp.visible === false){
|
|
271
|
+
delete _Apps[dbApp.code];
|
|
272
|
+
}
|
|
273
|
+
});
|
|
274
|
+
|
|
275
|
+
steedosI18n.translationApps(lng, _Apps);
|
|
276
|
+
result.apps = _Apps;
|
|
277
|
+
let assigned_menus = await getAssignedMenus(userSession);
|
|
278
|
+
steedosI18n.translationMenus(lng, assigned_menus);
|
|
279
|
+
result.assigned_menus = assigned_menus;
|
|
280
|
+
|
|
281
|
+
let _Dashboards = {}
|
|
282
|
+
_.each( result.dashboards, function(dashboard, key){
|
|
283
|
+
if(!dashboard._id){
|
|
284
|
+
dashboard._id = key
|
|
285
|
+
}
|
|
286
|
+
_Dashboards[dashboard._id] = dashboard
|
|
287
|
+
})
|
|
288
|
+
result.dashboards = _Dashboards
|
|
289
|
+
|
|
290
|
+
result.plugins = getPlugins ? getPlugins() : null
|
|
291
|
+
await getUserObjects(userId, spaceId, result.objects);
|
|
292
|
+
// TODO object layout 是否需要控制审批记录显示?
|
|
293
|
+
_.each(spaceProcessDefinition, function(item){
|
|
294
|
+
if(result.objects[item.object_name]){
|
|
295
|
+
result.objects[item.object_name].enable_process = true
|
|
296
|
+
}
|
|
297
|
+
})
|
|
298
|
+
for (const key in result.objects) {
|
|
299
|
+
if (Object.prototype.hasOwnProperty.call(result.objects, key)) {
|
|
300
|
+
const objectConfig = result.objects[key];
|
|
301
|
+
try {
|
|
302
|
+
// const object = getObject(key);
|
|
303
|
+
// const relationsInfo = await object.getRelationsInfo();
|
|
304
|
+
// objectConfig.details = relationsInfo.details;
|
|
305
|
+
// objectConfig.masters = relationsInfo.masters;
|
|
306
|
+
// objectConfig.lookup_details = relationsInfo.lookup_details;
|
|
307
|
+
objectConfig.details = _.map(_.filter(allRelationsInfo.details, {objectName: key}), 'key');
|
|
308
|
+
objectConfig.masters = _.map(_.filter(allRelationsInfo.masters, {objectName: key}), 'key');
|
|
309
|
+
objectConfig.lookup_details = _.map(_.filter(allRelationsInfo.lookup_details, {objectName: key}));
|
|
310
|
+
_.each(objectConfig.triggers, function(trigger, key){
|
|
311
|
+
if(trigger?.on != 'client'){
|
|
312
|
+
delete objectConfig.triggers[key];
|
|
313
|
+
}
|
|
314
|
+
})
|
|
315
|
+
delete objectConfig.listeners
|
|
316
|
+
delete objectConfig.__filename
|
|
317
|
+
delete objectConfig.extend
|
|
318
|
+
} catch (error) {
|
|
319
|
+
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
return res.status(200).send(result);
|
|
324
|
+
}).run();
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
async function getObjectConfig(objectName, spaceId, userSession) {
|
|
328
|
+
let objectConfig: any = {}
|
|
329
|
+
try {
|
|
330
|
+
let object = getObject(objectName)
|
|
331
|
+
let _objectConfig = null;
|
|
332
|
+
const userObjectConfig = await object.getRecordView(userSession);
|
|
333
|
+
if (userObjectConfig) {
|
|
334
|
+
_objectConfig = userObjectConfig
|
|
335
|
+
} else {
|
|
336
|
+
_objectConfig = clone(object.toConfig())
|
|
337
|
+
}
|
|
338
|
+
objectConfig = Creator.convertObject(_objectConfig, spaceId);
|
|
339
|
+
objectConfig.name = objectName
|
|
340
|
+
objectConfig.datasource = object.datasource.name;
|
|
341
|
+
objectConfig.permissions = await object.getUserObjectPermission(userSession);
|
|
342
|
+
const relationsInfo = await object.getRelationsInfo();
|
|
343
|
+
objectConfig.details = relationsInfo.details;
|
|
344
|
+
objectConfig.masters = relationsInfo.masters;
|
|
345
|
+
objectConfig.lookup_details = relationsInfo.lookup_details;
|
|
346
|
+
return objectConfig;
|
|
347
|
+
} catch (error) {
|
|
348
|
+
console.warn('not load object', objectName)
|
|
349
|
+
}
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
async function getUserObjectsListViews(userId, spaceId) {
|
|
353
|
+
const listViews = {};
|
|
354
|
+
const objectsViews = await getObject("object_listviews").find({filters: [['space', '=', spaceId],[ [ "owner", "=", userId ], "or", [ "shared", "=", true ] ]]});
|
|
355
|
+
let objectNames = _.pluck(objectsViews, 'object_name');
|
|
356
|
+
objectNames = _.uniq(objectNames);
|
|
357
|
+
const _getUserObjectListViews = function(object_name) {
|
|
358
|
+
var _user_object_list_views, olistViews;
|
|
359
|
+
_user_object_list_views = {};
|
|
360
|
+
olistViews = _.filter(objectsViews, function(ov) {
|
|
361
|
+
return ov.object_name === object_name;
|
|
362
|
+
});
|
|
363
|
+
_.each(olistViews, function(listview) {
|
|
364
|
+
return _user_object_list_views[listview._id] = listview;
|
|
365
|
+
});
|
|
366
|
+
return _user_object_list_views;
|
|
367
|
+
};
|
|
368
|
+
_.forEach(objectNames, function(key) {
|
|
369
|
+
var list_view;
|
|
370
|
+
list_view = _getUserObjectListViews(key);
|
|
371
|
+
if (!_.isEmpty(list_view)) {
|
|
372
|
+
return listViews[key] = list_view;
|
|
373
|
+
}
|
|
374
|
+
});
|
|
375
|
+
return listViews;
|
|
376
|
+
};
|
|
377
|
+
|
|
378
|
+
// async function getUserObjectListViews(userId, spaceId, object_name){
|
|
379
|
+
// const _user_object_list_views = {};
|
|
380
|
+
// const object_listview = await getObject("object_listviews").find({filters: [['object_name', '=', object_name],['space', '=', spaceId],[ [ "owner", "=", userId ], "or", [ "shared", "=", true ] ]]});
|
|
381
|
+
// object_listview.forEach(function(listview) {
|
|
382
|
+
// return _user_object_list_views[listview._id] = listview;
|
|
383
|
+
// });
|
|
384
|
+
// return _user_object_list_views;
|
|
385
|
+
// }
|
|
386
|
+
|
|
387
|
+
export async function getSpaceObjectBootStrap(req, res) {
|
|
388
|
+
return Fiber(async function () {
|
|
389
|
+
let userSession = req.user;
|
|
390
|
+
let userId = userSession.userId;
|
|
391
|
+
let urlParams = req.params;
|
|
392
|
+
let spaceId = req.headers['x-space-id'] || urlParams.spaceId
|
|
393
|
+
if (!userSession) {
|
|
394
|
+
return res.status(500).send();
|
|
395
|
+
}
|
|
396
|
+
const objectNames = urlParams.objectNames
|
|
397
|
+
const objects = {};
|
|
398
|
+
if (objectNames) {
|
|
399
|
+
const objectNamesArray = objectNames.split(',');
|
|
400
|
+
let dbObjects = Creator.getCollection('objects').find({ name: { $in: objectNamesArray } }).fetch() || []
|
|
401
|
+
let creatorObjects = Creator.getAllPermissions(spaceId, userId).objects;
|
|
402
|
+
let lng = userSession.language;
|
|
403
|
+
for (const objectName of objectNamesArray) {
|
|
404
|
+
let _object = _.find(dbObjects, function (item) { return item.name === objectName }) || {}
|
|
405
|
+
let objectConfig: any = {}
|
|
406
|
+
if (_.isEmpty(_object)) {
|
|
407
|
+
objectConfig = creatorObjects[objectName];
|
|
408
|
+
if (_.isEmpty(objectConfig)) {
|
|
409
|
+
objectConfig = await getObjectConfig(objectName, spaceId, userSession);
|
|
410
|
+
} else {
|
|
411
|
+
const object = getObject(objectName);
|
|
412
|
+
const relationsInfo = await object.getRelationsInfo();
|
|
413
|
+
objectConfig.details = relationsInfo.details;
|
|
414
|
+
objectConfig.masters = relationsInfo.masters;
|
|
415
|
+
objectConfig.lookup_details = relationsInfo.lookup_details;
|
|
416
|
+
}
|
|
417
|
+
} else {
|
|
418
|
+
if (userSession.is_space_admin || _object.in_development == '0' && _object.is_enable) {
|
|
419
|
+
if (_object.datasource == 'meteor') {
|
|
420
|
+
objectConfig = creatorObjects[objectName]
|
|
421
|
+
const object = getObject(objectName);
|
|
422
|
+
const relationsInfo = await object.getRelationsInfo();
|
|
423
|
+
objectConfig.details = relationsInfo.details;
|
|
424
|
+
objectConfig.masters = relationsInfo.masters;
|
|
425
|
+
objectConfig.lookup_details = relationsInfo.lookup_details;
|
|
426
|
+
} else {
|
|
427
|
+
objectConfig = await getObjectConfig(objectName, spaceId, userSession);
|
|
428
|
+
}
|
|
429
|
+
}
|
|
430
|
+
}
|
|
431
|
+
if (objectConfig) {
|
|
432
|
+
delete objectConfig.db
|
|
433
|
+
// objectConfig.list_views = await getUserObjectListViews(userId, spaceId, objectName)
|
|
434
|
+
steedosI18n.translationObject(lng, objectConfig.name, objectConfig)
|
|
435
|
+
|
|
436
|
+
objectConfig = await getUserObject(userId, spaceId, objectConfig)
|
|
437
|
+
|
|
438
|
+
// TODO object layout 是否需要控制审批记录显示?
|
|
439
|
+
let spaceProcessDefinition = await getObject("process_definition").directFind({ filters: [['space', '=', spaceId], ['object_name', '=', objectName], ['active', '=', true]] })
|
|
440
|
+
if (spaceProcessDefinition.length > 0) {
|
|
441
|
+
objectConfig.enable_process = true
|
|
442
|
+
}
|
|
443
|
+
|
|
444
|
+
_.each(objectConfig.triggers, function (trigger, key) {
|
|
445
|
+
if (trigger?.on != 'client') {
|
|
446
|
+
delete objectConfig.triggers[key];
|
|
447
|
+
}
|
|
448
|
+
})
|
|
449
|
+
|
|
450
|
+
delete objectConfig.listeners
|
|
451
|
+
delete objectConfig.__filename
|
|
452
|
+
delete objectConfig.extend
|
|
453
|
+
objects[objectConfig.name] = objectConfig;
|
|
454
|
+
}
|
|
455
|
+
}
|
|
456
|
+
}
|
|
457
|
+
return res.status(200).send({
|
|
458
|
+
objects: objects
|
|
459
|
+
});
|
|
460
|
+
}).run();
|
|
461
|
+
}
|
|
462
|
+
|
|
463
|
+
bootStrapExpress.use('/api/bootstrap/:spaceId/:objectNames', requireAuthentication, getSpaceObjectBootStrap)
|
|
464
|
+
bootStrapExpress.use('/api/bootstrap/:spaceId/', requireAuthentication, getSpaceBootStrap)
|
|
465
|
+
|
|
466
|
+
exports.default = bootStrapExpress;
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* @Author: baozhoutao@steedos.com
|
|
3
|
+
* @Date: 2022-06-09 10:19:47
|
|
4
|
+
* @LastEditors: baozhoutao@steedos.com
|
|
5
|
+
* @LastEditTime: 2022-06-10 15:52:17
|
|
6
|
+
* @Description:
|
|
7
|
+
*/
|
|
8
|
+
import { getSteedosSchema } from "@steedos/objectql";
|
|
9
|
+
const express = require("express");
|
|
10
|
+
const router = express.Router();
|
|
11
|
+
const core = require('@steedos/core');
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
const callObjectServiceAction = async function(actionName, userSession, data?){
|
|
15
|
+
const broker = getSteedosSchema().broker;
|
|
16
|
+
return broker.call(actionName, data, { meta: { user: userSession}})
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
router.get('/service/api/:objectServiceName/fields', core.requireAuthentication, async function (req, res) {
|
|
21
|
+
const userSession = req.user;
|
|
22
|
+
try {
|
|
23
|
+
const { objectServiceName } = req.params;
|
|
24
|
+
const result = await callObjectServiceAction(`${objectServiceName}.getFields`, userSession);
|
|
25
|
+
res.status(200).send(result);
|
|
26
|
+
} catch (error) {
|
|
27
|
+
res.status(500).send(error.message);
|
|
28
|
+
}
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
router.get('/service/api/:objectServiceName/getUserObjectPermission', core.requireAuthentication, async function (req, res) {
|
|
32
|
+
const userSession = req.user;
|
|
33
|
+
try {
|
|
34
|
+
const { objectServiceName } = req.params;
|
|
35
|
+
const result = await callObjectServiceAction(`${objectServiceName}.getUserObjectPermission`, userSession);
|
|
36
|
+
res.status(200).send(result);
|
|
37
|
+
} catch (error) {
|
|
38
|
+
res.status(500).send(error.message);
|
|
39
|
+
}
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
router.get('/service/api/:objectServiceName/recordPermissions/:recordId', core.requireAuthentication, async function (req, res) {
|
|
43
|
+
const userSession = req.user;
|
|
44
|
+
try {
|
|
45
|
+
const { objectServiceName, recordId } = req.params;
|
|
46
|
+
const result = await callObjectServiceAction(`${objectServiceName}.getRecordPermissionsById`, userSession, {
|
|
47
|
+
recordId: recordId
|
|
48
|
+
});
|
|
49
|
+
res.status(200).send(result);
|
|
50
|
+
} catch (error) {
|
|
51
|
+
res.status(500).send(error.message);
|
|
52
|
+
}
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
router.get('/service/api/:objectServiceName/uiSchema', core.requireAuthentication, async function (req, res) {
|
|
56
|
+
const userSession = req.user;
|
|
57
|
+
try {
|
|
58
|
+
const { objectServiceName } = req.params;
|
|
59
|
+
const result = await callObjectServiceAction(`${objectServiceName}.getRecordView`, userSession);
|
|
60
|
+
res.status(200).send(result);
|
|
61
|
+
} catch (error) {
|
|
62
|
+
res.status(500).send(error.message);
|
|
63
|
+
}
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
router.post('/service/api/:objectServiceName/defUiSchema', core.requireAuthentication, async function (req, res) {
|
|
67
|
+
const userSession = req.user;
|
|
68
|
+
try {
|
|
69
|
+
const { objectServiceName } = req.params;
|
|
70
|
+
const result = await callObjectServiceAction(`${objectServiceName}.createDefaultRecordView`, userSession);
|
|
71
|
+
res.status(200).send(result);
|
|
72
|
+
} catch (error) {
|
|
73
|
+
res.status(500).send(error.message);
|
|
74
|
+
}
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
router.get('/service/api/:objectServiceName/uiSchemaTemplate', core.requireAuthentication, async function (req, res) {
|
|
78
|
+
const userSession = req.user;
|
|
79
|
+
try {
|
|
80
|
+
const { objectServiceName } = req.params;
|
|
81
|
+
const result = await callObjectServiceAction(`${objectServiceName}.getDefaultRecordView`, userSession);
|
|
82
|
+
res.status(200).send(result);
|
|
83
|
+
} catch (error) {
|
|
84
|
+
res.status(500).send(error.message);
|
|
85
|
+
}
|
|
86
|
+
});
|
|
87
|
+
|
|
88
|
+
router.get('/service/api/:objectServiceName/relateds', core.requireAuthentication, async function (req, res) {
|
|
89
|
+
const userSession = req.user;
|
|
90
|
+
try {
|
|
91
|
+
const { objectServiceName } = req.params;
|
|
92
|
+
const result = await callObjectServiceAction(`${objectServiceName}.getRelateds`, userSession);
|
|
93
|
+
res.status(200).send(result);
|
|
94
|
+
} catch (error) {
|
|
95
|
+
res.status(500).send(error.message);
|
|
96
|
+
}
|
|
97
|
+
});
|
|
98
|
+
|
|
99
|
+
exports.default = router;
|