strapi-plugin-comments 2.0.0-beta.3 → 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.
- package/README.md +335 -11
- package/admin/src/components/DiscussionThread/index.js +9 -2
- package/admin/src/components/DiscussionThreadItem/index.js +27 -12
- package/admin/src/components/DiscussionThreadItemActions/index.js +61 -50
- 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/DiscussionThreadItemMeta/index.js +16 -5
- package/admin/src/components/DiscussionThreadItemWarnings/index.js +16 -10
- package/admin/src/components/Nav/index.js +5 -1
- package/admin/src/components/ReportsReviewModal/index.js +5 -0
- package/admin/src/components/ReportsReviewTable/index.js +60 -52
- package/admin/src/components/icons/review.js +2 -2
- package/admin/src/index.js +1 -1
- 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 +69 -48
- package/admin/src/pages/Discover/components/DiscoverTableRow/styles.js +8 -0
- package/admin/src/pages/Discover/index.js +72 -56
- 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 +1 -1
- package/admin/src/utils/getRelatedGroups.js +1 -3
- package/admin/src/utils/index.js +6 -2
- package/admin/src/utils/renderEntryTitle.js +14 -0
- package/admin/src/utils/renderInitials.js +5 -0
- package/admin/src/utils/resolveCommentStatus.js +30 -0
- package/admin/src/utils/resolveCommentStatusColor.js +22 -0
- package/package.json +8 -3
- package/permissions.js +19 -0
- package/server/bootstrap.js +38 -2
- package/server/config/index.js +9 -3
- package/server/controllers/admin.js +3 -3
- package/server/controllers/client.js +4 -18
- package/server/controllers/utils/parsers.js +17 -0
- package/server/graphql/index.js +26 -0
- package/server/graphql/mutations/createAbuseReport.js +20 -0
- package/server/graphql/mutations/createComment.js +20 -0
- package/server/graphql/mutations/index.js +21 -0
- package/server/graphql/mutations/removeComment.js +20 -0
- package/server/graphql/mutations/updateComment.js +20 -0
- package/server/graphql/queries/findAllFlat.js +29 -0
- package/server/graphql/queries/findAllInHierarchy.js +31 -0
- package/server/graphql/queries/index.js +19 -0
- package/server/graphql/resolvers-config.js +10 -0
- package/server/graphql/types/comment-author-user.js +9 -0
- package/server/graphql/types/comment-author.js +9 -0
- package/server/graphql/types/comment-nested.js +16 -0
- package/server/graphql/types/comment.js +16 -0
- package/server/graphql/types/create-comment-author.js +9 -0
- package/server/graphql/types/create-comment.js +9 -0
- package/server/graphql/types/create-report.js +9 -0
- package/server/graphql/types/id.js +24 -0
- package/server/graphql/types/identify-comment-author.js +6 -0
- package/server/graphql/types/index.js +17 -0
- package/server/graphql/types/remove-comment.js +8 -0
- package/server/graphql/types/report-reason.js +10 -0
- package/server/graphql/types/report.js +11 -0
- package/server/graphql/types/update-comment.js +9 -0
- package/server/register.js +3 -1
- package/server/services/admin.js +42 -15
- package/server/services/client.js +54 -38
- package/server/services/common.js +38 -67
- package/server/services/graphql.js +190 -0
- package/server/services/index.js +2 -0
- package/server/services/utils/functions.js +24 -17
- package/server/utils/constants.js +3 -3
- package/strapi-server.js +33 -0
- package/admin/src/components/EntityDetails/index.js +0 -53
package/README.md
CHANGED
|
@@ -50,9 +50,16 @@ Enjoy 🎉
|
|
|
50
50
|
|
|
51
51
|
Complete installation requirements are exact same as for Strapi itself and can be found in the documentation under [Installation Requirements](https://docs.strapi.io/developer-docs/latest/getting-started/introduction.html).
|
|
52
52
|
|
|
53
|
+
**Minimum environment requirements**
|
|
54
|
+
- Node.js `>=14.x.x`
|
|
55
|
+
- NPM `>=7.x.x`
|
|
56
|
+
|
|
57
|
+
In our minimum support we're following [official Node.js releases timelines](https://nodejs.org/en/about/releases/).
|
|
58
|
+
|
|
53
59
|
**Supported Strapi versions**:
|
|
54
60
|
|
|
55
|
-
- Strapi v4.0.
|
|
61
|
+
- Strapi v4.0.5 (recently tested)
|
|
62
|
+
- Strapi v4.x
|
|
56
63
|
|
|
57
64
|
(This plugin is not working with v3.x and not may work with the older Strapi v4 versions, but these are not tested nor officially supported at this time.)
|
|
58
65
|
|
|
@@ -76,10 +83,14 @@ To setup amend default plugin configuration we recommend to put following snippe
|
|
|
76
83
|
comments: {
|
|
77
84
|
badWords: false,
|
|
78
85
|
moderatorRoles: ["Authenticated"],
|
|
86
|
+
approvalFlow: ['api::page.page'],
|
|
79
87
|
entryLabel: {
|
|
80
88
|
'*': ['Title', 'title', 'Name', 'name', 'Subject', 'subject'],
|
|
81
89
|
'api::page.page': ['MyField'],
|
|
82
90
|
},
|
|
91
|
+
reportReasons: {
|
|
92
|
+
'MY_CUSTOM_REASON': 'MY_CUSTOM_REASON',
|
|
93
|
+
},
|
|
83
94
|
},
|
|
84
95
|
...
|
|
85
96
|
```
|
|
@@ -87,11 +98,28 @@ To setup amend default plugin configuration we recommend to put following snippe
|
|
|
87
98
|
### Properties
|
|
88
99
|
- `badWords` - Enabled support for [bad words filtering](https://www.npmjs.com/package/bad-words). Can be turned off or overwritten using [options reference](https://www.npmjs.com/package/bad-words#constructor). Default value: `true`.
|
|
89
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.
|
|
90
|
-
- `
|
|
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.
|
|
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'`.
|
|
91
104
|
|
|
92
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)**.
|
|
107
|
+
|
|
108
|
+
See [available GQL specification section](#public-graphql-specification).
|
|
109
|
+
|
|
110
|
+
## RBAC
|
|
111
|
+
Plugin provides granular permissions based on Strapi RBAC functionality.
|
|
112
|
+
|
|
113
|
+
### Mandatory permissions
|
|
114
|
+
For any role different than **Super Admin**, to access the **Comments panel** you must set following permissions:
|
|
115
|
+
- _Plugins_ -> _Content-type-builder_ -> _Read_ - gives you ability to fetch Content Type schema
|
|
116
|
+
- _Plugins_ -> _Comments_ -> _Comments: Read_ - gives you the basic read access to **Comments Panel**
|
|
93
117
|
|
|
94
|
-
|
|
118
|
+
### Optional permissions
|
|
119
|
+
Feature / Capability focused permissions:
|
|
120
|
+
- _Plugins_ -> _Comments_ -> _Comments: Moderate_ - allows you to block, unblock, approve & reject comments
|
|
121
|
+
- _Plugins_ -> _Comments_ -> _Reports: Read_ - allows you to see the list of issued abuse reports against comments
|
|
122
|
+
- _Plugins_ -> _Comments_ -> _Reports: Moderate_ - allows you to review (resolve) issued abuse reports against comments
|
|
95
123
|
|
|
96
124
|
## Public API Comment model
|
|
97
125
|
|
|
@@ -104,10 +132,14 @@ To setup amend default plugin configuration we recommend to put following snippe
|
|
|
104
132
|
"blockedThread": true,
|
|
105
133
|
"blockReason": null,
|
|
106
134
|
"authorUser": null,
|
|
107
|
-
"
|
|
108
|
-
"
|
|
109
|
-
"
|
|
110
|
-
|
|
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
|
+
},
|
|
111
143
|
"createdAt": "2020-07-14T20:13:01.649Z",
|
|
112
144
|
"updatedAt": "2020-07-14T20:13:01.670Z",
|
|
113
145
|
"related": {}, // Related content type entity
|
|
@@ -122,6 +154,8 @@ To setup amend default plugin configuration we recommend to put following snippe
|
|
|
122
154
|
"blocked": true,
|
|
123
155
|
"blockedThread": null,
|
|
124
156
|
"blockReason": null,
|
|
157
|
+
"removed": null,
|
|
158
|
+
"approvalStatus": "REJECTED", // Only in case of enabled approval flow. Default: null
|
|
125
159
|
"authorUser": {
|
|
126
160
|
"id": 1,
|
|
127
161
|
"username": "Sample User",
|
|
@@ -220,7 +254,6 @@ Posts a Comment related to specified instance of Content Type like for example `
|
|
|
220
254
|
},
|
|
221
255
|
"content": "My sample response",
|
|
222
256
|
"threadOf": 2, // id of comment we would like to start / continue the thread (Optional)
|
|
223
|
-
"related": "api::page.page:1"
|
|
224
257
|
}
|
|
225
258
|
```
|
|
226
259
|
|
|
@@ -230,7 +263,6 @@ Posts a Comment related to specified instance of Content Type like for example `
|
|
|
230
263
|
"authorUser": 1, // id of a author user. Optional in case of 'enableUsers: true' in the plugin configuration
|
|
231
264
|
"content": "My sample response",
|
|
232
265
|
"threadOf": 2, // id of comment we would like to start / continue the thread (Optional)
|
|
233
|
-
"related": "api::page.page:1"
|
|
234
266
|
}
|
|
235
267
|
```
|
|
236
268
|
|
|
@@ -308,7 +340,7 @@ Deletes a specified Comment based on it `commentId` and related to specified ins
|
|
|
308
340
|
- `409` - Conflict. Occurs when trying to delete a non existing comment.
|
|
309
341
|
|
|
310
342
|
|
|
311
|
-
### Report
|
|
343
|
+
### Issue Abuse Report against specified Comment
|
|
312
344
|
|
|
313
345
|
`POST <host>/comments/api::<collection name>.<content type name>:<entity id>/comment/<commentId>/report-abuse`
|
|
314
346
|
|
|
@@ -325,7 +357,7 @@ Reports abuse in specified Comment content based on it `commentId` and related t
|
|
|
325
357
|
}
|
|
326
358
|
```
|
|
327
359
|
|
|
328
|
-
*Available reason enums:* `
|
|
360
|
+
*Available reason enums:* `BAD_WORDS`, `OTHER`, `DISCRIMINATION` (want more? See [configuration section](#configuration).)
|
|
329
361
|
|
|
330
362
|
**Example response body**
|
|
331
363
|
|
|
@@ -339,6 +371,298 @@ Reports abuse in specified Comment content based on it `commentId` and related t
|
|
|
339
371
|
- `200` - Successful. Response with reported abuse.
|
|
340
372
|
- `409` - Conflict. Occurs when trying to report an abuse to a non existing comment.
|
|
341
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
|
+
|
|
342
666
|
## Examples
|
|
343
667
|
|
|
344
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.
|
|
@@ -18,7 +18,7 @@ import { getMessage, getUrl } from '../../utils';
|
|
|
18
18
|
import LoadingIndicatorOverlay from '../LoadingIndicatorOverlay';
|
|
19
19
|
import { LoadingIndicatorContainer } from '../LoadingIndicatorOverlay/styles';
|
|
20
20
|
|
|
21
|
-
const DiscussionThread = ({ level = [], selected = {}, isReloading }) => {
|
|
21
|
+
const DiscussionThread = ({ level = [], selected = {}, allowedActions, isReloading }) => {
|
|
22
22
|
const rootThread = selected?.threadOf;
|
|
23
23
|
return (<LoadingIndicatorContainer as={Box} padding={4}>
|
|
24
24
|
{ isReloading && <LoadingIndicatorOverlay />}
|
|
@@ -34,12 +34,14 @@ const DiscussionThread = ({ level = [], selected = {}, isReloading }) => {
|
|
|
34
34
|
<Divider />
|
|
35
35
|
</Box>
|
|
36
36
|
<Flex as="ul" direction="column" alignItems="flex-start">
|
|
37
|
-
{ rootThread && (<DiscussionThreadItem {...rootThread} isThreadAuthor root pinned />) }
|
|
37
|
+
{ rootThread && (<DiscussionThreadItem {...rootThread} allowedActions={allowedActions} isThreadAuthor root pinned />) }
|
|
38
38
|
{ level.map(item => {
|
|
39
39
|
const isSelected = selected.id === item.id;
|
|
40
40
|
const isThreadAuthor = !isNil(selected?.threadOf?.authorId) && (selected?.threadOf?.authorId === item.authorId);
|
|
41
41
|
return (<DiscussionThreadItem
|
|
42
|
+
key={`comment-${item.id}`}
|
|
42
43
|
{...item}
|
|
44
|
+
allowedActions={allowedActions}
|
|
43
45
|
root={isNil(rootThread)}
|
|
44
46
|
blockedThread={rootThread?.blockedThread || item.blockedThread}
|
|
45
47
|
isSelected={isSelected}
|
|
@@ -53,6 +55,11 @@ const DiscussionThread = ({ level = [], selected = {}, isReloading }) => {
|
|
|
53
55
|
DiscussionThread.propTypes = {
|
|
54
56
|
level: PropTypes.array.isRequired,
|
|
55
57
|
selected: PropTypes.object.isRequired,
|
|
58
|
+
allowedActions: PropTypes.shape({
|
|
59
|
+
canModerate: PropTypes.bool,
|
|
60
|
+
canAccessReports: PropTypes.bool,
|
|
61
|
+
canReviewReports: PropTypes.bool,
|
|
62
|
+
}),
|
|
56
63
|
isReloading: PropTypes.bool,
|
|
57
64
|
};
|
|
58
65
|
|
|
@@ -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,11 +16,24 @@ 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
|
-
const DiscussionThreadItem = (
|
|
24
|
-
const {
|
|
22
|
+
const DiscussionThreadItem = (props) => {
|
|
23
|
+
const {
|
|
24
|
+
isSelected,
|
|
25
|
+
isThreadAuthor,
|
|
26
|
+
content,
|
|
27
|
+
root,
|
|
28
|
+
preview,
|
|
29
|
+
pinned,
|
|
30
|
+
blocked,
|
|
31
|
+
removed,
|
|
32
|
+
blockedThread,
|
|
33
|
+
gotThread,
|
|
34
|
+
threadFirstItemId,
|
|
35
|
+
authorUser,
|
|
36
|
+
author } = props;
|
|
25
37
|
|
|
26
38
|
let background = 'neutral100';
|
|
27
39
|
let borderColor = 'neutral200';
|
|
@@ -45,11 +57,9 @@ const DiscussionThreadItem = (item) => {
|
|
|
45
57
|
StyledComponent = DiscussionThreadItemRoot;
|
|
46
58
|
}
|
|
47
59
|
|
|
48
|
-
const avatar =
|
|
49
|
-
const name =
|
|
60
|
+
const avatar = author?.avatar || authorUser?.avatar;
|
|
61
|
+
const name = author?.name || `${authorUser?.firstName} ${authorUser?.lastName}`;
|
|
50
62
|
const isBlocked = blocked || blockedThread;
|
|
51
|
-
|
|
52
|
-
const renderInitials = value => value.split(' ').map(_ => first(_)).join('').toUpperCase();
|
|
53
63
|
|
|
54
64
|
return (<StyledComponent as="li">
|
|
55
65
|
<DiscussionThreadItemContent as={Flex} direction="row">
|
|
@@ -62,16 +72,16 @@ const DiscussionThreadItem = (item) => {
|
|
|
62
72
|
<Box as={Flex} grow={1} alignItems="center">
|
|
63
73
|
<Typography variant="omega">{ content }</Typography>
|
|
64
74
|
</Box>
|
|
65
|
-
{ !preview && (<DiscussionThreadItemActions { ...
|
|
75
|
+
{ !preview && (<DiscussionThreadItemActions { ...props } root={root || pinned} />) }
|
|
66
76
|
</DiscussionThreadItemBoxContent>
|
|
67
|
-
{ !(preview || isBlocked) && (<DiscussionThreadItemWarnings { ...
|
|
77
|
+
{ !(preview || isBlocked || removed) && (<DiscussionThreadItemWarnings { ...props } gotThread={gotThread || root} />) }
|
|
68
78
|
</Flex>
|
|
69
79
|
<Divider background={dividerColor} />
|
|
70
|
-
<DiscussionThreadItemMeta { ...
|
|
80
|
+
<DiscussionThreadItemMeta { ...props } />
|
|
71
81
|
</DiscussionThreadItemBox>
|
|
72
82
|
</DiscussionThreadItemContent>
|
|
73
83
|
|
|
74
|
-
{ (gotThread && !(preview || pinned)) && (<DiscussionThreadItemLinkBox direction="column" alignItems="flex-end">
|
|
84
|
+
{ (gotThread && !(removed || preview || pinned)) && (<DiscussionThreadItemLinkBox direction="column" alignItems="flex-end">
|
|
75
85
|
<Link to={getUrl(`discover/${threadFirstItemId}`)} endIcon={<ArrowRight />}>
|
|
76
86
|
{ getMessage('page.details.panel.discussion.nav.drilldown') }
|
|
77
87
|
</Link>
|
|
@@ -81,6 +91,11 @@ const DiscussionThreadItem = (item) => {
|
|
|
81
91
|
|
|
82
92
|
DiscussionThreadItem.propTypes = {
|
|
83
93
|
content: PropTypes.string.isRequired,
|
|
94
|
+
allowedActions: PropTypes.shape({
|
|
95
|
+
canModerate: PropTypes.bool,
|
|
96
|
+
canAccessReports: PropTypes.bool,
|
|
97
|
+
canReviewReports: PropTypes.bool,
|
|
98
|
+
}),
|
|
84
99
|
};
|
|
85
100
|
|
|
86
101
|
export default DiscussionThreadItem;
|