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

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 (156) hide show
  1. package/.circleci/config.yml +2 -2
  2. package/README.md +53 -126
  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 +59 -0
  6. package/admin/src/components/DiscussionThreadItem/index.js +87 -0
  7. package/admin/src/components/DiscussionThreadItem/styles.js +88 -0
  8. package/admin/src/components/DiscussionThreadItemActions/index.js +178 -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 +141 -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 +43 -0
  20. package/admin/src/components/ReportsReviewTable/index.js +146 -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/components/icons/index.js +6 -0
  25. package/admin/src/components/icons/lock.js +22 -0
  26. package/admin/src/components/icons/review.js +18 -0
  27. package/admin/src/components/icons/unlock.js +20 -0
  28. package/admin/src/index.js +58 -42
  29. package/admin/src/pages/App/index.js +71 -0
  30. package/admin/src/pages/App/reducer/actions.js +8 -0
  31. package/admin/src/pages/App/reducer/constants.js +4 -0
  32. package/admin/src/pages/App/reducer/index.js +26 -0
  33. package/admin/src/pages/App/reducer/init.js +7 -0
  34. package/admin/src/pages/App/reducer/selectors.js +35 -0
  35. package/admin/src/pages/App/utils/api.js +12 -0
  36. package/admin/src/pages/ComingSoonPage/index.js +25 -0
  37. package/admin/src/pages/Details/index.js +109 -0
  38. package/admin/src/pages/Details/utils/api.js +41 -0
  39. package/admin/src/pages/Discover/components/DiscoverTableRow/index.js +196 -0
  40. package/admin/src/pages/Discover/index.js +157 -0
  41. package/admin/src/pages/Discover/utils/api.js +14 -0
  42. package/admin/src/pages/Discover/utils/filtersSchema.js +9 -0
  43. package/admin/src/permissions.js +13 -37
  44. package/admin/src/pluginId.js +2 -4
  45. package/admin/src/reducers.js +8 -0
  46. package/admin/src/translations/en.json +73 -37
  47. package/admin/src/translations/fr.json +1 -0
  48. package/admin/src/utils/axiosInstance.js +35 -0
  49. package/admin/src/utils/constants.js +25 -6
  50. package/admin/src/utils/getApiUrl.js +5 -0
  51. package/admin/src/utils/getMessage.js +21 -0
  52. package/admin/src/utils/getRelatedGroups.js +5 -0
  53. package/admin/src/utils/getUrl.js +5 -0
  54. package/admin/src/utils/handleAPIError.js +15 -0
  55. package/admin/src/utils/index.js +6 -0
  56. package/codecov.yml +2 -1
  57. package/content-types/comment.js +97 -0
  58. package/content-types/index.js +11 -0
  59. package/content-types/report.js +54 -0
  60. package/package.json +11 -25
  61. package/server/bootstrap.js +5 -0
  62. package/server/config/index.js +10 -0
  63. package/server/controllers/admin.js +134 -0
  64. package/server/controllers/client.js +117 -0
  65. package/server/controllers/index.js +9 -0
  66. package/{controllers → server/controllers}/utils/__tests__/functions.test.js +0 -0
  67. package/{controllers → server/controllers}/utils/functions.js +1 -1
  68. package/server/destroy.js +5 -0
  69. package/server/index.js +22 -0
  70. package/server/register.js +5 -0
  71. package/server/routes/admin.js +92 -0
  72. package/server/routes/client.js +52 -0
  73. package/server/routes/index.js +15 -0
  74. package/server/services/admin.js +215 -0
  75. package/server/services/client.js +227 -0
  76. package/server/services/common.js +197 -0
  77. package/server/services/index.js +11 -0
  78. package/{services → server/services}/utils/__tests__/functions.test.js +0 -0
  79. package/{services → server/services}/utils/functions.js +17 -6
  80. package/server/utils/constants.js +16 -0
  81. package/{services → server}/utils/error.js +0 -0
  82. package/server/utils/functions.js +19 -0
  83. package/strapi-admin.js +3 -0
  84. package/strapi-server.js +9 -0
  85. package/admin/src/assets/images/icon-cross-blue.svg +0 -1
  86. package/admin/src/assets/images/icon_remove.svg +0 -19
  87. package/admin/src/assets/images/logo.svg +0 -5
  88. package/admin/src/components/AbuseReportsPopUp/ItemPreviewContainer.js +0 -8
  89. package/admin/src/components/AbuseReportsPopUp/ModalFooter.js +0 -31
  90. package/admin/src/components/AbuseReportsPopUp/TableContainer.js +0 -63
  91. package/admin/src/components/AbuseReportsPopUp/index.js +0 -148
  92. package/admin/src/components/Container/index.js +0 -7
  93. package/admin/src/components/EmptyView/index.js +0 -25
  94. package/admin/src/components/Filters/index.js +0 -151
  95. package/admin/src/components/Filters/index.styled.js +0 -82
  96. package/admin/src/components/Filters/utils.js +0 -21
  97. package/admin/src/components/Item/CardItem.js +0 -30
  98. package/admin/src/components/Item/CardWrapper.js +0 -10
  99. package/admin/src/components/Item/index.js +0 -107
  100. package/admin/src/components/ItemDetails/CardItem.js +0 -33
  101. package/admin/src/components/ItemDetails/CardLevelCounter.js +0 -46
  102. package/admin/src/components/ItemDetails/CardLevelCounterLink.js +0 -24
  103. package/admin/src/components/ItemDetails/CardLevelWrapper.js +0 -22
  104. package/admin/src/components/ItemDetails/CardWrapper.js +0 -52
  105. package/admin/src/components/ItemDetails/index.js +0 -167
  106. package/admin/src/components/ItemFooter/CardItemAuthor.js +0 -10
  107. package/admin/src/components/ItemFooter/CardItemRelation.js +0 -18
  108. package/admin/src/components/ItemFooter/Wrapper.js +0 -20
  109. package/admin/src/components/ItemFooter/index.js +0 -87
  110. package/admin/src/components/ItemHeader/CardHeaderBlocked.js +0 -24
  111. package/admin/src/components/ItemHeader/CardHeaderIndicator.js +0 -30
  112. package/admin/src/components/ItemHeader/CardHeaderIndicatorBlue.js +0 -11
  113. package/admin/src/components/ItemHeader/CardHeaderIndicatorRed.js +0 -11
  114. package/admin/src/components/ItemHeader/CardHeaderIndicatorsContainer.js +0 -18
  115. package/admin/src/components/ItemHeader/CardHeaderPending.js +0 -11
  116. package/admin/src/components/ItemHeader/CardHeaderReports.js +0 -40
  117. package/admin/src/components/ItemHeader/Wrapper.js +0 -16
  118. package/admin/src/components/ItemHeader/index.js +0 -97
  119. package/admin/src/components/ItemModeration/Wrapper.js +0 -19
  120. package/admin/src/components/ItemModeration/index.js +0 -84
  121. package/admin/src/components/List/Container.js +0 -20
  122. package/admin/src/components/List/index.js +0 -21
  123. package/admin/src/components/Search/index.js +0 -83
  124. package/admin/src/containers/App/Wrapper.js +0 -14
  125. package/admin/src/containers/App/index.js +0 -47
  126. package/admin/src/containers/DataManagerProvider/actions.js +0 -15
  127. package/admin/src/containers/DataManagerProvider/index.js +0 -332
  128. package/admin/src/containers/DataManagerProvider/init.js +0 -5
  129. package/admin/src/containers/DataManagerProvider/reducer.js +0 -59
  130. package/admin/src/containers/DetailsView/Wrapper.js +0 -18
  131. package/admin/src/containers/DetailsView/index.js +0 -106
  132. package/admin/src/containers/ListView/FadedWrapper.js +0 -42
  133. package/admin/src/containers/ListView/Footer.js +0 -53
  134. package/admin/src/containers/ListView/Wrapper.js +0 -17
  135. package/admin/src/containers/ListView/components.js +0 -138
  136. package/admin/src/containers/ListView/index.js +0 -45
  137. package/admin/src/containers/Panel/actions.js +0 -5
  138. package/admin/src/containers/Panel/index.js +0 -191
  139. package/admin/src/containers/Panel/index.styled.js +0 -6
  140. package/admin/src/containers/Panel/reducer.js +0 -44
  141. package/admin/src/contexts/DataManagerContext.js +0 -5
  142. package/admin/src/hooks/useDataManager.js +0 -6
  143. package/admin/src/lifecycles.js +0 -3
  144. package/admin/src/translations/index.js +0 -7
  145. package/admin/src/utils/getTrad.js +0 -5
  146. package/admin/src/utils/getTradId.js +0 -5
  147. package/config/functions/bootstrap.js +0 -62
  148. package/config/routes.json +0 -142
  149. package/config/schema.graphql.js +0 -268
  150. package/controllers/comments.js +0 -228
  151. package/models/comment.js +0 -8
  152. package/models/comment.settings.json +0 -102
  153. package/models/report.js +0 -8
  154. package/models/report.settings.json +0 -49
  155. package/services/comments.js +0 -539
  156. 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,24 @@ To setup amend default plugin configuration we recommend to put following snippe
99
74
  ```js
100
75
  ...
101
76
  comments: {
102
- enableUsers: true,
103
- badWords: false,
104
- moderatorRoles: ["Authenticated"]
77
+ badWords: false,
78
+ moderatorRoles: ["Authenticated"],
79
+ entryLabel: {
80
+ '*': ['Title', 'title', 'Name', 'name', 'Subject', 'subject'],
81
+ 'api::page.page': ['MyField'],
82
+ },
105
83
  },
106
84
  ...
107
85
  ```
108
86
 
109
87
  ### 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
88
  - `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.
89
+ - `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
+ - `entryLabel` - ordered list of property names per Content Type to generate related entity label. Default set as `*`.
113
91
 
114
92
  ## Additional GQL Configuration
115
93
 
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
94
+ > To be done
146
95
 
147
96
  ## Public API Comment model
148
97
 
@@ -154,14 +103,15 @@ To setup amend default plugin configuration we recommend to put following snippe
154
103
  "blocked": null,
155
104
  "blockedThread": true,
156
105
  "blockReason": null,
157
- "points": 1,
158
106
  "authorUser": null,
159
107
  "authorId": "207ccfdc-94ba-45eb-979c-790f6f49c392",
160
108
  "authorName": "Joe Doe",
161
109
  "authorEmail": "jdoe@sample.com",
162
110
  "authorAvatar": null,
163
- "created_at": "2020-07-14T20:13:01.649Z",
164
- "updated_at": "2020-07-14T20:13:01.670Z"
111
+ "createdAt": "2020-07-14T20:13:01.649Z",
112
+ "updatedAt": "2020-07-14T20:13:01.670Z",
113
+ "related": {}, // Related content type entity
114
+ "reports": [] // Reports issued against this comment
165
115
  }
166
116
  ```
167
117
  ### Strapi User
@@ -172,7 +122,6 @@ To setup amend default plugin configuration we recommend to put following snippe
172
122
  "blocked": true,
173
123
  "blockedThread": null,
174
124
  "blockReason": null,
175
- "points": null,
176
125
  "authorUser": {
177
126
  "id": 1,
178
127
  "username": "Sample User",
@@ -188,8 +137,10 @@ To setup amend default plugin configuration we recommend to put following snippe
188
137
  "authorName": null,
189
138
  "authorEmail": null,
190
139
  "authorAvatar": null,
191
- "created_at": "2020-07-14T20:13:01.649Z",
192
- "updated_at": "2020-07-14T20:13:01.670Z"
140
+ "createdAt": "2020-07-14T20:13:01.649Z",
141
+ "updatedAt": "2020-07-14T20:13:01.670Z",
142
+ "related": {}, // Related content type entity
143
+ "reports": [] // Reports issued against this comment
193
144
  }
194
145
 
195
146
  ```
@@ -198,11 +149,11 @@ To setup amend default plugin configuration we recommend to put following snippe
198
149
 
199
150
  ### Get Comments
200
151
 
201
- `GET <host>/comments/<content-type>:<id>`
152
+ `GET <host>/comments/api::<collection name>.<content type name>:<entity id>`
202
153
 
203
- Return a hierarchical tree structure of comments for specified instance of Content Type like for example `Article` with `ID: 1`
154
+ Return a hierarchical tree structure of comments for specified instance of Content Type like for example `Page` with `ID: 1`
204
155
 
205
- **Example URL**: `https://localhost:1337/comments/article:1`
156
+ **Example URL**: `https://localhost:1337/comments/api::page.page:1`
206
157
 
207
158
  **Example response body**
208
159
 
@@ -224,11 +175,11 @@ Return a hierarchical tree structure of comments for specified instance of Conte
224
175
 
225
176
  ### Get Comments (flat structure)
226
177
 
227
- `GET <host>/comments/<content-type>:<id>/flat`
178
+ `GET <host>/comments/api::<collection name>.<content type name>:<entity id>/flat`
228
179
 
229
- Return a flat structure of comments for specified instance of Content Type like for example `Article` with `ID: 1`
180
+ Return a flat structure of comments for specified instance of Content Type like for example `Page` with `ID: 1`
230
181
 
231
- **Example URL**: `https://localhost:1337/comments/article:1/flat`
182
+ **Example URL**: `https://localhost:1337/comments/api::page.page:1/flat`
232
183
 
233
184
  **Example response body**
234
185
 
@@ -250,27 +201,26 @@ Return a flat structure of comments for specified instance of Content Type like
250
201
 
251
202
  ### Post a Comment
252
203
 
253
- `POST <host>/comments/<content-type>:<id>`
204
+ `POST <host>/comments/api::<collection name>.<content type name>:<entity id>`
254
205
 
255
- Posts a Comment related to specified instance of Content Type like for example `Article` with `ID: 1`
206
+ Posts a Comment related to specified instance of Content Type like for example `Page` with `ID: 1`
256
207
 
257
- **Example URL**: `https://localhost:1337/comments/article:1`
208
+ **Example URL**: `https://localhost:1337/comments/api::page.page:1`
258
209
 
259
210
  **Example request body**
260
211
 
261
212
  *Generic (non Strapi User)*
262
213
  ```
263
214
  {
264
- "authorId": "<any ID like value>",
265
- "authorName": "Joe Doe",
266
- "authorEmail": "jdoe@sample.com",
215
+ "author": {
216
+ "id": "<any ID like value>",
217
+ "name": "Joe Doe",
218
+ "email": "jdoe@sample.com",
219
+ "avatar": "<any image url>"
220
+ },
267
221
  "content": "My sample response",
268
222
  "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
- }]
223
+ "related": "api::page.page:1"
274
224
  }
275
225
  ```
276
226
 
@@ -280,11 +230,7 @@ Posts a Comment related to specified instance of Content Type like for example `
280
230
  "authorUser": 1, // id of a author user. Optional in case of 'enableUsers: true' in the plugin configuration
281
231
  "content": "My sample response",
282
232
  "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
- }]
233
+ "related": "api::page.page:1"
288
234
  }
289
235
  ```
290
236
 
@@ -302,20 +248,20 @@ Posts a Comment related to specified instance of Content Type like for example `
302
248
 
303
249
  ### Update Comment
304
250
 
305
- `PUT <host>/comments/<content-type>:<id>/comment/<commentId>`
251
+ `PUT <host>/comments/api::<collection name>.<content type name>:<entity id>/comment/<commentId>`
306
252
 
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`
253
+ 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
254
 
309
- **Example URL**: `https://localhost:1337/comments/article:1/comment/2`
255
+ **Example URL**: `https://localhost:1337/comments/api::page.page:1/comment/2`
310
256
 
311
257
  **Example request body**
312
258
 
313
259
  *Generic (non Strapi User)*
314
260
  ```
315
261
  {
316
- "authorId": "<any ID like value>",
317
- "authorName": "Joe Doe",
318
- "authorEmail": "jdoe@sample.com",
262
+ "author": {
263
+ "id": "<any ID like value>"
264
+ },
319
265
  "content": "My sample response"
320
266
  }
321
267
  ```
@@ -343,11 +289,11 @@ Updates a specified Comment content based on it `commentId` and related to speci
343
289
 
344
290
  ### Delete Comment
345
291
 
346
- `DELETE <host>/comments/<content-type>:<id>/<commentId>?authorId=<authorId>`
292
+ `DELETE <host>/comments/api::<collection name>.<content type name>:<entity id>/<commentId>?authorId=<authorId>`
347
293
 
348
- Deletes a specified Comment based on it `commentId` and related to specified instance of Content Type like for example `Article` with `ID: 1`.
294
+ Deletes a specified Comment based on it `commentId` and related to specified instance of Content Type like for example `Page` with `ID: 1`.
349
295
 
350
- **Example URL**: `https://localhost:1337/comments/article:1/1?authorId=1`
296
+ **Example URL**: `https://localhost:1337/comments/api::page.page:1/comment/1?authorId=1`
351
297
 
352
298
  **Example response body**
353
299
 
@@ -361,33 +307,14 @@ Deletes a specified Comment based on it `commentId` and related to specified ins
361
307
  - `200` - Successful with blank Response.
362
308
  - `409` - Conflict. Occurs when trying to delete a non existing comment.
363
309
 
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
310
 
384
311
  ### Report abuse in the Comment
385
312
 
386
- `POST <host>/comments/<content-type>:<id>/comment/<commentId>/report-abuse`
313
+ `POST <host>/comments/api::<collection name>.<content type name>:<entity id>/comment/<commentId>/report-abuse`
387
314
 
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.
315
+ 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
316
 
390
- **Example URL**: `https://localhost:1337/comments/article:1/comment/2/report-abuse`
317
+ **Example URL**: `https://localhost:1337/comments/api::page.page:1/comment/2/report-abuse`
391
318
 
392
319
  **Example request body**
393
320
 
@@ -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,59 @@
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 pinned />) }
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
+ root={isNil(rootThread)}
44
+ blockedThread={rootThread?.blockedThread || item.blockedThread}
45
+ isSelected={isSelected}
46
+ isThreadAuthor={isThreadAuthor}
47
+ />);
48
+ })}
49
+ </Flex>
50
+ </LoadingIndicatorContainer>);
51
+ };
52
+
53
+ DiscussionThread.propTypes = {
54
+ level: PropTypes.array.isRequired,
55
+ selected: PropTypes.object.isRequired,
56
+ isReloading: PropTypes.bool,
57
+ };
58
+
59
+ 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, pinned, 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 || pinned} />) }
66
+ </DiscussionThreadItemBoxContent>
67
+ { !(preview || isBlocked) && (<DiscussionThreadItemWarnings { ...item } gotThread={gotThread || root} />) }
68
+ </Flex>
69
+ <Divider background={dividerColor} />
70
+ <DiscussionThreadItemMeta { ...item } />
71
+ </DiscussionThreadItemBox>
72
+ </DiscussionThreadItemContent>
73
+
74
+ { (gotThread && !(preview || pinned)) && (<DiscussionThreadItemLinkBox direction="column" 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,88 @@
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
+ width: 100%;
10
+ margin-top: .5rem;
11
+ margin-bottom: .5rem;
12
+ `
13
+
14
+ const DiscussionThreadItemStyled = styled(Box)`
15
+ display: flex;
16
+ flex-direction: column;
17
+ width: 100%;
18
+ margin-bottom: 1rem;
19
+
20
+ ${AvatarWrapper},
21
+ ${InitialsWrapper} {
22
+ align-self: flex-start;
23
+ margin-top: .4rem;
24
+ }
25
+ `;
26
+
27
+ export const DiscussionThreadItemContent = styled(Box)`
28
+ max-width: 45%;
29
+ `;
30
+
31
+ export const DiscussionThreadItemLeft = styled(DiscussionThreadItemStyled)`
32
+ align-items: flex-start;
33
+ padding-left: 4rem;
34
+ text-align: left;
35
+
36
+ ${DiscussionThreadItemContent} {
37
+ align-self: flex-start;
38
+ }
39
+
40
+ ${AvatarWrapper},
41
+ ${InitialsWrapper} {
42
+ margin-right: 1rem;
43
+ }
44
+ `;
45
+
46
+ export const DiscussionThreadItemRight = styled(DiscussionThreadItemStyled)`
47
+ align-items: flex-end;
48
+ padding-right: 4rem;
49
+ text-align: left;
50
+
51
+ ${DiscussionThreadItemContent} {
52
+ align-self: flex-end;
53
+ flex-direction: row-reverse;
54
+ }
55
+
56
+ ${AvatarWrapper},
57
+ ${InitialsWrapper} {
58
+ margin-left: 1rem;
59
+ }
60
+
61
+ ${DiscussionThreadItemLinkBox} {
62
+ margin-right: 3rem;
63
+ }
64
+ `;
65
+
66
+ export const DiscussionThreadItemBox = styled(Box)`
67
+
68
+ `;
69
+
70
+ export const DiscussionThreadItemBoxContent = styled(Box)`
71
+ width: 100%;
72
+ align-items: stretch;
73
+ `
74
+
75
+ export const DiscussionThreadItemRoot = styled(DiscussionThreadItemLeft)`
76
+ padding-left: 0;
77
+ padding-right: 0;
78
+
79
+
80
+ ${DiscussionThreadItemContent} {
81
+ width: 100%;
82
+ max-width: 100%;
83
+ }
84
+
85
+ ${DiscussionThreadItemBox} {
86
+ flex-grow: 1;
87
+ }
88
+ `;