strapi-plugin-comments 2.0.0-beta.6 → 2.0.0-beta.7

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.
Files changed (43) hide show
  1. package/README.md +310 -7
  2. package/admin/src/components/DiscussionThreadItem/index.js +4 -8
  3. package/admin/src/components/DiscussionThreadItemMeta/index.js +16 -5
  4. package/admin/src/pages/Discover/components/DiscoverTableRow/index.js +8 -1
  5. package/admin/src/pages/Discover/index.js +4 -1
  6. package/admin/src/translations/en.json +1 -0
  7. package/admin/src/utils/index.js +2 -0
  8. package/admin/src/utils/renderInitials.js +5 -0
  9. package/package.json +2 -1
  10. package/server/config/index.js +5 -0
  11. package/server/controllers/client.js +4 -19
  12. package/server/controllers/utils/parsers.js +17 -0
  13. package/server/graphql/index.js +26 -0
  14. package/server/graphql/mutations/createAbuseReport.js +20 -0
  15. package/server/graphql/mutations/createComment.js +20 -0
  16. package/server/graphql/mutations/index.js +21 -0
  17. package/server/graphql/mutations/removeComment.js +20 -0
  18. package/server/graphql/mutations/updateComment.js +20 -0
  19. package/server/graphql/queries/findAllFlat.js +29 -0
  20. package/server/graphql/queries/findAllInHierarchy.js +31 -0
  21. package/server/graphql/queries/index.js +19 -0
  22. package/server/graphql/resolvers-config.js +10 -0
  23. package/server/graphql/types/comment-author-user.js +9 -0
  24. package/server/graphql/types/comment-author.js +9 -0
  25. package/server/graphql/types/comment-nested.js +16 -0
  26. package/server/graphql/types/comment.js +16 -0
  27. package/server/graphql/types/create-comment-author.js +9 -0
  28. package/server/graphql/types/create-comment.js +9 -0
  29. package/server/graphql/types/create-report.js +9 -0
  30. package/server/graphql/types/id.js +24 -0
  31. package/server/graphql/types/identify-comment-author.js +6 -0
  32. package/server/graphql/types/index.js +17 -0
  33. package/server/graphql/types/remove-comment.js +8 -0
  34. package/server/graphql/types/report-reason.js +10 -0
  35. package/server/graphql/types/report.js +11 -0
  36. package/server/graphql/types/update-comment.js +9 -0
  37. package/server/register.js +3 -1
  38. package/server/services/admin.js +8 -8
  39. package/server/services/client.js +35 -27
  40. package/server/services/common.js +10 -4
  41. package/server/services/graphql.js +190 -0
  42. package/server/services/index.js +2 -0
  43. package/server/services/utils/functions.js +17 -3
package/README.md CHANGED
@@ -88,6 +88,9 @@ To setup amend default plugin configuration we recommend to put following snippe
88
88
  '*': ['Title', 'title', 'Name', 'name', 'Subject', 'subject'],
89
89
  'api::page.page': ['MyField'],
90
90
  },
91
+ reportReasons: {
92
+ 'MY_CUSTOM_REASON': 'MY_CUSTOM_REASON',
93
+ },
91
94
  },
92
95
  ...
93
96
  ```
@@ -97,10 +100,12 @@ To setup amend default plugin configuration we recommend to put following snippe
97
100
  - `moderatorRoles` - Optional list of names of roles. Users with those roles will be notified by email when a new abuse report is created. This feature requires a built-in [Strapi email plugin](https://docs.strapi.io/developer-docs/latest/plugins/email.html) configured.
98
101
  - `approvalFlow` - list of Content Types which are supporting approval flow. Values must be in format like `'api::<collection name>.<content type name>'`. For not included, posted comments are going to be immediately visible.
99
102
  - `entryLabel` - ordered list of property names per Content Type to generate related entity label. Keys must be in format like `'api::<collection name>.<content type name>'`. Default formatting set as `*`.
103
+ - `reportReasons` - set of enums you would like to use for issuing abuse reports. Provided by default `'BAD_LANGUAGE'`, `'DISCRIMINATION'` and `'OTHER'`.
100
104
 
101
105
  ## Additional GQL Configuration
106
+ All you need to do is to install and enable `@strapi/plugin-graphql` for you instance based on the **[official Strapi v4 docs](https://docs.strapi.io/developer-docs/latest/plugins/graphql.html#configurations)**.
102
107
 
103
- > To be done
108
+ See [available GQL specification section](#public-graphql-specification).
104
109
 
105
110
  ## RBAC
106
111
  Plugin provides granular permissions based on Strapi RBAC functionality.
@@ -127,10 +132,14 @@ Feature / Capability focused permissions:
127
132
  "blockedThread": true,
128
133
  "blockReason": null,
129
134
  "authorUser": null,
130
- "authorId": "207ccfdc-94ba-45eb-979c-790f6f49c392",
131
- "authorName": "Joe Doe",
132
- "authorEmail": "jdoe@sample.com",
133
- "authorAvatar": null,
135
+ "removed": null,
136
+ "approvalStatus": "APPROVED", // Only in case of enabled approval flow. Default: null
137
+ "author": {
138
+ "id": "207ccfdc-94ba-45eb-979c-790f6f49c392",
139
+ "name": "Joe Doe",
140
+ "email": "jdoe@sample.com",
141
+ "avatar": null,
142
+ },
134
143
  "createdAt": "2020-07-14T20:13:01.649Z",
135
144
  "updatedAt": "2020-07-14T20:13:01.670Z",
136
145
  "related": {}, // Related content type entity
@@ -145,6 +154,8 @@ Feature / Capability focused permissions:
145
154
  "blocked": true,
146
155
  "blockedThread": null,
147
156
  "blockReason": null,
157
+ "removed": null,
158
+ "approvalStatus": "REJECTED", // Only in case of enabled approval flow. Default: null
148
159
  "authorUser": {
149
160
  "id": 1,
150
161
  "username": "Sample User",
@@ -329,7 +340,7 @@ Deletes a specified Comment based on it `commentId` and related to specified ins
329
340
  - `409` - Conflict. Occurs when trying to delete a non existing comment.
330
341
 
331
342
 
332
- ### Report abuse in the Comment
343
+ ### Issue Abuse Report against specified Comment
333
344
 
334
345
  `POST <host>/comments/api::<collection name>.<content type name>:<entity id>/comment/<commentId>/report-abuse`
335
346
 
@@ -346,7 +357,7 @@ Reports abuse in specified Comment content based on it `commentId` and related t
346
357
  }
347
358
  ```
348
359
 
349
- *Available reason enums:* `OTHER`, `BAD_WORDS`, `DISCRIMINATION`
360
+ *Available reason enums:* `BAD_WORDS`, `OTHER`, `DISCRIMINATION` (want more? See [configuration section](#configuration).)
350
361
 
351
362
  **Example response body**
352
363
 
@@ -360,6 +371,298 @@ Reports abuse in specified Comment content based on it `commentId` and related t
360
371
  - `200` - Successful. Response with reported abuse.
361
372
  - `409` - Conflict. Occurs when trying to report an abuse to a non existing comment.
362
373
 
374
+ ## Public GraphQL specification
375
+
376
+ > *To test all queries and understand the schemas use GraphQL Playground exposed by `@strapi/plugin-graphql` on `http://localhost:1337/graphql`*
377
+
378
+ ### Get Comments
379
+
380
+ *REST API equivalent: [Public API -> Get Comments](#get-comments)*
381
+
382
+ **Example request**
383
+
384
+ ```graphql
385
+ query {
386
+ findAllFlat(
387
+ relation: "api::page.page:1"
388
+ filters: { content: { contains: "Test" } }
389
+ ) {
390
+ id
391
+ content
392
+ blocked
393
+ threadOf {
394
+ id
395
+ }
396
+ author {
397
+ id
398
+ name
399
+ }
400
+ }
401
+ }
402
+ ```
403
+
404
+ **Example response**
405
+
406
+ ```json
407
+ {
408
+ "data": {
409
+ "findAllFlat": [
410
+ {
411
+ "id": 3,
412
+ "content": "Test",
413
+ "blocked": false,
414
+ "threadOf": null,
415
+ "author": {
416
+ "id": "123456",
417
+ "name": "Joe Doe"
418
+ }
419
+ },
420
+ //...
421
+ ]
422
+ }
423
+ ```
424
+
425
+ ### Get Comments (flat structure)
426
+
427
+ *REST API equivalent: [Public API -> Get Comments (flat structure)](#get-comments-flat-structure)*
428
+
429
+ **Example request**
430
+
431
+ ```graphql
432
+ query {
433
+ findAllInHierarchy(relation: "api::page.page:1") {
434
+ id
435
+ content
436
+ blocked
437
+ children {
438
+ id
439
+ content
440
+ }
441
+ threadOf {
442
+ id
443
+ }
444
+ author {
445
+ id
446
+ name
447
+ }
448
+ }
449
+ }
450
+ ```
451
+
452
+ **Example response**
453
+
454
+ ```json
455
+ {
456
+ "data": {
457
+ "findAllInHierarchy": [
458
+ {
459
+ "id": 1,
460
+ "content": "Test",
461
+ "blocked": false,
462
+ "children": [
463
+ {
464
+ "id": 6,
465
+ "content": "Text to search for"
466
+ },
467
+ //...
468
+ ],
469
+ "threadOf": null,
470
+ "author": {
471
+ "id": "123456",
472
+ "name": "Joe Doe"
473
+ }
474
+ },
475
+ //...
476
+ ]
477
+ }
478
+ }
479
+ ```
480
+
481
+ ### Post a Comment
482
+
483
+ *REST API equivalent: [Public API -> Post a Comment](#post-a-comment)*
484
+
485
+ **Example request**
486
+
487
+ ```graphql
488
+ mutation createComment {
489
+ createComment(
490
+ input: {
491
+ relation: "api::page.page:1"
492
+ content: "Hello World!"
493
+ threadOf: 3
494
+ author: { id: "12345678", name: "John Wick", email: "test@test.pl" }
495
+ }
496
+ ) {
497
+ id
498
+ content
499
+ threadOf {
500
+ id
501
+ }
502
+ author {
503
+ id
504
+ name
505
+ }
506
+ }
507
+ }
508
+ ```
509
+
510
+ **Example response**
511
+
512
+ ```json
513
+ {
514
+ "data": {
515
+ "createComment": {
516
+ "id": 34,
517
+ "content": "Hello World!",
518
+ "threadOf": {
519
+ "id": 3
520
+ },
521
+ "author": {
522
+ "id": "12345678",
523
+ "name": "John Wick"
524
+ }
525
+ }
526
+ }
527
+ }
528
+ ```
529
+
530
+ ### Update Comment
531
+
532
+ *REST API equivalent: [Public API -> Update Comment](#update-comment)*
533
+
534
+ **Example request**
535
+
536
+ ```graphql
537
+ mutation updateComment {
538
+ updateComment(
539
+ input: {
540
+ id: 34
541
+ relation: "api::page.page:1"
542
+ content: "I've changed it!"
543
+ author: { id: "12345678" }
544
+ }
545
+ ) {
546
+ id
547
+ content
548
+ threadOf {
549
+ id
550
+ }
551
+ author {
552
+ id
553
+ name
554
+ }
555
+ createdAt
556
+ updatedAt
557
+ }
558
+ }
559
+ ```
560
+
561
+ **Example response**
562
+
563
+ ```json
564
+ {
565
+ "data": {
566
+ "updateComment": {
567
+ "id": 34,
568
+ "content": "I've changed it!",
569
+ "threadOf": {
570
+ "id": 3
571
+ },
572
+ "author": {
573
+ "id": "12345678",
574
+ "name": "John Wick"
575
+ },
576
+ "createdAt": "2022-01-26T07:45:35.978Z",
577
+ "updatedAt": "2022-01-26T07:47:44.659Z"
578
+ }
579
+ }
580
+ }
581
+ ```
582
+
583
+ ### Delete Comment
584
+
585
+ *REST API equivalent: [Public API -> Delete Comment](#delete-comment)*
586
+
587
+ **Example request**
588
+
589
+ ```graphql
590
+ mutation removeComment {
591
+ removeComment(
592
+ input: { id: 33, relation: "api::page.page:1", author: { id: "12345678" } }
593
+ ) {
594
+ id
595
+ removed
596
+ }
597
+ }
598
+ ```
599
+
600
+ **Example response**
601
+
602
+ ```json
603
+ {
604
+ "data": {
605
+ "removeComment": {
606
+ "id": 33,
607
+ "removed": true
608
+ }
609
+ }
610
+ }
611
+ ```
612
+
613
+ ### Issue Abuse Report against specified Comment
614
+
615
+ *REST API equivalent: [Public API -> Issue Abuse Report against specified Comment](#issue-abuse-report-against-specified-comment)*
616
+
617
+ **Example request body**
618
+
619
+ ```graphql
620
+ mutation createAbuseReport {
621
+ createAbuseReport(
622
+ input: {
623
+ commentId: 34
624
+ relation: "api::page.page:1"
625
+ reason: BAD_LANGUAGE
626
+ content: "Rude language"
627
+ }
628
+ ) {
629
+ id
630
+ reason
631
+ content
632
+ related {
633
+ id
634
+ author {
635
+ id
636
+ name
637
+ }
638
+ }
639
+ }
640
+ }
641
+ ```
642
+
643
+ *Available reason enums:* `BAD_WORDS`, `OTHER`, `DISCRIMINATION` (want more? See [configuration section](#configuration).)
644
+
645
+ **Example response**
646
+
647
+ ```json
648
+ {
649
+ "data": {
650
+ "createAbuseReport": {
651
+ "id": 28,
652
+ "content": "Rude language",
653
+ "reason": "DISCRIMINATION",
654
+ "related": {
655
+ "id": 34,
656
+ "author": {
657
+ "id": "12345678",
658
+ "name": "John Wick"
659
+ }
660
+ }
661
+ }
662
+ }
663
+ }
664
+ ```
665
+
363
666
  ## Examples
364
667
 
365
668
  Live example of plugin usage can be found in the [VirtusLab Strapi Examples](https://github.com/VirtusLab/strapi-examples/tree/master/strapi-plugin-comments) repository.
@@ -6,7 +6,6 @@
6
6
 
7
7
  import React from 'react';
8
8
  import PropTypes from 'prop-types';
9
- import { first } from 'lodash';
10
9
  import { Avatar, Initials } from '@strapi/design-system/Avatar';
11
10
  import { Box } from '@strapi/design-system/Box';
12
11
  import { Divider } from '@strapi/design-system/Divider';
@@ -17,7 +16,7 @@ import { ArrowRight } from '@strapi/icons';
17
16
  import DiscussionThreadItemMeta from '../DiscussionThreadItemMeta';
18
17
  import { AvatarWrapper, DiscussionThreadItemBox, DiscussionThreadItemBoxContent, DiscussionThreadItemContent, DiscussionThreadItemLeft, DiscussionThreadItemLinkBox, DiscussionThreadItemRight, DiscussionThreadItemRoot } from './styles';
19
18
  import DiscussionThreadItemActions from '../DiscussionThreadItemActions';
20
- import { getMessage, getUrl } from '../../utils';
19
+ import { getMessage, getUrl, renderInitials } from '../../utils';
21
20
  import DiscussionThreadItemWarnings from '../DiscussionThreadItemWarnings';
22
21
 
23
22
  const DiscussionThreadItem = (props) => {
@@ -34,8 +33,7 @@ const DiscussionThreadItem = (props) => {
34
33
  gotThread,
35
34
  threadFirstItemId,
36
35
  authorUser,
37
- authorAvatar,
38
- authorName } = props;
36
+ author } = props;
39
37
 
40
38
  let background = 'neutral100';
41
39
  let borderColor = 'neutral200';
@@ -59,11 +57,9 @@ const DiscussionThreadItem = (props) => {
59
57
  StyledComponent = DiscussionThreadItemRoot;
60
58
  }
61
59
 
62
- const avatar = authorAvatar || authorUser?.avatar;
63
- const name = authorName || `${authorUser?.firstName} ${authorUser?.lastName}`;
60
+ const avatar = author?.avatar || authorUser?.avatar;
61
+ const name = author?.name || `${authorUser?.firstName} ${authorUser?.lastName}`;
64
62
  const isBlocked = blocked || blockedThread;
65
-
66
- const renderInitials = value => value.split(' ').map(_ => first(_)).join('').toUpperCase();
67
63
 
68
64
  return (<StyledComponent as="li">
69
65
  <DiscussionThreadItemContent as={Flex} direction="row">
@@ -9,22 +9,33 @@ import PropTypes from 'prop-types';
9
9
  import { useIntl } from 'react-intl';
10
10
  import { Box } from '@strapi/design-system/Box';
11
11
  import { Flex } from '@strapi/design-system/Flex';
12
+ import { Stack } from '@strapi/design-system/Stack';
12
13
  import { Typography } from '@strapi/design-system/Typography';
13
14
 
14
- const DiscussionThreadItemMeta = ({ authorName, authorEmail, createdAt, updatedAt }) => {
15
+ const DiscussionThreadItemMeta = ({ author, createdAt, updatedAt }) => {
15
16
 
16
17
  const { formatDate } = useIntl();
17
18
 
18
19
  const dateTime = formatDate(updatedAt || createdAt, { dateStyle: 'short', timeStyle: 'short' });
20
+ const { name } = author;
19
21
 
20
- return (<Flex as={Box} paddingTop={2} direction="row" justifyContent="space-between">
21
- <Typography variant="pi" fontWeight="bold">{ authorName }</Typography>
22
- <Typography variant="pi">{ dateTime }</Typography>
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>
23
27
  </Flex>);
24
28
  };
25
29
 
26
30
  DiscussionThreadItemMeta.propTypes = {
27
-
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,
28
39
  };
29
40
 
30
41
  export default DiscussionThreadItemMeta;
@@ -3,6 +3,7 @@ import PropTypes from 'prop-types';
3
3
  import { useIntl } from 'react-intl';
4
4
  import { useMutation, useQueryClient } from 'react-query';
5
5
  import { isNil, isEmpty, orderBy } from 'lodash';
6
+ import { Avatar, Initials } from '@strapi/design-system/Avatar';
6
7
  import { Badge } from '@strapi/design-system/Badge';
7
8
  import { Box } from '@strapi/design-system/Box';
8
9
  import { Button } from '@strapi/design-system/Button';
@@ -15,7 +16,7 @@ import { Tr, Td } from '@strapi/design-system/Table';
15
16
  import { Typography } from '@strapi/design-system/Typography';
16
17
  import { Eye } from '@strapi/icons';
17
18
  import { useNotification, useOverlayBlocker } from '@strapi/helper-plugin';
18
- import { getMessage, getUrl, handleAPIError, resolveCommentStatus, resolveCommentStatusColor } from '../../../../utils';
19
+ import { getMessage, getUrl, handleAPIError, renderInitials, resolveCommentStatus, resolveCommentStatusColor } from '../../../../utils';
19
20
  import ReportsReviewModal from '../../../../components/ReportsReviewModal';
20
21
  import ReportsReviewTable from '../../../../components/ReportsReviewTable';
21
22
  import { blockItem, blockItemThread, resolveReport } from '../../../utils/api';
@@ -132,6 +133,12 @@ const DiscoverTableRow = ({ config, item, allowedActions: { canModerate, canAcce
132
133
  <Td>
133
134
  <Typography textColor="neutral800" fontWeight="bold">#{ item.id }</Typography>
134
135
  </Td>
136
+ <Td>
137
+ <Stack size={2} horizontal>
138
+ { item.author?.avatar ? <Avatar src={item.author?.avatar} alt={item.author.name} /> : <Initials>{ renderInitials(item.author.name) }</Initials> }
139
+ <Typography textColor="neutral800" variant="pi">{ item.author.name }</Typography>
140
+ </Stack>
141
+ </Td>
135
142
  <Td style={{ maxWidth: '30vw' }}>
136
143
  <Typography textColor="neutral800" ellipsis>{item.content}</Typography>
137
144
  </Td>
@@ -91,7 +91,7 @@ const Discover = ({ config }) => {
91
91
 
92
92
  const emptyContent = _q ? 'search' : 'comments';
93
93
 
94
- const COL_COUNT = 7;
94
+ const COL_COUNT = 8;
95
95
 
96
96
  if (canAccess) {
97
97
  return <Box background="neutral100">
@@ -114,6 +114,9 @@ const Discover = ({ config }) => {
114
114
  <Th>
115
115
  <Typography variant="sigma">{ getMessage('page.discover.table.header.id') }</Typography>
116
116
  </Th>
117
+ <Th>
118
+ <Typography variant="sigma">{ getMessage('page.discover.table.header.author') }</Typography>
119
+ </Th>
117
120
  <Th>
118
121
  <Typography variant="sigma">{ getMessage('page.discover.table.header.message') }</Typography>
119
122
  </Th>
@@ -17,6 +17,7 @@
17
17
  "page.discover.header": "Discover threads",
18
18
  "page.discover.header.count": "entries found",
19
19
  "page.discover.table.header.id": "ID",
20
+ "page.discover.table.header.author": "Author",
20
21
  "page.discover.table.header.message": "Message",
21
22
  "page.discover.table.header.thread": "Thread of",
22
23
  "page.discover.table.header.entry": "Entry",
@@ -4,5 +4,7 @@ export { default as getUrl } from './getUrl';
4
4
  export { default as getMessage } from './getMessage';
5
5
  export { default as handleAPIError } from './handleAPIError';
6
6
  export { default as getRelatedGroups } from './getRelatedGroups';
7
+ export { default as renderEntryTitle } from './renderEntryTitle';
8
+ export { default as renderInitials } from './renderInitials';
7
9
  export { default as resolveCommentStatus } from './resolveCommentStatus';
8
10
  export { default as resolveCommentStatusColor } from './resolveCommentStatusColor';
@@ -0,0 +1,5 @@
1
+ import { first } from 'lodash';
2
+
3
+ const renderInitials = (value = '') => value.split(' ').map(_ => first(_)).join('').toUpperCase();
4
+
5
+ export default renderInitials;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "strapi-plugin-comments",
3
- "version": "2.0.0-beta.6",
3
+ "version": "2.0.0-beta.7",
4
4
  "description": "Strapi - Comments plugin",
5
5
  "strapi": {
6
6
  "name": "comments",
@@ -16,6 +16,7 @@
16
16
  },
17
17
  "dependencies": {
18
18
  "@strapi/utils": "^4.0.5",
19
+ "@strapi/plugin-graphql": "^4.0.5",
19
20
  "bad-words": "^3.0.4"
20
21
  },
21
22
  "devDependencies": {
@@ -7,5 +7,10 @@ module.exports = {
7
7
  entryLabel: {
8
8
  '*': ['Title', 'title', 'Name', 'name', 'Subject', 'subject']
9
9
  },
10
+ reportReasons: {
11
+ 'BAD_LANGUAGE': 'BAD_LANGUAGE',
12
+ 'DISCRIMINATION': 'DISCRIMINATION',
13
+ 'OTHER': 'OTHER',
14
+ },
10
15
  }
11
16
  };
@@ -2,7 +2,7 @@
2
2
 
3
3
  const { getPluginService } = require('./../utils/functions');
4
4
  const { parseParams, throwError } = require('./utils/functions');
5
- const _ = require('lodash');
5
+ const { flatInput } = require('./utils/parsers');
6
6
 
7
7
  module.exports = {
8
8
 
@@ -15,16 +15,7 @@ module.exports = {
15
15
  const { relation } = parseParams(params);
16
16
  try {
17
17
  return this.getService('common')
18
- .findAllFlat({
19
- query: {
20
- ...query,
21
- $or: [{ removed: { $null: true } }, { removed: false }],
22
- related: relation,
23
- },
24
- populate: {
25
- threadOf: true,
26
- },
27
- });
18
+ .findAllFlat(flatInput(relation, query));
28
19
  } catch (e) {
29
20
  throwError(ctx, e);
30
21
  }
@@ -36,13 +27,7 @@ module.exports = {
36
27
  try {
37
28
  return await this.getService('common')
38
29
  .findAllInHierarchy({
39
- query: {
40
- ...query,
41
- related: relation,
42
- },
43
- populate: {
44
- threadOf: true,
45
- },
30
+ ...flatInput(relation, query),
46
31
  dropBlockedThreads: true,
47
32
  });
48
33
  } catch (e) {
@@ -102,8 +87,8 @@ module.exports = {
102
87
  try {
103
88
  return await this.getService()
104
89
  .markAsRemoved(
105
- relationId,
106
90
  commentId,
91
+ relationId,
107
92
  authorId,
108
93
  );
109
94
  } catch (e) {
@@ -0,0 +1,17 @@
1
+ 'use strict'
2
+
3
+ module.exports = {
4
+ flatInput(relation, query) {
5
+ return {
6
+ query: {
7
+ ...query,
8
+ $or: [{ removed: { $null: true } }, { removed: false }],
9
+ related: relation,
10
+ },
11
+ populate: {
12
+ threadOf: true,
13
+ },
14
+ };
15
+ },
16
+
17
+ };
@@ -0,0 +1,26 @@
1
+ 'use strict'
2
+
3
+ const getTypes = require('./types');
4
+ const getQueries = require('./queries');
5
+ const getMutations = require('./mutations');
6
+ const getResolversConfig = require('./resolvers-config');
7
+ const { getModelUid } = require('../services/utils/functions');
8
+
9
+ module.exports = () => {
10
+ const extensionService = strapi.plugin('graphql').service('extension');
11
+
12
+ extensionService.shadowCRUD(getModelUid('comment')).disable();
13
+ extensionService.shadowCRUD(getModelUid('comment-report')).disable();
14
+
15
+ extensionService.use(({ nexus }) => {
16
+ const types = getTypes({ strapi, nexus });
17
+ const queries = getQueries({ strapi, nexus });
18
+ const mutations = getMutations({ strapi, nexus });
19
+ const resolversConfig = getResolversConfig({ strapi });
20
+
21
+ return {
22
+ types: [types, queries, mutations],
23
+ resolversConfig,
24
+ }
25
+ });
26
+ }
@@ -0,0 +1,20 @@
1
+ 'use strict'
2
+
3
+ const { getPluginService } = require('../../utils/functions');
4
+
5
+ module.exports = ({ nexus }) => {
6
+ const { nonNull } = nexus;
7
+
8
+ return {
9
+ type: nonNull('Report'),
10
+ args: {
11
+ input: nonNull('CreateReport'),
12
+ },
13
+ async resolve(obj, args) {
14
+ const { input } = args;
15
+ const { commentId, relation, ...body } = input;
16
+ return await getPluginService('client')
17
+ .reportAbuse(commentId, relation, body);
18
+ },
19
+ };
20
+ }
@@ -0,0 +1,20 @@
1
+ 'use strict'
2
+
3
+ const { getPluginService } = require('../../utils/functions');
4
+
5
+ module.exports = ({ nexus }) => {
6
+ const { nonNull } = nexus;
7
+
8
+ return {
9
+ type: nonNull('CommentSingle'),
10
+ args: {
11
+ input: nonNull('CreateComment'),
12
+ },
13
+ async resolve(obj, args) {
14
+ const { input } = args;
15
+ const { relation, ...body } = input;
16
+ return await getPluginService('client')
17
+ .create(relation, body);
18
+ },
19
+ };
20
+ }