decidim-comments 0.22.0 → 0.23.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (88) hide show
  1. checksums.yaml +4 -4
  2. data/app/assets/javascripts/decidim/comments/bundle.js +53 -53
  3. data/app/assets/javascripts/decidim/comments/bundle.js.map +1 -1
  4. data/app/cells/decidim/comments/comment_activity_cell.rb +2 -22
  5. data/app/cells/decidim/comments/comment_cell.rb +22 -0
  6. data/app/cells/decidim/comments/comment_m/footer.erb +5 -0
  7. data/app/cells/decidim/comments/comment_m/top.erb +7 -0
  8. data/app/cells/decidim/comments/comment_m_cell.rb +29 -0
  9. data/app/commands/decidim/comments/create_comment.rb +1 -1
  10. data/app/events/decidim/comments/comment_event.rb +1 -9
  11. data/app/forms/decidim/comments/comment_form.rb +8 -1
  12. data/app/frontend/comments/add_comment_form.component.test.tsx +30 -28
  13. data/app/frontend/comments/add_comment_form.component.tsx +32 -16
  14. data/app/frontend/comments/comment.component.test.tsx +35 -4
  15. data/app/frontend/comments/comment.component.tsx +24 -15
  16. data/app/frontend/comments/comment_thread.component.test.tsx +9 -8
  17. data/app/frontend/comments/comment_thread.component.tsx +3 -1
  18. data/app/frontend/comments/comments.component.test.tsx +17 -14
  19. data/app/frontend/comments/comments.component.tsx +28 -4
  20. data/app/frontend/comments/down_vote_button.component.tsx +24 -9
  21. data/app/frontend/comments/up_vote_button.component.tsx +24 -9
  22. data/app/frontend/mutations/add_comment.mutation.graphql +2 -2
  23. data/app/frontend/mutations/down_vote.mutation.graphql +2 -2
  24. data/app/frontend/mutations/up_vote.mutation.graphql +2 -2
  25. data/app/frontend/queries/comments.query.graphql +2 -2
  26. data/app/frontend/support/schema.ts +1060 -735
  27. data/app/helpers/decidim/comments/comment_cells_helper.rb +33 -0
  28. data/app/models/decidim/comments/comment.rb +80 -21
  29. data/app/models/decidim/comments/seed.rb +1 -1
  30. data/app/types/decidim/comments/commentable_interface.rb +1 -1
  31. data/app/types/decidim/comments/commentable_mutation_type.rb +4 -1
  32. data/config/locales/am-ET.yml +1 -0
  33. data/config/locales/bg.yml +6 -0
  34. data/config/locales/ca.yml +1 -0
  35. data/config/locales/cs.yml +2 -1
  36. data/config/locales/da.yml +1 -0
  37. data/config/locales/de.yml +29 -28
  38. data/config/locales/en.yml +1 -0
  39. data/config/locales/eo.yml +1 -0
  40. data/config/locales/es-MX.yml +1 -0
  41. data/config/locales/es-PY.yml +1 -0
  42. data/config/locales/es.yml +3 -2
  43. data/config/locales/et.yml +1 -0
  44. data/config/locales/fi-plain.yml +1 -0
  45. data/config/locales/fi.yml +2 -1
  46. data/config/locales/fr-CA.yml +2 -1
  47. data/config/locales/fr.yml +2 -1
  48. data/config/locales/gl.yml +13 -0
  49. data/config/locales/hr.yml +1 -0
  50. data/config/locales/hu.yml +1 -1
  51. data/config/locales/is-IS.yml +0 -2
  52. data/config/locales/is.yml +76 -0
  53. data/config/locales/it.yml +1 -0
  54. data/config/locales/ja-JP.yml +2 -2
  55. data/config/locales/ja.yml +121 -0
  56. data/config/locales/ko-KR.yml +1 -0
  57. data/config/locales/ko.yml +1 -0
  58. data/config/locales/lt.yml +1 -0
  59. data/config/locales/{lv-LV.yml → lv.yml} +0 -0
  60. data/config/locales/mt.yml +1 -0
  61. data/config/locales/nl.yml +11 -10
  62. data/config/locales/om-ET.yml +1 -0
  63. data/config/locales/pl.yml +6 -5
  64. data/config/locales/si-LK.yml +1 -0
  65. data/config/locales/so-SO.yml +1 -0
  66. data/config/locales/sv.yml +1 -0
  67. data/config/locales/sw-KE.yml +1 -0
  68. data/config/locales/ti-ER.yml +1 -0
  69. data/config/locales/tr-TR.yml +53 -33
  70. data/config/locales/uk.yml +0 -1
  71. data/config/locales/vi-VN.yml +1 -0
  72. data/config/locales/vi.yml +1 -0
  73. data/config/locales/zh-CN.yml +121 -0
  74. data/config/locales/zh-TW.yml +1 -0
  75. data/db/migrate/20200706123136_make_comments_handle_i18n.rb +41 -0
  76. data/db/migrate/20200828101910_add_commentable_counter_cache_to_comments.rb +9 -0
  77. data/lib/decidim/comments/api/comment_type.rb +5 -1
  78. data/lib/decidim/comments/comment_serializer.rb +7 -2
  79. data/lib/decidim/comments/comment_vote_serializer.rb +5 -1
  80. data/lib/decidim/comments/commentable.rb +11 -0
  81. data/lib/decidim/comments/comments_helper.rb +28 -4
  82. data/lib/decidim/comments/engine.rb +13 -0
  83. data/lib/decidim/comments/mutation_extensions.rb +8 -0
  84. data/lib/decidim/comments/query_extensions.rb +4 -0
  85. data/lib/decidim/comments/test/factories.rb +10 -1
  86. data/lib/decidim/comments/test/shared_examples/comment_event.rb +1 -1
  87. data/lib/decidim/comments/version.rb +1 -1
  88. metadata +42 -14
@@ -2,14 +2,15 @@ import { mount, ReactWrapper, shallow } from "enzyme";
2
2
  import * as $ from "jquery";
3
3
  import * as React from "react";
4
4
 
5
- import { AddCommentForm, MAX_LENGTH } from "./add_comment_form.component";
5
+ import { AddCommentForm } from "./add_comment_form.component";
6
6
 
7
7
  import generateUserData from "../support/generate_user_data";
8
8
  import generateUserGroupData from "../support/generate_user_group_data";
9
9
  import { loadLocaleTranslations } from "../support/load_translations";
10
10
 
11
- describe("<AddCommentForm />", () => {
11
+ describe("<AddCommentForm commentsMaxLength={commentsMaxLength} />", () => {
12
12
  let session: any = null;
13
+ const commentsMaxLength: number = 1000;
13
14
  const commentable = {
14
15
  id: "1",
15
16
  type: "Decidim::DummyResources::DummyResource"
@@ -18,6 +19,7 @@ describe("<AddCommentForm />", () => {
18
19
  const addCommentStub = (): any => {
19
20
  return null;
20
21
  };
22
+ const context = {locale: undefined, toggleTranslations: undefined};
21
23
 
22
24
  beforeEach(() => {
23
25
  loadLocaleTranslations("en");
@@ -35,44 +37,44 @@ describe("<AddCommentForm />", () => {
35
37
  });
36
38
 
37
39
  it("should render a div with class add-comment", () => {
38
- const wrapper = shallow(<AddCommentForm addComment={addCommentStub} session={session} commentable={commentable} rootCommentable={commentable} orderBy={orderBy} />);
40
+ const wrapper = shallow(<AddCommentForm commentsMaxLength={commentsMaxLength} addComment={addCommentStub} session={session} commentable={commentable} rootCommentable={commentable} orderBy={orderBy} />);
39
41
  expect(wrapper.find("div.add-comment")).toBeDefined();
40
42
  });
41
43
 
42
44
  it("should have a reference to body textarea", () => {
43
- const wrapper = mount(<AddCommentForm addComment={addCommentStub} session={session} commentable={commentable} rootCommentable={commentable} orderBy={orderBy} />);
45
+ const wrapper = mount(<AddCommentForm commentsMaxLength={commentsMaxLength} addComment={addCommentStub} session={session} commentable={commentable} rootCommentable={commentable} orderBy={orderBy} />);
44
46
  expect((wrapper.instance() as AddCommentForm).bodyTextArea).toBeDefined();
45
47
  });
46
48
 
47
49
  it("should initialize with a state property disabled as true", () => {
48
- const wrapper = mount(<AddCommentForm addComment={addCommentStub} session={session} commentable={commentable} rootCommentable={commentable} orderBy={orderBy} />);
50
+ const wrapper = mount(<AddCommentForm commentsMaxLength={commentsMaxLength} addComment={addCommentStub} session={session} commentable={commentable} rootCommentable={commentable} orderBy={orderBy} />);
49
51
  expect(wrapper.state()).toHaveProperty("disabled", true);
50
52
  });
51
53
 
52
54
  it("should have a default prop showTitle as true", () => {
53
- const wrapper = mount(<AddCommentForm addComment={addCommentStub} session={session} commentable={commentable} rootCommentable={commentable} orderBy={orderBy} />);
55
+ const wrapper = mount(<AddCommentForm commentsMaxLength={commentsMaxLength} addComment={addCommentStub} session={session} commentable={commentable} rootCommentable={commentable} orderBy={orderBy} />);
54
56
  expect(wrapper.props()).toHaveProperty("showTitle", true);
55
57
  });
56
58
 
57
59
  it("should not render the title if prop showTitle is false", () => {
58
- const wrapper = shallow(<AddCommentForm addComment={addCommentStub} session={session} commentable={commentable} showTitle={false} rootCommentable={commentable} orderBy={orderBy} />);
60
+ const wrapper = shallow(<AddCommentForm commentsMaxLength={commentsMaxLength} addComment={addCommentStub} session={session} commentable={commentable} showTitle={false} rootCommentable={commentable} orderBy={orderBy} />);
59
61
  expect(wrapper.find("h4.section-heading").exists()).toBeFalsy();
60
62
  });
61
63
 
62
64
  it("should have a default prop submitButtonClassName as 'button button--sc'", () => {
63
- const wrapper = mount(<AddCommentForm addComment={addCommentStub} session={session} commentable={commentable} rootCommentable={commentable} orderBy={orderBy} />);
65
+ const wrapper = mount(<AddCommentForm commentsMaxLength={commentsMaxLength} addComment={addCommentStub} session={session} commentable={commentable} rootCommentable={commentable} orderBy={orderBy} />);
64
66
  expect(wrapper.props()).toHaveProperty("submitButtonClassName", "button button--sc");
65
67
  });
66
68
 
67
69
  it("should use prop submitButtonClassName as a className prop for submit button", () => {
68
- const wrapper = shallow(<AddCommentForm addComment={addCommentStub} session={session} commentable={commentable} submitButtonClassName="button small hollow" rootCommentable={commentable} orderBy={orderBy} />);
70
+ const wrapper = shallow(<AddCommentForm commentsMaxLength={commentsMaxLength} addComment={addCommentStub} session={session} commentable={commentable} submitButtonClassName="button small hollow" rootCommentable={commentable} orderBy={orderBy} />);
69
71
  expect(wrapper.find('button[type="submit"]').hasClass("button")).toBeTruthy();
70
72
  expect(wrapper.find('button[type="submit"]').hasClass("small")).toBeTruthy();
71
73
  expect(wrapper.find('button[type="submit"]').hasClass("hollow")).toBeTruthy();
72
74
  });
73
75
 
74
76
  it("should enable the submit button if textarea is not blank", () => {
75
- const wrapper = mount(<AddCommentForm addComment={addCommentStub} session={session} commentable={commentable} rootCommentable={commentable} orderBy={orderBy} />);
77
+ const wrapper = mount(<AddCommentForm commentsMaxLength={commentsMaxLength} addComment={addCommentStub} session={session} commentable={commentable} rootCommentable={commentable} orderBy={orderBy} />);
76
78
  wrapper.find("textarea").simulate("change", {
77
79
  target: {
78
80
  value: "This is a comment"
@@ -82,7 +84,7 @@ describe("<AddCommentForm />", () => {
82
84
  });
83
85
 
84
86
  it("should disable the submit button if textarea is blank", () => {
85
- const wrapper = mount(<AddCommentForm addComment={addCommentStub} session={session} commentable={commentable} rootCommentable={commentable} orderBy={orderBy} />);
87
+ const wrapper = mount(<AddCommentForm commentsMaxLength={commentsMaxLength} addComment={addCommentStub} session={session} commentable={commentable} rootCommentable={commentable} orderBy={orderBy} />);
86
88
  wrapper.find("textarea").simulate("change", {
87
89
  target: {
88
90
  value: "This will be deleted"
@@ -97,19 +99,19 @@ describe("<AddCommentForm />", () => {
97
99
  });
98
100
 
99
101
  it("should not render a div with class 'opinion-toggle'", () => {
100
- const wrapper = shallow(<AddCommentForm addComment={addCommentStub} session={session} commentable={commentable} rootCommentable={commentable} orderBy={orderBy} />);
102
+ const wrapper = shallow(<AddCommentForm commentsMaxLength={commentsMaxLength} addComment={addCommentStub} session={session} commentable={commentable} rootCommentable={commentable} orderBy={orderBy} />);
101
103
  expect(wrapper.find(".opinion-toggle").exists()).toBeFalsy();
102
104
  });
103
105
 
104
106
  it("should render the remaining character count", () => {
105
- const wrapper = shallow(<AddCommentForm addComment={addCommentStub} session={session} commentable={commentable} rootCommentable={commentable} orderBy={orderBy} />);
107
+ const wrapper = shallow(<AddCommentForm commentsMaxLength={commentsMaxLength} addComment={addCommentStub} session={session} commentable={commentable} rootCommentable={commentable} orderBy={orderBy} />);
106
108
  const commentBody = "This is a new comment!";
107
109
  wrapper.find("textarea").simulate("change", {
108
110
  target: {
109
111
  value: commentBody
110
112
  }
111
113
  });
112
- expect(wrapper.find(".remaining-character-count").text()).toContain(MAX_LENGTH - commentBody.length);
114
+ expect(wrapper.find(".remaining-character-count").text()).toContain(commentsMaxLength - commentBody.length);
113
115
  });
114
116
 
115
117
  describe("submitting the form", () => {
@@ -121,14 +123,14 @@ describe("<AddCommentForm />", () => {
121
123
  beforeEach(() => {
122
124
  addComment = jasmine.createSpy("addComment");
123
125
  onCommentAdded = jasmine.createSpy("onCommentAdded");
124
- wrapper = mount(<AddCommentForm addComment={addComment} session={session} commentable={commentable} onCommentAdded={onCommentAdded} rootCommentable={commentable} orderBy={orderBy} />);
126
+ wrapper = mount(<AddCommentForm commentsMaxLength={commentsMaxLength} addComment={addComment} session={session} commentable={commentable} onCommentAdded={onCommentAdded} rootCommentable={commentable} orderBy={orderBy} />);
125
127
  message = "This will be submitted";
126
128
  (wrapper.instance() as AddCommentForm).bodyTextArea.value = message;
127
129
  });
128
130
 
129
131
  it("should call addComment prop with the textarea value and state property alignment", () => {
130
132
  wrapper.find("form").simulate("submit");
131
- expect(addComment).toHaveBeenCalledWith({ body: message, alignment: 0 });
133
+ expect(addComment).toHaveBeenCalledWith({ body: message, alignment: 0 }, context);
132
134
  });
133
135
 
134
136
  it("should reset textarea", () => {
@@ -149,25 +151,25 @@ describe("<AddCommentForm />", () => {
149
151
  });
150
152
 
151
153
  it("should initialize state with a property alignment and value 0", () => {
152
- const wrapper = shallow(<AddCommentForm addComment={addCommentStub} session={session} commentable={commentable} arguable={true} rootCommentable={commentable} orderBy={orderBy} />);
154
+ const wrapper = shallow(<AddCommentForm commentsMaxLength={commentsMaxLength} addComment={addCommentStub} session={session} commentable={commentable} arguable={true} rootCommentable={commentable} orderBy={orderBy} />);
153
155
  expect(wrapper.state()).toHaveProperty("alignment", 0);
154
156
  });
155
157
 
156
158
  describe("when receiving an optional prop arguable with value true", () => {
157
159
  it("should render a div with class 'opinion-toggle'", () => {
158
- const wrapper = shallow(<AddCommentForm addComment={addCommentStub} session={session} commentable={commentable} arguable={true} rootCommentable={commentable} orderBy={orderBy} />);
160
+ const wrapper = shallow(<AddCommentForm commentsMaxLength={commentsMaxLength} addComment={addCommentStub} session={session} commentable={commentable} arguable={true} rootCommentable={commentable} orderBy={orderBy} />);
159
161
  expect(wrapper.find(".opinion-toggle")).toBeDefined();
160
162
  });
161
163
 
162
164
  it("should set state alignment to 1 if user clicks ok button and change its class", () => {
163
- const wrapper = shallow(<AddCommentForm addComment={addCommentStub} session={session} commentable={commentable} arguable={true} rootCommentable={commentable} orderBy={orderBy} />);
165
+ const wrapper = shallow(<AddCommentForm commentsMaxLength={commentsMaxLength} addComment={addCommentStub} session={session} commentable={commentable} arguable={true} rootCommentable={commentable} orderBy={orderBy} />);
164
166
  wrapper.find(".opinion-toggle--ok").simulate("click");
165
167
  expect(wrapper.find(".opinion-toggle--ok").hasClass("is-active")).toBeTruthy();
166
168
  expect(wrapper.state()).toHaveProperty("alignment", 1);
167
169
  });
168
170
 
169
171
  it("should set state alignment to -11 if user clicks ko button and change its class", () => {
170
- const wrapper = shallow(<AddCommentForm addComment={addCommentStub} session={session} commentable={commentable} arguable={true} rootCommentable={commentable} orderBy={orderBy} />);
172
+ const wrapper = shallow(<AddCommentForm commentsMaxLength={commentsMaxLength} addComment={addCommentStub} session={session} commentable={commentable} arguable={true} rootCommentable={commentable} orderBy={orderBy} />);
171
173
  wrapper.find(".opinion-toggle--ko").simulate("click");
172
174
  expect(wrapper.find(".opinion-toggle--ko").hasClass("is-active")).toBeTruthy();
173
175
  expect(wrapper.state()).toHaveProperty("alignment", -1);
@@ -180,7 +182,7 @@ describe("<AddCommentForm />", () => {
180
182
 
181
183
  beforeEach(() => {
182
184
  addComment = jasmine.createSpy("addComment");
183
- wrapper = mount(<AddCommentForm addComment={addComment} session={session} commentable={commentable} arguable={true} rootCommentable={commentable} orderBy={orderBy} />);
185
+ wrapper = mount(<AddCommentForm commentsMaxLength={commentsMaxLength} addComment={addComment} session={session} commentable={commentable} arguable={true} rootCommentable={commentable} orderBy={orderBy} />);
184
186
  message = "This will be submitted";
185
187
  (wrapper.instance() as AddCommentForm).bodyTextArea.value = message;
186
188
  });
@@ -188,7 +190,7 @@ describe("<AddCommentForm />", () => {
188
190
  it("should call addComment prop with the state's property alignment", () => {
189
191
  wrapper.find("button.opinion-toggle--ko").simulate("click");
190
192
  wrapper.find("form").simulate("submit");
191
- expect(addComment).toHaveBeenCalledWith({ body: message, alignment: -1 });
193
+ expect(addComment).toHaveBeenCalledWith({ body: message, alignment: -1 }, context);
192
194
  });
193
195
 
194
196
  it("should reset the state to its initial state", () => {
@@ -208,12 +210,12 @@ describe("<AddCommentForm />", () => {
208
210
  });
209
211
 
210
212
  it("should have a reference to user_group_id select", () => {
211
- const wrapper = mount(<AddCommentForm addComment={addCommentStub} session={session} commentable={commentable} rootCommentable={commentable} orderBy={orderBy} />);
213
+ const wrapper = mount(<AddCommentForm commentsMaxLength={commentsMaxLength} addComment={addCommentStub} session={session} commentable={commentable} rootCommentable={commentable} orderBy={orderBy} />);
212
214
  expect((wrapper.instance() as AddCommentForm).userGroupIdSelect).toBeDefined();
213
215
  });
214
216
 
215
217
  it("should render a select with option tags for each verified user group", () => {
216
- const wrapper = mount(<AddCommentForm addComment={addCommentStub} session={session} commentable={commentable} rootCommentable={commentable} orderBy={orderBy} />);
218
+ const wrapper = mount(<AddCommentForm commentsMaxLength={commentsMaxLength} addComment={addCommentStub} session={session} commentable={commentable} rootCommentable={commentable} orderBy={orderBy} />);
217
219
  expect(wrapper.find("select").children("option").length).toBe(3);
218
220
  });
219
221
 
@@ -225,7 +227,7 @@ describe("<AddCommentForm />", () => {
225
227
 
226
228
  beforeEach(() => {
227
229
  addComment = jasmine.createSpy("addComment");
228
- wrapper = mount(<AddCommentForm addComment={addComment} session={session} commentable={commentable} rootCommentable={commentable} orderBy={orderBy} />);
230
+ wrapper = mount(<AddCommentForm commentsMaxLength={commentsMaxLength} addComment={addComment} session={session} commentable={commentable} rootCommentable={commentable} orderBy={orderBy} />);
229
231
  message = "This will be submitted";
230
232
  userGroupId = session.verifiedUserGroups[1].id;
231
233
  (wrapper.instance() as AddCommentForm).bodyTextArea.value = message;
@@ -234,7 +236,7 @@ describe("<AddCommentForm />", () => {
234
236
 
235
237
  it("should call addComment prop with the body textarea, alignment and user_group_id select values", () => {
236
238
  wrapper.find("form").simulate("submit");
237
- expect(addComment).toHaveBeenCalledWith({ body: message, alignment: 0, userGroupId });
239
+ expect(addComment).toHaveBeenCalledWith({ body: message, alignment: 0, userGroupId }, context);
238
240
  });
239
241
 
240
242
  describe("when user_group_id is blank", () => {
@@ -244,7 +246,7 @@ describe("<AddCommentForm />", () => {
244
246
 
245
247
  it("should call addComment prop with the body textarea and alignment", () => {
246
248
  wrapper.find("form").simulate("submit");
247
- expect(addComment).toHaveBeenCalledWith({ body: message, alignment: 0 });
249
+ expect(addComment).toHaveBeenCalledWith({ body: message, alignment: 0 }, context);
248
250
  });
249
251
  });
250
252
  });
@@ -256,7 +258,7 @@ describe("<AddCommentForm />", () => {
256
258
  });
257
259
 
258
260
  it("display a message to sign in or sign up", () => {
259
- const wrapper = mount(<AddCommentForm addComment={addCommentStub} session={session} commentable={commentable} rootCommentable={commentable} orderBy={orderBy} />);
261
+ const wrapper = mount(<AddCommentForm commentsMaxLength={commentsMaxLength} addComment={addCommentStub} session={session} commentable={commentable} rootCommentable={commentable} orderBy={orderBy} />);
260
262
  expect(wrapper.find("span").text()).toContain("sign up");
261
263
  });
262
264
  });
@@ -4,6 +4,8 @@ import * as React from "react";
4
4
  import { graphql } from "react-apollo";
5
5
  import * as uuid from "uuid";
6
6
 
7
+ const PropTypes = require("prop-types");
8
+
7
9
  import Icon from "../application/icon.component";
8
10
 
9
11
  const { I18n, Translate } = require("react-i18nify");
@@ -27,9 +29,10 @@ interface AddCommentFormProps {
27
29
  autoFocus?: boolean;
28
30
  arguable?: boolean;
29
31
  userAllowedToComment?: boolean;
30
- addComment?: (data: { body: string, alignment: number, userGroupId?: string }) => void;
32
+ addComment?: (data: { body: string, alignment: number, userGroupId?: string }, context: any) => void;
31
33
  onCommentAdded?: () => void;
32
34
  orderBy: string;
35
+ commentsMaxLength: number;
33
36
  }
34
37
 
35
38
  interface AddCommentFormState {
@@ -39,8 +42,6 @@ interface AddCommentFormState {
39
42
  remainingCharacterCount: number;
40
43
  }
41
44
 
42
- export const MAX_LENGTH = 1000;
43
-
44
45
  /**
45
46
  * Renders a form to create new comments.
46
47
  * @class
@@ -54,6 +55,11 @@ export class AddCommentForm extends React.Component<AddCommentFormProps, AddComm
54
55
  autoFocus: false
55
56
  };
56
57
 
58
+ public static contextTypes: any = {
59
+ locale: PropTypes.string,
60
+ toggleTranslations: PropTypes.bool
61
+ };
62
+
57
63
  public bodyTextArea: HTMLTextAreaElement;
58
64
  public userGroupIdSelect: HTMLSelectElement;
59
65
 
@@ -64,7 +70,7 @@ export class AddCommentForm extends React.Component<AddCommentFormProps, AddComm
64
70
  disabled: true,
65
71
  error: false,
66
72
  alignment: 0,
67
- remainingCharacterCount: MAX_LENGTH
73
+ remainingCharacterCount: props.commentsMaxLength
68
74
  };
69
75
  }
70
76
 
@@ -176,7 +182,7 @@ export class AddCommentForm extends React.Component<AddCommentFormProps, AddComm
176
182
  * @returns {Void|DOMElement} - The heading or an empty element
177
183
  */
178
184
  private _renderTextArea() {
179
- const { commentable: { id, type }, autoFocus } = this.props;
185
+ const { commentable: { id, type }, autoFocus, commentsMaxLength } = this.props;
180
186
  const { error } = this.state;
181
187
  const className = classnames({ "is-invalid-input": error });
182
188
 
@@ -185,11 +191,11 @@ export class AddCommentForm extends React.Component<AddCommentFormProps, AddComm
185
191
  id: `add-comment-${type}-${id}`,
186
192
  className,
187
193
  rows: "4",
188
- maxLength: MAX_LENGTH,
194
+ maxLength: commentsMaxLength,
189
195
  required: "required",
190
- pattern: `^(.){0,${MAX_LENGTH}}$`,
196
+ pattern: `^(.){0,${commentsMaxLength}}$`,
191
197
  placeholder: I18n.t("components.add_comment_form.form.body.placeholder"),
192
- onChange: (evt: React.ChangeEvent<HTMLTextAreaElement>) => this._checkCommentBody(evt.target.value)
198
+ onChange: (evt: React.ChangeEvent<HTMLTextAreaElement>) => this._checkCommentBody(evt.target.value, commentsMaxLength as number)
193
199
  };
194
200
 
195
201
  if (autoFocus) {
@@ -207,12 +213,13 @@ export class AddCommentForm extends React.Component<AddCommentFormProps, AddComm
207
213
  * @returns {Void|DOMElement} - The error or an empty element
208
214
  */
209
215
  private _renderTextAreaError() {
216
+ const { commentsMaxLength } = this.props;
210
217
  const { error } = this.state;
211
218
 
212
219
  if (error) {
213
220
  return (
214
221
  <span className="form-error is-visible">
215
- {I18n.t("components.add_comment_form.form.form_error", { length: MAX_LENGTH })}
222
+ {I18n.t("components.add_comment_form.form.form_error", { length: commentsMaxLength })}
216
223
  </span>
217
224
  );
218
225
  }
@@ -317,10 +324,10 @@ export class AddCommentForm extends React.Component<AddCommentFormProps, AddComm
317
324
  * @param {string} body - The comment's body
318
325
  * @returns {Void} - Returns nothing
319
326
  */
320
- private _checkCommentBody(body: string) {
327
+ private _checkCommentBody(body: string, commentsMaxLength: number) {
321
328
  this.setState({
322
- disabled: body === "", error: body === "" || body.length > MAX_LENGTH,
323
- remainingCharacterCount: MAX_LENGTH - body.length
329
+ disabled: body === "", error: body === "" || body.length > commentsMaxLength,
330
+ remainingCharacterCount: commentsMaxLength - body.length
324
331
  });
325
332
  }
326
333
 
@@ -343,7 +350,7 @@ export class AddCommentForm extends React.Component<AddCommentFormProps, AddComm
343
350
  }
344
351
 
345
352
  if (addComment) {
346
- addComment(addCommentParams);
353
+ addComment(addCommentParams, this.context);
347
354
  }
348
355
 
349
356
  this.bodyTextArea.value = "";
@@ -360,10 +367,12 @@ const getCommentsQuery = require("../queries/comments.query.graphql");
360
367
 
361
368
  const AddCommentFormWithMutation = graphql<addCommentMutation, AddCommentFormProps>(addCommentMutation, {
362
369
  props: ({ ownProps, mutate }) => ({
363
- addComment: ({ body, alignment, userGroupId }: { body: string, alignment: number, userGroupId: string }) => {
370
+ addComment: ({ body, alignment, userGroupId }: { body: string, alignment: number, userGroupId: string }, { locale, toggleTranslations }: any) => {
364
371
  if (mutate) {
365
372
  mutate({
366
373
  variables: {
374
+ locale,
375
+ toggleTranslations,
367
376
  commentableId: ownProps.commentable.id,
368
377
  commentableType: ownProps.commentable.type,
369
378
  body,
@@ -381,10 +390,14 @@ const AddCommentFormWithMutation = graphql<addCommentMutation, AddCommentFormPro
381
390
  createdAt: new Date().toISOString(),
382
391
  body,
383
392
  formattedBody: body,
393
+ formattedCreatedAt: new Date().toISOString(),
384
394
  alignment,
385
395
  author: {
386
396
  __typename: "User",
387
397
  name: ownProps.session && ownProps.session.user.name,
398
+ nickname: ownProps.session && ownProps.session.user.name,
399
+ profilePath: null,
400
+ badge: null,
388
401
  avatarUrl: ownProps.session && ownProps.session.user.avatarUrl,
389
402
  deleted: false
390
403
  },
@@ -402,14 +415,17 @@ const AddCommentFormWithMutation = graphql<addCommentMutation, AddCommentFormPro
402
415
  },
403
416
  update: (store, { data }: { data: addCommentMutation }) => {
404
417
  const variables = {
418
+ locale,
419
+ toggleTranslations,
405
420
  commentableId: ownProps.rootCommentable.id,
406
421
  commentableType: ownProps.rootCommentable.type,
407
- orderBy: ownProps.orderBy
422
+ orderBy: ownProps.orderBy,
423
+ singleCommentId: null
408
424
  };
409
425
  const prev = store.readQuery<GetCommentsQuery>({
410
426
  query: getCommentsQuery,
411
427
  variables
412
- });
428
+ });
413
429
  const { id, type } = ownProps.commentable;
414
430
  const newComment = data.commentable && data.commentable.addComment;
415
431
  let comments = [];
@@ -1,8 +1,8 @@
1
- import { mount, shallow } from "enzyme";
1
+ import {mount, shallow} from "enzyme";
2
2
  import * as $ from "jquery";
3
3
  import * as React from "react";
4
4
 
5
- import { CommentFragment } from "../support/schema";
5
+ import {CommentFragment} from "../support/schema";
6
6
  import AddCommentForm from "./add_comment_form.component";
7
7
  import Comment from "./comment.component";
8
8
  import DownVoteButton from "./down_vote_button.component";
@@ -11,13 +11,15 @@ import UpVoteButton from "./up_vote_button.component";
11
11
  import generateCommentsData from "../support/generate_comments_data";
12
12
  import generateUserData from "../support/generate_user_data";
13
13
 
14
- import { loadLocaleTranslations } from "../support/load_translations";
14
+ import {loadLocaleTranslations} from "../support/load_translations";
15
15
 
16
16
  describe("<Comment />", () => {
17
+ const commentsMaxLength: number = 1000;
17
18
  const orderBy = "older";
18
19
  const rootCommentable = {
19
20
  id: "1",
20
- type: "Decidim::DummyResources::DummyResource"
21
+ type: "Decidim::DummyResources::DummyResource",
22
+ commentsMaxLength: 1000
21
23
  };
22
24
  let comment: CommentFragment;
23
25
  let session: any = null;
@@ -48,6 +50,7 @@ describe("<Comment />", () => {
48
50
  session={session}
49
51
  rootCommentable={rootCommentable}
50
52
  orderBy={orderBy}
53
+ commentsMaxLength={commentsMaxLength}
51
54
  />
52
55
  );
53
56
  expect(wrapper.find(".comment").exists()).toBeTruthy();
@@ -60,6 +63,7 @@ describe("<Comment />", () => {
60
63
  session={session}
61
64
  rootCommentable={rootCommentable}
62
65
  orderBy={orderBy}
66
+ commentsMaxLength={commentsMaxLength}
63
67
  />
64
68
  );
65
69
  expect(wrapper.find("time").prop("dateTime")).toEqual(comment.createdAt);
@@ -72,6 +76,7 @@ describe("<Comment />", () => {
72
76
  session={session}
73
77
  rootCommentable={rootCommentable}
74
78
  orderBy={orderBy}
79
+ commentsMaxLength={commentsMaxLength}
75
80
  />
76
81
  );
77
82
  expect(wrapper.find("span.author__name").text()).toEqual(
@@ -86,6 +91,7 @@ describe("<Comment />", () => {
86
91
  session={session}
87
92
  rootCommentable={rootCommentable}
88
93
  orderBy={orderBy}
94
+ commentsMaxLength={commentsMaxLength}
89
95
  />
90
96
  );
91
97
  expect(wrapper.find("span.author__nickname").text()).toEqual(
@@ -105,6 +111,7 @@ describe("<Comment />", () => {
105
111
  session={session}
106
112
  rootCommentable={rootCommentable}
107
113
  orderBy={orderBy}
114
+ commentsMaxLength={commentsMaxLength}
108
115
  />
109
116
  );
110
117
  expect(
@@ -120,6 +127,7 @@ describe("<Comment />", () => {
120
127
  session={session}
121
128
  rootCommentable={rootCommentable}
122
129
  orderBy={orderBy}
130
+ commentsMaxLength={commentsMaxLength}
123
131
  />
124
132
  );
125
133
  expect(wrapper.find(".author__avatar img").prop("src")).toEqual(
@@ -134,6 +142,7 @@ describe("<Comment />", () => {
134
142
  session={session}
135
143
  rootCommentable={rootCommentable}
136
144
  orderBy={orderBy}
145
+ commentsMaxLength={commentsMaxLength}
137
146
  />
138
147
  );
139
148
  expect(wrapper.find("div.comment__content").html()).toContain(
@@ -148,6 +157,7 @@ describe("<Comment />", () => {
148
157
  session={session}
149
158
  rootCommentable={rootCommentable}
150
159
  orderBy={orderBy}
160
+ commentsMaxLength={commentsMaxLength}
151
161
  />
152
162
  );
153
163
  expect(wrapper.state()).toHaveProperty("showReplyForm", false);
@@ -160,6 +170,7 @@ describe("<Comment />", () => {
160
170
  session={session}
161
171
  rootCommentable={rootCommentable}
162
172
  orderBy={orderBy}
173
+ commentsMaxLength={commentsMaxLength}
163
174
  />
164
175
  );
165
176
  expect(wrapper.find(AddCommentForm).exists()).toBeFalsy();
@@ -181,6 +192,7 @@ describe("<Comment />", () => {
181
192
  isRootComment={true}
182
193
  rootCommentable={rootCommentable}
183
194
  orderBy={orderBy}
195
+ commentsMaxLength={commentsMaxLength}
184
196
  />
185
197
  );
186
198
  expect(wrapper.find("div.comment__additionalreply").exists()).toBeFalsy();
@@ -194,6 +206,7 @@ describe("<Comment />", () => {
194
206
  session={session}
195
207
  rootCommentable={rootCommentable}
196
208
  orderBy={orderBy}
209
+ commentsMaxLength={commentsMaxLength}
197
210
  />
198
211
  );
199
212
  expect(wrapper.find("div.comment__additionalreply").exists()).toBeFalsy();
@@ -208,6 +221,7 @@ describe("<Comment />", () => {
208
221
  isRootComment={true}
209
222
  rootCommentable={rootCommentable}
210
223
  orderBy={orderBy}
224
+ commentsMaxLength={commentsMaxLength}
211
225
  />
212
226
  );
213
227
  expect(wrapper.find("div.comment__additionalreply").exists()).toBeTruthy();
@@ -221,6 +235,7 @@ describe("<Comment />", () => {
221
235
  votable={true}
222
236
  rootCommentable={rootCommentable}
223
237
  orderBy={orderBy}
238
+ commentsMaxLength={commentsMaxLength}
224
239
  />
225
240
  );
226
241
  wrapper.find(Comment).forEach((node, idx) => {
@@ -239,6 +254,7 @@ describe("<Comment />", () => {
239
254
  articleClassName="comment comment--nested"
240
255
  rootCommentable={rootCommentable}
241
256
  orderBy={orderBy}
257
+ commentsMaxLength={commentsMaxLength}
242
258
  />
243
259
  );
244
260
  wrapper.find(Comment).forEach(node => {
@@ -255,6 +271,7 @@ describe("<Comment />", () => {
255
271
  session={session}
256
272
  rootCommentable={rootCommentable}
257
273
  orderBy={orderBy}
274
+ commentsMaxLength={commentsMaxLength}
258
275
  />
259
276
  );
260
277
  expect(wrapper.prop("articleClassName")).toEqual("comment");
@@ -267,6 +284,7 @@ describe("<Comment />", () => {
267
284
  session={session}
268
285
  rootCommentable={rootCommentable}
269
286
  orderBy={orderBy}
287
+ commentsMaxLength={commentsMaxLength}
270
288
  />
271
289
  );
272
290
  expect(wrapper.prop("isRootComment")).toBeFalsy();
@@ -284,6 +302,7 @@ describe("<Comment />", () => {
284
302
  session={session}
285
303
  rootCommentable={rootCommentable}
286
304
  orderBy={orderBy}
305
+ commentsMaxLength={commentsMaxLength}
287
306
  />
288
307
  );
289
308
  expect(wrapper.find("button.comment__reply").exists()).toBeFalsy();
@@ -302,6 +321,7 @@ describe("<Comment />", () => {
302
321
  session={session}
303
322
  rootCommentable={rootCommentable}
304
323
  orderBy={orderBy}
324
+ commentsMaxLength={commentsMaxLength}
305
325
  />
306
326
  );
307
327
  expect(wrapper.find("button.comment__reply").exists()).toBeFalsy();
@@ -314,6 +334,7 @@ describe("<Comment />", () => {
314
334
  session={session}
315
335
  rootCommentable={rootCommentable}
316
336
  orderBy={orderBy}
337
+ commentsMaxLength={commentsMaxLength}
317
338
  />
318
339
  );
319
340
  expect(wrapper.find(".flag-modal").exists()).toBeFalsy();
@@ -328,6 +349,7 @@ describe("<Comment />", () => {
328
349
  session={session}
329
350
  rootCommentable={rootCommentable}
330
351
  orderBy={orderBy}
352
+ commentsMaxLength={commentsMaxLength}
331
353
  />
332
354
  );
333
355
  expect(wrapper.find("span.alignment.label").text()).toEqual("In favor");
@@ -341,6 +363,7 @@ describe("<Comment />", () => {
341
363
  session={session}
342
364
  rootCommentable={rootCommentable}
343
365
  orderBy={orderBy}
366
+ commentsMaxLength={commentsMaxLength}
344
367
  />
345
368
  );
346
369
  expect(wrapper.find("span.alert.label").text()).toEqual("Against");
@@ -353,6 +376,7 @@ describe("<Comment />", () => {
353
376
  session={session}
354
377
  rootCommentable={rootCommentable}
355
378
  orderBy={orderBy}
379
+ commentsMaxLength={commentsMaxLength}
356
380
  />
357
381
  );
358
382
  expect(wrapper.find(".flag-modal").exists()).toBeTruthy();
@@ -367,6 +391,7 @@ describe("<Comment />", () => {
367
391
  session={session}
368
392
  rootCommentable={rootCommentable}
369
393
  orderBy={orderBy}
394
+ commentsMaxLength={commentsMaxLength}
370
395
  />
371
396
  );
372
397
  expect(wrapper.find(".flag-modal form").exists()).toBeFalsy();
@@ -382,6 +407,7 @@ describe("<Comment />", () => {
382
407
  votable={true}
383
408
  rootCommentable={rootCommentable}
384
409
  orderBy={orderBy}
410
+ commentsMaxLength={commentsMaxLength}
385
411
  />
386
412
  );
387
413
  expect(wrapper.find(UpVoteButton).prop("comment")).toEqual(comment);
@@ -395,6 +421,7 @@ describe("<Comment />", () => {
395
421
  votable={true}
396
422
  rootCommentable={rootCommentable}
397
423
  orderBy={orderBy}
424
+ commentsMaxLength={commentsMaxLength}
398
425
  />
399
426
  );
400
427
  expect(wrapper.find(DownVoteButton).prop("comment")).toEqual(comment);
@@ -413,6 +440,7 @@ describe("<Comment />", () => {
413
440
  session={session}
414
441
  rootCommentable={rootCommentable}
415
442
  orderBy={orderBy}
443
+ commentsMaxLength={commentsMaxLength}
416
444
  />
417
445
  );
418
446
  expect(wrapper.find("button.comment__reply").exists()).toBeFalsy();
@@ -425,6 +453,7 @@ describe("<Comment />", () => {
425
453
  session={session}
426
454
  rootCommentable={rootCommentable}
427
455
  orderBy={orderBy}
456
+ commentsMaxLength={commentsMaxLength}
428
457
  />
429
458
  );
430
459
  expect(wrapper.find(".flag-modal").exists()).toBeFalsy();
@@ -438,6 +467,7 @@ describe("<Comment />", () => {
438
467
  votable={true}
439
468
  rootCommentable={rootCommentable}
440
469
  orderBy={orderBy}
470
+ commentsMaxLength={commentsMaxLength}
441
471
  />
442
472
  );
443
473
  expect(wrapper.find(".comment__votes--up").exists()).toBeFalsy();
@@ -451,6 +481,7 @@ describe("<Comment />", () => {
451
481
  votable={true}
452
482
  rootCommentable={rootCommentable}
453
483
  orderBy={orderBy}
484
+ commentsMaxLength={commentsMaxLength}
454
485
  />
455
486
  );
456
487
  expect(wrapper.find(".comment__votes--down").exists()).toBeFalsy();