strapi-plugin-comments 1.0.2-beta.1 → 2.0.0-beta.2

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 (149) hide show
  1. package/.circleci/config.yml +2 -2
  2. package/README.md +71 -95
  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 +58 -42
  25. package/admin/src/pages/App/index.js +60 -0
  26. package/admin/src/pages/App/reducer/actions.js +8 -0
  27. package/admin/src/pages/App/reducer/constants.js +4 -0
  28. package/admin/src/pages/App/reducer/index.js +27 -0
  29. package/admin/src/pages/App/reducer/init.js +7 -0
  30. package/admin/src/pages/App/reducer/selectors.js +35 -0
  31. package/admin/src/pages/App/utils/api.js +20 -0
  32. package/admin/src/pages/ComingSoonPage/index.js +25 -0
  33. package/admin/src/pages/Details/index.js +109 -0
  34. package/admin/src/pages/Details/utils/api.js +41 -0
  35. package/admin/src/pages/Discover/index.js +203 -0
  36. package/admin/src/pages/Discover/utils/api.js +20 -0
  37. package/admin/src/pages/Discover/utils/filtersSchema.js +9 -0
  38. package/admin/src/permissions.js +13 -33
  39. package/admin/src/pluginId.js +2 -4
  40. package/admin/src/reducers.js +8 -0
  41. package/admin/src/translations/en.json +72 -33
  42. package/admin/src/translations/fr.json +1 -0
  43. package/admin/src/utils/axiosInstance.js +35 -0
  44. package/admin/src/utils/constants.js +28 -0
  45. package/admin/src/utils/getApiUrl.js +5 -0
  46. package/admin/src/utils/getMessage.js +14 -0
  47. package/admin/src/utils/getRelatedGroups.js +5 -0
  48. package/admin/src/utils/getUrl.js +5 -0
  49. package/admin/src/utils/handleAPIError.js +15 -0
  50. package/admin/src/utils/index.js +6 -0
  51. package/codecov.yml +2 -1
  52. package/content-types/comment.js +97 -0
  53. package/content-types/index.js +11 -0
  54. package/content-types/report.js +54 -0
  55. package/package.json +11 -25
  56. package/server/bootstrap.js +5 -0
  57. package/server/config/index.js +10 -0
  58. package/server/controllers/admin.js +134 -0
  59. package/server/controllers/client.js +109 -0
  60. package/server/controllers/index.js +9 -0
  61. package/{controllers → server/controllers}/utils/__tests__/functions.test.js +0 -0
  62. package/{controllers → server/controllers}/utils/functions.js +1 -1
  63. package/server/destroy.js +5 -0
  64. package/server/index.js +22 -0
  65. package/server/register.js +5 -0
  66. package/server/routes/admin.js +92 -0
  67. package/server/routes/client.js +52 -0
  68. package/server/routes/index.js +15 -0
  69. package/server/services/admin.js +186 -0
  70. package/server/services/client.js +227 -0
  71. package/server/services/common.js +191 -0
  72. package/server/services/index.js +11 -0
  73. package/{services → server/services}/utils/__tests__/functions.test.js +7 -9
  74. package/{services → server/services}/utils/functions.js +19 -8
  75. package/server/utils/constants.js +16 -0
  76. package/{services → server}/utils/error.js +0 -0
  77. package/server/utils/functions.js +19 -0
  78. package/strapi-admin.js +3 -0
  79. package/strapi-server.js +9 -0
  80. package/admin/src/assets/images/icon-cross-blue.svg +0 -1
  81. package/admin/src/assets/images/icon_remove.svg +0 -19
  82. package/admin/src/assets/images/logo.svg +0 -5
  83. package/admin/src/components/AbuseReportsPopUp/ItemPreviewContainer.js +0 -8
  84. package/admin/src/components/AbuseReportsPopUp/ModalFooter.js +0 -31
  85. package/admin/src/components/AbuseReportsPopUp/TableContainer.js +0 -63
  86. package/admin/src/components/AbuseReportsPopUp/index.js +0 -148
  87. package/admin/src/components/Container/index.js +0 -7
  88. package/admin/src/components/EmptyView/index.js +0 -25
  89. package/admin/src/components/Filters/index.js +0 -151
  90. package/admin/src/components/Filters/index.styled.js +0 -82
  91. package/admin/src/components/Filters/utils.js +0 -21
  92. package/admin/src/components/Item/CardItem.js +0 -30
  93. package/admin/src/components/Item/CardWrapper.js +0 -10
  94. package/admin/src/components/Item/index.js +0 -92
  95. package/admin/src/components/ItemDetails/CardItem.js +0 -33
  96. package/admin/src/components/ItemDetails/CardLevelCounter.js +0 -46
  97. package/admin/src/components/ItemDetails/CardLevelCounterLink.js +0 -24
  98. package/admin/src/components/ItemDetails/CardLevelWrapper.js +0 -22
  99. package/admin/src/components/ItemDetails/CardWrapper.js +0 -52
  100. package/admin/src/components/ItemDetails/index.js +0 -151
  101. package/admin/src/components/ItemFooter/CardItemAuthor.js +0 -10
  102. package/admin/src/components/ItemFooter/CardItemRelation.js +0 -18
  103. package/admin/src/components/ItemFooter/Wrapper.js +0 -20
  104. package/admin/src/components/ItemFooter/index.js +0 -87
  105. package/admin/src/components/ItemHeader/CardHeaderBlocked.js +0 -24
  106. package/admin/src/components/ItemHeader/CardHeaderIndicator.js +0 -30
  107. package/admin/src/components/ItemHeader/CardHeaderIndicatorBlue.js +0 -11
  108. package/admin/src/components/ItemHeader/CardHeaderIndicatorRed.js +0 -11
  109. package/admin/src/components/ItemHeader/CardHeaderIndicatorsContainer.js +0 -18
  110. package/admin/src/components/ItemHeader/CardHeaderReports.js +0 -40
  111. package/admin/src/components/ItemHeader/Wrapper.js +0 -16
  112. package/admin/src/components/ItemHeader/index.js +0 -80
  113. package/admin/src/components/ItemModeration/Wrapper.js +0 -19
  114. package/admin/src/components/ItemModeration/index.js +0 -47
  115. package/admin/src/components/List/Container.js +0 -20
  116. package/admin/src/components/List/index.js +0 -21
  117. package/admin/src/components/Search/index.js +0 -83
  118. package/admin/src/containers/App/Wrapper.js +0 -14
  119. package/admin/src/containers/App/index.js +0 -47
  120. package/admin/src/containers/DataManagerProvider/actions.js +0 -11
  121. package/admin/src/containers/DataManagerProvider/index.js +0 -280
  122. package/admin/src/containers/DataManagerProvider/init.js +0 -5
  123. package/admin/src/containers/DataManagerProvider/reducer.js +0 -59
  124. package/admin/src/containers/DetailsView/Wrapper.js +0 -18
  125. package/admin/src/containers/DetailsView/index.js +0 -100
  126. package/admin/src/containers/ListView/FadedWrapper.js +0 -42
  127. package/admin/src/containers/ListView/Footer.js +0 -53
  128. package/admin/src/containers/ListView/Wrapper.js +0 -17
  129. package/admin/src/containers/ListView/components.js +0 -138
  130. package/admin/src/containers/ListView/index.js +0 -45
  131. package/admin/src/containers/Panel/actions.js +0 -5
  132. package/admin/src/containers/Panel/index.js +0 -191
  133. package/admin/src/containers/Panel/index.styled.js +0 -6
  134. package/admin/src/containers/Panel/reducer.js +0 -44
  135. package/admin/src/contexts/DataManagerContext.js +0 -5
  136. package/admin/src/hooks/useDataManager.js +0 -6
  137. package/admin/src/lifecycles.js +0 -3
  138. package/admin/src/translations/index.js +0 -7
  139. package/admin/src/utils/getTrad.js +0 -5
  140. package/admin/src/utils/getTradId.js +0 -5
  141. package/config/functions/bootstrap.js +0 -48
  142. package/config/routes.json +0 -116
  143. package/config/schema.graphql.js +0 -270
  144. package/controllers/comments.js +0 -211
  145. package/models/comment.js +0 -8
  146. package/models/comment.settings.json +0 -98
  147. package/models/report.js +0 -8
  148. package/models/report.settings.json +0 -49
  149. package/services/comments.js +0 -486
@@ -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">
@@ -7,17 +7,19 @@
7
7
  <a href="https://www.npmjs.org/package/strapi-plugin-comments">
8
8
  <img src="https://img.shields.io/npm/dm/strapi-plugin-comments.svg" alt="Monthly download on NPM" />
9
9
  </a>
10
- <a href="https://circleci.com/gh/VirtusLab/strapi-plugin-comments">
11
- <img src="https://circleci.com/gh/VirtusLab/strapi-plugin-comments.svg?style=shield" alt="CircleCI" />
10
+ <a href="https://circleci.com/gh/VirtusLab-Open-Source/strapi-plugin-comments">
11
+ <img src="https://circleci.com/gh/VirtusLab-Open-Source/strapi-plugin-comments.svg?style=shield" alt="CircleCI" />
12
12
  </a>
13
- <a href="https://codecov.io/gh/VirtusLab/strapi-plugin-comments">
14
- <img src="https://codecov.io/gh/VirtusLab/strapi-plugin-comments/coverage.svg?branch=master" alt="codecov.io" />
13
+ <a href="https://codecov.io/gh/VirtusLab-Open-Source/strapi-plugin-comments">
14
+ <img src="https://codecov.io/gh/VirtusLab-Open-Source/strapi-plugin-comments/coverage.svg?branch=master" alt="codecov.io" />
15
15
  </a>
16
16
  </p>
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 <a href="https://strapi.io/documentation/v3.x/installation/cli.html#step-1-make-sure-requirements-are-met">Installation Requirements</a>.
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.0 (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
 
@@ -64,81 +65,58 @@ Complete installation requirements are exact same as for Strapi itself and can b
64
65
  - **Any Content Type relation:** Comments can by linked to any of your Content Types by default. Simply, you're controlling it.
65
66
  - **Moderation Panel:** Search & Filter through the bucket with your auditory comments. Manage them by blocking single ones or full threads. All in combined list &amp; hierarchical tree view of threads.
66
67
  - **Automated Bad Words filtering:** By detault end users are not allowed to post abusing comments where bad words have been used.
67
- - **Abuse Reporting & Reviewing:** Don't allow inferior language, react to reports from your community
68
-
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
- ```
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
- ```
84
- "attributes": {
85
- ...,
86
- "comments": {
87
- "plugin": "comments",
88
- "collection": "comment",
89
- "via": "related"
90
- },
91
- ...
92
- },
93
- ```
68
+ - **Abuse Reporting & Reviewing:** Don't allow inferior language, react to reports from your community, send email notifiactions about abuse reports
94
69
 
95
70
  ## Configuration
96
- To setup amend default plugin configuration we recommend to put following snippet as part of `config/custom.js` or `config/<env>/custom.js` file. If you've got already configurations for other plugins stores by this way, use just the `navigation` part within exising `plugins` item.
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
 
98
- ```
73
+
74
+ ```js
99
75
  ...
100
- plugins: {
101
- comments: {
102
- enableUsers: true,
103
- badWords: false,
104
- },
76
+ comments: {
77
+ badWords: false,
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
- - `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`.
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`.
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.
86
+
87
+ ## Additional GQL Configuration
88
+
89
+ > To be done
112
90
 
113
91
  ## Public API Comment model
114
92
 
115
93
  ### Generic (non Strapi User)
116
- ```
94
+ ```json
117
95
  {
118
96
  "id": 1,
119
97
  "content": "My comment content",
120
98
  "blocked": null,
121
99
  "blockedThread": true,
122
100
  "blockReason": null,
123
- "points": 1,
124
101
  "authorUser": null,
125
102
  "authorId": "207ccfdc-94ba-45eb-979c-790f6f49c392",
126
103
  "authorName": "Joe Doe",
127
104
  "authorEmail": "jdoe@sample.com",
128
105
  "authorAvatar": null,
129
- "created_at": "2020-07-14T20:13:01.649Z",
130
- "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
131
110
  }
132
111
  ```
133
112
  ### Strapi User
134
- ```
113
+ ```json
135
114
  {
136
115
  "id": 1,
137
116
  "content": "My comment content",
138
117
  "blocked": true,
139
118
  "blockedThread": null,
140
119
  "blockReason": null,
141
- "points": null,
142
120
  "authorUser": {
143
121
  "id": 1,
144
122
  "username": "Sample User",
@@ -154,8 +132,10 @@ To setup amend default plugin configuration we recommend to put following snippe
154
132
  "authorName": null,
155
133
  "authorEmail": null,
156
134
  "authorAvatar": null,
157
- "created_at": "2020-07-14T20:13:01.649Z",
158
- "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
159
139
  }
160
140
 
161
141
  ```
@@ -164,11 +144,11 @@ To setup amend default plugin configuration we recommend to put following snippe
164
144
 
165
145
  ### Get Comments
166
146
 
167
- `GET <host>/comments/<content-type>:<id>`
147
+ `GET <host>/comments/api::<collection name>.<content type name>:<entity id>`
168
148
 
169
- 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`
170
150
 
171
- **Example URL**: `https://localhost:1337/comments/article:1`
151
+ **Example URL**: `https://localhost:1337/comments/api::page.page:1`
172
152
 
173
153
  **Example response body**
174
154
 
@@ -190,11 +170,11 @@ Return a hierarchical tree structure of comments for specified instance of Conte
190
170
 
191
171
  ### Get Comments (flat structure)
192
172
 
193
- `GET <host>/comments/<content-type>:<id>/flat`
173
+ `GET <host>/comments/api::<collection name>.<content type name>:<entity id>/flat`
194
174
 
195
- 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`
196
176
 
197
- **Example URL**: `https://localhost:1337/comments/article:1/flat`
177
+ **Example URL**: `https://localhost:1337/comments/api::page.page:1/flat`
198
178
 
199
179
  **Example response body**
200
180
 
@@ -216,27 +196,26 @@ Return a flat structure of comments for specified instance of Content Type like
216
196
 
217
197
  ### Post a Comment
218
198
 
219
- `POST <host>/comments/<content-type>:<id>`
199
+ `POST <host>/comments/api::<collection name>.<content type name>:<entity id>`
220
200
 
221
- 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`
222
202
 
223
- **Example URL**: `https://localhost:1337/comments/article:1`
203
+ **Example URL**: `https://localhost:1337/comments/api::page.page:1`
224
204
 
225
205
  **Example request body**
226
206
 
227
207
  *Generic (non Strapi User)*
228
208
  ```
229
209
  {
230
- "authorId": "<any ID like value>",
231
- "authorName": "Joe Doe",
232
- "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
+ },
233
216
  "content": "My sample response",
234
217
  "threadOf": 2, // id of comment we would like to start / continue the thread (Optional)
235
- "related": [{
236
- "refId": 1,
237
- "ref": "article",
238
- "field": "comments"
239
- }]
218
+ "related": "api::page.page:1"
240
219
  }
241
220
  ```
242
221
 
@@ -246,11 +225,7 @@ Posts a Comment related to specified instance of Content Type like for example `
246
225
  "authorUser": 1, // id of a author user. Optional in case of 'enableUsers: true' in the plugin configuration
247
226
  "content": "My sample response",
248
227
  "threadOf": 2, // id of comment we would like to start / continue the thread (Optional)
249
- "related": [{
250
- "refId": 1,
251
- "ref": "article",
252
- "field": "comments"
253
- }]
228
+ "related": "api::page.page:1"
254
229
  }
255
230
  ```
256
231
 
@@ -268,20 +243,20 @@ Posts a Comment related to specified instance of Content Type like for example `
268
243
 
269
244
  ### Update Comment
270
245
 
271
- `PUT <host>/comments/<content-type>:<id>/comment/<commentId>`
246
+ `PUT <host>/comments/api::<collection name>.<content type name>:<entity id>/comment/<commentId>`
272
247
 
273
- 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`
274
249
 
275
- **Example URL**: `https://localhost:1337/comments/article:1/comment/2`
250
+ **Example URL**: `https://localhost:1337/comments/api::page.page:1/comment/2`
276
251
 
277
252
  **Example request body**
278
253
 
279
254
  *Generic (non Strapi User)*
280
255
  ```
281
256
  {
282
- "authorId": "<any ID like value>",
283
- "authorName": "Joe Doe",
284
- "authorEmail": "jdoe@sample.com",
257
+ "author": {
258
+ "id": "<any ID like value>"
259
+ },
285
260
  "content": "My sample response"
286
261
  }
287
262
  ```
@@ -307,33 +282,34 @@ Updates a specified Comment content based on it `commentId` and related to speci
307
282
  - `400` - Bad Request. Missing field values or bad words check fails. Error message will provide relevant reason.
308
283
  - `409` - Conflict. Occurs when trying to update a non existing or not own comment. Possible cause might be that `authorId` or `authorUser` mismatch with existing comment.
309
284
 
310
- ### Like Comment
285
+ ### Delete Comment
311
286
 
312
- `PATCH <host>/comments/<content-type>:<id>/comment/<commentId>/like`
287
+ `DELETE <host>/comments/api::<collection name>.<content type name>:<entity id>/<commentId>?authorId=<authorId>`
313
288
 
314
- Likes 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`.
315
290
 
316
- **Example URL**: `https://localhost:1337/comments/article:1/comment/2/like`
291
+ **Example URL**: `https://localhost:1337/comments/api::page.page:1/comment/1?authorId=1`
317
292
 
318
293
  **Example response body**
319
294
 
320
295
  ```
321
296
  {
322
- -- Comment Model fields ---
297
+ -- Empty Response ---
323
298
  }
324
299
  ```
325
300
 
326
301
  **Possible response codes**
327
- - `200` - Successful. Response with liked Comment Model.
328
- - `409` - Conflict. Occurs when trying to like a non existing comment.
302
+ - `200` - Successful with blank Response.
303
+ - `409` - Conflict. Occurs when trying to delete a non existing comment.
304
+
329
305
 
330
306
  ### Report abuse in the Comment
331
307
 
332
- `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`
333
309
 
334
- 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.
335
311
 
336
- **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`
337
313
 
338
314
  **Example request body**
339
315
 
@@ -370,10 +346,10 @@ Feel free to fork and make a Pull Request to this plugin project. All the input
370
346
 
371
347
  For general help using Strapi, please refer to [the official Strapi documentation](https://strapi.io/documentation/). For additional help, you can use one of these channels to ask a question:
372
348
 
373
- - [Slack](http://slack.strapi.io) We're present on official Strapi slack workspace. Look for @cyp3r and DM.
349
+ - [Discord](https://discord.strapi.io/) We're present on official Strapi Discord workspace. Look for @cyp3r and DM.
374
350
  - [Slack - VirtusLab Open Source](https://virtuslab-oss.slack.com) We're present on a public channel #strapi-molecules
375
- - [GitHub](https://github.com/VirtusLab/strapi-plugin-comments/issues) (Bug reports, Contributions, Questions and Discussions)
351
+ - [GitHub](https://github.com/VirtusLab-Open-Source/strapi-plugin-comments/issues) (Bug reports, Contributions, Questions and Discussions)
376
352
 
377
353
  ## License
378
354
 
379
- [MIT License](LICENSE.md) Copyright (c) 2020 [VirtusLab Sp. z o.o.](https://virtuslab.com/) &amp; [Strapi Solutions](https://strapi.io/).
355
+ [MIT License](LICENSE.md) Copyright (c) [VirtusLab Sp. z o.o.](https://virtuslab.com/) &amp; [Strapi Solutions](https://strapi.io/).
@@ -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
+