decidim-comments 0.23.0 → 0.24.0.rc1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (151) hide show
  1. checksums.yaml +4 -4
  2. data/app/assets/javascripts/decidim/comments/bundle.js.map +1 -1
  3. data/app/assets/javascripts/decidim/comments/comments.component.js.es6 +292 -0
  4. data/app/assets/javascripts/decidim/comments/comments.component.test.js +581 -0
  5. data/app/assets/javascripts/decidim/comments/comments.js.erb +1 -1
  6. data/app/cells/decidim/comments/comment/actions.erb +7 -0
  7. data/app/cells/decidim/comments/comment/alignment_badge.erb +4 -0
  8. data/app/cells/decidim/comments/comment/author.erb +1 -0
  9. data/app/cells/decidim/comments/comment/show.erb +40 -0
  10. data/app/cells/decidim/comments/comment/utilities.erb +13 -0
  11. data/app/cells/decidim/comments/comment/votes.erb +25 -0
  12. data/app/cells/decidim/comments/comment_card_cell.rb +22 -0
  13. data/app/cells/decidim/comments/comment_cell.rb +142 -8
  14. data/app/cells/decidim/comments/comment_form/comment_as.erb +10 -0
  15. data/app/cells/decidim/comments/comment_form/show.erb +24 -0
  16. data/app/cells/decidim/comments/comment_form_cell.rb +94 -0
  17. data/app/cells/decidim/comments/comment_m/top.erb +1 -1
  18. data/app/cells/decidim/comments/comment_thread/show.erb +6 -0
  19. data/app/cells/decidim/comments/comment_thread/title.erb +3 -0
  20. data/app/cells/decidim/comments/comment_thread_cell.rb +30 -0
  21. data/app/cells/decidim/comments/comments/add_comment.erb +30 -0
  22. data/app/cells/decidim/comments/comments/blocked_comments_warning.erb +3 -0
  23. data/app/cells/decidim/comments/comments/order_control.erb +37 -0
  24. data/app/cells/decidim/comments/comments/show.erb +32 -0
  25. data/app/cells/decidim/comments/comments/single_comment_warning.erb +9 -0
  26. data/app/cells/decidim/comments/comments/user_comments_blocked_warning.erb +3 -0
  27. data/app/cells/decidim/comments/comments_cell.rb +134 -0
  28. data/app/commands/decidim/comments/vote_comment.rb +34 -10
  29. data/app/controllers/decidim/comments/application_controller.rb +16 -0
  30. data/app/controllers/decidim/comments/comments_controller.rb +122 -0
  31. data/app/controllers/decidim/comments/votes_controller.rb +41 -0
  32. data/app/events/decidim/comments/comment_created_event.rb +1 -1
  33. data/app/events/decidim/comments/comment_downvoted_event.rb +8 -0
  34. data/app/events/decidim/comments/comment_event.rb +1 -9
  35. data/app/events/decidim/comments/comment_upvoted_event.rb +8 -0
  36. data/app/events/decidim/comments/comment_voted_event.rb +26 -0
  37. data/app/forms/decidim/comments/comment_form.rb +6 -2
  38. data/app/models/decidim/comments/comment.rb +33 -11
  39. data/app/models/decidim/comments/seed.rb +1 -1
  40. data/app/permissions/decidim/comments/permissions.rb +59 -0
  41. data/app/queries/decidim/comments/metrics/comment_participants_metric_measure.rb +2 -2
  42. data/app/queries/decidim/comments/metrics/comments_metric_manage.rb +5 -6
  43. data/app/queries/decidim/comments/sorted_comments.rb +18 -14
  44. data/app/views/decidim/comments/comments/_comment.html.erb +5 -0
  45. data/app/views/decidim/comments/comments/_comments.html.erb +1 -0
  46. data/app/views/decidim/comments/comments/create.js.erb +16 -0
  47. data/app/views/decidim/comments/comments/error.js.erb +1 -0
  48. data/app/views/decidim/comments/comments/index.js.erb +24 -0
  49. data/app/views/decidim/comments/comments/reload.js.erb +21 -0
  50. data/app/views/decidim/comments/votes/create.js.erb +23 -0
  51. data/app/views/decidim/comments/votes/error.js.erb +1 -0
  52. data/config/locales/ar.yml +0 -2
  53. data/config/locales/ca.yml +7 -2
  54. data/config/locales/cs.yml +20 -3
  55. data/config/locales/de.yml +46 -30
  56. data/config/locales/el.yml +0 -2
  57. data/config/locales/en.yml +17 -2
  58. data/config/locales/es-MX.yml +7 -2
  59. data/config/locales/es-PY.yml +7 -2
  60. data/config/locales/es.yml +7 -2
  61. data/config/locales/eu.yml +0 -2
  62. data/config/locales/fi-plain.yml +17 -2
  63. data/config/locales/fi.yml +17 -2
  64. data/config/locales/fr-CA.yml +17 -2
  65. data/config/locales/fr.yml +17 -2
  66. data/config/locales/gl.yml +20 -2
  67. data/config/locales/hu.yml +0 -2
  68. data/config/locales/id-ID.yml +0 -2
  69. data/config/locales/is-IS.yml +0 -1
  70. data/config/locales/it.yml +5 -2
  71. data/config/locales/ja.yml +12 -8
  72. data/config/locales/lv.yml +0 -2
  73. data/config/locales/nl.yml +7 -9
  74. data/config/locales/no.yml +0 -2
  75. data/config/locales/pl.yml +22 -4
  76. data/config/locales/pt-BR.yml +0 -2
  77. data/config/locales/pt.yml +0 -2
  78. data/config/locales/ro-RO.yml +0 -2
  79. data/config/locales/ru.yml +0 -2
  80. data/config/locales/si-LK.yml +1 -0
  81. data/config/locales/sk.yml +0 -2
  82. data/config/locales/sv.yml +7 -2
  83. data/config/locales/sw-KE.yml +1 -0
  84. data/config/locales/tr-TR.yml +60 -35
  85. data/config/locales/uk.yml +0 -1
  86. data/config/locales/zh-CN.yml +0 -2
  87. data/lib/decidim/api/add_comment_type.rb +13 -0
  88. data/lib/decidim/api/comment_mutation_type.rb +22 -0
  89. data/lib/decidim/api/comment_type.rb +89 -0
  90. data/lib/decidim/api/commentable_interface.rb +50 -0
  91. data/lib/decidim/api/commentable_mutation_type.rb +30 -0
  92. data/{app/types/decidim/comments → lib/decidim/api}/commentable_type.rb +2 -5
  93. data/lib/decidim/comments.rb +1 -3
  94. data/lib/decidim/comments/api.rb +12 -0
  95. data/lib/decidim/comments/comments_helper.rb +10 -52
  96. data/lib/decidim/comments/engine.rb +9 -7
  97. data/lib/decidim/comments/mutation_extensions.rb +22 -22
  98. data/lib/decidim/comments/query_extensions.rb +12 -14
  99. data/lib/decidim/comments/test.rb +1 -0
  100. data/lib/decidim/comments/test/shared_examples/comment_voted_event.rb +65 -0
  101. data/lib/decidim/comments/version.rb +1 -1
  102. metadata +72 -69
  103. data/app/assets/javascripts/decidim/comments/bundle.js +0 -268
  104. data/app/frontend/application/apollo_client.ts +0 -12
  105. data/app/frontend/application/application.component.test.tsx +0 -23
  106. data/app/frontend/application/application.component.tsx +0 -35
  107. data/app/frontend/application/icon.component.test.tsx +0 -38
  108. data/app/frontend/application/icon.component.tsx +0 -46
  109. data/app/frontend/comments/add_comment_form.component.test.tsx +0 -265
  110. data/app/frontend/comments/add_comment_form.component.tsx +0 -482
  111. data/app/frontend/comments/comment.component.test.tsx +0 -490
  112. data/app/frontend/comments/comment.component.tsx +0 -677
  113. data/app/frontend/comments/comment_order_selector.component.test.tsx +0 -29
  114. data/app/frontend/comments/comment_order_selector.component.tsx +0 -106
  115. data/app/frontend/comments/comment_thread.component.test.tsx +0 -82
  116. data/app/frontend/comments/comment_thread.component.tsx +0 -81
  117. data/app/frontend/comments/comments.component.test.tsx +0 -150
  118. data/app/frontend/comments/comments.component.tsx +0 -289
  119. data/app/frontend/comments/down_vote_button.component.test.tsx +0 -59
  120. data/app/frontend/comments/down_vote_button.component.tsx +0 -133
  121. data/app/frontend/comments/up_vote_button.component.test.tsx +0 -59
  122. data/app/frontend/comments/up_vote_button.component.tsx +0 -133
  123. data/app/frontend/comments/vote_button.component.tsx +0 -50
  124. data/app/frontend/comments/vote_button_component.test.tsx +0 -64
  125. data/app/frontend/entry.ts +0 -38
  126. data/app/frontend/entry_test.ts +0 -6
  127. data/app/frontend/fragments/add_comment_form_commentable.fragment.graphql +0 -4
  128. data/app/frontend/fragments/add_comment_form_session.fragment.graphql +0 -6
  129. data/app/frontend/fragments/comment.fragment.graphql +0 -14
  130. data/app/frontend/fragments/comment_data.fragment.graphql +0 -27
  131. data/app/frontend/fragments/comment_thread.fragment.graphql +0 -6
  132. data/app/frontend/fragments/down_vote_button.fragment.graphql +0 -6
  133. data/app/frontend/fragments/up_vote_button.fragment.graphql +0 -6
  134. data/app/frontend/mutations/add_comment.mutation.graphql +0 -9
  135. data/app/frontend/mutations/down_vote.mutation.graphql +0 -9
  136. data/app/frontend/mutations/up_vote.mutation.graphql +0 -9
  137. data/app/frontend/queries/comments.query.graphql +0 -26
  138. data/app/frontend/support/asset_url.ts +0 -11
  139. data/app/frontend/support/generate_comments_data.ts +0 -49
  140. data/app/frontend/support/generate_user_data.ts +0 -14
  141. data/app/frontend/support/generate_user_group_data.ts +0 -14
  142. data/app/frontend/support/graphql_transformer.js +0 -32
  143. data/app/frontend/support/load_translations.ts +0 -48
  144. data/app/frontend/support/require_all.ts +0 -10
  145. data/app/frontend/support/resolve_graphql_query.ts +0 -37
  146. data/app/frontend/support/schema.ts +0 -2026
  147. data/app/types/decidim/comments/commentable_interface.rb +0 -61
  148. data/app/types/decidim/comments/commentable_mutation_type.rb +0 -33
  149. data/lib/decidim/comments/api/add_comment_type.rb +0 -13
  150. data/lib/decidim/comments/api/comment_mutation_type.rb +0 -20
  151. data/lib/decidim/comments/api/comment_type.rb +0 -89
@@ -1,482 +0,0 @@
1
- /* eslint-disable no-return-assign, react/no-unused-prop-types, max-lines */
2
- import * as classnames from "classnames";
3
- import * as React from "react";
4
- import { graphql } from "react-apollo";
5
- import * as uuid from "uuid";
6
-
7
- const PropTypes = require("prop-types");
8
-
9
- import Icon from "../application/icon.component";
10
-
11
- const { I18n, Translate } = require("react-i18nify");
12
-
13
- import {
14
- AddCommentFormCommentableFragment,
15
- AddCommentFormSessionFragment,
16
- addCommentMutation,
17
- CommentFragment,
18
- GetCommentsQuery
19
- } from "../support/schema";
20
-
21
- interface AddCommentFormProps {
22
- session: AddCommentFormSessionFragment & {
23
- user: any;
24
- } | null;
25
- commentable: AddCommentFormCommentableFragment;
26
- rootCommentable: AddCommentFormCommentableFragment;
27
- showTitle?: boolean;
28
- submitButtonClassName?: string;
29
- autoFocus?: boolean;
30
- arguable?: boolean;
31
- userAllowedToComment?: boolean;
32
- addComment?: (data: { body: string, alignment: number, userGroupId?: string }, context: any) => void;
33
- onCommentAdded?: () => void;
34
- orderBy: string;
35
- commentsMaxLength: number;
36
- }
37
-
38
- interface AddCommentFormState {
39
- disabled: boolean;
40
- error: boolean;
41
- alignment: number;
42
- remainingCharacterCount: number;
43
- }
44
-
45
- /**
46
- * Renders a form to create new comments.
47
- * @class
48
- * @augments Component
49
- */
50
- export class AddCommentForm extends React.Component<AddCommentFormProps, AddCommentFormState> {
51
- public static defaultProps = {
52
- showTitle: true,
53
- submitButtonClassName: "button button--sc",
54
- arguable: false,
55
- autoFocus: false
56
- };
57
-
58
- public static contextTypes: any = {
59
- locale: PropTypes.string,
60
- toggleTranslations: PropTypes.bool
61
- };
62
-
63
- public bodyTextArea: HTMLTextAreaElement;
64
- public userGroupIdSelect: HTMLSelectElement;
65
-
66
- constructor(props: AddCommentFormProps) {
67
- super(props);
68
-
69
- this.state = {
70
- disabled: true,
71
- error: false,
72
- alignment: 0,
73
- remainingCharacterCount: props.commentsMaxLength
74
- };
75
- }
76
-
77
- public render() {
78
- return (
79
- <div className="add-comment">
80
- {this._renderHeading()}
81
- {this._renderAccountMessage()}
82
- {this._renderOpinionButtons()}
83
- {this._renderForm()}
84
- </div>
85
- );
86
- }
87
-
88
- public componentDidMount() {
89
- this._attachMentions();
90
- }
91
-
92
- /**
93
- * Trick to reuse input_mentions.js logic
94
- */
95
- private _attachMentions() {
96
- window.$(document).trigger("attach-mentions-element", this.bodyTextArea);
97
- }
98
-
99
- /**
100
- * Render the form heading based on showTitle prop
101
- * @private
102
- * @returns {Void|DOMElement} - The heading or an empty element
103
- */
104
- private _renderHeading() {
105
- const { showTitle } = this.props;
106
-
107
- if (showTitle) {
108
- return (
109
- <h4 className="section-heading">
110
- {I18n.t("components.add_comment_form.title")}
111
- </h4>
112
- );
113
- }
114
-
115
- return null;
116
- }
117
-
118
- /**
119
- * Render a message telling the user to sign in or sign up to leave a comment.
120
- * @private
121
- * @returns {Void|DOMElement} - The message or an empty element.
122
- */
123
- private _renderAccountMessage() {
124
- const { session } = this.props;
125
-
126
- if (!session) {
127
- return (
128
- <p>
129
- <Translate
130
- value="components.add_comment_form.account_message"
131
- sign_in_url="/users/sign_in"
132
- sign_up_url="/users/sign_up"
133
- dangerousHTML={true}
134
- />
135
- </p>
136
- );
137
- }
138
-
139
- return null;
140
- }
141
-
142
- /**
143
- * Render the add comment form if session is present.
144
- * @private
145
- * @returns {Void|DOMElement} - The add comment form on an empty element.
146
- */
147
- private _renderForm() {
148
- const { session, submitButtonClassName, commentable: { id, type } } = this.props;
149
- const { disabled, remainingCharacterCount } = this.state;
150
-
151
- if (session) {
152
- return (
153
- <form onSubmit={this.addComment}>
154
- {this._renderCommentAs()}
155
- <div className="field">
156
- <label className="show-for-sr" htmlFor={`add-comment-${type}-${id}`}>{I18n.t("components.add_comment_form.form.body.label")}</label>
157
- <div className="hashtags__container">
158
- {this._renderTextArea()}
159
- </div>
160
- {this._renderTextAreaError()}
161
- <button
162
- type="submit"
163
- className={submitButtonClassName}
164
- disabled={disabled}
165
- >
166
- {I18n.t("components.add_comment_form.form.submit")}
167
- </button>
168
- <span className="remaining-character-count">
169
- {I18n.t("components.add_comment_form.remaining_characters", { count: remainingCharacterCount })}
170
- </span>
171
- </div>
172
- </form>
173
- );
174
- }
175
-
176
- return null;
177
- }
178
-
179
- /**
180
- * Render the form heading based on showTitle prop
181
- * @private
182
- * @returns {Void|DOMElement} - The heading or an empty element
183
- */
184
- private _renderTextArea() {
185
- const { commentable: { id, type }, autoFocus, commentsMaxLength } = this.props;
186
- const { error } = this.state;
187
- const className = classnames({ "is-invalid-input": error });
188
-
189
- const textAreaProps: any = {
190
- ref: (textarea: HTMLTextAreaElement) => {this.bodyTextArea = textarea; },
191
- id: `add-comment-${type}-${id}`,
192
- className,
193
- rows: "4",
194
- maxLength: commentsMaxLength,
195
- required: "required",
196
- pattern: `^(.){0,${commentsMaxLength}}$`,
197
- placeholder: I18n.t("components.add_comment_form.form.body.placeholder"),
198
- onChange: (evt: React.ChangeEvent<HTMLTextAreaElement>) => this._checkCommentBody(evt.target.value, commentsMaxLength as number)
199
- };
200
-
201
- if (autoFocus) {
202
- textAreaProps.autoFocus = "autoFocus";
203
- }
204
-
205
- return (
206
- <textarea {...textAreaProps} />
207
- );
208
- }
209
-
210
- /**
211
- * Render the text area form error if state has an error
212
- * @private
213
- * @returns {Void|DOMElement} - The error or an empty element
214
- */
215
- private _renderTextAreaError() {
216
- const { commentsMaxLength } = this.props;
217
- const { error } = this.state;
218
-
219
- if (error) {
220
- return (
221
- <span className="form-error is-visible">
222
- {I18n.t("components.add_comment_form.form.form_error", { length: commentsMaxLength })}
223
- </span>
224
- );
225
- }
226
-
227
- return null;
228
- }
229
-
230
- private setAlignment = (alignment: number) => {
231
- return () => {
232
- this.setState({ alignment });
233
- };
234
- }
235
-
236
- /**
237
- * Render opinion buttons or not based on the arguable prop
238
- * @private
239
- * @returns {Void|DOMElement} - Returns nothing or a wrapper with buttons
240
- */
241
- private _renderOpinionButtons() {
242
- const { session, arguable } = this.props;
243
- const { alignment } = this.state;
244
- const buttonClassName = classnames("button", "tiny", "button--muted");
245
- const okButtonClassName = classnames(buttonClassName, "opinion-toggle--ok", {
246
- "is-active": alignment === 1
247
- });
248
- const koButtonClassName = classnames(buttonClassName, "opinion-toggle--ko", {
249
- "is-active": alignment === -1
250
- });
251
- const neutralButtonClassName = classnames(buttonClassName, "opinion-toggle--meh", {
252
- "is-active": alignment === 0
253
- });
254
-
255
- if (session && arguable) {
256
- return (
257
- <div className="opinion-toggle button-group">
258
- <button
259
- className={okButtonClassName}
260
- onClick={this.setAlignment(1)}
261
- >
262
- <Icon iconExtraClassName="" name="icon-thumb-up" />
263
- </button>
264
- <button
265
- className={neutralButtonClassName}
266
- onClick={this.setAlignment(0)}
267
- >
268
- {I18n.t("components.add_comment_form.opinion.neutral")}
269
- </button>
270
- <button
271
- className={koButtonClassName}
272
- onClick={this.setAlignment(-1)}
273
- >
274
- <Icon iconExtraClassName="" name="icon-thumb-down" />
275
- </button>
276
- </div>
277
- );
278
- }
279
-
280
- return null;
281
- }
282
-
283
- private setUserGroupIdSelect = (select: HTMLSelectElement) => {this.userGroupIdSelect = select; };
284
-
285
- /**
286
- * Render a select with an option for each user's verified group
287
- * @private
288
- * @returns {Void|DOMElement} - Returns nothing or a form field.
289
- */
290
- private _renderCommentAs() {
291
- const { session, commentable: { id, type } } = this.props;
292
-
293
- if (session) {
294
- const { user, verifiedUserGroups } = session;
295
-
296
- if (verifiedUserGroups.length > 0) {
297
- return (
298
- <div className="field">
299
- <label htmlFor={`add-comment-${type}-${id}-user-group-id`}>
300
- {I18n.t("components.add_comment_form.form.user_group_id.label")}
301
- </label>
302
- <select
303
- ref={this.setUserGroupIdSelect}
304
- id={`add-comment-${type}-${id}-user-group-id`}
305
- >
306
- <option value="">{user.name}</option>
307
- {
308
- verifiedUserGroups.map((userGroup) => (
309
- <option key={userGroup.id} value={userGroup.id}>{userGroup.name}</option>
310
- ))
311
- }
312
- </select>
313
- </div>
314
- );
315
- }
316
- }
317
-
318
- return null;
319
- }
320
-
321
- /**
322
- * Check comment's body and disable form if it's empty
323
- * @private
324
- * @param {string} body - The comment's body
325
- * @returns {Void} - Returns nothing
326
- */
327
- private _checkCommentBody(body: string, commentsMaxLength: number) {
328
- this.setState({
329
- disabled: body === "", error: body === "" || body.length > commentsMaxLength,
330
- remainingCharacterCount: commentsMaxLength - body.length
331
- });
332
- }
333
-
334
- /**
335
- * Handle form's submission and calls `addComment` prop with the value of the
336
- * form's textarea. It prevents the default form submission event.
337
- * @private
338
- * @param {DOMEvent} evt - The form's submission event
339
- * @returns {Void} - Returns nothing
340
- */
341
- private addComment = (evt: React.FormEvent<HTMLFormElement>) => {
342
- const { alignment } = this.state;
343
- const { addComment, onCommentAdded } = this.props;
344
- const addCommentParams: { body: string, alignment: number, userGroupId?: string } = { body: this.bodyTextArea.value, alignment };
345
-
346
- evt.preventDefault();
347
-
348
- if (this.userGroupIdSelect && this.userGroupIdSelect.value !== "") {
349
- addCommentParams.userGroupId = this.userGroupIdSelect.value;
350
- }
351
-
352
- if (addComment) {
353
- addComment(addCommentParams, this.context);
354
- }
355
-
356
- this.bodyTextArea.value = "";
357
- this.setState({ alignment: 0 });
358
-
359
- if (onCommentAdded) {
360
- onCommentAdded();
361
- }
362
- }
363
- }
364
-
365
- const addCommentMutation = require("../mutations/add_comment.mutation.graphql");
366
- const getCommentsQuery = require("../queries/comments.query.graphql");
367
-
368
- const AddCommentFormWithMutation = graphql<addCommentMutation, AddCommentFormProps>(addCommentMutation, {
369
- props: ({ ownProps, mutate }) => ({
370
- addComment: ({ body, alignment, userGroupId }: { body: string, alignment: number, userGroupId: string }, { locale, toggleTranslations }: any) => {
371
- if (mutate) {
372
- mutate({
373
- variables: {
374
- locale,
375
- toggleTranslations,
376
- commentableId: ownProps.commentable.id,
377
- commentableType: ownProps.commentable.type,
378
- body,
379
- alignment,
380
- userGroupId
381
- },
382
- optimisticResponse: {
383
- commentable: {
384
- __typename: "CommentableMutation",
385
- addComment: {
386
- __typename: "Comment",
387
- id: uuid(),
388
- sgid: uuid(),
389
- type: "Decidim::Comments::Comment",
390
- createdAt: new Date().toISOString(),
391
- body,
392
- formattedBody: body,
393
- formattedCreatedAt: new Date().toISOString(),
394
- alignment,
395
- author: {
396
- __typename: "User",
397
- name: ownProps.session && ownProps.session.user.name,
398
- nickname: ownProps.session && ownProps.session.user.name,
399
- profilePath: null,
400
- badge: null,
401
- avatarUrl: ownProps.session && ownProps.session.user.avatarUrl,
402
- deleted: false
403
- },
404
- comments: [],
405
- hasComments: false,
406
- acceptsNewComments: false,
407
- userAllowedToComment: false,
408
- upVotes: 0,
409
- upVoted: false,
410
- downVotes: 0,
411
- downVoted: false,
412
- alreadyReported: false
413
- }
414
- }
415
- },
416
- update: (store, { data }: { data: addCommentMutation }) => {
417
- const variables = {
418
- locale,
419
- toggleTranslations,
420
- commentableId: ownProps.rootCommentable.id,
421
- commentableType: ownProps.rootCommentable.type,
422
- orderBy: ownProps.orderBy,
423
- singleCommentId: null
424
- };
425
- const prev = store.readQuery<GetCommentsQuery>({
426
- query: getCommentsQuery,
427
- variables
428
- });
429
- const { id, type } = ownProps.commentable;
430
- const newComment = data.commentable && data.commentable.addComment;
431
- let comments = [];
432
-
433
- const commentReducer = (comment: CommentFragment): CommentFragment => {
434
- const replies = comment.comments || [];
435
-
436
- if (newComment && comment.id === id) {
437
- return {
438
- ...comment,
439
- hasComments: true,
440
- comments: [
441
- ...replies,
442
- newComment
443
- ]
444
- };
445
- }
446
- return {
447
- ...comment,
448
- comments: replies.map(commentReducer)
449
- };
450
- };
451
-
452
- if (prev) {
453
- if (type === "Decidim::Comments::Comment") {
454
- comments = prev.commentable.comments.map(commentReducer);
455
- } else {
456
- comments = [
457
- ...prev.commentable.comments,
458
- newComment
459
- ];
460
- }
461
-
462
- store.writeQuery({
463
- query: getCommentsQuery,
464
- data: {
465
- ...prev,
466
- commentable: {
467
- ...prev.commentable,
468
- totalCommentsCount: prev.commentable.totalCommentsCount + 1,
469
- comments
470
- }
471
- },
472
- variables
473
- });
474
- }
475
- }
476
- });
477
- }
478
- }
479
- })
480
- })(AddCommentForm);
481
-
482
- export default AddCommentFormWithMutation;