strapi-plugin-comments 2.0.0-rc.2 → 2.0.3
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/.husky/pre-commit +4 -0
- package/README.md +53 -9
- package/__mocks__/initSetup.js +82 -0
- package/admin/src/components/ActionButton/styles.js +10 -0
- package/admin/src/components/DiscussionThread/index.js +2 -6
- package/admin/src/components/DiscussionThreadItem/index.js +25 -68
- package/admin/src/components/DiscussionThreadItem/styles.js +4 -79
- package/admin/src/components/DiscussionThreadItemActions/index.js +82 -40
- package/admin/src/components/DiscussionThreadItemActions/styles.js +1 -12
- package/admin/src/components/DiscussionThreadItemApprovalFlowActions/index.js +2 -3
- package/admin/src/components/DiscussionThreadItemFooter/index.js +47 -0
- package/admin/src/components/DiscussionThreadItemFooter/styles.js +13 -0
- package/admin/src/components/DiscussionThreadItemReviewAction/index.js +131 -0
- package/admin/src/components/IconButton/styles.js +14 -0
- package/admin/src/components/ReportsReviewModal/index.js +1 -1
- package/admin/src/components/ReportsReviewTable/index.js +12 -6
- package/admin/src/components/StatusBadge/index.js +17 -0
- package/admin/src/components/StatusBadge/styles.js +17 -0
- package/admin/src/hooks/useConfig.js +43 -0
- package/admin/src/index.js +31 -2
- package/admin/src/pages/Details/components/DetailsEntity/index.js +42 -24
- package/admin/src/pages/Details/components/DetailsFilters/index.js +8 -10
- package/admin/src/pages/Details/index.js +11 -17
- package/admin/src/pages/Discover/components/DiscoverTableRow/index.js +30 -67
- package/admin/src/pages/Settings/index.js +342 -0
- package/admin/src/pages/Settings/utils/api.js +50 -0
- package/admin/src/permissions.js +3 -0
- package/admin/src/translations/en.json +50 -16
- package/admin/src/utils/index.js +2 -1
- package/admin/src/utils/parseRegExp.js +10 -0
- package/admin/src/utils/resolveCommentStatus.js +4 -4
- package/package.json +12 -7
- package/server/bootstrap.js +24 -0
- package/server/config/index.js +1 -0
- package/server/controllers/admin.js +33 -8
- package/server/controllers/client.js +4 -4
- package/server/controllers/utils/__tests__/functions.test.js +2 -2
- package/server/controllers/utils/parsers.js +3 -1
- package/server/graphql/index.js +7 -8
- package/server/graphql/queries/findAllFlat.js +4 -2
- package/server/graphql/queries/findAllInHierarchy.js +3 -3
- package/server/graphql/resolvers-config.js +2 -4
- package/server/graphql/types/comment-nested.js +1 -0
- package/server/graphql/types/report-reason.js +10 -10
- package/server/register.js +1 -3
- package/server/routes/admin.js +24 -0
- package/server/services/__tests__/common.test.js +246 -0
- package/server/services/admin.js +60 -6
- package/server/services/client.js +13 -9
- package/server/services/common.js +86 -11
- package/server/services/utils/__tests__/functions.test.js +20 -73
- package/server/services/utils/functions.js +9 -17
- package/server/utils/__tests__/functions.test.js +17 -0
- package/server/utils/constants.js +10 -0
- package/strapi-server.js +12 -5
- package/.circleci/config.yml +0 -48
- package/.eslintrc +0 -35
- package/.github/pull_request_template.md +0 -13
- package/.nvmrc +0 -1
- package/admin/src/components/DiscussionThreadItemMeta/index.js +0 -42
- package/admin/src/components/DiscussionThreadItemWarnings/index.js +0 -147
- package/admin/src/components/DiscussionThreadItemWarnings/styles.js +0 -7
- package/codecov.yml +0 -4
- package/public/assets/logo.png +0 -0
- package/public/assets/preview.png +0 -0
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
const
|
|
4
|
-
|
|
3
|
+
const BadWordsFilter = require('bad-words');
|
|
4
|
+
const { isArray, isNumber, isObject, isNil, isString, first, parseInt, set, get } = require('lodash');
|
|
5
|
+
const { REGEX, CONFIG_PARAMS } = require('../utils/constants');
|
|
5
6
|
const PluginError = require('./../utils/error');
|
|
6
7
|
const {
|
|
7
8
|
getModelUid,
|
|
@@ -9,6 +10,7 @@ const {
|
|
|
9
10
|
buildNestedStructure,
|
|
10
11
|
filterOurResolvedReports,
|
|
11
12
|
buildAuthorModel,
|
|
13
|
+
buildConfigQueryProp,
|
|
12
14
|
} = require('./utils/functions');
|
|
13
15
|
|
|
14
16
|
/**
|
|
@@ -17,21 +19,64 @@ const {
|
|
|
17
19
|
|
|
18
20
|
module.exports = ({ strapi }) => ({
|
|
19
21
|
|
|
20
|
-
getConfig(prop, defaultValue) {
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
22
|
+
async getConfig(prop, defaultValue, useLocal = false) {
|
|
23
|
+
const queryProp = buildConfigQueryProp(prop);
|
|
24
|
+
const pluginStore = await this.getPluginStore();
|
|
25
|
+
const config = await pluginStore.get({ key: 'config' });
|
|
26
|
+
|
|
27
|
+
let result;
|
|
28
|
+
if (config && !useLocal) {
|
|
29
|
+
result = queryProp ? get(config, queryProp) : config;;
|
|
30
|
+
} else {
|
|
31
|
+
result = this.getLocalConfig(queryProp, defaultValue);
|
|
24
32
|
}
|
|
25
|
-
return
|
|
33
|
+
return isNil(result) ? defaultValue : result;
|
|
34
|
+
},
|
|
35
|
+
|
|
36
|
+
async getPluginStore() {
|
|
37
|
+
return strapi.store({ type: 'plugin', name: 'comments' });
|
|
38
|
+
},
|
|
39
|
+
|
|
40
|
+
getLocalConfig(prop, defaultValue) {
|
|
41
|
+
const queryProp = buildConfigQueryProp(prop);
|
|
42
|
+
const result = strapi.config.get(`plugin.comments${ queryProp ? '.' + queryProp : ''}`);
|
|
43
|
+
return isNil(result) ? defaultValue : result;
|
|
26
44
|
},
|
|
27
45
|
|
|
28
46
|
// Find comments in the flat structure
|
|
29
|
-
async findAllFlat({
|
|
47
|
+
async findAllFlat({
|
|
48
|
+
query = {},
|
|
49
|
+
populate = {},
|
|
50
|
+
sort,
|
|
51
|
+
pagination }, relatedEntity = null) {
|
|
30
52
|
|
|
31
53
|
const defaultPopulate = {
|
|
32
54
|
authorUser: true,
|
|
33
55
|
};
|
|
34
56
|
|
|
57
|
+
let queryExtension = {};
|
|
58
|
+
|
|
59
|
+
if (sort && (isString(sort) || isArray(sort))) {
|
|
60
|
+
queryExtension = {
|
|
61
|
+
...queryExtension,
|
|
62
|
+
orderBy: (isString(sort) ? [sort] : sort)
|
|
63
|
+
.map(_ => REGEX.sorting.test(_) ? _ : `${_}:asc`)
|
|
64
|
+
.reduce((prev, curr) => {
|
|
65
|
+
const [type = 'asc', ...parts] = curr.split(':').reverse();
|
|
66
|
+
return { ...set(prev, parts.reverse().join('.'), type) };
|
|
67
|
+
}, {})
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
if (pagination && isObject(pagination)) {
|
|
72
|
+
const { page = 1, pageSize = 10 } = pagination;
|
|
73
|
+
queryExtension = {
|
|
74
|
+
...queryExtension,
|
|
75
|
+
offset: (page - 1) * pageSize,
|
|
76
|
+
limit: pageSize,
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
|
|
35
80
|
const entries = await strapi.db.query(getModelUid('comment'))
|
|
36
81
|
.findMany({
|
|
37
82
|
where: {
|
|
@@ -41,6 +86,7 @@ module.exports = ({ strapi }) => ({
|
|
|
41
86
|
...defaultPopulate,
|
|
42
87
|
...populate,
|
|
43
88
|
},
|
|
89
|
+
...queryExtension,
|
|
44
90
|
});
|
|
45
91
|
|
|
46
92
|
const entriesWithThreads = await Promise.all(entries.map(async _ => {
|
|
@@ -75,10 +121,11 @@ module.exports = ({ strapi }) => ({
|
|
|
75
121
|
async findAllInHierarchy ({
|
|
76
122
|
query,
|
|
77
123
|
populate = {},
|
|
124
|
+
sort,
|
|
78
125
|
startingFromId = null,
|
|
79
126
|
dropBlockedThreads = false,
|
|
80
127
|
}, relatedEntity) {
|
|
81
|
-
const entities = await this.findAllFlat({ query, populate }, relatedEntity);
|
|
128
|
+
const entities = await this.findAllFlat({ query, populate, sort }, relatedEntity);
|
|
82
129
|
return buildNestedStructure(entities, startingFromId, 'threadOf', dropBlockedThreads, false);
|
|
83
130
|
},
|
|
84
131
|
|
|
@@ -93,7 +140,7 @@ module.exports = ({ strapi }) => ({
|
|
|
93
140
|
},
|
|
94
141
|
});
|
|
95
142
|
if (!entity){
|
|
96
|
-
throw new PluginError(404, '
|
|
143
|
+
throw new PluginError(404, 'Comment does not exist. Check your payload please.');
|
|
97
144
|
}
|
|
98
145
|
return filterOurResolvedReports(this.sanitizeCommentEntity(entity));
|
|
99
146
|
},
|
|
@@ -115,7 +162,7 @@ module.exports = ({ strapi }) => ({
|
|
|
115
162
|
Object.entries(data)
|
|
116
163
|
.map(async ([relatedUid, relatedStringIds]) =>
|
|
117
164
|
strapi.db.query(relatedUid).findMany({
|
|
118
|
-
where: { id: Array.from(new Set(relatedStringIds)) }
|
|
165
|
+
where: { id: Array.from(new Set(relatedStringIds)) },
|
|
119
166
|
}).then(relatedEntities => relatedEntities.map(_ =>
|
|
120
167
|
({
|
|
121
168
|
..._,
|
|
@@ -170,4 +217,32 @@ module.exports = ({ strapi }) => ({
|
|
|
170
217
|
isValidUserContext(user) {
|
|
171
218
|
return user ? !isNil(user?.id) : true;
|
|
172
219
|
},
|
|
220
|
+
|
|
221
|
+
async parseRelationString(relation) {
|
|
222
|
+
const [ uid, relatedStringId ] = getRelatedGroups(relation);
|
|
223
|
+
const parsedRelatedId = parseInt(relatedStringId);
|
|
224
|
+
const relatedId = isNumber(parsedRelatedId) ? parsedRelatedId : relatedStringId;
|
|
225
|
+
|
|
226
|
+
const enabledCollections = await this.getConfig(CONFIG_PARAMS.ENABLED_COLLECTIONS, []);
|
|
227
|
+
if (!enabledCollections.includes(uid)) {
|
|
228
|
+
throw new PluginError(403, `Action not allowed for collection '${uid}'. Use one of: ${ enabledCollections.join(', ') }`);
|
|
229
|
+
}
|
|
230
|
+
return [ uid, relatedId];
|
|
231
|
+
},
|
|
232
|
+
|
|
233
|
+
async checkBadWords(content) {
|
|
234
|
+
const config = await this.getConfig(CONFIG_PARAMS.BAD_WORDS, true);
|
|
235
|
+
if (config) {
|
|
236
|
+
const filter = new BadWordsFilter(isObject(config) ? config : undefined);
|
|
237
|
+
if (content && filter.isProfane(content)) {
|
|
238
|
+
throw new PluginError(400, 'Bad language used! Please polite your comment...', {
|
|
239
|
+
content: {
|
|
240
|
+
original: content,
|
|
241
|
+
filtered: content && filter.clean(content),
|
|
242
|
+
},
|
|
243
|
+
});
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
return content;
|
|
247
|
+
},
|
|
173
248
|
});
|
|
@@ -1,86 +1,22 @@
|
|
|
1
|
-
const PluginError = require('
|
|
2
|
-
const {
|
|
1
|
+
const PluginError = require('../../../utils/error');
|
|
2
|
+
const { resolveUserContextError, getModelUid, buildConfigQueryProp } = require('../functions');
|
|
3
3
|
|
|
4
4
|
beforeEach(() => {
|
|
5
5
|
Object.defineProperty(global, 'strapi', {
|
|
6
|
-
value:
|
|
7
|
-
plugins: {
|
|
8
|
-
comments: {
|
|
9
|
-
package: require('../../../package.json'),
|
|
10
|
-
services: {
|
|
11
|
-
comments: require('../../comments'),
|
|
12
|
-
},
|
|
13
|
-
models: {
|
|
14
|
-
comment: require('../../../models/comment.settings.json'),
|
|
15
|
-
report: require('../../../models/report.settings.json'),
|
|
16
|
-
}
|
|
17
|
-
}
|
|
18
|
-
},
|
|
19
|
-
config: {
|
|
20
|
-
plugins: {
|
|
21
|
-
comments: {
|
|
22
|
-
enableUsers: false,
|
|
23
|
-
}
|
|
24
|
-
}
|
|
25
|
-
}
|
|
26
|
-
},
|
|
6
|
+
value: require('../../../../__mocks__/initSetup')(),
|
|
27
7
|
writable: true,
|
|
28
8
|
});
|
|
29
9
|
})
|
|
30
10
|
|
|
31
|
-
describe('Test
|
|
32
|
-
|
|
33
|
-
describe('Bad Words filtering', () => {
|
|
34
|
-
const text = 'Lorem ipsum dolor sit fuck amet';
|
|
11
|
+
describe('Test service functions utils', () => {
|
|
35
12
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
checkBadWords(text);
|
|
40
|
-
} catch (e) {
|
|
41
|
-
expect(e).toBeInstanceOf(PluginError);
|
|
42
|
-
expect(e).toHaveProperty('status', 400);
|
|
43
|
-
expect(e).toHaveProperty('name', 'Strapi:Plugin:Comments');
|
|
44
|
-
expect(e).toHaveProperty('message', 'Bad language used! Please polite your comment...');
|
|
45
|
-
expect(e).toHaveProperty('payload');
|
|
46
|
-
expect(e.payload).toEqual(expect.objectContaining({
|
|
47
|
-
content: {
|
|
48
|
-
original: text,
|
|
49
|
-
filtered: text.replace('fuck', '****'),
|
|
50
|
-
}
|
|
51
|
-
}));
|
|
52
|
-
}
|
|
13
|
+
describe('Getting models uid\'s ', () => {
|
|
14
|
+
test('Should get comments uid', () => {
|
|
15
|
+
expect(getModelUid('comment')).toBe('plugins::comments.comment');
|
|
53
16
|
});
|
|
54
17
|
|
|
55
|
-
test('Should
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
expect(checkBadWords(text)).toEqual(text);
|
|
59
|
-
});
|
|
60
|
-
});
|
|
61
|
-
|
|
62
|
-
describe('Extracting metadata', () => {
|
|
63
|
-
test('Should extract plugin metadata properly', () => {
|
|
64
|
-
const { model, service, plugin, pluginName } = extractMeta(strapi.plugins);
|
|
65
|
-
|
|
66
|
-
expect(model).toHaveProperty('info.name', 'comment');
|
|
67
|
-
expect(service).toHaveProperty('findAll');
|
|
68
|
-
expect(Object.keys(plugin)).toEqual(expect.arrayContaining(['package', 'services', 'models']));
|
|
69
|
-
expect(pluginName).toBe('comments');
|
|
70
|
-
});
|
|
71
|
-
});
|
|
72
|
-
|
|
73
|
-
describe('Validating user context', () => {
|
|
74
|
-
test('Context should be skipped based on config', () => {
|
|
75
|
-
global.strapi.config.plugins.comments.enableUsers = false;
|
|
76
|
-
expect(isValidUserContext(undefined)).toEqual(true);
|
|
77
|
-
expect(isValidUserContext({ id: 1 })).toEqual(true);
|
|
78
|
-
});
|
|
79
|
-
|
|
80
|
-
test('Context should be verified based on input', () => {
|
|
81
|
-
global.strapi.config.plugins.comments.enableUsers = true;
|
|
82
|
-
expect(isValidUserContext(undefined)).toEqual(false);
|
|
83
|
-
expect(isValidUserContext({ id: 1 })).toEqual(true);
|
|
18
|
+
test('Should get report uid', () => {
|
|
19
|
+
expect(getModelUid('comment-report')).toBe('plugins::comments.comment-report');
|
|
84
20
|
});
|
|
85
21
|
});
|
|
86
22
|
|
|
@@ -103,4 +39,15 @@ describe('Test Comments service functions utils', () => {
|
|
|
103
39
|
}
|
|
104
40
|
});
|
|
105
41
|
});
|
|
42
|
+
|
|
43
|
+
describe('Building config query props', () => {
|
|
44
|
+
test('Should return prop as is', () => {
|
|
45
|
+
expect(buildConfigQueryProp('my.sample.prop')).toBe('my.sample.prop');
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
test('Should build query prop with \'.\'', () => {
|
|
49
|
+
expect(buildConfigQueryProp(['my', 'sample', 'prop'])).toBe('my.sample.prop');
|
|
50
|
+
});
|
|
51
|
+
});
|
|
52
|
+
|
|
106
53
|
});
|
|
@@ -1,7 +1,6 @@
|
|
|
1
|
-
const BadWordsFilter = require('bad-words');
|
|
2
1
|
const PluginError = require('./../../utils/error');
|
|
3
2
|
const { REGEX } = require('./../../utils/constants')
|
|
4
|
-
const { first,
|
|
3
|
+
const { first, isObject, isArray, isEmpty } = require('lodash');
|
|
5
4
|
|
|
6
5
|
const buildNestedStructure = (
|
|
7
6
|
entities,
|
|
@@ -63,21 +62,6 @@ module.exports = {
|
|
|
63
62
|
reports: (item.reports || []).filter(report => !report.resolved),
|
|
64
63
|
} : item),
|
|
65
64
|
|
|
66
|
-
checkBadWords: content => {
|
|
67
|
-
const config = get(strapi.config, 'plugins.comments.badWords', true);
|
|
68
|
-
if (config) {
|
|
69
|
-
const filter = new BadWordsFilter(isObject(config) ? config : undefined);
|
|
70
|
-
if (content && filter.isProfane(content)) {
|
|
71
|
-
throw new PluginError(400, 'Bad language used! Please polite your comment...', {
|
|
72
|
-
content: {
|
|
73
|
-
original: content,
|
|
74
|
-
filtered: content && filter.clean(content),
|
|
75
|
-
},
|
|
76
|
-
});
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
|
-
return content;
|
|
80
|
-
},
|
|
81
65
|
convertContentTypeNameToSlug: str => {
|
|
82
66
|
const plainConversion = str.replace(/[A-Z]/g, letter => `-${letter.toLowerCase()}`);
|
|
83
67
|
return first(plainConversion) === '-' ? plainConversion.slice(1, plainConversion.length) : plainConversion;
|
|
@@ -109,6 +93,14 @@ module.exports = {
|
|
|
109
93
|
};
|
|
110
94
|
},
|
|
111
95
|
|
|
96
|
+
buildConfigQueryProp(prop) {
|
|
97
|
+
let queryProp = prop;
|
|
98
|
+
if (prop && isArray(prop)) {
|
|
99
|
+
queryProp = prop.join('.');
|
|
100
|
+
}
|
|
101
|
+
return queryProp;
|
|
102
|
+
},
|
|
103
|
+
|
|
112
104
|
resolveUserContextError: user => {
|
|
113
105
|
if (user) {
|
|
114
106
|
throw new PluginError(401, 'Not authenticated');
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
const { getPluginService } = require('../functions');
|
|
2
|
+
|
|
3
|
+
beforeEach(() => {
|
|
4
|
+
Object.defineProperty(global, 'strapi', {
|
|
5
|
+
value: require('../../../__mocks__/initSetup')(),
|
|
6
|
+
writable: true,
|
|
7
|
+
});
|
|
8
|
+
})
|
|
9
|
+
|
|
10
|
+
describe('Test plugin functions utils', () => {
|
|
11
|
+
|
|
12
|
+
describe('Get plugin service', () => {
|
|
13
|
+
test('Should get common service', () => {
|
|
14
|
+
expect(getPluginService('common')).toHaveProperty('findAllFlat');
|
|
15
|
+
});
|
|
16
|
+
});
|
|
17
|
+
});
|
|
@@ -1,3 +1,11 @@
|
|
|
1
|
+
const CONFIG_PARAMS = {
|
|
2
|
+
ENABLED_COLLECTIONS: 'enabledCollections',
|
|
3
|
+
APPROVAL_FLOW: 'approvalFlow',
|
|
4
|
+
ENTRY_LABEL: 'entryLabel',
|
|
5
|
+
MODERATOR_ROLES: 'moderatorRoles',
|
|
6
|
+
BAD_WORDS: 'badWords',
|
|
7
|
+
};
|
|
8
|
+
|
|
1
9
|
const APPROVAL_STATUS = {
|
|
2
10
|
PENDING: "PENDING",
|
|
3
11
|
APPROVED: "APPROVED",
|
|
@@ -8,9 +16,11 @@ const REGEX = {
|
|
|
8
16
|
uid: /^(?<type>[a-z0-9-]+)\:{2}(?<api>[a-z0-9-]+)\.{1}(?<contentType>[a-z0-9-]+)$/i,
|
|
9
17
|
relatedUid: /^(?<uid>[a-z0-9-]+\:{2}[a-z0-9-]+\.[a-z0-9-]+)\:{1}(?<id>[a-z0-9-]+)$/i,
|
|
10
18
|
email: /\S+@\S+\.\S+/,
|
|
19
|
+
sorting: /^(?<path>[a-z0-9-_\:\.]+)\:+(asc|desc)$/i
|
|
11
20
|
};
|
|
12
21
|
|
|
13
22
|
module.exports = {
|
|
23
|
+
CONFIG_PARAMS,
|
|
14
24
|
APPROVAL_STATUS,
|
|
15
25
|
REGEX,
|
|
16
26
|
};
|
package/strapi-server.js
CHANGED
|
@@ -4,7 +4,7 @@ const { isArray, isEmpty, isString } = require('lodash');
|
|
|
4
4
|
|
|
5
5
|
const server = require('./server');
|
|
6
6
|
const contentTypes = require('./content-types');
|
|
7
|
-
const { REGEX } = require('./server/utils/constants');
|
|
7
|
+
const { REGEX, CONFIG_PARAMS } = require('./server/utils/constants');
|
|
8
8
|
|
|
9
9
|
module.exports = () => ({
|
|
10
10
|
...server,
|
|
@@ -15,24 +15,31 @@ module.exports = () => ({
|
|
|
15
15
|
...server.config.default,
|
|
16
16
|
}),
|
|
17
17
|
validator: (config) => {
|
|
18
|
+
// Check enabledCollections values
|
|
19
|
+
const enabledCollectionsValid = config[CONFIG_PARAMS.ENABLED_COLLECTIONS]
|
|
20
|
+
.filter(_ => !REGEX.uid.test(_)).length === 0;
|
|
21
|
+
if (!enabledCollectionsValid) {
|
|
22
|
+
throw new Error(`'enabledCollections' must contain Content Types identifiers in the format like 'api::<collection name>.<content type name>'`);
|
|
23
|
+
}
|
|
24
|
+
|
|
18
25
|
// Check moderatorRoles values
|
|
19
|
-
const moderatorRolesValid = config.
|
|
26
|
+
const moderatorRolesValid = config[CONFIG_PARAMS.MODERATOR_ROLES]
|
|
20
27
|
.filter(_ => !isString(_)).length === 0;
|
|
21
28
|
if (!moderatorRolesValid) {
|
|
22
29
|
throw new Error(`'moderatorRoles' must roles keys`);
|
|
23
30
|
}
|
|
24
31
|
|
|
25
32
|
// Check approvalFlow values
|
|
26
|
-
const approvalFlowValid = config.
|
|
33
|
+
const approvalFlowValid = config[CONFIG_PARAMS.APPROVAL_FLOW]
|
|
27
34
|
.filter(_ => !REGEX.uid.test(_)).length === 0;
|
|
28
35
|
if (!approvalFlowValid) {
|
|
29
36
|
throw new Error(`'approvalFlow' must contain Content Types identifiers in the format like 'api::<collection name>.<content type name>'`);
|
|
30
37
|
}
|
|
31
38
|
|
|
32
39
|
// Check entryLabel keys and values
|
|
33
|
-
const entryLabelKeysValid = Object.keys(config.
|
|
40
|
+
const entryLabelKeysValid = Object.keys(config[CONFIG_PARAMS.ENTRY_LABEL])
|
|
34
41
|
.filter(_ => _ !== '*')
|
|
35
|
-
.filter(_ => !(REGEX.uid.test(_) && isArray(config.
|
|
42
|
+
.filter(_ => !(REGEX.uid.test(_) && isArray(config[CONFIG_PARAMS.ENTRY_LABEL][_]) && !isEmpty(config[CONFIG_PARAMS.ENTRY_LABEL][_]))).length === 0;
|
|
36
43
|
|
|
37
44
|
if (!entryLabelKeysValid) {
|
|
38
45
|
throw new Error(`'entryLabel' must contain records in the format like 'api::<collection name>.<content type name>': ['Field1', 'field_2']`);
|
package/.circleci/config.yml
DELETED
|
@@ -1,48 +0,0 @@
|
|
|
1
|
-
version: 2.1
|
|
2
|
-
orbs:
|
|
3
|
-
codecov: codecov/codecov@1.1.1
|
|
4
|
-
jobs:
|
|
5
|
-
build-and-test:
|
|
6
|
-
environment:
|
|
7
|
-
CODECOV_TOKEN: 02e2d4e8-88c4-4e5d-99da-a9a2888634c6
|
|
8
|
-
docker:
|
|
9
|
-
- image: circleci/node:12.13.0
|
|
10
|
-
working_directory: ~/repo
|
|
11
|
-
steps:
|
|
12
|
-
- checkout
|
|
13
|
-
- run:
|
|
14
|
-
name: set GIT name and email
|
|
15
|
-
command: |
|
|
16
|
-
git config --global -l
|
|
17
|
-
git config --global user.email "$GIT_COMMITTER_EMAIL"
|
|
18
|
-
git config --global user.name "$GIT_COMMITTER_NAME"
|
|
19
|
-
git config --global -l
|
|
20
|
-
- restore_cache:
|
|
21
|
-
keys:
|
|
22
|
-
# when lock file changes, use increasingly general patterns to restore cache
|
|
23
|
-
- strapi-plugin-comments-v2-{{ checksum "yarn.lock" }}
|
|
24
|
-
- strapi-plugin-comments-
|
|
25
|
-
- run:
|
|
26
|
-
name: Echo versions
|
|
27
|
-
command: |
|
|
28
|
-
node --version
|
|
29
|
-
yarn --version
|
|
30
|
-
- run:
|
|
31
|
-
name: Install
|
|
32
|
-
command: |
|
|
33
|
-
yarn install
|
|
34
|
-
- run:
|
|
35
|
-
name: Test
|
|
36
|
-
command: |
|
|
37
|
-
yarn test:unit
|
|
38
|
-
- codecov/upload:
|
|
39
|
-
flags: unittest
|
|
40
|
-
file:
|
|
41
|
-
- save_cache:
|
|
42
|
-
paths:
|
|
43
|
-
- ./node_modules
|
|
44
|
-
key: strapi-plugin-comments-v2-{{ checksum "yarn.lock" }}
|
|
45
|
-
workflows:
|
|
46
|
-
build-and-test:
|
|
47
|
-
jobs:
|
|
48
|
-
- build-and-test
|
package/.eslintrc
DELETED
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"parserOptions": {
|
|
3
|
-
"jsx": true,
|
|
4
|
-
"useJSXTextNode": true,
|
|
5
|
-
"sourceType": "module"
|
|
6
|
-
},
|
|
7
|
-
"plugins": ["react-hooks", "import"],
|
|
8
|
-
"rules": {
|
|
9
|
-
"no-console": "warn",
|
|
10
|
-
"curly": "warn",
|
|
11
|
-
"prefer-template": "warn",
|
|
12
|
-
|
|
13
|
-
"react-hooks/rules-of-hooks": "error",
|
|
14
|
-
"react-hooks/exhaustive-deps": "error",
|
|
15
|
-
|
|
16
|
-
"import/no-default-export": "warn",
|
|
17
|
-
"import/newline-after-import": "warn",
|
|
18
|
-
"import/order": [
|
|
19
|
-
"warn",
|
|
20
|
-
{
|
|
21
|
-
"newlines-between": "always",
|
|
22
|
-
"alphabetize": { "order": "asc" },
|
|
23
|
-
"pathGroupsExcludedImportTypes": ["builtin"],
|
|
24
|
-
"groups": [
|
|
25
|
-
"builtin",
|
|
26
|
-
"external",
|
|
27
|
-
"internal",
|
|
28
|
-
"parent",
|
|
29
|
-
"sibling",
|
|
30
|
-
"index"
|
|
31
|
-
]
|
|
32
|
-
}
|
|
33
|
-
]
|
|
34
|
-
}
|
|
35
|
-
}
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
## Ticket
|
|
2
|
-
|
|
3
|
-
https://github.com/VirtusLab/strapi-plugin-comments/issues/-<your-ticket-#>
|
|
4
|
-
|
|
5
|
-
## Summary
|
|
6
|
-
|
|
7
|
-
What does this PR do/solve?
|
|
8
|
-
|
|
9
|
-
> PRs should be as small as they need to be, if this section starts becoming a novel you should _seriously_ consider breaking it up into multiple PRs
|
|
10
|
-
|
|
11
|
-
## Test Plan
|
|
12
|
-
|
|
13
|
-
How are you testing the work you're submitting?
|
package/.nvmrc
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
v14.17.3
|
|
@@ -1,42 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
*
|
|
3
|
-
* Entity Details
|
|
4
|
-
*
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
|
-
import React from 'react';
|
|
8
|
-
import PropTypes from 'prop-types';
|
|
9
|
-
import { useIntl } from 'react-intl';
|
|
10
|
-
import { Box } from '@strapi/design-system/Box';
|
|
11
|
-
import { Flex } from '@strapi/design-system/Flex';
|
|
12
|
-
import { Stack } from '@strapi/design-system/Stack';
|
|
13
|
-
import { Typography } from '@strapi/design-system/Typography';
|
|
14
|
-
|
|
15
|
-
const DiscussionThreadItemMeta = ({ author, createdAt, updatedAt }) => {
|
|
16
|
-
|
|
17
|
-
const { formatDate } = useIntl();
|
|
18
|
-
|
|
19
|
-
const dateTime = formatDate(updatedAt || createdAt, { dateStyle: 'short', timeStyle: 'short' });
|
|
20
|
-
const { name } = author;
|
|
21
|
-
|
|
22
|
-
return (<Flex as={Box} paddingTop={2} direction="row">
|
|
23
|
-
<Stack size={2} horizontal style={{ flexGrow: 1, justifyContent: 'space-between'}}>
|
|
24
|
-
<Typography variant="pi" fontWeight="bold">{ name }</Typography>
|
|
25
|
-
<Typography variant="pi">{ dateTime }</Typography>
|
|
26
|
-
</Stack>
|
|
27
|
-
</Flex>);
|
|
28
|
-
};
|
|
29
|
-
|
|
30
|
-
DiscussionThreadItemMeta.propTypes = {
|
|
31
|
-
author: PropTypes.shape({
|
|
32
|
-
id: PropTypes.oneOfType(PropTypes.string, PropTypes.number).isRequired,
|
|
33
|
-
name: PropTypes.string.isRequired,
|
|
34
|
-
email: PropTypes.string,
|
|
35
|
-
avatar: PropTypes.string,
|
|
36
|
-
}).isRequired,
|
|
37
|
-
createdAt: PropTypes.string.isRequired,
|
|
38
|
-
updatedAt: PropTypes.string,
|
|
39
|
-
};
|
|
40
|
-
|
|
41
|
-
export default DiscussionThreadItemMeta;
|
|
42
|
-
|