strapi-plugin-comments 2.0.0-beta.1 → 2.0.0-beta.5
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/README.md +16 -5
- package/admin/src/components/DiscussionThread/index.js +3 -1
- package/admin/src/components/DiscussionThreadItem/index.js +4 -4
- package/admin/src/components/DiscussionThreadItem/styles.js +1 -0
- package/admin/src/components/DiscussionThreadItemActions/index.js +30 -44
- package/admin/src/components/DiscussionThreadItemActions/styles.js +0 -4
- package/admin/src/components/DiscussionThreadItemApprovalFlowActions/index.js +72 -0
- package/admin/src/components/DiscussionThreadItemApprovalFlowActions/styles.js +6 -0
- package/admin/src/components/DiscussionThreadItemWarnings/index.js +13 -9
- package/admin/src/components/Nav/index.js +5 -1
- package/admin/src/components/ReportsReviewModal/index.js +0 -2
- package/admin/src/components/ReportsReviewTable/index.js +9 -5
- package/admin/src/components/icons/index.js +6 -0
- package/admin/src/components/icons/lock.js +22 -0
- package/admin/src/components/icons/review.js +18 -0
- package/admin/src/components/icons/unlock.js +20 -0
- package/admin/src/index.js +6 -4
- package/admin/src/pages/App/index.js +42 -3
- package/admin/src/pages/App/reducer/actions.js +8 -0
- package/admin/src/pages/App/reducer/constants.js +4 -0
- package/admin/src/pages/App/reducer/index.js +26 -0
- package/admin/src/pages/App/reducer/init.js +7 -0
- package/admin/src/pages/App/reducer/selectors.js +35 -0
- package/admin/src/pages/App/utils/api.js +12 -0
- package/admin/src/pages/Details/components/DetailsEntity/index.js +66 -0
- package/admin/src/pages/Details/components/DetailsFilters/index.js +36 -0
- package/admin/src/pages/Details/components/DetailsFilters/styles.js +8 -0
- package/admin/src/pages/Details/index.js +41 -14
- package/admin/src/pages/Discover/components/DiscoverTableRow/index.js +190 -0
- package/admin/src/pages/Discover/components/DiscoverTableRow/styles.js +8 -0
- package/admin/src/pages/Discover/index.js +25 -50
- package/admin/src/pages/Discover/utils/api.js +2 -11
- package/admin/src/pages/{Details/utils → utils}/api.js +15 -3
- package/admin/src/reducers.js +8 -0
- package/admin/src/translations/en.json +16 -4
- package/admin/src/utils/constants.js +3 -6
- package/admin/src/utils/getMessage.js +10 -3
- package/admin/src/utils/getRelatedGroups.js +1 -3
- package/admin/src/utils/handleAPIError.js +1 -1
- package/admin/src/utils/index.js +4 -2
- package/admin/src/utils/renderEntryTitle.js +14 -0
- package/admin/src/utils/resolveCommentStatus.js +30 -0
- package/admin/src/utils/resolveCommentStatusColor.js +22 -0
- package/package.json +7 -3
- package/server/config/index.js +6 -1
- package/server/controllers/admin.js +8 -24
- package/server/controllers/client.js +11 -2
- package/server/services/admin.js +75 -14
- package/server/services/client.js +22 -14
- package/server/services/common.js +41 -70
- package/server/services/utils/functions.js +7 -14
- package/server/utils/constants.js +3 -3
- package/admin/src/components/EntityDetails/index.js +0 -53
package/server/services/admin.js
CHANGED
|
@@ -1,14 +1,12 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
const { getPluginService, parseParams } = require('./../utils/functions');
|
|
4
|
-
const {
|
|
5
|
-
const { first, isEmpty, isNil, uniq, get } = require('lodash');
|
|
4
|
+
const { isEmpty, isNil } = require('lodash');
|
|
6
5
|
const PluginError = require('./../utils/error');
|
|
7
6
|
const {
|
|
8
7
|
getModelUid,
|
|
9
8
|
getRelatedGroups,
|
|
10
9
|
filterOurResolvedReports,
|
|
11
|
-
convertContentTypeNameToSlug
|
|
12
10
|
} = require('./utils/functions');
|
|
13
11
|
const { APPROVAL_STATUS, REGEX } = require('./../utils/constants')
|
|
14
12
|
|
|
@@ -22,14 +20,36 @@ const { APPROVAL_STATUS, REGEX } = require('./../utils/constants')
|
|
|
22
20
|
return getPluginService('common');
|
|
23
21
|
},
|
|
24
22
|
|
|
23
|
+
// Config
|
|
24
|
+
async config() {
|
|
25
|
+
const entryLabel = this.getCommonService().getConfig('entryLabel');
|
|
26
|
+
const approvalFlow = this.getCommonService().getConfig('approvalFlow');
|
|
27
|
+
return {
|
|
28
|
+
entryLabel,
|
|
29
|
+
approvalFlow,
|
|
30
|
+
regex: Object.keys(REGEX).reduce((prev, curr) => ({
|
|
31
|
+
...prev,
|
|
32
|
+
[curr]: REGEX[curr].toString(),
|
|
33
|
+
}), {}),
|
|
34
|
+
};
|
|
35
|
+
},
|
|
36
|
+
|
|
25
37
|
// Find all comments
|
|
26
38
|
async findAll({ related, entity, ...query }) {
|
|
27
39
|
const { _q, orderBy, pageSize = 10, page = 1, filters, ...rest } = parseParams(query);
|
|
28
40
|
|
|
41
|
+
const defaultWhere = {
|
|
42
|
+
$or: [
|
|
43
|
+
{ removed: false },
|
|
44
|
+
{ removed: null },
|
|
45
|
+
],
|
|
46
|
+
};
|
|
47
|
+
|
|
29
48
|
let params = {
|
|
30
49
|
where: !isEmpty(filters) ? {
|
|
50
|
+
...defaultWhere,
|
|
31
51
|
...filters,
|
|
32
|
-
} :
|
|
52
|
+
} : { ...defaultWhere },
|
|
33
53
|
offset: (page - 1)*pageSize,
|
|
34
54
|
limit: pageSize,
|
|
35
55
|
orderBy: orderBy || [{ createdAt: 'desc' }],
|
|
@@ -47,7 +67,18 @@ const { APPROVAL_STATUS, REGEX } = require('./../utils/constants')
|
|
|
47
67
|
}
|
|
48
68
|
|
|
49
69
|
const entities = await strapi.db.query(getModelUid('comment'))
|
|
50
|
-
.findMany(
|
|
70
|
+
.findMany({
|
|
71
|
+
...params,
|
|
72
|
+
populate: {
|
|
73
|
+
authorUser: true,
|
|
74
|
+
threadOf: true,
|
|
75
|
+
reports: {
|
|
76
|
+
where: {
|
|
77
|
+
resolved: false
|
|
78
|
+
},
|
|
79
|
+
},
|
|
80
|
+
},
|
|
81
|
+
});
|
|
51
82
|
const total = await strapi.db.query(getModelUid('comment'))
|
|
52
83
|
.count({
|
|
53
84
|
where: params.where,
|
|
@@ -57,8 +88,6 @@ const { APPROVAL_STATUS, REGEX } = require('./../utils/constants')
|
|
|
57
88
|
.map(_ => filterOurResolvedReports(this.getCommonService().sanitizeCommentEntity(_)))
|
|
58
89
|
.map(_ => this.getCommonService().mergeRelatedEntityTo(_, relatedEntities));
|
|
59
90
|
|
|
60
|
-
console.log(relatedEntities);
|
|
61
|
-
|
|
62
91
|
return {
|
|
63
92
|
result,
|
|
64
93
|
pagination: {
|
|
@@ -71,12 +100,35 @@ const { APPROVAL_STATUS, REGEX } = require('./../utils/constants')
|
|
|
71
100
|
},
|
|
72
101
|
|
|
73
102
|
// Find single comment
|
|
74
|
-
async findOneAndThread(id) {
|
|
103
|
+
async findOneAndThread(id, { removed, ...query }) {
|
|
104
|
+
const defaultWhere = !removed ? {
|
|
105
|
+
$or: [
|
|
106
|
+
{ removed: false },
|
|
107
|
+
{ removed: null },
|
|
108
|
+
],
|
|
109
|
+
} : {};
|
|
110
|
+
|
|
111
|
+
const reportsPopulation = {
|
|
112
|
+
reports: {
|
|
113
|
+
where: {
|
|
114
|
+
resolved: false,
|
|
115
|
+
},
|
|
116
|
+
}
|
|
117
|
+
};
|
|
118
|
+
|
|
75
119
|
const entity = await strapi.db.query(getModelUid('comment')).findOne({
|
|
76
120
|
where: {
|
|
77
|
-
id
|
|
121
|
+
id,
|
|
122
|
+
},
|
|
123
|
+
populate: {
|
|
124
|
+
authorUser: true,
|
|
125
|
+
threadOf: {
|
|
126
|
+
populate: {
|
|
127
|
+
...reportsPopulation
|
|
128
|
+
},
|
|
129
|
+
},
|
|
130
|
+
...reportsPopulation,
|
|
78
131
|
},
|
|
79
|
-
populate: ['threadOf', 'threadOf.reports', 'authorUser', 'reports']
|
|
80
132
|
});
|
|
81
133
|
|
|
82
134
|
if (!entity){
|
|
@@ -100,22 +152,27 @@ const { APPROVAL_STATUS, REGEX } = require('./../utils/constants')
|
|
|
100
152
|
const entitiesOnSameLevel = await this.getCommonService()
|
|
101
153
|
.findAllInHierarchy({
|
|
102
154
|
query: {
|
|
155
|
+
...defaultWhere,
|
|
156
|
+
...query,
|
|
103
157
|
threadOf: levelThreadId,
|
|
104
158
|
related: entity.related,
|
|
105
159
|
},
|
|
160
|
+
populate: {
|
|
161
|
+
...reportsPopulation,
|
|
162
|
+
},
|
|
106
163
|
startingFromId: levelThreadId,
|
|
107
164
|
isAdmin: true
|
|
108
165
|
}, false);
|
|
109
166
|
|
|
110
|
-
const selectedEntity =
|
|
167
|
+
const selectedEntity = this.getCommonService().sanitizeCommentEntity(entity);
|
|
111
168
|
|
|
112
169
|
return {
|
|
113
170
|
entity: relatedEntity,
|
|
114
171
|
selected: {
|
|
115
172
|
...selectedEntity,
|
|
116
|
-
threadOf: selectedEntity.threadOf ?
|
|
173
|
+
threadOf: selectedEntity.threadOf ? selectedEntity.threadOf : null,
|
|
117
174
|
},
|
|
118
|
-
level: entitiesOnSameLevel
|
|
175
|
+
level: entitiesOnSameLevel,
|
|
119
176
|
};
|
|
120
177
|
},
|
|
121
178
|
|
|
@@ -132,9 +189,13 @@ const { APPROVAL_STATUS, REGEX } = require('./../utils/constants')
|
|
|
132
189
|
// Block / Unblock a comment thread
|
|
133
190
|
async blockCommentThread(id, forceStatus) {
|
|
134
191
|
const existingEntity = await this.getCommonService().findOne({ id });
|
|
192
|
+
const status = !isNil(forceStatus) ? forceStatus : !existingEntity.blockedThread;
|
|
135
193
|
const changedEntity = await strapi.db.query(getModelUid('comment')).update({
|
|
136
194
|
where: { id },
|
|
137
|
-
data: {
|
|
195
|
+
data: {
|
|
196
|
+
blocked: status,
|
|
197
|
+
blockedThread: status,
|
|
198
|
+
},
|
|
138
199
|
});
|
|
139
200
|
await this.blockNestedThreads(id, changedEntity.blockedThread);
|
|
140
201
|
|
|
@@ -26,18 +26,14 @@ module.exports = ({ strapi }) => ({
|
|
|
26
26
|
|
|
27
27
|
// Create a comment
|
|
28
28
|
async create(relation, data, user = undefined) {
|
|
29
|
-
const { content, threadOf
|
|
30
|
-
const singleRelationFulfilled =
|
|
31
|
-
|
|
32
|
-
if (relation !== related) {
|
|
33
|
-
throw new PluginError(400, `Insonsistent relation uid`);
|
|
34
|
-
}
|
|
35
|
-
|
|
29
|
+
const { content, threadOf } = data;
|
|
30
|
+
const singleRelationFulfilled = relation && REGEX.relatedUid.test(relation);
|
|
31
|
+
|
|
36
32
|
if(!singleRelationFulfilled) {
|
|
37
33
|
throw new PluginError(400, `Field "related" got incorrect format, use format like "api::<collection name>.<content type name>:<entity id>"`);
|
|
38
34
|
}
|
|
39
35
|
|
|
40
|
-
const [ uid, relatedStringId ] = getRelatedGroups(
|
|
36
|
+
const [ uid, relatedStringId ] = getRelatedGroups(relation);
|
|
41
37
|
const relatedId = parseInt(relatedStringId, 10);
|
|
42
38
|
|
|
43
39
|
const relatedEntity = await strapi.db.query(uid).findOne(relatedId);
|
|
@@ -45,9 +41,12 @@ module.exports = ({ strapi }) => ({
|
|
|
45
41
|
throw new PluginError(400, `Relation for field "related" does not exist. Check your payload please.`);
|
|
46
42
|
}
|
|
47
43
|
|
|
44
|
+
const isApprovalFlowEnabled = this.getCommonService().getConfig('approvalFlow', []).includes(uid) ||
|
|
45
|
+
relatedEntity.requireCommentsApproval;
|
|
46
|
+
|
|
48
47
|
const linkToThread = !isNil(threadOf) ? !!await this.getCommonService().findOne({
|
|
49
48
|
id: threadOf,
|
|
50
|
-
related,
|
|
49
|
+
related: relation,
|
|
51
50
|
}) : true;
|
|
52
51
|
const validContext = isValidUserContext(user);
|
|
53
52
|
|
|
@@ -87,7 +86,8 @@ module.exports = ({ strapi }) => ({
|
|
|
87
86
|
throw new PluginError(400, 'Object: "author" is invalid. Check your payload');
|
|
88
87
|
}
|
|
89
88
|
|
|
90
|
-
if (
|
|
89
|
+
if (isApprovalFlowEnabled &&
|
|
90
|
+
(!isNil(data.approvalStatus) && (data.approvalStatus !== APPROVAL_STATUS.PENDING))) {
|
|
91
91
|
throw new PluginError(400, 'Invalid approval status');
|
|
92
92
|
}
|
|
93
93
|
|
|
@@ -95,7 +95,8 @@ module.exports = ({ strapi }) => ({
|
|
|
95
95
|
data: {
|
|
96
96
|
...rest,
|
|
97
97
|
...authorData,
|
|
98
|
-
related,
|
|
98
|
+
related: relation,
|
|
99
|
+
approvalStatus: isApprovalFlowEnabled ? APPROVAL_STATUS.PENDING : null,
|
|
99
100
|
}
|
|
100
101
|
});
|
|
101
102
|
return this.getCommonService().sanitizeCommentEntity(entity);
|
|
@@ -160,7 +161,7 @@ module.exports = ({ strapi }) => ({
|
|
|
160
161
|
try {
|
|
161
162
|
await this.sendAbuseReportEmail(entity.reason, entity.content); // Could also add some info about relation
|
|
162
163
|
} catch (err) {
|
|
163
|
-
|
|
164
|
+
return entity;
|
|
164
165
|
}
|
|
165
166
|
} else {
|
|
166
167
|
throw new PluginError(500, 'Report cannot be created');
|
|
@@ -177,10 +178,17 @@ module.exports = ({ strapi }) => ({
|
|
|
177
178
|
$or: [{ authorUser: authorId }, { authorId }],
|
|
178
179
|
});
|
|
179
180
|
if (!entity){
|
|
180
|
-
throw
|
|
181
|
+
throw new PluginError(404, 'Entity not exist');
|
|
181
182
|
}
|
|
183
|
+
|
|
182
184
|
return strapi.db.query(getModelUid('comment'))
|
|
183
|
-
.update({
|
|
185
|
+
.update({
|
|
186
|
+
where: {
|
|
187
|
+
id: commentId,
|
|
188
|
+
related: relationId
|
|
189
|
+
},
|
|
190
|
+
data: { removed: true }
|
|
191
|
+
})
|
|
184
192
|
.then(({ id }) => this.markAsRemovedNested(id, true))
|
|
185
193
|
.then(() => ({ id: commentId }));
|
|
186
194
|
},
|
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
const { isArray,
|
|
3
|
+
const { isArray, uniq, first } = require('lodash');
|
|
4
4
|
// const { sanitizeEntity } = require('strapi-utils');
|
|
5
5
|
const PluginError = require('./../utils/error');
|
|
6
6
|
const {
|
|
7
|
-
extractMeta,
|
|
8
7
|
getModelUid,
|
|
9
8
|
getRelatedGroups,
|
|
10
9
|
buildNestedStructure,
|
|
@@ -16,71 +15,31 @@ const {
|
|
|
16
15
|
*/
|
|
17
16
|
|
|
18
17
|
module.exports = ({ strapi }) => ({
|
|
19
|
-
getAssociationModel(ormModel, related) {
|
|
20
|
-
const relatedAssociation = ormModel.associations.find(_ => _.alias === 'related');
|
|
21
|
-
if (relatedAssociation) {
|
|
22
|
-
return relatedAssociation.related.find(rel => rel.collectionName === related);
|
|
23
|
-
}
|
|
24
|
-
return null;
|
|
25
|
-
},
|
|
26
|
-
|
|
27
|
-
getMorphModel() {
|
|
28
|
-
const ormModel = strapi.query(getModelUid('comment'));
|
|
29
|
-
return ormModel.model.morph;
|
|
30
|
-
},
|
|
31
|
-
|
|
32
|
-
isMongoDB(){
|
|
33
|
-
return strapi.query(getModelUid('comment'))?.model?.orm === 'mongoose';
|
|
34
|
-
},
|
|
35
|
-
|
|
36
|
-
getMorphData(query) {
|
|
37
|
-
return this
|
|
38
|
-
.getMorphModel()
|
|
39
|
-
.query(function () {
|
|
40
|
-
this.where(query);
|
|
41
|
-
})
|
|
42
|
-
.fetchAll()
|
|
43
|
-
.then((entities) => entities.map(entity => entity.toJSON()));
|
|
44
|
-
},
|
|
45
|
-
|
|
46
|
-
checkEntityRelation(uid, entityId) {
|
|
47
|
-
const result = parsedRelation.some(ref => {
|
|
48
|
-
const model = strapi.query(ref);
|
|
49
|
-
return model && model.associations.length &&
|
|
50
|
-
model.associations.some(_ => _.plugin === 'comments' && _.collection === 'comment');
|
|
51
|
-
});
|
|
52
|
-
if (!result) {
|
|
53
|
-
throw new PluginError(400, 'Comment not have relation to this type content type.');
|
|
54
|
-
}
|
|
55
|
-
},
|
|
56
18
|
|
|
57
|
-
getConfig(prop) {
|
|
19
|
+
getConfig(prop, defaultValue) {
|
|
58
20
|
let queryProp = prop;
|
|
59
21
|
if (prop && isArray(prop)) {
|
|
60
22
|
queryProp = prop.join('.');
|
|
61
23
|
}
|
|
62
|
-
return strapi.config.get(`plugin.comments${ queryProp ? '.' + queryProp : ''}`);
|
|
24
|
+
return strapi.config.get(`plugin.comments${ queryProp ? '.' + queryProp : ''}`) || defaultValue;
|
|
63
25
|
},
|
|
64
26
|
|
|
65
27
|
// Find comments in the flat structure
|
|
66
|
-
async findAllFlat(query,
|
|
67
|
-
const criteria = {
|
|
68
|
-
...query,
|
|
69
|
-
$or: [{ removed: { $null: true } }, { removed: false }],
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
if (isAdmin){
|
|
73
|
-
delete criteria.$or;
|
|
74
|
-
}
|
|
28
|
+
async findAllFlat({ query = {}, populate = {} }, relatedEntity = null) {
|
|
75
29
|
|
|
76
|
-
const
|
|
30
|
+
const defaultPopulate = {
|
|
31
|
+
authorUser: true,
|
|
32
|
+
};
|
|
77
33
|
|
|
78
34
|
const entries = await strapi.db.query(getModelUid('comment'))
|
|
79
35
|
.findMany({
|
|
80
36
|
where: {
|
|
81
|
-
...
|
|
37
|
+
...query,
|
|
38
|
+
},
|
|
39
|
+
populate: {
|
|
40
|
+
...defaultPopulate,
|
|
41
|
+
...populate,
|
|
82
42
|
},
|
|
83
|
-
populate,
|
|
84
43
|
});
|
|
85
44
|
|
|
86
45
|
const entriesWithThreads = await Promise.all(entries.map(async _ => {
|
|
@@ -93,16 +52,16 @@ module.exports = ({ strapi }) => ({
|
|
|
93
52
|
return { id: _.id, itemsInTread: count, firstThreadItemId: first(nestedEntries)?.id }
|
|
94
53
|
}));
|
|
95
54
|
|
|
96
|
-
const relatedEntities = relatedEntity !== null ? [relatedEntity] : await this.findRelatedEntitiesFor([...
|
|
55
|
+
const relatedEntities = relatedEntity !== null ? [relatedEntity] : await this.findRelatedEntitiesFor([...entries]);
|
|
97
56
|
const result = entries
|
|
98
57
|
.map(_ => {
|
|
99
58
|
const threadedItem = entriesWithThreads.find(item => item.id === _.id);
|
|
100
|
-
return
|
|
59
|
+
return this.sanitizeCommentEntity({
|
|
101
60
|
..._,
|
|
102
61
|
threadOf: query.threadOf || _.threadOf || null,
|
|
103
62
|
gotThread: (threadedItem?.itemsInTread || 0) > 0,
|
|
104
63
|
threadFirstItemId: threadedItem?.firstThreadItemId,
|
|
105
|
-
})
|
|
64
|
+
});
|
|
106
65
|
});
|
|
107
66
|
|
|
108
67
|
if (relatedEntities.filter(_ => _).length > 0) {
|
|
@@ -114,11 +73,11 @@ module.exports = ({ strapi }) => ({
|
|
|
114
73
|
// Find comments and create relations tree structure
|
|
115
74
|
async findAllInHierarchy ({
|
|
116
75
|
query,
|
|
76
|
+
populate = {},
|
|
117
77
|
startingFromId = null,
|
|
118
78
|
dropBlockedThreads = false,
|
|
119
|
-
isAdmin = false,
|
|
120
79
|
}, relatedEntity) {
|
|
121
|
-
const entities = await this.findAllFlat(query,
|
|
80
|
+
const entities = await this.findAllFlat({ query, populate }, relatedEntity);
|
|
122
81
|
return buildNestedStructure(entities, startingFromId, 'threadOf', dropBlockedThreads, false);
|
|
123
82
|
},
|
|
124
83
|
|
|
@@ -129,24 +88,36 @@ module.exports = ({ strapi }) => ({
|
|
|
129
88
|
where: criteria
|
|
130
89
|
}, ['related', 'reports']);
|
|
131
90
|
if (!entity){
|
|
132
|
-
throw
|
|
91
|
+
throw new PluginError(404, 'Not found');
|
|
133
92
|
}
|
|
134
93
|
return filterOurResolvedReports(this.sanitizeCommentEntity(entity));
|
|
135
94
|
},
|
|
136
95
|
|
|
137
96
|
// Find all related entiries
|
|
138
97
|
async findRelatedEntitiesFor(entities = []) {
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
98
|
+
const data = entities.reduce((acc, cur) => {
|
|
99
|
+
const [relatedUid, relatedStringId] = getRelatedGroups(cur.related);
|
|
100
|
+
return {
|
|
101
|
+
...acc,
|
|
102
|
+
[relatedUid]: [...(acc[relatedUid] || []), parseInt(relatedStringId, 10)]
|
|
103
|
+
};
|
|
104
|
+
},
|
|
105
|
+
{}
|
|
106
|
+
);
|
|
107
|
+
return Promise.all(
|
|
108
|
+
Object.entries(data)
|
|
109
|
+
.map(async ([relatedUid, relatedStringIds]) =>
|
|
110
|
+
strapi.db.query(relatedUid).findMany({
|
|
111
|
+
where: { id: Array.from(new Set(relatedStringIds)) }
|
|
112
|
+
}).then(relatedEntities => relatedEntities.map(_ =>
|
|
113
|
+
({
|
|
114
|
+
..._,
|
|
115
|
+
uid: relatedUid,
|
|
116
|
+
})
|
|
117
|
+
))
|
|
118
|
+
)
|
|
119
|
+
)
|
|
120
|
+
.then(result => result.flat(2));
|
|
150
121
|
},
|
|
151
122
|
|
|
152
123
|
// Merge related entity with comment
|
|
@@ -34,9 +34,14 @@ const buildNestedStructure = (
|
|
|
34
34
|
module.exports = {
|
|
35
35
|
isEqualEntity: (existing, data, user) => {
|
|
36
36
|
const { authorUser, authorId } = existing;
|
|
37
|
-
console.log('data', data);
|
|
38
|
-
console.log(existing);
|
|
39
37
|
const { author } = data;
|
|
38
|
+
|
|
39
|
+
// Disallow approval status change by Client
|
|
40
|
+
if (data.approvalStatus && (existing.approvalStatus !== data.approvalStatus)) {
|
|
41
|
+
return false;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
// Make sure that author is exact the same
|
|
40
45
|
if (authorUser) {
|
|
41
46
|
const existingUserId = authorUser?.id || authorUser;
|
|
42
47
|
const receivedUserId = user?.id || author;
|
|
@@ -45,18 +50,6 @@ module.exports = {
|
|
|
45
50
|
return authorId === author?.id;
|
|
46
51
|
},
|
|
47
52
|
|
|
48
|
-
extractMeta: plugins => {
|
|
49
|
-
const { comments: plugin } = plugins;
|
|
50
|
-
const { comments: service } = plugin.services;
|
|
51
|
-
const { comment: model} = plugin.models;
|
|
52
|
-
return {
|
|
53
|
-
model,
|
|
54
|
-
service,
|
|
55
|
-
plugin,
|
|
56
|
-
pluginName: plugin.package.strapi.name.toLowerCase()
|
|
57
|
-
};
|
|
58
|
-
},
|
|
59
|
-
|
|
60
53
|
getRelatedGroups: related => related.split(REGEX.relatedUid).filter(s => s && s.length > 0),
|
|
61
54
|
|
|
62
55
|
getModelUid: name => {
|
|
@@ -5,9 +5,9 @@ const APPROVAL_STATUS = {
|
|
|
5
5
|
};
|
|
6
6
|
|
|
7
7
|
const REGEX = {
|
|
8
|
-
uid:
|
|
9
|
-
relatedUid:
|
|
10
|
-
email:
|
|
8
|
+
uid: /^(?<type>[a-z0-9-]+)\:{2}(?<api>[a-z0-9-]+)\.{1}(?<contentType>[a-z0-9-]+)$/i,
|
|
9
|
+
relatedUid: /^(?<uid>[a-z0-9-]+\:{2}[a-z0-9-]+\.[a-z0-9-]+)\:{1}(?<id>[a-z0-9-]+)$/i,
|
|
10
|
+
email: /\S+@\S+\.\S+/,
|
|
11
11
|
};
|
|
12
12
|
|
|
13
13
|
module.exports = {
|
|
@@ -1,53 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
*
|
|
3
|
-
* Entity Details
|
|
4
|
-
*
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
|
-
import React from 'react';
|
|
8
|
-
import PropTypes from 'prop-types';
|
|
9
|
-
import { isNil } from 'lodash';
|
|
10
|
-
import { Box } from '@strapi/design-system/Box';
|
|
11
|
-
import { Divider } from '@strapi/design-system/Divider';
|
|
12
|
-
import { Flex } from '@strapi/design-system/Flex';
|
|
13
|
-
import { Stack } from '@strapi/design-system/Stack';
|
|
14
|
-
import { Typography } from '@strapi/design-system/Typography';
|
|
15
|
-
import { getMessage } from '../../utils';
|
|
16
|
-
|
|
17
|
-
const EntityDetails = ({ data = {}, schema = {} }) => {
|
|
18
|
-
const { attributes = {} } = schema;
|
|
19
|
-
const keys = Object.keys(attributes);
|
|
20
|
-
|
|
21
|
-
if (keys.length === 0) {
|
|
22
|
-
return null;
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
const itemKeys = keys.filter(_ => (attributes[_].type === 'string') && !isNil(data[_]));
|
|
26
|
-
|
|
27
|
-
return (<Box padding={4}>
|
|
28
|
-
<Typography variant="sigma" textColor="neutral600" id="entity-details">
|
|
29
|
-
{ getMessage('page.details.panel.entity', 'Details') }
|
|
30
|
-
</Typography>
|
|
31
|
-
<Box paddingTop={2} paddingBottom={6}>
|
|
32
|
-
<Divider />
|
|
33
|
-
</Box>
|
|
34
|
-
<Stack size={itemKeys.length}>
|
|
35
|
-
{ itemKeys.map(_ =>
|
|
36
|
-
(<Flex justifyContent="space-between">
|
|
37
|
-
<Typography fontWeight="bold">
|
|
38
|
-
{ _ }
|
|
39
|
-
</Typography>
|
|
40
|
-
<Typography>{ data[_] }</Typography>
|
|
41
|
-
</Flex>))
|
|
42
|
-
}
|
|
43
|
-
</Stack>
|
|
44
|
-
</Box>);
|
|
45
|
-
};
|
|
46
|
-
|
|
47
|
-
EntityDetails.propTypes = {
|
|
48
|
-
data: PropTypes.object.isRequired,
|
|
49
|
-
schema: PropTypes.object.isRequired,
|
|
50
|
-
};
|
|
51
|
-
|
|
52
|
-
export default EntityDetails;
|
|
53
|
-
|