strapi-plugin-comments 2.0.0-beta.2 → 2.0.0-beta.6
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 +31 -5
- package/admin/src/components/DiscussionThread/index.js +10 -2
- package/admin/src/components/DiscussionThreadItem/index.js +25 -6
- package/admin/src/components/DiscussionThreadItem/styles.js +1 -0
- package/admin/src/components/DiscussionThreadItemActions/index.js +69 -56
- package/admin/src/components/DiscussionThreadItemActions/styles.js +0 -4
- package/admin/src/components/DiscussionThreadItemApprovalFlowActions/index.js +81 -0
- package/admin/src/components/DiscussionThreadItemApprovalFlowActions/styles.js +6 -0
- package/admin/src/components/DiscussionThreadItemWarnings/index.js +26 -16
- package/admin/src/components/Nav/index.js +5 -1
- package/admin/src/components/ReportsReviewModal/index.js +5 -2
- package/admin/src/components/ReportsReviewTable/index.js +69 -57
- 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 +1 -1
- package/admin/src/pages/App/index.js +20 -9
- package/admin/src/pages/App/reducer/index.js +0 -1
- package/admin/src/pages/App/reducer/selectors.js +1 -1
- package/admin/src/pages/App/utils/api.js +2 -10
- package/admin/src/pages/Details/components/DetailsEntity/index.js +66 -0
- package/admin/src/pages/Details/components/DetailsFilters/index.js +37 -0
- package/admin/src/pages/Details/components/DetailsFilters/styles.js +8 -0
- package/admin/src/pages/Details/index.js +75 -42
- package/admin/src/pages/Discover/components/DiscoverTableRow/index.js +210 -0
- package/admin/src/pages/Discover/components/DiscoverTableRow/styles.js +8 -0
- package/admin/src/pages/Discover/index.js +69 -102
- package/admin/src/pages/Discover/utils/api.js +2 -8
- package/admin/src/pages/{Details/utils → utils}/api.js +15 -3
- package/admin/src/permissions.js +10 -8
- package/admin/src/translations/en.json +17 -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/permissions.js +19 -0
- package/server/bootstrap.js +38 -2
- package/server/config/index.js +4 -3
- package/server/controllers/admin.js +3 -3
- package/server/controllers/client.js +11 -2
- package/server/services/admin.js +69 -13
- package/server/services/client.js +23 -15
- package/server/services/common.js +40 -69
- package/server/services/utils/functions.js +7 -14
- package/server/utils/constants.js +3 -3
- package/strapi-server.js +33 -0
- package/admin/src/components/EntityDetails/index.js +0 -53
package/admin/src/utils/index.js
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
export { default as axiosInstance } from './axiosInstance';
|
|
2
|
-
export { default as getApiURL } from './
|
|
2
|
+
export { default as getApiURL } from './getApiUrl';
|
|
3
3
|
export { default as getUrl } from './getUrl';
|
|
4
4
|
export { default as getMessage } from './getMessage';
|
|
5
5
|
export { default as handleAPIError } from './handleAPIError';
|
|
6
|
-
export { default as getRelatedGroups } from './getRelatedGroups';
|
|
6
|
+
export { default as getRelatedGroups } from './getRelatedGroups';
|
|
7
|
+
export { default as resolveCommentStatus } from './resolveCommentStatus';
|
|
8
|
+
export { default as resolveCommentStatusColor } from './resolveCommentStatusColor';
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { first } from 'lodash';
|
|
2
|
+
|
|
3
|
+
const renderEntryTitle = (entry, config = {}) => {
|
|
4
|
+
const { entryLabel } = config;
|
|
5
|
+
const rule = entry.uid in entryLabel ? entryLabel[entry.uid] : entryLabel['*'];
|
|
6
|
+
return first(
|
|
7
|
+
Object.keys(entry)
|
|
8
|
+
.filter(_ => (rule === _) || rule.includes(_))
|
|
9
|
+
.map(_ => entry[_])
|
|
10
|
+
.filter(_ => _)
|
|
11
|
+
);
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
export default renderEntryTitle;
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { isNil } from 'lodash';
|
|
2
|
+
import { COMMENT_STATUS } from './constants';
|
|
3
|
+
|
|
4
|
+
const resolveCommentStatus = ({ removed, blocked, blockedThread, approvalStatus, reviewFlowEnabled }) => {
|
|
5
|
+
const gotApprovalFlow = !isNil(approvalStatus);
|
|
6
|
+
|
|
7
|
+
if (reviewFlowEnabled) {
|
|
8
|
+
return COMMENT_STATUS.TO_REVIEW;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
if (removed) {
|
|
12
|
+
return COMMENT_STATUS.REMOVED;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
if (blocked || blockedThread) {
|
|
16
|
+
return COMMENT_STATUS.BLOCKED;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
if (gotApprovalFlow) {
|
|
20
|
+
const status = approvalStatus.toUpperCase();
|
|
21
|
+
if (Object.keys(COMMENT_STATUS).includes(status)) {
|
|
22
|
+
return status;
|
|
23
|
+
}
|
|
24
|
+
return COMMENT_STATUS.UNKNOWN;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
return COMMENT_STATUS.OPEN;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export default resolveCommentStatus;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { isNil } from 'lodash';
|
|
2
|
+
import { COMMENT_STATUS } from './constants';
|
|
3
|
+
|
|
4
|
+
const resolveCommentStatusColor = (status) => {
|
|
5
|
+
if (Object.keys(COMMENT_STATUS).includes(status)) {
|
|
6
|
+
switch (status) {
|
|
7
|
+
case COMMENT_STATUS.REMOVED:
|
|
8
|
+
return 'secondary';
|
|
9
|
+
case COMMENT_STATUS.TO_REVIEW:
|
|
10
|
+
case COMMENT_STATUS.REJECTED:
|
|
11
|
+
return 'warning';
|
|
12
|
+
case COMMENT_STATUS.BLOCKED:
|
|
13
|
+
return 'danger';
|
|
14
|
+
case COMMENT_STATUS.OPEN:
|
|
15
|
+
case COMMENT_STATUS.APPROVED:
|
|
16
|
+
return 'success';
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
return 'secondary';
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export default resolveCommentStatusColor;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "strapi-plugin-comments",
|
|
3
|
-
"version": "2.0.0-beta.
|
|
3
|
+
"version": "2.0.0-beta.6",
|
|
4
4
|
"description": "Strapi - Comments plugin",
|
|
5
5
|
"strapi": {
|
|
6
6
|
"name": "comments",
|
|
@@ -15,6 +15,7 @@
|
|
|
15
15
|
"url": "https://github.com/VirtusLab-Open-Source/strapi-plugin-comments"
|
|
16
16
|
},
|
|
17
17
|
"dependencies": {
|
|
18
|
+
"@strapi/utils": "^4.0.5",
|
|
18
19
|
"bad-words": "^3.0.4"
|
|
19
20
|
},
|
|
20
21
|
"devDependencies": {
|
|
@@ -23,6 +24,9 @@
|
|
|
23
24
|
"jest-cli": "^26.0.1",
|
|
24
25
|
"jest-styled-components": "^7.0.2"
|
|
25
26
|
},
|
|
27
|
+
"peerDependencies": {
|
|
28
|
+
"@strapi/strapi": "4.x"
|
|
29
|
+
},
|
|
26
30
|
"author": {
|
|
27
31
|
"name": "VirtusLab // Mateusz Ziarko",
|
|
28
32
|
"email": "mziarko@virtuslab.com",
|
|
@@ -41,8 +45,8 @@
|
|
|
41
45
|
}
|
|
42
46
|
],
|
|
43
47
|
"engines": {
|
|
44
|
-
"node": ">=
|
|
45
|
-
"npm": ">=
|
|
48
|
+
"node": ">=14.x.x <=17.x.x",
|
|
49
|
+
"npm": ">=7.x.x"
|
|
46
50
|
},
|
|
47
51
|
"keywords": ["strapi", "plugin", "comments"],
|
|
48
52
|
"license": "MIT"
|
package/permissions.js
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
module.exports = {
|
|
4
|
+
render: function(uid) {
|
|
5
|
+
return `plugin::comments.${uid}`;
|
|
6
|
+
},
|
|
7
|
+
comments: {
|
|
8
|
+
read: 'read',
|
|
9
|
+
moderate: 'moderate',
|
|
10
|
+
},
|
|
11
|
+
reports: {
|
|
12
|
+
read: 'reports.read',
|
|
13
|
+
action: 'reports.action',
|
|
14
|
+
},
|
|
15
|
+
settings: {
|
|
16
|
+
read: 'settings.read',
|
|
17
|
+
change: 'settings.change',
|
|
18
|
+
},
|
|
19
|
+
};
|
package/server/bootstrap.js
CHANGED
|
@@ -1,5 +1,41 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
3
|
+
const permissions = require('./../permissions');
|
|
4
|
+
|
|
5
|
+
module.exports = async ({ strapi }) => {
|
|
6
|
+
// Check if the plugin users-permissions is installed because the navigation needs it
|
|
7
|
+
if (Object.keys(strapi.plugins).indexOf("users-permissions") === -1) {
|
|
8
|
+
throw new Error(
|
|
9
|
+
"In order to make the comments plugin work the users-permissions plugin is required",
|
|
10
|
+
);
|
|
11
|
+
}
|
|
12
|
+
// Add permissions
|
|
13
|
+
const actions = [
|
|
14
|
+
{
|
|
15
|
+
section: "plugins",
|
|
16
|
+
displayName: "Comments: Read",
|
|
17
|
+
uid: permissions.comments.read,
|
|
18
|
+
pluginName: "comments",
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
section: "plugins",
|
|
22
|
+
displayName: "Comments: Moderate",
|
|
23
|
+
uid: permissions.comments.moderate,
|
|
24
|
+
pluginName: "comments",
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
section: "plugins",
|
|
28
|
+
displayName: "Reports: Read",
|
|
29
|
+
uid: permissions.reports.read,
|
|
30
|
+
pluginName: "comments",
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
section: "plugins",
|
|
34
|
+
displayName: "Reports: Moderate",
|
|
35
|
+
uid: permissions.reports.action,
|
|
36
|
+
pluginName: "comments",
|
|
37
|
+
},
|
|
38
|
+
];
|
|
39
|
+
|
|
40
|
+
await strapi.admin.services.permission.actionProvider.registerMany(actions);
|
|
5
41
|
};
|
package/server/config/index.js
CHANGED
|
@@ -16,11 +16,11 @@ module.exports = {
|
|
|
16
16
|
},
|
|
17
17
|
|
|
18
18
|
async findOne(ctx) {
|
|
19
|
-
const { params = {} } = ctx;
|
|
19
|
+
const { params = {}, query } = ctx;
|
|
20
20
|
const { id } = parseParams(params);
|
|
21
21
|
try {
|
|
22
22
|
return await this.getService()
|
|
23
|
-
.findOneAndThread(id);
|
|
23
|
+
.findOneAndThread(id, query);
|
|
24
24
|
} catch (e) {
|
|
25
25
|
throwError(ctx, e);
|
|
26
26
|
}
|
|
@@ -101,7 +101,7 @@ module.exports = {
|
|
|
101
101
|
}
|
|
102
102
|
},
|
|
103
103
|
|
|
104
|
-
async config() {
|
|
104
|
+
async config(ctx) {
|
|
105
105
|
try {
|
|
106
106
|
return await this.getService().config();
|
|
107
107
|
} catch (e) {
|
|
@@ -16,8 +16,14 @@ module.exports = {
|
|
|
16
16
|
try {
|
|
17
17
|
return this.getService('common')
|
|
18
18
|
.findAllFlat({
|
|
19
|
-
|
|
20
|
-
|
|
19
|
+
query: {
|
|
20
|
+
...query,
|
|
21
|
+
$or: [{ removed: { $null: true } }, { removed: false }],
|
|
22
|
+
related: relation,
|
|
23
|
+
},
|
|
24
|
+
populate: {
|
|
25
|
+
threadOf: true,
|
|
26
|
+
},
|
|
21
27
|
});
|
|
22
28
|
} catch (e) {
|
|
23
29
|
throwError(ctx, e);
|
|
@@ -34,6 +40,9 @@ module.exports = {
|
|
|
34
40
|
...query,
|
|
35
41
|
related: relation,
|
|
36
42
|
},
|
|
43
|
+
populate: {
|
|
44
|
+
threadOf: true,
|
|
45
|
+
},
|
|
37
46
|
dropBlockedThreads: true,
|
|
38
47
|
});
|
|
39
48
|
} catch (e) {
|
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
|
|
|
@@ -25,8 +23,14 @@ const { APPROVAL_STATUS, REGEX } = require('./../utils/constants')
|
|
|
25
23
|
// Config
|
|
26
24
|
async config() {
|
|
27
25
|
const entryLabel = this.getCommonService().getConfig('entryLabel');
|
|
26
|
+
const approvalFlow = this.getCommonService().getConfig('approvalFlow');
|
|
28
27
|
return {
|
|
29
28
|
entryLabel,
|
|
29
|
+
approvalFlow,
|
|
30
|
+
regex: Object.keys(REGEX).reduce((prev, curr) => ({
|
|
31
|
+
...prev,
|
|
32
|
+
[curr]: REGEX[curr].toString(),
|
|
33
|
+
}), {}),
|
|
30
34
|
};
|
|
31
35
|
},
|
|
32
36
|
|
|
@@ -34,10 +38,18 @@ const { APPROVAL_STATUS, REGEX } = require('./../utils/constants')
|
|
|
34
38
|
async findAll({ related, entity, ...query }) {
|
|
35
39
|
const { _q, orderBy, pageSize = 10, page = 1, filters, ...rest } = parseParams(query);
|
|
36
40
|
|
|
41
|
+
const defaultWhere = {
|
|
42
|
+
$or: [
|
|
43
|
+
{ removed: false },
|
|
44
|
+
{ removed: null },
|
|
45
|
+
],
|
|
46
|
+
};
|
|
47
|
+
|
|
37
48
|
let params = {
|
|
38
49
|
where: !isEmpty(filters) ? {
|
|
50
|
+
...defaultWhere,
|
|
39
51
|
...filters,
|
|
40
|
-
} :
|
|
52
|
+
} : { ...defaultWhere },
|
|
41
53
|
offset: (page - 1)*pageSize,
|
|
42
54
|
limit: pageSize,
|
|
43
55
|
orderBy: orderBy || [{ createdAt: 'desc' }],
|
|
@@ -55,7 +67,18 @@ const { APPROVAL_STATUS, REGEX } = require('./../utils/constants')
|
|
|
55
67
|
}
|
|
56
68
|
|
|
57
69
|
const entities = await strapi.db.query(getModelUid('comment'))
|
|
58
|
-
.findMany(
|
|
70
|
+
.findMany({
|
|
71
|
+
...params,
|
|
72
|
+
populate: {
|
|
73
|
+
authorUser: true,
|
|
74
|
+
threadOf: true,
|
|
75
|
+
reports: {
|
|
76
|
+
where: {
|
|
77
|
+
resolved: false
|
|
78
|
+
},
|
|
79
|
+
},
|
|
80
|
+
},
|
|
81
|
+
});
|
|
59
82
|
const total = await strapi.db.query(getModelUid('comment'))
|
|
60
83
|
.count({
|
|
61
84
|
where: params.where,
|
|
@@ -65,24 +88,48 @@ const { APPROVAL_STATUS, REGEX } = require('./../utils/constants')
|
|
|
65
88
|
.map(_ => filterOurResolvedReports(this.getCommonService().sanitizeCommentEntity(_)))
|
|
66
89
|
.map(_ => this.getCommonService().mergeRelatedEntityTo(_, relatedEntities));
|
|
67
90
|
|
|
91
|
+
const pageCount = Math.floor(total / pageSize);
|
|
68
92
|
return {
|
|
69
93
|
result,
|
|
70
94
|
pagination: {
|
|
71
95
|
page: page,
|
|
72
96
|
pageSize: pageSize,
|
|
73
|
-
pageCount:
|
|
97
|
+
pageCount: total % pageSize === 0 ? pageCount : pageCount + 1,
|
|
74
98
|
total,
|
|
75
99
|
},
|
|
76
100
|
};
|
|
77
101
|
},
|
|
78
102
|
|
|
79
103
|
// Find single comment
|
|
80
|
-
async findOneAndThread(id) {
|
|
104
|
+
async findOneAndThread(id, { removed, ...query }) {
|
|
105
|
+
const defaultWhere = !removed ? {
|
|
106
|
+
$or: [
|
|
107
|
+
{ removed: false },
|
|
108
|
+
{ removed: null },
|
|
109
|
+
],
|
|
110
|
+
} : {};
|
|
111
|
+
|
|
112
|
+
const reportsPopulation = {
|
|
113
|
+
reports: {
|
|
114
|
+
where: {
|
|
115
|
+
resolved: false,
|
|
116
|
+
},
|
|
117
|
+
}
|
|
118
|
+
};
|
|
119
|
+
|
|
81
120
|
const entity = await strapi.db.query(getModelUid('comment')).findOne({
|
|
82
121
|
where: {
|
|
83
|
-
id
|
|
122
|
+
id,
|
|
123
|
+
},
|
|
124
|
+
populate: {
|
|
125
|
+
authorUser: true,
|
|
126
|
+
threadOf: {
|
|
127
|
+
populate: {
|
|
128
|
+
...reportsPopulation
|
|
129
|
+
},
|
|
130
|
+
},
|
|
131
|
+
...reportsPopulation,
|
|
84
132
|
},
|
|
85
|
-
populate: ['threadOf', 'threadOf.reports', 'authorUser', 'reports']
|
|
86
133
|
});
|
|
87
134
|
|
|
88
135
|
if (!entity){
|
|
@@ -106,22 +153,27 @@ const { APPROVAL_STATUS, REGEX } = require('./../utils/constants')
|
|
|
106
153
|
const entitiesOnSameLevel = await this.getCommonService()
|
|
107
154
|
.findAllInHierarchy({
|
|
108
155
|
query: {
|
|
156
|
+
...defaultWhere,
|
|
157
|
+
...query,
|
|
109
158
|
threadOf: levelThreadId,
|
|
110
159
|
related: entity.related,
|
|
111
160
|
},
|
|
161
|
+
populate: {
|
|
162
|
+
...reportsPopulation,
|
|
163
|
+
},
|
|
112
164
|
startingFromId: levelThreadId,
|
|
113
165
|
isAdmin: true
|
|
114
166
|
}, false);
|
|
115
167
|
|
|
116
|
-
const selectedEntity =
|
|
168
|
+
const selectedEntity = this.getCommonService().sanitizeCommentEntity(entity);
|
|
117
169
|
|
|
118
170
|
return {
|
|
119
171
|
entity: relatedEntity,
|
|
120
172
|
selected: {
|
|
121
173
|
...selectedEntity,
|
|
122
|
-
threadOf: selectedEntity.threadOf ?
|
|
174
|
+
threadOf: selectedEntity.threadOf ? selectedEntity.threadOf : null,
|
|
123
175
|
},
|
|
124
|
-
level: entitiesOnSameLevel
|
|
176
|
+
level: entitiesOnSameLevel,
|
|
125
177
|
};
|
|
126
178
|
},
|
|
127
179
|
|
|
@@ -138,9 +190,13 @@ const { APPROVAL_STATUS, REGEX } = require('./../utils/constants')
|
|
|
138
190
|
// Block / Unblock a comment thread
|
|
139
191
|
async blockCommentThread(id, forceStatus) {
|
|
140
192
|
const existingEntity = await this.getCommonService().findOne({ id });
|
|
193
|
+
const status = !isNil(forceStatus) ? forceStatus : !existingEntity.blockedThread;
|
|
141
194
|
const changedEntity = await strapi.db.query(getModelUid('comment')).update({
|
|
142
195
|
where: { id },
|
|
143
|
-
data: {
|
|
196
|
+
data: {
|
|
197
|
+
blocked: status,
|
|
198
|
+
blockedThread: status,
|
|
199
|
+
},
|
|
144
200
|
});
|
|
145
201
|
await this.blockNestedThreads(id, changedEntity.blockedThread);
|
|
146
202
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
const config = require('
|
|
3
|
+
const config = require('../config');
|
|
4
4
|
const { getPluginService } = require('./../utils/functions');
|
|
5
5
|
const { isNil, isEmpty } = require('lodash');
|
|
6
6
|
const PluginError = require('./../utils/error');
|
|
@@ -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 _ => {
|
|
@@ -97,12 +56,12 @@ module.exports = ({ strapi }) => ({
|
|
|
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
|