@reldens/cms 0.82.0 → 0.84.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.
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
*
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
+
const { DeleteRelationsWarning } = require('./delete-relations-warning');
|
|
7
8
|
const { sc } = require('@reldens/utils');
|
|
8
9
|
|
|
9
10
|
class ContentsBuilder
|
|
@@ -29,6 +30,10 @@ class ContentsBuilder
|
|
|
29
30
|
this.fetchUploadProperties = props.fetchUploadProperties;
|
|
30
31
|
this.fetchTranslation = props.fetchTranslation;
|
|
31
32
|
this.fetchEntityIdPropertyKey = props.fetchEntityIdPropertyKey;
|
|
33
|
+
this.relationsWarning = new DeleteRelationsWarning({
|
|
34
|
+
translations: props.translations,
|
|
35
|
+
resources: props.resources
|
|
36
|
+
});
|
|
32
37
|
this.adminContents = {};
|
|
33
38
|
}
|
|
34
39
|
|
|
@@ -116,7 +121,7 @@ class ContentsBuilder
|
|
|
116
121
|
async buildEntitiesContents()
|
|
117
122
|
{
|
|
118
123
|
let entitiesContents = {};
|
|
119
|
-
let reverseRelations = this.buildReverseRelationsMap();
|
|
124
|
+
let reverseRelations = this.relationsWarning.buildReverseRelationsMap();
|
|
120
125
|
for(let driverResource of this.resources()){
|
|
121
126
|
let templateTitle = this.translations.labels[driverResource.id()];
|
|
122
127
|
let entityName = (driverResource.id().replace(/_/g, '-'));
|
|
@@ -130,7 +135,7 @@ class ContentsBuilder
|
|
|
130
135
|
let editProperties = Object.keys(driverResource.options.properties);
|
|
131
136
|
editProperties.splice(editProperties.indexOf(idProperty), 1);
|
|
132
137
|
let entityId = driverResource.id();
|
|
133
|
-
let deleteRelationsWarning = this.
|
|
138
|
+
let deleteRelationsWarning = this.relationsWarning.fetchWarning(entityId, reverseRelations);
|
|
134
139
|
let filters = driverResource.options.filterProperties.map((property) => {
|
|
135
140
|
return {
|
|
136
141
|
propertyKey: property,
|
|
@@ -228,48 +233,6 @@ class ContentsBuilder
|
|
|
228
233
|
return editFields;
|
|
229
234
|
}
|
|
230
235
|
|
|
231
|
-
buildReverseRelationsMap()
|
|
232
|
-
{
|
|
233
|
-
let reverseRelations = {};
|
|
234
|
-
for(let resource of this.resources()){
|
|
235
|
-
let childLabel = sc.get(this.translations.labels, resource.id(), resource.id());
|
|
236
|
-
this.addResourceReverseRelations(reverseRelations, resource.options.properties, childLabel);
|
|
237
|
-
}
|
|
238
|
-
return reverseRelations;
|
|
239
|
-
}
|
|
240
|
-
|
|
241
|
-
addResourceReverseRelations(reverseRelations, properties, childLabel)
|
|
242
|
-
{
|
|
243
|
-
for(let propertyKey of Object.keys(properties)){
|
|
244
|
-
let property = properties[propertyKey];
|
|
245
|
-
if('reference' !== property.type){
|
|
246
|
-
continue;
|
|
247
|
-
}
|
|
248
|
-
if(!reverseRelations[property.reference]){
|
|
249
|
-
reverseRelations[property.reference] = {deleted: [], unlinked: []};
|
|
250
|
-
}
|
|
251
|
-
let relationGroup = true === property.unlinkOnDelete ? 'unlinked' : 'deleted';
|
|
252
|
-
if(-1 === reverseRelations[property.reference][relationGroup].indexOf(childLabel)){
|
|
253
|
-
reverseRelations[property.reference][relationGroup].push(childLabel);
|
|
254
|
-
}
|
|
255
|
-
}
|
|
256
|
-
}
|
|
257
|
-
|
|
258
|
-
fetchDeleteRelationsWarning(entityId, reverseRelations)
|
|
259
|
-
{
|
|
260
|
-
return this.buildRelationsSentence(entityId, reverseRelations, 'deleted', 'confirmDeleteRelations')
|
|
261
|
-
+this.buildRelationsSentence(entityId, reverseRelations, 'unlinked', 'confirmUnlinkRelations');
|
|
262
|
-
}
|
|
263
|
-
|
|
264
|
-
buildRelationsSentence(entityId, reverseRelations, relationGroup, messageKey)
|
|
265
|
-
{
|
|
266
|
-
let childLabels = sc.get(sc.get(reverseRelations, entityId, {}), relationGroup, []);
|
|
267
|
-
if(0 === childLabels.length){
|
|
268
|
-
return '';
|
|
269
|
-
}
|
|
270
|
-
return ' '+this.translations.messages[messageKey]+' '+[...childLabels].sort().join(', ')+'.';
|
|
271
|
-
}
|
|
272
|
-
|
|
273
236
|
async render(content, params)
|
|
274
237
|
{
|
|
275
238
|
return await this.renderCallback(content, params);
|
|
@@ -19,7 +19,8 @@ module.exports.DefaultTranslations = {
|
|
|
19
19
|
confirmClearCacheMessage: 'Are you sure you want to clear all cache? This action cannot be undone.',
|
|
20
20
|
clearCacheWarning: 'This will clear all cached routes and may impact site performance temporarily.',
|
|
21
21
|
confirmDeleteRelations: 'The following related records will also be deleted:',
|
|
22
|
-
confirmUnlinkRelations: 'The following related records will be kept but unlinked from it:'
|
|
22
|
+
confirmUnlinkRelations: 'The following related records will be kept but unlinked from it:',
|
|
23
|
+
confirmBlockingRelations: 'The following related records reference it and may block the delete:'
|
|
23
24
|
},
|
|
24
25
|
labels: {
|
|
25
26
|
navigation: 'Reldens - CMS',
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
/**
|
|
2
|
+
*
|
|
3
|
+
* Reldens - DeleteRelationsWarning
|
|
4
|
+
*
|
|
5
|
+
* Builds the delete confirmation warning for an entity by grouping every entity that references it, using the
|
|
6
|
+
* relation onDelete rule: "cascade" means the related records are deleted with it, "setNull" and "setDefault"
|
|
7
|
+
* mean they are kept and only unlinked, and anything else (restrict, no action, or an unknown rule) is reported
|
|
8
|
+
* as possibly blocking the delete instead of claiming an outcome that will not happen.
|
|
9
|
+
*
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
const { sc } = require('@reldens/utils');
|
|
13
|
+
|
|
14
|
+
class DeleteRelationsWarning
|
|
15
|
+
{
|
|
16
|
+
|
|
17
|
+
constructor(props)
|
|
18
|
+
{
|
|
19
|
+
this.translations = props.translations;
|
|
20
|
+
this.resources = props.resources;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
buildReverseRelationsMap()
|
|
24
|
+
{
|
|
25
|
+
let reverseRelations = {};
|
|
26
|
+
for(let resource of this.resources()){
|
|
27
|
+
let childLabel = sc.get(this.translations.labels, resource.id(), resource.id());
|
|
28
|
+
this.addResourceReverseRelations(reverseRelations, resource.options.properties, childLabel);
|
|
29
|
+
}
|
|
30
|
+
return reverseRelations;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
addResourceReverseRelations(reverseRelations, properties, childLabel)
|
|
34
|
+
{
|
|
35
|
+
for(let propertyKey of Object.keys(properties)){
|
|
36
|
+
let property = properties[propertyKey];
|
|
37
|
+
if('reference' !== property.type){
|
|
38
|
+
continue;
|
|
39
|
+
}
|
|
40
|
+
if(!reverseRelations[property.reference]){
|
|
41
|
+
reverseRelations[property.reference] = {deleted: [], unlinked: [], blocking: []};
|
|
42
|
+
}
|
|
43
|
+
let relationGroup = this.fetchRelationGroup(property.onDelete);
|
|
44
|
+
if(-1 === reverseRelations[property.reference][relationGroup].indexOf(childLabel)){
|
|
45
|
+
reverseRelations[property.reference][relationGroup].push(childLabel);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
fetchRelationGroup(onDelete)
|
|
51
|
+
{
|
|
52
|
+
if('cascade' === onDelete){
|
|
53
|
+
return 'deleted';
|
|
54
|
+
}
|
|
55
|
+
if('setNull' === onDelete || 'setDefault' === onDelete){
|
|
56
|
+
return 'unlinked';
|
|
57
|
+
}
|
|
58
|
+
return 'blocking';
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
fetchWarning(entityId, reverseRelations)
|
|
62
|
+
{
|
|
63
|
+
return this.buildRelationsSentence(entityId, reverseRelations, 'deleted', 'confirmDeleteRelations')
|
|
64
|
+
+this.buildRelationsSentence(entityId, reverseRelations, 'unlinked', 'confirmUnlinkRelations')
|
|
65
|
+
+this.buildRelationsSentence(entityId, reverseRelations, 'blocking', 'confirmBlockingRelations');
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
buildRelationsSentence(entityId, reverseRelations, relationGroup, messageKey)
|
|
69
|
+
{
|
|
70
|
+
let childLabels = sc.get(sc.get(reverseRelations, entityId, {}), relationGroup, []);
|
|
71
|
+
if(0 === childLabels.length){
|
|
72
|
+
return '';
|
|
73
|
+
}
|
|
74
|
+
return ' '+this.translations.messages[messageKey]+' '+[...childLabels].sort().join(', ')+'.';
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
module.exports.DeleteRelationsWarning = DeleteRelationsWarning;
|
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.84.0",
|
|
5
5
|
"description": "Reldens - CMS",
|
|
6
6
|
"author": "Damian A. Pastorini",
|
|
7
7
|
"license": "MIT",
|
|
@@ -35,7 +35,7 @@
|
|
|
35
35
|
},
|
|
36
36
|
"dependencies": {
|
|
37
37
|
"@reldens/server-utils": "^0.56.0",
|
|
38
|
-
"@reldens/storage": "^0.
|
|
38
|
+
"@reldens/storage": "^0.111.0",
|
|
39
39
|
"@reldens/utils": "^0.57.0",
|
|
40
40
|
"dotenv": "17.4.2",
|
|
41
41
|
"mustache": "4.2.0"
|