strapi-plugin-comments 1.0.2 → 2.0.0-beta.3

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 (154) hide show
  1. package/.circleci/config.yml +2 -2
  2. package/README.md +70 -109
  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 -33
  44. package/admin/src/pluginId.js +2 -4
  45. package/admin/src/reducers.js +8 -0
  46. package/admin/src/translations/en.json +73 -33
  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 +28 -0
  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 +7 -9
  79. package/{services → server/services}/utils/functions.js +19 -8
  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 -92
  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 -151
  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/CardHeaderReports.js +0 -40
  116. package/admin/src/components/ItemHeader/Wrapper.js +0 -16
  117. package/admin/src/components/ItemHeader/index.js +0 -80
  118. package/admin/src/components/ItemModeration/Wrapper.js +0 -19
  119. package/admin/src/components/ItemModeration/index.js +0 -47
  120. package/admin/src/components/List/Container.js +0 -20
  121. package/admin/src/components/List/index.js +0 -21
  122. package/admin/src/components/Search/index.js +0 -83
  123. package/admin/src/containers/App/Wrapper.js +0 -14
  124. package/admin/src/containers/App/index.js +0 -47
  125. package/admin/src/containers/DataManagerProvider/actions.js +0 -11
  126. package/admin/src/containers/DataManagerProvider/index.js +0 -280
  127. package/admin/src/containers/DataManagerProvider/init.js +0 -5
  128. package/admin/src/containers/DataManagerProvider/reducer.js +0 -59
  129. package/admin/src/containers/DetailsView/Wrapper.js +0 -18
  130. package/admin/src/containers/DetailsView/index.js +0 -100
  131. package/admin/src/containers/ListView/FadedWrapper.js +0 -42
  132. package/admin/src/containers/ListView/Footer.js +0 -53
  133. package/admin/src/containers/ListView/Wrapper.js +0 -17
  134. package/admin/src/containers/ListView/components.js +0 -138
  135. package/admin/src/containers/ListView/index.js +0 -45
  136. package/admin/src/containers/Panel/actions.js +0 -5
  137. package/admin/src/containers/Panel/index.js +0 -191
  138. package/admin/src/containers/Panel/index.styled.js +0 -6
  139. package/admin/src/containers/Panel/reducer.js +0 -44
  140. package/admin/src/contexts/DataManagerContext.js +0 -5
  141. package/admin/src/hooks/useDataManager.js +0 -6
  142. package/admin/src/lifecycles.js +0 -3
  143. package/admin/src/translations/index.js +0 -7
  144. package/admin/src/utils/getTrad.js +0 -5
  145. package/admin/src/utils/getTradId.js +0 -5
  146. package/config/functions/bootstrap.js +0 -48
  147. package/config/routes.json +0 -116
  148. package/config/schema.graphql.js +0 -270
  149. package/controllers/comments.js +0 -211
  150. package/models/comment.js +0 -8
  151. package/models/comment.settings.json +0 -98
  152. package/models/report.js +0 -8
  153. package/models/report.settings.json +0 -49
  154. 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.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
 
@@ -64,81 +65,63 @@ 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,
76
+ comments: {
103
77
  badWords: false,
104
- },
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
- - `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`.
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`.
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 `*`.
91
+
92
+ ## Additional GQL Configuration
93
+
94
+ > To be done
112
95
 
113
96
  ## Public API Comment model
114
97
 
115
98
  ### Generic (non Strapi User)
116
- ```
99
+ ```json
117
100
  {
118
101
  "id": 1,
119
102
  "content": "My comment content",
120
103
  "blocked": null,
121
104
  "blockedThread": true,
122
105
  "blockReason": null,
123
- "points": 1,
124
106
  "authorUser": null,
125
107
  "authorId": "207ccfdc-94ba-45eb-979c-790f6f49c392",
126
108
  "authorName": "Joe Doe",
127
109
  "authorEmail": "jdoe@sample.com",
128
110
  "authorAvatar": null,
129
- "created_at": "2020-07-14T20:13:01.649Z",
130
- "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
131
115
  }
132
116
  ```
133
117
  ### Strapi User
134
- ```
118
+ ```json
135
119
  {
136
120
  "id": 1,
137
121
  "content": "My comment content",
138
122
  "blocked": true,
139
123
  "blockedThread": null,
140
124
  "blockReason": null,
141
- "points": null,
142
125
  "authorUser": {
143
126
  "id": 1,
144
127
  "username": "Sample User",
@@ -154,8 +137,10 @@ To setup amend default plugin configuration we recommend to put following snippe
154
137
  "authorName": null,
155
138
  "authorEmail": null,
156
139
  "authorAvatar": null,
157
- "created_at": "2020-07-14T20:13:01.649Z",
158
- "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
159
144
  }
160
145
 
161
146
  ```
@@ -164,11 +149,11 @@ To setup amend default plugin configuration we recommend to put following snippe
164
149
 
165
150
  ### Get Comments
166
151
 
167
- `GET <host>/comments/<content-type>:<id>`
152
+ `GET <host>/comments/api::<collection name>.<content type name>:<entity id>`
168
153
 
169
- 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`
170
155
 
171
- **Example URL**: `https://localhost:1337/comments/article:1`
156
+ **Example URL**: `https://localhost:1337/comments/api::page.page:1`
172
157
 
173
158
  **Example response body**
174
159
 
@@ -190,11 +175,11 @@ Return a hierarchical tree structure of comments for specified instance of Conte
190
175
 
191
176
  ### Get Comments (flat structure)
192
177
 
193
- `GET <host>/comments/<content-type>:<id>/flat`
178
+ `GET <host>/comments/api::<collection name>.<content type name>:<entity id>/flat`
194
179
 
195
- 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`
196
181
 
197
- **Example URL**: `https://localhost:1337/comments/article:1/flat`
182
+ **Example URL**: `https://localhost:1337/comments/api::page.page:1/flat`
198
183
 
199
184
  **Example response body**
200
185
 
@@ -216,27 +201,26 @@ Return a flat structure of comments for specified instance of Content Type like
216
201
 
217
202
  ### Post a Comment
218
203
 
219
- `POST <host>/comments/<content-type>:<id>`
204
+ `POST <host>/comments/api::<collection name>.<content type name>:<entity id>`
220
205
 
221
- 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`
222
207
 
223
- **Example URL**: `https://localhost:1337/comments/article:1`
208
+ **Example URL**: `https://localhost:1337/comments/api::page.page:1`
224
209
 
225
210
  **Example request body**
226
211
 
227
212
  *Generic (non Strapi User)*
228
213
  ```
229
214
  {
230
- "authorId": "<any ID like value>",
231
- "authorName": "Joe Doe",
232
- "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
+ },
233
221
  "content": "My sample response",
234
222
  "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
- }]
223
+ "related": "api::page.page:1"
240
224
  }
241
225
  ```
242
226
 
@@ -246,11 +230,7 @@ Posts a Comment related to specified instance of Content Type like for example `
246
230
  "authorUser": 1, // id of a author user. Optional in case of 'enableUsers: true' in the plugin configuration
247
231
  "content": "My sample response",
248
232
  "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
- }]
233
+ "related": "api::page.page:1"
254
234
  }
255
235
  ```
256
236
 
@@ -268,20 +248,20 @@ Posts a Comment related to specified instance of Content Type like for example `
268
248
 
269
249
  ### Update Comment
270
250
 
271
- `PUT <host>/comments/<content-type>:<id>/comment/<commentId>`
251
+ `PUT <host>/comments/api::<collection name>.<content type name>:<entity id>/comment/<commentId>`
272
252
 
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`
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`
274
254
 
275
- **Example URL**: `https://localhost:1337/comments/article:1/comment/2`
255
+ **Example URL**: `https://localhost:1337/comments/api::page.page:1/comment/2`
276
256
 
277
257
  **Example request body**
278
258
 
279
259
  *Generic (non Strapi User)*
280
260
  ```
281
261
  {
282
- "authorId": "<any ID like value>",
283
- "authorName": "Joe Doe",
284
- "authorEmail": "jdoe@sample.com",
262
+ "author": {
263
+ "id": "<any ID like value>"
264
+ },
285
265
  "content": "My sample response"
286
266
  }
287
267
  ```
@@ -309,11 +289,11 @@ Updates a specified Comment content based on it `commentId` and related to speci
309
289
 
310
290
  ### Delete Comment
311
291
 
312
- `DELETE <host>/comments/<content-type>:<id>/<commentId>?authorId=<authorId>`
292
+ `DELETE <host>/comments/api::<collection name>.<content type name>:<entity id>/<commentId>?authorId=<authorId>`
313
293
 
314
- 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`.
315
295
 
316
- **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`
317
297
 
318
298
  **Example response body**
319
299
 
@@ -327,33 +307,14 @@ Deletes a specified Comment based on it `commentId` and related to specified ins
327
307
  - `200` - Successful with blank Response.
328
308
  - `409` - Conflict. Occurs when trying to delete a non existing comment.
329
309
 
330
- ### Like Comment
331
-
332
- `PATCH <host>/comments/<content-type>:<id>/comment/<commentId>/like`
333
-
334
- Likes a specified Comment based on it `commentId` and related to specified instance of Content Type like for example `Article` with `ID: 1`.
335
-
336
- **Example URL**: `https://localhost:1337/comments/article:1/comment/2/like`
337
-
338
- **Example response body**
339
-
340
- ```
341
- {
342
- -- Comment Model fields ---
343
- }
344
- ```
345
-
346
- **Possible response codes**
347
- - `200` - Successful. Response with liked Comment Model.
348
- - `409` - Conflict. Occurs when trying to like a non existing comment.
349
310
 
350
311
  ### Report abuse in the Comment
351
312
 
352
- `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`
353
314
 
354
- 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.
355
316
 
356
- **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`
357
318
 
358
319
  **Example request body**
359
320
 
@@ -390,10 +351,10 @@ Feel free to fork and make a Pull Request to this plugin project. All the input
390
351
 
391
352
  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:
392
353
 
393
- - [Slack](http://slack.strapi.io) We're present on official Strapi slack workspace. Look for @cyp3r and DM.
354
+ - [Discord](https://discord.strapi.io/) We're present on official Strapi Discord workspace. Look for @cyp3r and DM.
394
355
  - [Slack - VirtusLab Open Source](https://virtuslab-oss.slack.com) We're present on a public channel #strapi-molecules
395
- - [GitHub](https://github.com/VirtusLab/strapi-plugin-comments/issues) (Bug reports, Contributions, Questions and Discussions)
356
+ - [GitHub](https://github.com/VirtusLab-Open-Source/strapi-plugin-comments/issues) (Bug reports, Contributions, Questions and Discussions)
396
357
 
397
358
  ## License
398
359
 
399
- [MIT License](LICENSE.md) Copyright (c) 2020 [VirtusLab Sp. z o.o.](https://virtuslab.com/) &amp; [Strapi Solutions](https://strapi.io/).
360
+ [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,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
+