strapi-plugin-comments 1.0.4 → 2.0.0-beta.1

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 (144) hide show
  1. package/.circleci/config.yml +2 -2
  2. package/README.md +47 -125
  3. package/admin/src/components/ConfirmationDialog/index.js +56 -0
  4. package/admin/src/components/DiscussionStatus/index.js +33 -0
  5. package/admin/src/components/DiscussionThread/index.js +58 -0
  6. package/admin/src/components/DiscussionThreadItem/index.js +87 -0
  7. package/admin/src/components/DiscussionThreadItem/styles.js +87 -0
  8. package/admin/src/components/DiscussionThreadItemActions/index.js +176 -0
  9. package/admin/src/components/DiscussionThreadItemActions/styles.js +22 -0
  10. package/admin/src/components/DiscussionThreadItemMeta/index.js +31 -0
  11. package/admin/src/components/DiscussionThreadItemWarnings/index.js +137 -0
  12. package/admin/src/components/DiscussionThreadItemWarnings/styles.js +7 -0
  13. package/admin/src/components/EntityDetails/index.js +53 -0
  14. package/admin/src/{containers → components}/Initializer/index.js +4 -4
  15. package/admin/src/components/LoadingIndicatorOverlay/index.js +15 -0
  16. package/admin/src/components/LoadingIndicatorOverlay/styles.js +20 -0
  17. package/admin/src/components/Nav/index.js +45 -0
  18. package/admin/src/components/PluginIcon/index.js +12 -0
  19. package/admin/src/components/ReportsReviewModal/index.js +45 -0
  20. package/admin/src/components/ReportsReviewTable/index.js +142 -0
  21. package/admin/src/components/TableFilters/index.js +53 -0
  22. package/admin/src/components/TablePagination/index.js +35 -0
  23. package/admin/src/components/icons/comments.js +9 -0
  24. package/admin/src/index.js +56 -42
  25. package/admin/src/pages/App/index.js +32 -0
  26. package/admin/src/pages/ComingSoonPage/index.js +25 -0
  27. package/admin/src/pages/Details/index.js +109 -0
  28. package/admin/src/pages/Details/utils/api.js +41 -0
  29. package/admin/src/pages/Discover/index.js +185 -0
  30. package/admin/src/pages/Discover/utils/api.js +23 -0
  31. package/admin/src/pages/Discover/utils/filtersSchema.js +9 -0
  32. package/admin/src/permissions.js +13 -37
  33. package/admin/src/pluginId.js +2 -4
  34. package/admin/src/translations/en.json +72 -37
  35. package/admin/src/translations/fr.json +1 -0
  36. package/admin/src/utils/axiosInstance.js +35 -0
  37. package/admin/src/utils/constants.js +25 -6
  38. package/admin/src/utils/getApiUrl.js +5 -0
  39. package/admin/src/utils/getMessage.js +14 -0
  40. package/admin/src/utils/getRelatedGroups.js +5 -0
  41. package/admin/src/utils/getUrl.js +5 -0
  42. package/admin/src/utils/handleAPIError.js +15 -0
  43. package/admin/src/utils/index.js +6 -0
  44. package/codecov.yml +2 -1
  45. package/content-types/comment.js +97 -0
  46. package/content-types/index.js +11 -0
  47. package/content-types/report.js +54 -0
  48. package/package.json +11 -25
  49. package/server/bootstrap.js +5 -0
  50. package/server/config/index.js +6 -0
  51. package/server/controllers/admin.js +150 -0
  52. package/server/controllers/client.js +109 -0
  53. package/server/controllers/index.js +9 -0
  54. package/{controllers → server/controllers}/utils/__tests__/functions.test.js +0 -0
  55. package/{controllers → server/controllers}/utils/functions.js +1 -1
  56. package/server/destroy.js +5 -0
  57. package/server/index.js +22 -0
  58. package/server/register.js +5 -0
  59. package/server/routes/admin.js +92 -0
  60. package/server/routes/client.js +52 -0
  61. package/server/routes/index.js +15 -0
  62. package/server/services/admin.js +180 -0
  63. package/server/services/client.js +227 -0
  64. package/server/services/common.js +191 -0
  65. package/server/services/index.js +11 -0
  66. package/{services → server/services}/utils/__tests__/functions.test.js +0 -0
  67. package/{services → server/services}/utils/functions.js +17 -6
  68. package/server/utils/constants.js +16 -0
  69. package/{services → server}/utils/error.js +0 -0
  70. package/server/utils/functions.js +19 -0
  71. package/strapi-admin.js +3 -0
  72. package/strapi-server.js +9 -0
  73. package/admin/src/assets/images/icon-cross-blue.svg +0 -1
  74. package/admin/src/assets/images/icon_remove.svg +0 -19
  75. package/admin/src/assets/images/logo.svg +0 -5
  76. package/admin/src/components/AbuseReportsPopUp/ItemPreviewContainer.js +0 -8
  77. package/admin/src/components/AbuseReportsPopUp/ModalFooter.js +0 -31
  78. package/admin/src/components/AbuseReportsPopUp/TableContainer.js +0 -63
  79. package/admin/src/components/AbuseReportsPopUp/index.js +0 -148
  80. package/admin/src/components/Container/index.js +0 -7
  81. package/admin/src/components/EmptyView/index.js +0 -25
  82. package/admin/src/components/Filters/index.js +0 -151
  83. package/admin/src/components/Filters/index.styled.js +0 -82
  84. package/admin/src/components/Filters/utils.js +0 -21
  85. package/admin/src/components/Item/CardItem.js +0 -30
  86. package/admin/src/components/Item/CardWrapper.js +0 -10
  87. package/admin/src/components/Item/index.js +0 -107
  88. package/admin/src/components/ItemDetails/CardItem.js +0 -33
  89. package/admin/src/components/ItemDetails/CardLevelCounter.js +0 -46
  90. package/admin/src/components/ItemDetails/CardLevelCounterLink.js +0 -24
  91. package/admin/src/components/ItemDetails/CardLevelWrapper.js +0 -22
  92. package/admin/src/components/ItemDetails/CardWrapper.js +0 -52
  93. package/admin/src/components/ItemDetails/index.js +0 -167
  94. package/admin/src/components/ItemFooter/CardItemAuthor.js +0 -10
  95. package/admin/src/components/ItemFooter/CardItemRelation.js +0 -18
  96. package/admin/src/components/ItemFooter/Wrapper.js +0 -20
  97. package/admin/src/components/ItemFooter/index.js +0 -87
  98. package/admin/src/components/ItemHeader/CardHeaderBlocked.js +0 -24
  99. package/admin/src/components/ItemHeader/CardHeaderIndicator.js +0 -30
  100. package/admin/src/components/ItemHeader/CardHeaderIndicatorBlue.js +0 -11
  101. package/admin/src/components/ItemHeader/CardHeaderIndicatorRed.js +0 -11
  102. package/admin/src/components/ItemHeader/CardHeaderIndicatorsContainer.js +0 -18
  103. package/admin/src/components/ItemHeader/CardHeaderPending.js +0 -11
  104. package/admin/src/components/ItemHeader/CardHeaderReports.js +0 -40
  105. package/admin/src/components/ItemHeader/Wrapper.js +0 -16
  106. package/admin/src/components/ItemHeader/index.js +0 -97
  107. package/admin/src/components/ItemModeration/Wrapper.js +0 -19
  108. package/admin/src/components/ItemModeration/index.js +0 -84
  109. package/admin/src/components/List/Container.js +0 -20
  110. package/admin/src/components/List/index.js +0 -21
  111. package/admin/src/components/Search/index.js +0 -83
  112. package/admin/src/containers/App/Wrapper.js +0 -14
  113. package/admin/src/containers/App/index.js +0 -47
  114. package/admin/src/containers/DataManagerProvider/actions.js +0 -15
  115. package/admin/src/containers/DataManagerProvider/index.js +0 -332
  116. package/admin/src/containers/DataManagerProvider/init.js +0 -5
  117. package/admin/src/containers/DataManagerProvider/reducer.js +0 -59
  118. package/admin/src/containers/DetailsView/Wrapper.js +0 -18
  119. package/admin/src/containers/DetailsView/index.js +0 -106
  120. package/admin/src/containers/ListView/FadedWrapper.js +0 -42
  121. package/admin/src/containers/ListView/Footer.js +0 -53
  122. package/admin/src/containers/ListView/Wrapper.js +0 -17
  123. package/admin/src/containers/ListView/components.js +0 -138
  124. package/admin/src/containers/ListView/index.js +0 -45
  125. package/admin/src/containers/Panel/actions.js +0 -5
  126. package/admin/src/containers/Panel/index.js +0 -191
  127. package/admin/src/containers/Panel/index.styled.js +0 -6
  128. package/admin/src/containers/Panel/reducer.js +0 -44
  129. package/admin/src/contexts/DataManagerContext.js +0 -5
  130. package/admin/src/hooks/useDataManager.js +0 -6
  131. package/admin/src/lifecycles.js +0 -3
  132. package/admin/src/translations/index.js +0 -7
  133. package/admin/src/utils/getTrad.js +0 -5
  134. package/admin/src/utils/getTradId.js +0 -5
  135. package/config/functions/bootstrap.js +0 -62
  136. package/config/routes.json +0 -142
  137. package/config/schema.graphql.js +0 -268
  138. package/controllers/comments.js +0 -228
  139. package/models/comment.js +0 -8
  140. package/models/comment.settings.json +0 -102
  141. package/models/report.js +0 -8
  142. package/models/report.settings.json +0 -49
  143. package/services/comments.js +0 -539
  144. package/services/utils/constants.js +0 -9
@@ -20,7 +20,7 @@ jobs:
20
20
  - restore_cache:
21
21
  keys:
22
22
  # when lock file changes, use increasingly general patterns to restore cache
23
- - strapi-plugin-comments-v1-{{ checksum "yarn.lock" }}
23
+ - strapi-plugin-comments-v2-{{ checksum "yarn.lock" }}
24
24
  - strapi-plugin-comments-
25
25
  - run:
26
26
  name: Echo versions
@@ -41,7 +41,7 @@ jobs:
41
41
  - save_cache:
42
42
  paths:
43
43
  - ./node_modules
44
- key: strapi-plugin-comments-v1-{{ checksum "yarn.lock" }}
44
+ key: strapi-plugin-comments-v2-{{ checksum "yarn.lock" }}
45
45
  workflows:
46
46
  build-and-test:
47
47
  jobs:
package/README.md CHANGED
@@ -1,4 +1,4 @@
1
- # Strapi - Comments plugin
1
+ # Strapi v4 - Comments plugin - BETA
2
2
 
3
3
  <p align="center">
4
4
  <a href="https://www.npmjs.org/package/strapi-plugin-comments">
@@ -17,7 +17,9 @@
17
17
 
18
18
  A plugin for [Strapi Headless CMS](https://github.com/strapi/strapi) that provides end to end comments feature with their moderation panel, bad words filtering, abuse reporting and more.
19
19
 
20
- <img src="public/assets/preview.png" alt="UI preview" />
20
+ ### Versions
21
+ - **Stable** - [v1.0.4](https://github.com/VirtusLab-Open-Source/strapi-plugin-comments)
22
+ - **Beta** - v4 support - [v2.0.0-beta.x](https://github.com/VirtusLab-Open-Source/strapi-plugin-comments/tree/feat/strapi-v4)
21
23
 
22
24
  ### ⏳ Installation
23
25
 
@@ -46,14 +48,13 @@ Enjoy 🎉
46
48
 
47
49
  ### 🖐 Requirements
48
50
 
49
- Complete installation requirements are exact same as for Strapi itself and can be found in the documentation under [Installation Requirements](https://strapi.io/documentation/v3.x/installation/cli.html#step-1-make-sure-requirements-are-met).
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).
50
52
 
51
53
  **Supported Strapi versions**:
52
54
 
53
- - Strapi v3.6.8 (recently tested)
54
- - Strapi v3.x
55
+ - Strapi v4.0.2 (recently tested)
55
56
 
56
- (This plugin may work with the older Strapi versions, but these are not tested nor officially supported at this time.)
57
+ (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.)
57
58
 
58
59
  **We recommend always using the latest version of Strapi to start your new projects**.
59
60
 
@@ -66,32 +67,6 @@ Complete installation requirements are exact same as for Strapi itself and can b
66
67
  - **Automated Bad Words filtering:** By detault end users are not allowed to post abusing comments where bad words have been used.
67
68
  - **Abuse Reporting & Reviewing:** Don't allow inferior language, react to reports from your community, send email notifiactions about abuse reports
68
69
 
69
- ## Content Type model relation to Comment
70
-
71
- To enable Content Type to work with Comments, you've to add following field to your model `*.settings.json`:
72
-
73
- ```json
74
- "comments": {
75
- "plugin": "comments",
76
- "collection": "comment",
77
- "via": "related"
78
- }
79
- ```
80
-
81
- inside the `attributes` section like in example below:
82
-
83
- ```json
84
- "attributes": {
85
- ...,
86
- "comments": {
87
- "plugin": "comments",
88
- "collection": "comment",
89
- "via": "related"
90
- },
91
- ...
92
- },
93
- ```
94
-
95
70
  ## Configuration
96
71
  To setup amend default plugin configuration we recommend to put following snippet as part of `config/plugins.js` or `config/<env>/plugins.js` file. If the file does not exist yet, you have to create it manually. If you've got already configurations for other plugins stores by this way, use just the `comments` part within exising `plugins` item.
97
72
 
@@ -99,50 +74,19 @@ To setup amend default plugin configuration we recommend to put following snippe
99
74
  ```js
100
75
  ...
101
76
  comments: {
102
- enableUsers: true,
103
77
  badWords: false,
104
- moderatorRoles: ["Authenticated"]
78
+ moderatorRoles: ["Authenticated"]
105
79
  },
106
80
  ...
107
81
  ```
108
82
 
109
83
  ### Properties
110
- - `enableUsers` - Enabled support for built-in Strapi users, if endpoints are exposed with usage of `Authenticated` policy or JWT tokens are in use by the Client App. Default value: `false`.
111
84
  - `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`.
112
- - `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://strapi.io/documentation/developer-docs/latest/development/plugins/email.html) configured.
85
+ - `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.
113
86
 
114
87
  ## Additional GQL Configuration
115
88
 
116
- > **Note**
117
- > Introduced in `v1.0.2`
118
-
119
- ```js
120
- ...
121
- comments: {
122
- enableUsers: true,
123
- badWords: false,
124
- relatedContentTypes: {
125
- pages: {
126
- uuid: 'application::pages.pages',
127
- contentManager: true,
128
- isSingle: true, // optional
129
- __contentType: '',
130
- key: 'title',
131
- value: 'id',
132
- url: 'my-custom-url/:id' // optional
133
- }
134
- }
135
- },
136
- ...
137
- ```
138
-
139
- ### Properties
140
- - `relatedContentTypes` - list of properties where each single one reflects the related collection like `pages`, `posts`, etc. Each of collection properties should contain following set:
141
- - `uuid` - strapi content type `uuid`
142
- - `contentManager` - boolean to mark if element taken from **Strapi Content Manager** or maybe custom plugin
143
- - `isSingle` (optional) - boolean to identify collection type or single type
144
- - `key/value` - will be used to take id and example title to display link on the list
145
- - `url` (optional) - to be defined if `contentManager` is set to **false**. Reflects the custom url that returns the content type items. With id as identifier - which is dynamically replaced
89
+ > To be done
146
90
 
147
91
  ## Public API Comment model
148
92
 
@@ -154,14 +98,15 @@ To setup amend default plugin configuration we recommend to put following snippe
154
98
  "blocked": null,
155
99
  "blockedThread": true,
156
100
  "blockReason": null,
157
- "points": 1,
158
101
  "authorUser": null,
159
102
  "authorId": "207ccfdc-94ba-45eb-979c-790f6f49c392",
160
103
  "authorName": "Joe Doe",
161
104
  "authorEmail": "jdoe@sample.com",
162
105
  "authorAvatar": null,
163
- "created_at": "2020-07-14T20:13:01.649Z",
164
- "updated_at": "2020-07-14T20:13:01.670Z"
106
+ "createdAt": "2020-07-14T20:13:01.649Z",
107
+ "updatedAt": "2020-07-14T20:13:01.670Z",
108
+ "related": {}, // Related content type entity
109
+ "reports": [] // Reports issued against this comment
165
110
  }
166
111
  ```
167
112
  ### Strapi User
@@ -172,7 +117,6 @@ To setup amend default plugin configuration we recommend to put following snippe
172
117
  "blocked": true,
173
118
  "blockedThread": null,
174
119
  "blockReason": null,
175
- "points": null,
176
120
  "authorUser": {
177
121
  "id": 1,
178
122
  "username": "Sample User",
@@ -188,8 +132,10 @@ To setup amend default plugin configuration we recommend to put following snippe
188
132
  "authorName": null,
189
133
  "authorEmail": null,
190
134
  "authorAvatar": null,
191
- "created_at": "2020-07-14T20:13:01.649Z",
192
- "updated_at": "2020-07-14T20:13:01.670Z"
135
+ "createdAt": "2020-07-14T20:13:01.649Z",
136
+ "updatedAt": "2020-07-14T20:13:01.670Z",
137
+ "related": {}, // Related content type entity
138
+ "reports": [] // Reports issued against this comment
193
139
  }
194
140
 
195
141
  ```
@@ -198,11 +144,11 @@ To setup amend default plugin configuration we recommend to put following snippe
198
144
 
199
145
  ### Get Comments
200
146
 
201
- `GET <host>/comments/<content-type>:<id>`
147
+ `GET <host>/comments/api::<collection name>.<content type name>:<entity id>`
202
148
 
203
- Return a hierarchical tree structure of comments for specified instance of Content Type like for example `Article` with `ID: 1`
149
+ Return a hierarchical tree structure of comments for specified instance of Content Type like for example `Page` with `ID: 1`
204
150
 
205
- **Example URL**: `https://localhost:1337/comments/article:1`
151
+ **Example URL**: `https://localhost:1337/comments/api::page.page:1`
206
152
 
207
153
  **Example response body**
208
154
 
@@ -224,11 +170,11 @@ Return a hierarchical tree structure of comments for specified instance of Conte
224
170
 
225
171
  ### Get Comments (flat structure)
226
172
 
227
- `GET <host>/comments/<content-type>:<id>/flat`
173
+ `GET <host>/comments/api::<collection name>.<content type name>:<entity id>/flat`
228
174
 
229
- Return a flat structure of comments for specified instance of Content Type like for example `Article` with `ID: 1`
175
+ Return a flat structure of comments for specified instance of Content Type like for example `Page` with `ID: 1`
230
176
 
231
- **Example URL**: `https://localhost:1337/comments/article:1/flat`
177
+ **Example URL**: `https://localhost:1337/comments/api::page.page:1/flat`
232
178
 
233
179
  **Example response body**
234
180
 
@@ -250,27 +196,26 @@ Return a flat structure of comments for specified instance of Content Type like
250
196
 
251
197
  ### Post a Comment
252
198
 
253
- `POST <host>/comments/<content-type>:<id>`
199
+ `POST <host>/comments/api::<collection name>.<content type name>:<entity id>`
254
200
 
255
- Posts a Comment related to specified instance of Content Type like for example `Article` with `ID: 1`
201
+ Posts a Comment related to specified instance of Content Type like for example `Page` with `ID: 1`
256
202
 
257
- **Example URL**: `https://localhost:1337/comments/article:1`
203
+ **Example URL**: `https://localhost:1337/comments/api::page.page:1`
258
204
 
259
205
  **Example request body**
260
206
 
261
207
  *Generic (non Strapi User)*
262
208
  ```
263
209
  {
264
- "authorId": "<any ID like value>",
265
- "authorName": "Joe Doe",
266
- "authorEmail": "jdoe@sample.com",
210
+ "author": {
211
+ "id": "<any ID like value>",
212
+ "name": "Joe Doe",
213
+ "email": "jdoe@sample.com",
214
+ "avatar": "<any image url>"
215
+ },
267
216
  "content": "My sample response",
268
217
  "threadOf": 2, // id of comment we would like to start / continue the thread (Optional)
269
- "related": [{
270
- "refId": 1,
271
- "ref": "article",
272
- "field": "comments"
273
- }]
218
+ "related": "api::page.page:1"
274
219
  }
275
220
  ```
276
221
 
@@ -280,11 +225,7 @@ Posts a Comment related to specified instance of Content Type like for example `
280
225
  "authorUser": 1, // id of a author user. Optional in case of 'enableUsers: true' in the plugin configuration
281
226
  "content": "My sample response",
282
227
  "threadOf": 2, // id of comment we would like to start / continue the thread (Optional)
283
- "related": [{
284
- "refId": 1,
285
- "ref": "article",
286
- "field": "comments"
287
- }]
228
+ "related": "api::page.page:1"
288
229
  }
289
230
  ```
290
231
 
@@ -302,20 +243,20 @@ Posts a Comment related to specified instance of Content Type like for example `
302
243
 
303
244
  ### Update Comment
304
245
 
305
- `PUT <host>/comments/<content-type>:<id>/comment/<commentId>`
246
+ `PUT <host>/comments/api::<collection name>.<content type name>:<entity id>/comment/<commentId>`
306
247
 
307
- Updates a specified Comment content based on it `commentId` and related to specified instance of Content Type like for example `Article` with `ID: 1`
248
+ Updates a specified Comment content based on it `commentId` and related to specified instance of Content Type like for example `Page` with `ID: 1`
308
249
 
309
- **Example URL**: `https://localhost:1337/comments/article:1/comment/2`
250
+ **Example URL**: `https://localhost:1337/comments/api::page.page:1/comment/2`
310
251
 
311
252
  **Example request body**
312
253
 
313
254
  *Generic (non Strapi User)*
314
255
  ```
315
256
  {
316
- "authorId": "<any ID like value>",
317
- "authorName": "Joe Doe",
318
- "authorEmail": "jdoe@sample.com",
257
+ "author": {
258
+ "id": "<any ID like value>"
259
+ },
319
260
  "content": "My sample response"
320
261
  }
321
262
  ```
@@ -343,11 +284,11 @@ Updates a specified Comment content based on it `commentId` and related to speci
343
284
 
344
285
  ### Delete Comment
345
286
 
346
- `DELETE <host>/comments/<content-type>:<id>/<commentId>?authorId=<authorId>`
287
+ `DELETE <host>/comments/api::<collection name>.<content type name>:<entity id>/<commentId>?authorId=<authorId>`
347
288
 
348
- Deletes a specified Comment based on it `commentId` and related to specified instance of Content Type like for example `Article` with `ID: 1`.
289
+ Deletes a specified Comment based on it `commentId` and related to specified instance of Content Type like for example `Page` with `ID: 1`.
349
290
 
350
- **Example URL**: `https://localhost:1337/comments/article:1/1?authorId=1`
291
+ **Example URL**: `https://localhost:1337/comments/api::page.page:1/comment/1?authorId=1`
351
292
 
352
293
  **Example response body**
353
294
 
@@ -361,33 +302,14 @@ Deletes a specified Comment based on it `commentId` and related to specified ins
361
302
  - `200` - Successful with blank Response.
362
303
  - `409` - Conflict. Occurs when trying to delete a non existing comment.
363
304
 
364
- ### Like Comment
365
-
366
- `PATCH <host>/comments/<content-type>:<id>/comment/<commentId>/like`
367
-
368
- Likes a specified Comment based on it `commentId` and related to specified instance of Content Type like for example `Article` with `ID: 1`.
369
-
370
- **Example URL**: `https://localhost:1337/comments/article:1/comment/2/like`
371
-
372
- **Example response body**
373
-
374
- ```
375
- {
376
- -- Comment Model fields ---
377
- }
378
- ```
379
-
380
- **Possible response codes**
381
- - `200` - Successful. Response with liked Comment Model.
382
- - `409` - Conflict. Occurs when trying to like a non existing comment.
383
305
 
384
306
  ### Report abuse in the Comment
385
307
 
386
- `POST <host>/comments/<content-type>:<id>/comment/<commentId>/report-abuse`
308
+ `POST <host>/comments/api::<collection name>.<content type name>:<entity id>/comment/<commentId>/report-abuse`
387
309
 
388
- Reports abuse in specified Comment content based on it `commentId` and related to specified instance of Content Type like for example `Article` with `ID: 1` and requests moderator attention.
310
+ Reports abuse in specified Comment content based on it `commentId` and related to specified instance of Content Type like for example `Page` with `ID: 1` and requests moderator attention.
389
311
 
390
- **Example URL**: `https://localhost:1337/comments/article:1/comment/2/report-abuse`
312
+ **Example URL**: `https://localhost:1337/comments/api::page.page:1/comment/2/report-abuse`
391
313
 
392
314
  **Example request body**
393
315
 
@@ -0,0 +1,56 @@
1
+ /**
2
+ *
3
+ * Entity Details
4
+ *
5
+ */
6
+
7
+ import React from 'react';
8
+ import PropTypes from 'prop-types';
9
+ import { Button } from '@strapi/design-system/Button';
10
+ import { Dialog, DialogBody, DialogFooter } from '@strapi/design-system/Dialog';
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
+ import { ExclamationMarkCircle, Check } from '@strapi/icons';
15
+ import { getMessage } from '../../utils';
16
+
17
+ const ConfirmationDialog = ({
18
+ isVisible = false,
19
+ isActionAsync = false,
20
+ children,
21
+ onConfirm,
22
+ onCancel,
23
+ header,
24
+ labelCancel,
25
+ labelConfirm,
26
+ iconConfirm
27
+ }) => (
28
+ <Dialog onClose={onCancel} title={header || getMessage('compontents.confirmation.dialog.header', 'Confirmation')} isOpen={isVisible}>
29
+ <DialogBody icon={<ExclamationMarkCircle />}>
30
+ <Stack size={2}>
31
+ <Flex justifyContent="center">
32
+ <Typography id="dialog-confirm-description">{children || getMessage('compontents.confirmation.dialog.description') }</Typography>
33
+ </Flex>
34
+ </Stack>
35
+ </DialogBody>
36
+ <DialogFooter startAction={<Button onClick={onCancel} variant="tertiary" disabled={isActionAsync}>
37
+ { labelCancel || getMessage('compontents.confirmation.dialog.button.cancel', 'Cancel') }
38
+ </Button>} endAction={<Button onClick={onConfirm} variant="danger-light" startIcon={iconConfirm || <Check />} disabled={isActionAsync}>
39
+ { labelConfirm || getMessage('compontents.confirmation.dialog.button.confirm', 'Confirm') }
40
+ </Button>} />
41
+ </Dialog>
42
+ );
43
+
44
+ ConfirmationDialog.propTypes = {
45
+ isVisible: PropTypes.bool,
46
+ isActionAsync: PropTypes.bool,
47
+ children: PropTypes.array.isRequired,
48
+ header: PropTypes.string,
49
+ labelCancel: PropTypes.string,
50
+ labelConfirm: PropTypes.string,
51
+ iconConfirm: PropTypes.object,
52
+ onConfirm: PropTypes.func.isRequired,
53
+ onCancel: PropTypes.func.isRequired,
54
+ };
55
+
56
+ export default ConfirmationDialog;
@@ -0,0 +1,33 @@
1
+ /**
2
+ *
3
+ * Entity Details
4
+ *
5
+ */
6
+
7
+ import React from 'react';
8
+ import PropTypes from 'prop-types';
9
+ import { isNil } from 'lodash';
10
+ import { Box } from '@strapi/design-system/Box';
11
+ import { Status } from '@strapi/design-system/Status';
12
+ import { Typography } from '@strapi/design-system/Typography';
13
+ import { getMessage } from '../../utils';
14
+
15
+ const DiscussionStatus = ({ blocked, blockedThread }) => {
16
+ let variant = 'success';
17
+
18
+ return (
19
+ <Box styles={{ marginBottom: 10 }}>
20
+ <Status variant={variant}>
21
+ <Typography>
22
+ { getMessage('page.details.panel.status', 'Discussion is') } <Typography fontWeight="bold">{ getMessage('page.details.panel.open', 'OPEN') } </Typography>
23
+ </Typography>
24
+ </Status>
25
+ </Box>);
26
+ };
27
+
28
+ DiscussionStatus.propTypes = {
29
+
30
+ };
31
+
32
+ export default DiscussionStatus;
33
+
@@ -0,0 +1,58 @@
1
+ /**
2
+ *
3
+ * Entity Details
4
+ *
5
+ */
6
+
7
+ import React from 'react';
8
+ import PropTypes from 'prop-types';
9
+ import { isNil } from 'lodash';
10
+ import { Box } from '@strapi/design-system/Box';
11
+ import { Divider } from '@strapi/design-system/Divider';
12
+ import { Flex } from '@strapi/design-system/Flex';
13
+ import { Link } from '@strapi/design-system/Link';
14
+ import { Typography } from '@strapi/design-system/Typography';
15
+ import { ArrowUp } from '@strapi/icons';
16
+ import DiscussionThreadItem from '../DiscussionThreadItem';
17
+ import { getMessage, getUrl } from '../../utils';
18
+ import LoadingIndicatorOverlay from '../LoadingIndicatorOverlay';
19
+ import { LoadingIndicatorContainer } from '../LoadingIndicatorOverlay/styles';
20
+
21
+ const DiscussionThread = ({ level = [], selected = {}, isReloading }) => {
22
+ const rootThread = selected?.threadOf;
23
+ return (<LoadingIndicatorContainer as={Box} padding={4}>
24
+ { isReloading && <LoadingIndicatorOverlay />}
25
+ <Flex as={Box} direction="row" justifyContent="space-between">
26
+ <Typography variant="sigma" textColor="neutral600" id="entity-details">
27
+ { getMessage('page.details.panel.discussion', 'Discussion') }
28
+ </Typography>
29
+ { rootThread && (<Link to={getUrl(`discover/${rootThread.id}`)} startIcon={<ArrowUp />}>
30
+ { getMessage('page.details.panel.discussion.nav.back') }
31
+ </Link>) }
32
+ </Flex>
33
+ <Box paddingTop={2} paddingBottom={6}>
34
+ <Divider />
35
+ </Box>
36
+ <Flex as="ul" direction="column" alignItems="flex-start">
37
+ { rootThread && (<DiscussionThreadItem {...rootThread} isThreadAuthor root />) }
38
+ { level.map(item => {
39
+ const isSelected = selected.id === item.id;
40
+ const isThreadAuthor = !isNil(selected?.threadOf?.authorId) && (selected?.threadOf?.authorId === item.authorId);
41
+ return (<DiscussionThreadItem
42
+ {...item}
43
+ blockedThread={rootThread?.blockedThread || item.blockedThread}
44
+ isSelected={isSelected}
45
+ isThreadAuthor={isThreadAuthor}
46
+ />);
47
+ })}
48
+ </Flex>
49
+ </LoadingIndicatorContainer>);
50
+ };
51
+
52
+ DiscussionThread.propTypes = {
53
+ level: PropTypes.array.isRequired,
54
+ selected: PropTypes.object.isRequired,
55
+ isReloading: PropTypes.bool,
56
+ };
57
+
58
+ export default DiscussionThread;
@@ -0,0 +1,87 @@
1
+ /**
2
+ *
3
+ * Entity Details
4
+ *
5
+ */
6
+
7
+ import React from 'react';
8
+ import PropTypes from 'prop-types';
9
+ import { first } from 'lodash';
10
+ import { Avatar, Initials } from '@strapi/design-system/Avatar';
11
+ import { Box } from '@strapi/design-system/Box';
12
+ import { Divider } from '@strapi/design-system/Divider';
13
+ import { Flex } from '@strapi/design-system/Flex';
14
+ import { Link } from '@strapi/design-system/Link';
15
+ import { Typography } from '@strapi/design-system/Typography';
16
+ import { ArrowRight } from '@strapi/icons';
17
+ import DiscussionThreadItemMeta from '../DiscussionThreadItemMeta';
18
+ import { AvatarWrapper, DiscussionThreadItemBox, DiscussionThreadItemBoxContent, DiscussionThreadItemContent, DiscussionThreadItemLeft, DiscussionThreadItemLinkBox, DiscussionThreadItemRight, DiscussionThreadItemRoot } from './styles';
19
+ import DiscussionThreadItemActions from '../DiscussionThreadItemActions';
20
+ import { getMessage, getUrl } from '../../utils';
21
+ import DiscussionThreadItemWarnings from '../DiscussionThreadItemWarnings';
22
+
23
+ const DiscussionThreadItem = (item) => {
24
+ const { id, isSelected, isThreadAuthor, content, root, preview, blocked, blockedThread, gotThread, threadFirstItemId, authorUser, authorAvatar, authorName } = item;
25
+
26
+ let background = 'neutral100';
27
+ let borderColor = 'neutral200';
28
+ let dividerColor = 'neutral200';
29
+ let StyledComponent = DiscussionThreadItemRight;
30
+
31
+ if(isThreadAuthor || root){
32
+ StyledComponent = DiscussionThreadItemLeft;
33
+ borderColor = 'neutral100';
34
+ dividerColor = 'neutral100';
35
+ background = null;
36
+ }
37
+
38
+ if (isSelected) {
39
+ background = 'secondary100'
40
+ borderColor = 'secondary500';
41
+ dividerColor = 'secondary200';
42
+ }
43
+
44
+ if (root) {
45
+ StyledComponent = DiscussionThreadItemRoot;
46
+ }
47
+
48
+ const avatar = authorAvatar || authorUser?.avatar;
49
+ const name = authorName || `${authorUser?.firstName} ${authorUser?.lastName}`;
50
+ const isBlocked = blocked || blockedThread;
51
+
52
+ const renderInitials = value => value.split(' ').map(_ => first(_)).join('').toUpperCase();
53
+
54
+ return (<StyledComponent as="li">
55
+ <DiscussionThreadItemContent as={Flex} direction="row">
56
+ <AvatarWrapper>
57
+ { avatar ? <Avatar src={avatar} alt={name} /> : <Initials>{ renderInitials(name) }</Initials> }
58
+ </AvatarWrapper>
59
+ <DiscussionThreadItemBox hasRadius shadow="filterShadow" borderColor={borderColor} background={background} padding={2}>
60
+ <Flex as={Box} paddingBottom={2} direction="column">
61
+ <DiscussionThreadItemBoxContent as={Flex} direction="row">
62
+ <Box as={Flex} grow={1} alignItems="center">
63
+ <Typography variant="omega">{ content }</Typography>
64
+ </Box>
65
+ { !preview && (<DiscussionThreadItemActions { ...item } root={root} />) }
66
+ </DiscussionThreadItemBoxContent>
67
+ { !(preview || isBlocked) && (<DiscussionThreadItemWarnings { ...item } />) }
68
+ </Flex>
69
+ <Divider background={dividerColor} />
70
+ <DiscussionThreadItemMeta { ...item } />
71
+ </DiscussionThreadItemBox>
72
+ </DiscussionThreadItemContent>
73
+
74
+ { (gotThread && !preview) && (<DiscussionThreadItemLinkBox direction="row" alignItems="flex-end">
75
+ <Link to={getUrl(`discover/${threadFirstItemId}`)} endIcon={<ArrowRight />}>
76
+ { getMessage('page.details.panel.discussion.nav.drilldown') }
77
+ </Link>
78
+ </DiscussionThreadItemLinkBox>) }
79
+ </StyledComponent>);
80
+ };
81
+
82
+ DiscussionThreadItem.propTypes = {
83
+ content: PropTypes.string.isRequired,
84
+ };
85
+
86
+ export default DiscussionThreadItem;
87
+
@@ -0,0 +1,87 @@
1
+ import styled from 'styled-components';
2
+ import { Box } from '@strapi/design-system/Box';
3
+ import { Flex } from '@strapi/design-system/Flex';
4
+
5
+ export const AvatarWrapper = styled(Box)``;
6
+ export const InitialsWrapper = styled(Box)``;
7
+
8
+ export const DiscussionThreadItemLinkBox = styled(Flex)`
9
+ margin-top: .5rem;
10
+ margin-bottom: .5rem;
11
+ `
12
+
13
+ const DiscussionThreadItemStyled = styled(Box)`
14
+ display: flex;
15
+ flex-direction: column;
16
+ width: 100%;
17
+ margin-bottom: 1rem;
18
+
19
+ ${AvatarWrapper},
20
+ ${InitialsWrapper} {
21
+ align-self: flex-start;
22
+ margin-top: .4rem;
23
+ }
24
+ `;
25
+
26
+ export const DiscussionThreadItemContent = styled(Box)`
27
+ max-width: 45%;
28
+ `;
29
+
30
+ export const DiscussionThreadItemLeft = styled(DiscussionThreadItemStyled)`
31
+ align-items: flex-start;
32
+ padding-left: 4rem;
33
+ text-align: left;
34
+
35
+ ${DiscussionThreadItemContent} {
36
+ align-self: flex-start;
37
+ }
38
+
39
+ ${AvatarWrapper},
40
+ ${InitialsWrapper} {
41
+ margin-right: 1rem;
42
+ }
43
+ `;
44
+
45
+ export const DiscussionThreadItemRight = styled(DiscussionThreadItemStyled)`
46
+ align-items: flex-end;
47
+ padding-right: 4rem;
48
+ text-align: left;
49
+
50
+ ${DiscussionThreadItemContent} {
51
+ align-self: flex-end;
52
+ flex-direction: row-reverse;
53
+ }
54
+
55
+ ${AvatarWrapper},
56
+ ${InitialsWrapper} {
57
+ margin-left: 1rem;
58
+ }
59
+
60
+ ${DiscussionThreadItemLinkBox} {
61
+ margin-right: 3rem;
62
+ }
63
+ `;
64
+
65
+ export const DiscussionThreadItemBox = styled(Box)`
66
+
67
+ `;
68
+
69
+ export const DiscussionThreadItemBoxContent = styled(Box)`
70
+ width: 100%;
71
+ align-items: stretch;
72
+ `
73
+
74
+ export const DiscussionThreadItemRoot = styled(DiscussionThreadItemLeft)`
75
+ padding-left: 0;
76
+ padding-right: 0;
77
+
78
+
79
+ ${DiscussionThreadItemContent} {
80
+ width: 100%;
81
+ max-width: 100%;
82
+ }
83
+
84
+ ${DiscussionThreadItemBox} {
85
+ flex-grow: 1;
86
+ }
87
+ `;