@reldens/cms 0.25.0 → 0.27.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/reldens-cms-generate-entities.js +1 -1
- package/bin/reldens-cms.js +1 -1
- package/lib/admin-manager/contents-builder.js +258 -258
- package/lib/admin-manager/router-contents.js +724 -720
- package/lib/admin-manager/router.js +228 -228
- package/lib/admin-manager.js +282 -279
- package/package.json +3 -3
package/lib/admin-manager.js
CHANGED
|
@@ -1,279 +1,282 @@
|
|
|
1
|
-
/**
|
|
2
|
-
*
|
|
3
|
-
* Reldens - AdminManager
|
|
4
|
-
*
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
|
-
const { UploaderFactory } = require('@reldens/server-utils');
|
|
8
|
-
const { ValidatorInterface, Logger, sc } = require('@reldens/utils');
|
|
9
|
-
const { ContentsBuilder } = require('./admin-manager/contents-builder');
|
|
10
|
-
const { Router } = require('./admin-manager/router');
|
|
11
|
-
const { RouterContents } = require('./admin-manager/router-contents');
|
|
12
|
-
const { CacheRoutesHandler } = require('./cache/cache-routes-handler');
|
|
13
|
-
const { AddCacheButtonSubscriber } = require('./cache/add-cache-button-subscriber');
|
|
14
|
-
|
|
15
|
-
class AdminManager
|
|
16
|
-
{
|
|
17
|
-
|
|
18
|
-
constructor(configData)
|
|
19
|
-
{
|
|
20
|
-
this.events = configData?.events;
|
|
21
|
-
this.renderCallback = configData?.renderCallback;
|
|
22
|
-
this.dataServer = configData?.dataServer;
|
|
23
|
-
this.authenticationCallback = configData?.authenticationCallback;
|
|
24
|
-
this.app = configData?.app;
|
|
25
|
-
this.applicationFramework = configData?.appServerFactory?.applicationFramework;
|
|
26
|
-
this.bodyParser = configData?.appServerFactory?.bodyParser;
|
|
27
|
-
this.session = configData?.appServerFactory?.session;
|
|
28
|
-
this.validator = configData?.validator;
|
|
29
|
-
this.buckets = sc.get(configData, 'buckets', {});
|
|
30
|
-
this.translations = sc.get(configData, 'translations', {});
|
|
31
|
-
this.adminFilesContents = sc.get(configData, 'adminFilesContents', false);
|
|
32
|
-
this.secret = sc.get(configData, 'secret', '');
|
|
33
|
-
this.rootPath = sc.get(configData, 'rootPath', '');
|
|
34
|
-
this.adminRoleId = sc.get(configData, 'adminRoleId', 0);
|
|
35
|
-
this.buildAdminCssOnActivation = sc.get(configData, 'buildAdminCssOnActivation', false);
|
|
36
|
-
this.buildAdminScriptsOnActivation = sc.get(configData, 'buildAdminScriptsOnActivation', false);
|
|
37
|
-
this.updateAdminAssetsDistOnActivation = sc.get(configData, 'updateAdminAssetsDistOnActivation', false);
|
|
38
|
-
this.stylesFilePath = sc.get(configData, 'stylesFilePath', '');
|
|
39
|
-
this.scriptsFilePath = sc.get(configData, 'scriptsFilePath', '');
|
|
40
|
-
this.autoSyncDistCallback = sc.get(configData, 'autoSyncDistCallback', false);
|
|
41
|
-
this.branding = sc.get(configData, 'branding', {});
|
|
42
|
-
this.entities = sc.get(configData, 'entities', {});
|
|
43
|
-
this.cacheManager = sc.get(configData, 'cacheManager', false);
|
|
44
|
-
this.logoutPath = '/logout';
|
|
45
|
-
this.loginPath = '/login';
|
|
46
|
-
this.viewPath = '/view';
|
|
47
|
-
this.editPath = '/edit';
|
|
48
|
-
this.savePath = '/save';
|
|
49
|
-
this.deletePath = '/delete';
|
|
50
|
-
this.mimeTypes = sc.get(configData, 'mimeTypes', false);
|
|
51
|
-
this.allowedExtensions = sc.get(configData, 'allowedExtensions', false);
|
|
52
|
-
this.uploaderFactory = sc.get(configData, 'uploaderFactory', new UploaderFactory({
|
|
53
|
-
mimeTypes: this.mimeTypes,
|
|
54
|
-
allowedExtensions: this.allowedExtensions,
|
|
55
|
-
applySecureFileNames: sc.get(configData, 'applySecureFileNames', false)
|
|
56
|
-
}));
|
|
57
|
-
this.blackList = {};
|
|
58
|
-
this.emitEvent = (eventName, eventData = {}) => this.events.emit(eventName, {adminManager: this, ...eventData});
|
|
59
|
-
this.contentsBuilder = new ContentsBuilder({
|
|
60
|
-
renderCallback: this.renderCallback,
|
|
61
|
-
adminFilesContents: this.adminFilesContents,
|
|
62
|
-
stylesFilePath: this.stylesFilePath,
|
|
63
|
-
scriptsFilePath: this.scriptsFilePath,
|
|
64
|
-
rootPath: this.rootPath,
|
|
65
|
-
branding: this.branding,
|
|
66
|
-
translations: this.translations,
|
|
67
|
-
resources: () => this.resources,
|
|
68
|
-
buildAdminCssOnActivation: this.buildAdminCssOnActivation,
|
|
69
|
-
buildAdminScriptsOnActivation: this.buildAdminScriptsOnActivation,
|
|
70
|
-
updateAdminAssetsDistOnActivation: this.updateAdminAssetsDistOnActivation,
|
|
71
|
-
emitEvent: this.emitEvent,
|
|
72
|
-
editPath: this.editPath,
|
|
73
|
-
savePath: this.savePath,
|
|
74
|
-
deletePath: this.deletePath,
|
|
75
|
-
fetchUploadProperties: this.fetchUploadProperties.bind(this),
|
|
76
|
-
fetchTranslation: this.fetchTranslation.bind(this),
|
|
77
|
-
fetchEntityIdPropertyKey: this.fetchEntityIdPropertyKey.bind(this)
|
|
78
|
-
});
|
|
79
|
-
this.router = new Router({
|
|
80
|
-
app: this.app,
|
|
81
|
-
applicationFramework: this.applicationFramework,
|
|
82
|
-
bodyParser: this.bodyParser,
|
|
83
|
-
session: this.session,
|
|
84
|
-
secret: this.secret,
|
|
85
|
-
rootPath: this.rootPath,
|
|
86
|
-
adminRoleId: this.adminRoleId,
|
|
87
|
-
authenticationCallback: this.authenticationCallback,
|
|
88
|
-
uploaderFactory: this.uploaderFactory,
|
|
89
|
-
buckets: this.buckets,
|
|
90
|
-
blackList: this.blackList,
|
|
91
|
-
loginPath: this.loginPath,
|
|
92
|
-
logoutPath: this.logoutPath,
|
|
93
|
-
viewPath: this.viewPath,
|
|
94
|
-
editPath: this.editPath,
|
|
95
|
-
savePath: this.savePath,
|
|
96
|
-
deletePath: this.deletePath,
|
|
97
|
-
resources: () => this.resources,
|
|
98
|
-
emitEvent: this.emitEvent,
|
|
99
|
-
fetchUploadProperties: this.fetchUploadProperties.bind(this),
|
|
100
|
-
adminContents: () => this.contentsBuilder.adminContents,
|
|
101
|
-
generateListRouteContent: (...args) => this.routerContents.generateListRouteContent(...args),
|
|
102
|
-
generateViewRouteContent: (...args) => this.routerContents.generateViewRouteContent(...args),
|
|
103
|
-
generateEditRouteContent: (...args) => this.routerContents.generateEditRouteContent(...args),
|
|
104
|
-
processDeleteEntities: (...args) => this.routerContents.processDeleteEntities(...args),
|
|
105
|
-
processSaveEntity: (...args) => this.routerContents.processSaveEntity(...args)
|
|
106
|
-
});
|
|
107
|
-
this.routerContents = new RouterContents({
|
|
108
|
-
dataServer: this.dataServer,
|
|
109
|
-
translations: this.translations,
|
|
110
|
-
rootPath: this.rootPath,
|
|
111
|
-
relations: () => this.relations,
|
|
112
|
-
resourcesByReference: () => this.resourcesByReference,
|
|
113
|
-
adminFilesContents: this.adminFilesContents,
|
|
114
|
-
autoSyncDistCallback: this.autoSyncDistCallback,
|
|
115
|
-
viewPath: this.viewPath,
|
|
116
|
-
editPath: this.editPath,
|
|
117
|
-
deletePath: this.deletePath,
|
|
118
|
-
emitEvent: this.emitEvent,
|
|
119
|
-
adminContentsRender: (...args) => this.contentsBuilder.render(...args),
|
|
120
|
-
adminContentsRenderRoute: (...args) => this.contentsBuilder.renderRoute(...args),
|
|
121
|
-
adminContentsEntities: () => this.contentsBuilder.adminContents.entities,
|
|
122
|
-
adminContentsSideBar: () => this.contentsBuilder.adminContents.sideBar,
|
|
123
|
-
fetchTranslation: this.fetchTranslation.bind(this),
|
|
124
|
-
fetchEntityIdPropertyKey: this.fetchEntityIdPropertyKey.bind(this),
|
|
125
|
-
fetchUploadProperties: this.fetchUploadProperties.bind(this)
|
|
126
|
-
});
|
|
127
|
-
this.cacheRoutesHandler = new CacheRoutesHandler({
|
|
128
|
-
router: this.router,
|
|
129
|
-
rootPath: this.rootPath,
|
|
130
|
-
dataServer: this.dataServer,
|
|
131
|
-
cacheManager: this.cacheManager
|
|
132
|
-
});
|
|
133
|
-
this.addCacheButtonSubscriber = new AddCacheButtonSubscriber({
|
|
134
|
-
events: this.events,
|
|
135
|
-
cacheManager: this.cacheManager,
|
|
136
|
-
renderCallback: this.renderCallback,
|
|
137
|
-
cacheCleanButton: this.adminFilesContents.cacheCleanButton,
|
|
138
|
-
clearAllCacheButton: this.adminFilesContents.clearAllCacheButton,
|
|
139
|
-
translations: this.translations,
|
|
140
|
-
cacheCleanRoute: this.cacheRoutesHandler.cacheCleanRoute,
|
|
141
|
-
clearAllCacheRoute: this.cacheRoutesHandler.clearAllCacheRoute
|
|
142
|
-
});
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
async setupAdmin()
|
|
146
|
-
{
|
|
147
|
-
if(this.validator instanceof ValidatorInterface && !this.validator.validate(this)){
|
|
148
|
-
return false;
|
|
149
|
-
}
|
|
150
|
-
this.resourcesByReference = {};
|
|
151
|
-
this.resources = this.prepareResources(this.entities);
|
|
152
|
-
this.relations = this.prepareRelations(this.entities);
|
|
153
|
-
await this.contentsBuilder.buildAdminContents();
|
|
154
|
-
await this.contentsBuilder.buildAdminScripts();
|
|
155
|
-
await this.contentsBuilder.buildAdminCss();
|
|
156
|
-
await this.contentsBuilder.updateAdminAssets();
|
|
157
|
-
await this.events.emit('reldens.setupAdminRouter', {adminManager: this});
|
|
158
|
-
this.router.setupAdminRoutes();
|
|
159
|
-
await this.events.emit('reldens.setupAdminRoutes', {adminManager: this});
|
|
160
|
-
await this.router.setupEntitiesRoutes();
|
|
161
|
-
await this.events.emit('reldens.setupAdminManagers', {adminManager: this});
|
|
162
|
-
}
|
|
163
|
-
|
|
164
|
-
prepareResources(rawResources)
|
|
165
|
-
{
|
|
166
|
-
let rawResourcesKeys = Object.keys(rawResources);
|
|
167
|
-
if(!rawResources || 0 === rawResourcesKeys.length){
|
|
168
|
-
return [];
|
|
169
|
-
}
|
|
170
|
-
let registeredResources = [];
|
|
171
|
-
for(let i of rawResourcesKeys){
|
|
172
|
-
let rawResource = rawResources[i];
|
|
173
|
-
let tableName = rawResource.rawEntity.tableName();
|
|
174
|
-
let driverResource = {
|
|
175
|
-
id: () => {
|
|
176
|
-
return tableName;
|
|
177
|
-
},
|
|
178
|
-
entityKey: i,
|
|
179
|
-
entityPath: (tableName.replace(/_/g, '-')),
|
|
180
|
-
options: {
|
|
181
|
-
navigation: sc.hasOwn(rawResource.config, 'parentItemLabel') ? {
|
|
182
|
-
name: rawResource.config.parentItemLabel,
|
|
183
|
-
icon: rawResource.config.icon || 'List'
|
|
184
|
-
} : null,
|
|
185
|
-
listProperties: rawResource.config.listProperties || [],
|
|
186
|
-
showProperties: rawResource.config.showProperties || [],
|
|
187
|
-
filterProperties: rawResource.config.filterProperties || [],
|
|
188
|
-
editProperties: rawResource.config.editProperties || [],
|
|
189
|
-
properties: rawResource.config.properties || {},
|
|
190
|
-
titleProperty: sc.get(rawResource.config, 'titleProperty', null),
|
|
191
|
-
sort: sc.get(rawResource.config, 'sort', null),
|
|
192
|
-
navigationPosition: sc.get(rawResource.config, 'navigationPosition', 2000)
|
|
193
|
-
},
|
|
194
|
-
};
|
|
195
|
-
this.resourcesByReference[tableName] = driverResource;
|
|
196
|
-
registeredResources.push(driverResource);
|
|
197
|
-
}
|
|
198
|
-
registeredResources.sort((a, b) => a.options.navigationPosition - b.options.navigationPosition);
|
|
199
|
-
return registeredResources;
|
|
200
|
-
}
|
|
201
|
-
|
|
202
|
-
prepareRelations()
|
|
203
|
-
{
|
|
204
|
-
let registeredRelations = {};
|
|
205
|
-
for(let resource of this.resources){
|
|
206
|
-
for(let propertyKey of Object.keys(resource.options.properties)){
|
|
207
|
-
let property = resource.options.properties[propertyKey];
|
|
208
|
-
if('reference' !== property.type){
|
|
209
|
-
continue;
|
|
210
|
-
}
|
|
211
|
-
let relationResource = this.resources.filter((resource) => {
|
|
212
|
-
return resource.id() === property.reference;
|
|
213
|
-
}).shift();
|
|
214
|
-
let relationKey = property.alias || property.reference;
|
|
215
|
-
let titleProperty = relationResource?.options?.titleProperty;
|
|
216
|
-
if(!titleProperty){
|
|
217
|
-
continue;
|
|
218
|
-
}
|
|
219
|
-
if(!registeredRelations[property.reference]){
|
|
220
|
-
registeredRelations[property.reference] = {};
|
|
221
|
-
}
|
|
222
|
-
registeredRelations[property.reference][relationKey] = titleProperty;
|
|
223
|
-
}
|
|
224
|
-
}
|
|
225
|
-
return registeredRelations;
|
|
226
|
-
}
|
|
227
|
-
|
|
228
|
-
fetchUploadProperties(driverResource)
|
|
229
|
-
{
|
|
230
|
-
if(!driverResource.options.uploadProperties){
|
|
231
|
-
driverResource.options.uploadProperties = {};
|
|
232
|
-
for(let propertyKey of Object.keys(driverResource.options.properties)){
|
|
233
|
-
let property = driverResource.options.properties[propertyKey];
|
|
234
|
-
if(property.isUpload){
|
|
235
|
-
driverResource.options.uploadProperties[propertyKey] = property;
|
|
236
|
-
}
|
|
237
|
-
}
|
|
238
|
-
}
|
|
239
|
-
return driverResource.options.uploadProperties;
|
|
240
|
-
}
|
|
241
|
-
|
|
242
|
-
fetchEntityIdPropertyKey(driverResource)
|
|
243
|
-
{
|
|
244
|
-
let resourceProperties = driverResource?.options?.properties;
|
|
245
|
-
if(!resourceProperties){
|
|
246
|
-
Logger.error('Property "ID" not found.', resourceProperties);
|
|
247
|
-
return '';
|
|
248
|
-
}
|
|
249
|
-
if(resourceProperties['id']){
|
|
250
|
-
return 'id';
|
|
251
|
-
}
|
|
252
|
-
let idProperty = '';
|
|
253
|
-
let idProperties = Object.keys(resourceProperties).filter((propertyKey) => {
|
|
254
|
-
return resourceProperties[propertyKey].isId;
|
|
255
|
-
});
|
|
256
|
-
if(0 < idProperties.length){
|
|
257
|
-
idProperty = idProperties.shift();
|
|
258
|
-
}
|
|
259
|
-
return idProperty;
|
|
260
|
-
}
|
|
261
|
-
|
|
262
|
-
fetchTranslation(snippet, group)
|
|
263
|
-
{
|
|
264
|
-
if('' === snippet){
|
|
265
|
-
return snippet;
|
|
266
|
-
}
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
1
|
+
/**
|
|
2
|
+
*
|
|
3
|
+
* Reldens - AdminManager
|
|
4
|
+
*
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
const { UploaderFactory } = require('@reldens/server-utils');
|
|
8
|
+
const { ValidatorInterface, Logger, sc } = require('@reldens/utils');
|
|
9
|
+
const { ContentsBuilder } = require('./admin-manager/contents-builder');
|
|
10
|
+
const { Router } = require('./admin-manager/router');
|
|
11
|
+
const { RouterContents } = require('./admin-manager/router-contents');
|
|
12
|
+
const { CacheRoutesHandler } = require('./cache/cache-routes-handler');
|
|
13
|
+
const { AddCacheButtonSubscriber } = require('./cache/add-cache-button-subscriber');
|
|
14
|
+
|
|
15
|
+
class AdminManager
|
|
16
|
+
{
|
|
17
|
+
|
|
18
|
+
constructor(configData)
|
|
19
|
+
{
|
|
20
|
+
this.events = configData?.events;
|
|
21
|
+
this.renderCallback = configData?.renderCallback;
|
|
22
|
+
this.dataServer = configData?.dataServer;
|
|
23
|
+
this.authenticationCallback = configData?.authenticationCallback;
|
|
24
|
+
this.app = configData?.app;
|
|
25
|
+
this.applicationFramework = configData?.appServerFactory?.applicationFramework;
|
|
26
|
+
this.bodyParser = configData?.appServerFactory?.bodyParser;
|
|
27
|
+
this.session = configData?.appServerFactory?.session;
|
|
28
|
+
this.validator = configData?.validator;
|
|
29
|
+
this.buckets = sc.get(configData, 'buckets', {});
|
|
30
|
+
this.translations = sc.get(configData, 'translations', {});
|
|
31
|
+
this.adminFilesContents = sc.get(configData, 'adminFilesContents', false);
|
|
32
|
+
this.secret = sc.get(configData, 'secret', '');
|
|
33
|
+
this.rootPath = sc.get(configData, 'rootPath', '');
|
|
34
|
+
this.adminRoleId = sc.get(configData, 'adminRoleId', 0);
|
|
35
|
+
this.buildAdminCssOnActivation = sc.get(configData, 'buildAdminCssOnActivation', false);
|
|
36
|
+
this.buildAdminScriptsOnActivation = sc.get(configData, 'buildAdminScriptsOnActivation', false);
|
|
37
|
+
this.updateAdminAssetsDistOnActivation = sc.get(configData, 'updateAdminAssetsDistOnActivation', false);
|
|
38
|
+
this.stylesFilePath = sc.get(configData, 'stylesFilePath', '');
|
|
39
|
+
this.scriptsFilePath = sc.get(configData, 'scriptsFilePath', '');
|
|
40
|
+
this.autoSyncDistCallback = sc.get(configData, 'autoSyncDistCallback', false);
|
|
41
|
+
this.branding = sc.get(configData, 'branding', {});
|
|
42
|
+
this.entities = sc.get(configData, 'entities', {});
|
|
43
|
+
this.cacheManager = sc.get(configData, 'cacheManager', false);
|
|
44
|
+
this.logoutPath = '/logout';
|
|
45
|
+
this.loginPath = '/login';
|
|
46
|
+
this.viewPath = '/view';
|
|
47
|
+
this.editPath = '/edit';
|
|
48
|
+
this.savePath = '/save';
|
|
49
|
+
this.deletePath = '/delete';
|
|
50
|
+
this.mimeTypes = sc.get(configData, 'mimeTypes', false);
|
|
51
|
+
this.allowedExtensions = sc.get(configData, 'allowedExtensions', false);
|
|
52
|
+
this.uploaderFactory = sc.get(configData, 'uploaderFactory', new UploaderFactory({
|
|
53
|
+
mimeTypes: this.mimeTypes,
|
|
54
|
+
allowedExtensions: this.allowedExtensions,
|
|
55
|
+
applySecureFileNames: sc.get(configData, 'applySecureFileNames', false)
|
|
56
|
+
}));
|
|
57
|
+
this.blackList = {};
|
|
58
|
+
this.emitEvent = (eventName, eventData = {}) => this.events.emit(eventName, {adminManager: this, ...eventData});
|
|
59
|
+
this.contentsBuilder = new ContentsBuilder({
|
|
60
|
+
renderCallback: this.renderCallback,
|
|
61
|
+
adminFilesContents: this.adminFilesContents,
|
|
62
|
+
stylesFilePath: this.stylesFilePath,
|
|
63
|
+
scriptsFilePath: this.scriptsFilePath,
|
|
64
|
+
rootPath: this.rootPath,
|
|
65
|
+
branding: this.branding,
|
|
66
|
+
translations: this.translations,
|
|
67
|
+
resources: () => this.resources,
|
|
68
|
+
buildAdminCssOnActivation: this.buildAdminCssOnActivation,
|
|
69
|
+
buildAdminScriptsOnActivation: this.buildAdminScriptsOnActivation,
|
|
70
|
+
updateAdminAssetsDistOnActivation: this.updateAdminAssetsDistOnActivation,
|
|
71
|
+
emitEvent: this.emitEvent,
|
|
72
|
+
editPath: this.editPath,
|
|
73
|
+
savePath: this.savePath,
|
|
74
|
+
deletePath: this.deletePath,
|
|
75
|
+
fetchUploadProperties: this.fetchUploadProperties.bind(this),
|
|
76
|
+
fetchTranslation: this.fetchTranslation.bind(this),
|
|
77
|
+
fetchEntityIdPropertyKey: this.fetchEntityIdPropertyKey.bind(this)
|
|
78
|
+
});
|
|
79
|
+
this.router = new Router({
|
|
80
|
+
app: this.app,
|
|
81
|
+
applicationFramework: this.applicationFramework,
|
|
82
|
+
bodyParser: this.bodyParser,
|
|
83
|
+
session: this.session,
|
|
84
|
+
secret: this.secret,
|
|
85
|
+
rootPath: this.rootPath,
|
|
86
|
+
adminRoleId: this.adminRoleId,
|
|
87
|
+
authenticationCallback: this.authenticationCallback,
|
|
88
|
+
uploaderFactory: this.uploaderFactory,
|
|
89
|
+
buckets: this.buckets,
|
|
90
|
+
blackList: this.blackList,
|
|
91
|
+
loginPath: this.loginPath,
|
|
92
|
+
logoutPath: this.logoutPath,
|
|
93
|
+
viewPath: this.viewPath,
|
|
94
|
+
editPath: this.editPath,
|
|
95
|
+
savePath: this.savePath,
|
|
96
|
+
deletePath: this.deletePath,
|
|
97
|
+
resources: () => this.resources,
|
|
98
|
+
emitEvent: this.emitEvent,
|
|
99
|
+
fetchUploadProperties: this.fetchUploadProperties.bind(this),
|
|
100
|
+
adminContents: () => this.contentsBuilder.adminContents,
|
|
101
|
+
generateListRouteContent: (...args) => this.routerContents.generateListRouteContent(...args),
|
|
102
|
+
generateViewRouteContent: (...args) => this.routerContents.generateViewRouteContent(...args),
|
|
103
|
+
generateEditRouteContent: (...args) => this.routerContents.generateEditRouteContent(...args),
|
|
104
|
+
processDeleteEntities: (...args) => this.routerContents.processDeleteEntities(...args),
|
|
105
|
+
processSaveEntity: (...args) => this.routerContents.processSaveEntity(...args)
|
|
106
|
+
});
|
|
107
|
+
this.routerContents = new RouterContents({
|
|
108
|
+
dataServer: this.dataServer,
|
|
109
|
+
translations: this.translations,
|
|
110
|
+
rootPath: this.rootPath,
|
|
111
|
+
relations: () => this.relations,
|
|
112
|
+
resourcesByReference: () => this.resourcesByReference,
|
|
113
|
+
adminFilesContents: this.adminFilesContents,
|
|
114
|
+
autoSyncDistCallback: this.autoSyncDistCallback,
|
|
115
|
+
viewPath: this.viewPath,
|
|
116
|
+
editPath: this.editPath,
|
|
117
|
+
deletePath: this.deletePath,
|
|
118
|
+
emitEvent: this.emitEvent,
|
|
119
|
+
adminContentsRender: (...args) => this.contentsBuilder.render(...args),
|
|
120
|
+
adminContentsRenderRoute: (...args) => this.contentsBuilder.renderRoute(...args),
|
|
121
|
+
adminContentsEntities: () => this.contentsBuilder.adminContents.entities,
|
|
122
|
+
adminContentsSideBar: () => this.contentsBuilder.adminContents.sideBar,
|
|
123
|
+
fetchTranslation: this.fetchTranslation.bind(this),
|
|
124
|
+
fetchEntityIdPropertyKey: this.fetchEntityIdPropertyKey.bind(this),
|
|
125
|
+
fetchUploadProperties: this.fetchUploadProperties.bind(this)
|
|
126
|
+
});
|
|
127
|
+
this.cacheRoutesHandler = new CacheRoutesHandler({
|
|
128
|
+
router: this.router,
|
|
129
|
+
rootPath: this.rootPath,
|
|
130
|
+
dataServer: this.dataServer,
|
|
131
|
+
cacheManager: this.cacheManager
|
|
132
|
+
});
|
|
133
|
+
this.addCacheButtonSubscriber = new AddCacheButtonSubscriber({
|
|
134
|
+
events: this.events,
|
|
135
|
+
cacheManager: this.cacheManager,
|
|
136
|
+
renderCallback: this.renderCallback,
|
|
137
|
+
cacheCleanButton: this.adminFilesContents.cacheCleanButton,
|
|
138
|
+
clearAllCacheButton: this.adminFilesContents.clearAllCacheButton,
|
|
139
|
+
translations: this.translations,
|
|
140
|
+
cacheCleanRoute: this.cacheRoutesHandler.cacheCleanRoute,
|
|
141
|
+
clearAllCacheRoute: this.cacheRoutesHandler.clearAllCacheRoute
|
|
142
|
+
});
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
async setupAdmin()
|
|
146
|
+
{
|
|
147
|
+
if(this.validator instanceof ValidatorInterface && !this.validator.validate(this)){
|
|
148
|
+
return false;
|
|
149
|
+
}
|
|
150
|
+
this.resourcesByReference = {};
|
|
151
|
+
this.resources = this.prepareResources(this.entities);
|
|
152
|
+
this.relations = this.prepareRelations(this.entities);
|
|
153
|
+
await this.contentsBuilder.buildAdminContents();
|
|
154
|
+
await this.contentsBuilder.buildAdminScripts();
|
|
155
|
+
await this.contentsBuilder.buildAdminCss();
|
|
156
|
+
await this.contentsBuilder.updateAdminAssets();
|
|
157
|
+
await this.events.emit('reldens.setupAdminRouter', {adminManager: this});
|
|
158
|
+
this.router.setupAdminRoutes();
|
|
159
|
+
await this.events.emit('reldens.setupAdminRoutes', {adminManager: this});
|
|
160
|
+
await this.router.setupEntitiesRoutes();
|
|
161
|
+
await this.events.emit('reldens.setupAdminManagers', {adminManager: this});
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
prepareResources(rawResources)
|
|
165
|
+
{
|
|
166
|
+
let rawResourcesKeys = Object.keys(rawResources);
|
|
167
|
+
if(!rawResources || 0 === rawResourcesKeys.length){
|
|
168
|
+
return [];
|
|
169
|
+
}
|
|
170
|
+
let registeredResources = [];
|
|
171
|
+
for(let i of rawResourcesKeys){
|
|
172
|
+
let rawResource = rawResources[i];
|
|
173
|
+
let tableName = rawResource.rawEntity.tableName();
|
|
174
|
+
let driverResource = {
|
|
175
|
+
id: () => {
|
|
176
|
+
return tableName;
|
|
177
|
+
},
|
|
178
|
+
entityKey: i,
|
|
179
|
+
entityPath: (tableName.replace(/_/g, '-')),
|
|
180
|
+
options: {
|
|
181
|
+
navigation: sc.hasOwn(rawResource.config, 'parentItemLabel') ? {
|
|
182
|
+
name: rawResource.config.parentItemLabel,
|
|
183
|
+
icon: rawResource.config.icon || 'List'
|
|
184
|
+
} : null,
|
|
185
|
+
listProperties: rawResource.config.listProperties || [],
|
|
186
|
+
showProperties: rawResource.config.showProperties || [],
|
|
187
|
+
filterProperties: rawResource.config.filterProperties || [],
|
|
188
|
+
editProperties: rawResource.config.editProperties || [],
|
|
189
|
+
properties: rawResource.config.properties || {},
|
|
190
|
+
titleProperty: sc.get(rawResource.config, 'titleProperty', null),
|
|
191
|
+
sort: sc.get(rawResource.config, 'sort', null),
|
|
192
|
+
navigationPosition: sc.get(rawResource.config, 'navigationPosition', 2000)
|
|
193
|
+
},
|
|
194
|
+
};
|
|
195
|
+
this.resourcesByReference[tableName] = driverResource;
|
|
196
|
+
registeredResources.push(driverResource);
|
|
197
|
+
}
|
|
198
|
+
registeredResources.sort((a, b) => a.options.navigationPosition - b.options.navigationPosition);
|
|
199
|
+
return registeredResources;
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
prepareRelations()
|
|
203
|
+
{
|
|
204
|
+
let registeredRelations = {};
|
|
205
|
+
for(let resource of this.resources){
|
|
206
|
+
for(let propertyKey of Object.keys(resource.options.properties)){
|
|
207
|
+
let property = resource.options.properties[propertyKey];
|
|
208
|
+
if('reference' !== property.type){
|
|
209
|
+
continue;
|
|
210
|
+
}
|
|
211
|
+
let relationResource = this.resources.filter((resource) => {
|
|
212
|
+
return resource.id() === property.reference;
|
|
213
|
+
}).shift();
|
|
214
|
+
let relationKey = property.alias || property.reference;
|
|
215
|
+
let titleProperty = relationResource?.options?.titleProperty;
|
|
216
|
+
if(!titleProperty){
|
|
217
|
+
continue;
|
|
218
|
+
}
|
|
219
|
+
if(!registeredRelations[property.reference]){
|
|
220
|
+
registeredRelations[property.reference] = {};
|
|
221
|
+
}
|
|
222
|
+
registeredRelations[property.reference][relationKey] = titleProperty;
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
return registeredRelations;
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
fetchUploadProperties(driverResource)
|
|
229
|
+
{
|
|
230
|
+
if(!driverResource.options.uploadProperties){
|
|
231
|
+
driverResource.options.uploadProperties = {};
|
|
232
|
+
for(let propertyKey of Object.keys(driverResource.options.properties)){
|
|
233
|
+
let property = driverResource.options.properties[propertyKey];
|
|
234
|
+
if(property.isUpload){
|
|
235
|
+
driverResource.options.uploadProperties[propertyKey] = property;
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
return driverResource.options.uploadProperties;
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
fetchEntityIdPropertyKey(driverResource)
|
|
243
|
+
{
|
|
244
|
+
let resourceProperties = driverResource?.options?.properties;
|
|
245
|
+
if(!resourceProperties){
|
|
246
|
+
Logger.error('Property "ID" not found.', resourceProperties);
|
|
247
|
+
return '';
|
|
248
|
+
}
|
|
249
|
+
if(resourceProperties['id']){
|
|
250
|
+
return 'id';
|
|
251
|
+
}
|
|
252
|
+
let idProperty = '';
|
|
253
|
+
let idProperties = Object.keys(resourceProperties).filter((propertyKey) => {
|
|
254
|
+
return resourceProperties[propertyKey].isId;
|
|
255
|
+
});
|
|
256
|
+
if(0 < idProperties.length){
|
|
257
|
+
idProperty = idProperties.shift();
|
|
258
|
+
}
|
|
259
|
+
return idProperty;
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
fetchTranslation(snippet, group)
|
|
263
|
+
{
|
|
264
|
+
if('' === snippet){
|
|
265
|
+
return snippet;
|
|
266
|
+
}
|
|
267
|
+
if(group){
|
|
268
|
+
let translationGroup = sc.get(this.translations, group);
|
|
269
|
+
if(translationGroup){
|
|
270
|
+
let translationByGroup = sc.get(translationGroup, snippet, '');
|
|
271
|
+
if('' !== translationByGroup){
|
|
272
|
+
return translationByGroup;
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
let translation = sc.get(this.translations, snippet, snippet);
|
|
277
|
+
return translation === '' ? snippet : translation;
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
module.exports.AdminManager = AdminManager;
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@reldens/cms",
|
|
3
3
|
"scope": "@reldens",
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.27.0",
|
|
5
5
|
"description": "Reldens - CMS",
|
|
6
6
|
"author": "Damian A. Pastorini",
|
|
7
7
|
"license": "MIT",
|
|
@@ -34,9 +34,9 @@
|
|
|
34
34
|
},
|
|
35
35
|
"dependencies": {
|
|
36
36
|
"@reldens/server-utils": "^0.26.0",
|
|
37
|
-
"@reldens/storage": "^0.
|
|
37
|
+
"@reldens/storage": "^0.69.0",
|
|
38
38
|
"@reldens/utils": "^0.53.0",
|
|
39
|
-
"dotenv": "^17.2.
|
|
39
|
+
"dotenv": "^17.2.2",
|
|
40
40
|
"mustache": "^4.2.0"
|
|
41
41
|
}
|
|
42
42
|
}
|