decidim 0.0.6 → 0.0.7

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of decidim might be problematic. Click here for more details.

Files changed (308) hide show
  1. checksums.yaml +4 -4
  2. data/.babelrc +2 -1
  3. data/.ruby-version +1 -1
  4. data/.travis.yml +4 -6
  5. data/Dockerfile +2 -2
  6. data/Gemfile +1 -1
  7. data/Gemfile.lock +48 -48
  8. data/README.md +6 -1
  9. data/decidim-admin/app/assets/stylesheets/decidim/admin/_decidim.scss +9 -0
  10. data/decidim-admin/app/assets/stylesheets/decidim/admin/_variables.scss +7 -0
  11. data/decidim-admin/app/assets/stylesheets/decidim/admin/application.scss +2 -19
  12. data/decidim-admin/app/assets/stylesheets/decidim/admin/extra/_categories.scss +5 -0
  13. data/decidim-admin/app/assets/stylesheets/decidim/admin/{_email_preview.scss → extra/_email_preview.scss} +0 -0
  14. data/decidim-admin/app/assets/stylesheets/decidim/admin/{_login.scss → extra/_login.scss} +0 -0
  15. data/decidim-admin/app/assets/stylesheets/decidim/admin/extra/_select_multiple.scss +3 -0
  16. data/decidim-admin/app/assets/stylesheets/decidim/admin/extra/_title_bar.scss +5 -0
  17. data/decidim-admin/app/assets/stylesheets/decidim/admin/modules/_action-icon.scss +13 -0
  18. data/decidim-admin/app/assets/stylesheets/decidim/admin/modules/_buttons.scss +44 -0
  19. data/decidim-admin/app/assets/stylesheets/decidim/admin/modules/_callouts.scss +32 -0
  20. data/decidim-admin/app/assets/stylesheets/decidim/admin/modules/_cards.scss +36 -0
  21. data/decidim-admin/app/assets/stylesheets/decidim/admin/modules/_char-counter.scss +20 -0
  22. data/decidim-admin/app/assets/stylesheets/decidim/admin/modules/_component-counter.scss +17 -0
  23. data/decidim-admin/app/assets/stylesheets/decidim/admin/modules/_forms.scss +80 -0
  24. data/decidim-admin/app/assets/stylesheets/decidim/admin/modules/_icons.scss +65 -0
  25. data/decidim-admin/app/assets/stylesheets/decidim/admin/modules/_layout.scss +67 -0
  26. data/decidim-admin/app/assets/stylesheets/decidim/admin/modules/_main-nav.scss +41 -0
  27. data/decidim-admin/app/assets/stylesheets/decidim/admin/modules/_modules.scss +24 -0
  28. data/decidim-admin/app/assets/stylesheets/decidim/admin/modules/_process-header.scss +11 -0
  29. data/decidim-admin/app/assets/stylesheets/decidim/admin/modules/_secondary-nav.scss +95 -0
  30. data/decidim-admin/app/assets/stylesheets/decidim/admin/modules/_table-list.scss +78 -0
  31. data/decidim-admin/app/assets/stylesheets/decidim/admin/modules/_tabs.scss +49 -0
  32. data/decidim-admin/app/assets/stylesheets/decidim/admin/modules/_title-bar.scss +32 -0
  33. data/decidim-admin/app/assets/stylesheets/decidim/admin/modules/_typography.scss +15 -0
  34. data/decidim-admin/app/assets/stylesheets/decidim/admin/modules/_user-login.scss +23 -0
  35. data/decidim-admin/app/assets/stylesheets/decidim/admin/utils/_fontface.scss +27 -0
  36. data/decidim-admin/app/assets/stylesheets/decidim/admin/utils/_helpers.scss +25 -0
  37. data/decidim-admin/app/assets/stylesheets/decidim/admin/utils/_keyframes.scss +21 -0
  38. data/decidim-admin/app/assets/stylesheets/decidim/admin/utils/_mixins.scss +20 -0
  39. data/decidim-admin/app/assets/stylesheets/decidim/admin/utils/_settings.scss +590 -0
  40. data/decidim-admin/app/assets/stylesheets/decidim/admin/utils/_toggle-expand.scss +8 -0
  41. data/decidim-admin/app/commands/decidim/admin/create_attachment.rb +13 -4
  42. data/decidim-admin/app/commands/decidim/admin/update_participatory_process.rb +3 -3
  43. data/decidim-admin/app/commands/decidim/admin/update_participatory_process_admin.rb +40 -0
  44. data/decidim-admin/app/controllers/decidim/admin/application_controller.rb +7 -1
  45. data/decidim-admin/app/controllers/decidim/admin/newsletters_controller.rb +1 -1
  46. data/decidim-admin/app/controllers/decidim/admin/organization_controller.rb +2 -0
  47. data/decidim-admin/app/controllers/decidim/admin/participatory_process_user_roles_controller.rb +29 -0
  48. data/decidim-admin/app/controllers/decidim/admin/participatory_processes_controller.rb +2 -2
  49. data/decidim-admin/app/controllers/decidim/admin/scopes_controller.rb +2 -0
  50. data/decidim-admin/app/controllers/decidim/admin/static_pages_controller.rb +2 -0
  51. data/decidim-admin/app/controllers/decidim/admin/user_groups_controller.rb +3 -1
  52. data/decidim-admin/app/controllers/decidim/admin/users_controller.rb +1 -1
  53. data/decidim-admin/app/helpers/decidim/admin/application_helper.rb +8 -0
  54. data/decidim-admin/app/helpers/decidim/admin/icon_link_helper.rb +30 -0
  55. data/decidim-admin/app/jobs/decidim/admin/newsletter_job.rb +1 -1
  56. data/decidim-admin/app/queries/decidim/admin/process_admin_roles_for_process.rb +1 -1
  57. data/decidim-admin/app/views/decidim/admin/attachments/_form.html.erb +29 -8
  58. data/decidim-admin/app/views/decidim/admin/attachments/edit.html.erb +3 -5
  59. data/decidim-admin/app/views/decidim/admin/attachments/index.html.erb +45 -35
  60. data/decidim-admin/app/views/decidim/admin/attachments/new.html.erb +3 -5
  61. data/decidim-admin/app/views/decidim/admin/categories/_form.html.erb +18 -10
  62. data/decidim-admin/app/views/decidim/admin/categories/edit.html.erb +3 -5
  63. data/decidim-admin/app/views/decidim/admin/categories/index.html.erb +57 -42
  64. data/decidim-admin/app/views/decidim/admin/categories/new.html.erb +3 -5
  65. data/decidim-admin/app/views/decidim/admin/dashboard/show.html.erb +6 -3
  66. data/decidim-admin/app/views/decidim/admin/features/_feature.html.erb +11 -11
  67. data/decidim-admin/app/views/decidim/admin/features/_form.html.erb +56 -48
  68. data/decidim-admin/app/views/decidim/admin/features/edit.html.erb +3 -5
  69. data/decidim-admin/app/views/decidim/admin/features/index.html.erb +21 -19
  70. data/decidim-admin/app/views/decidim/admin/features/new.html.erb +3 -4
  71. data/decidim-admin/app/views/decidim/admin/moderations/index.html.erb +71 -61
  72. data/decidim-admin/app/views/decidim/admin/newsletters/_form.html.erb +7 -1
  73. data/decidim-admin/app/views/decidim/admin/newsletters/edit.html.erb +10 -8
  74. data/decidim-admin/app/views/decidim/admin/newsletters/index.html.erb +50 -43
  75. data/decidim-admin/app/views/decidim/admin/newsletters/new.html.erb +10 -8
  76. data/decidim-admin/app/views/decidim/admin/newsletters/show.html.erb +20 -12
  77. data/decidim-admin/app/views/decidim/admin/organization/_form.html.erb +98 -62
  78. data/decidim-admin/app/views/decidim/admin/organization/edit.html.erb +11 -8
  79. data/decidim-admin/app/views/decidim/admin/participatory_process_groups/_form.html.erb +4 -4
  80. data/decidim-admin/app/views/decidim/admin/participatory_process_groups/edit.html.erb +15 -9
  81. data/decidim-admin/app/views/decidim/admin/participatory_process_groups/index.html.erb +37 -35
  82. data/decidim-admin/app/views/decidim/admin/participatory_process_groups/new.html.erb +10 -8
  83. data/decidim-admin/app/views/decidim/admin/participatory_process_steps/_form.html.erb +21 -11
  84. data/decidim-admin/app/views/decidim/admin/participatory_process_steps/edit.html.erb +3 -4
  85. data/decidim-admin/app/views/decidim/admin/participatory_process_steps/index.html.erb +60 -51
  86. data/decidim-admin/app/views/decidim/admin/participatory_process_steps/new.html.erb +4 -5
  87. data/decidim-admin/app/views/decidim/admin/participatory_process_user_roles/_form.html.erb +23 -0
  88. data/decidim-admin/app/views/decidim/admin/participatory_process_user_roles/edit.html.erb +7 -0
  89. data/decidim-admin/app/views/decidim/admin/participatory_process_user_roles/index.html.erb +46 -34
  90. data/decidim-admin/app/views/decidim/admin/participatory_process_user_roles/new.html.erb +7 -0
  91. data/decidim-admin/app/views/decidim/admin/participatory_processes/_form.html.erb +103 -72
  92. data/decidim-admin/app/views/decidim/admin/participatory_processes/edit.html.erb +15 -17
  93. data/decidim-admin/app/views/decidim/admin/participatory_processes/index.html.erb +52 -43
  94. data/decidim-admin/app/views/decidim/admin/participatory_processes/new.html.erb +6 -5
  95. data/decidim-admin/app/views/decidim/admin/scopes/edit.html.erb +9 -7
  96. data/decidim-admin/app/views/decidim/admin/scopes/index.html.erb +37 -36
  97. data/decidim-admin/app/views/decidim/admin/scopes/new.html.erb +9 -6
  98. data/decidim-admin/app/views/decidim/admin/static_pages/_form.html.erb +3 -3
  99. data/decidim-admin/app/views/decidim/admin/static_pages/edit.html.erb +10 -8
  100. data/decidim-admin/app/views/decidim/admin/static_pages/index.html.erb +38 -37
  101. data/decidim-admin/app/views/decidim/admin/static_pages/new.html.erb +10 -8
  102. data/decidim-admin/app/views/decidim/admin/user_groups/index.html.erb +37 -31
  103. data/decidim-admin/app/views/decidim/admin/users/_form.html.erb +5 -4
  104. data/decidim-admin/app/views/decidim/admin/users/index.html.erb +57 -52
  105. data/decidim-admin/app/views/decidim/admin/users/new.html.erb +10 -7
  106. data/decidim-admin/app/views/layouts/decidim/admin/_application.html.erb +23 -36
  107. data/decidim-admin/app/views/layouts/decidim/admin/_callouts_full.html.erb +10 -0
  108. data/decidim-admin/app/views/layouts/decidim/admin/_language_chooser.html.erb +9 -9
  109. data/decidim-admin/app/views/layouts/decidim/admin/_main_nav.html.erb +11 -0
  110. data/decidim-admin/app/views/layouts/decidim/admin/_template_bottom.html.erb +2 -0
  111. data/decidim-admin/app/views/layouts/decidim/admin/_template_top.html.erb +3 -0
  112. data/decidim-admin/app/views/layouts/decidim/admin/_title_bar.html.erb +20 -0
  113. data/decidim-admin/app/views/layouts/decidim/admin/newsletters.erb +14 -0
  114. data/decidim-admin/app/views/layouts/decidim/admin/pages.html.erb +14 -0
  115. data/decidim-admin/app/views/layouts/decidim/admin/participatory_process.html.erb +55 -53
  116. data/decidim-admin/app/views/layouts/decidim/admin/participatory_process_groups.html.erb +14 -0
  117. data/decidim-admin/app/views/layouts/decidim/admin/participatory_processes.html.erb +14 -0
  118. data/decidim-admin/app/views/layouts/decidim/admin/settings.html.erb +19 -0
  119. data/decidim-admin/app/views/layouts/decidim/admin/users.html.erb +21 -0
  120. data/decidim-admin/config/i18n-tasks.yml +1 -0
  121. data/decidim-admin/config/locales/ca.yml +77 -22
  122. data/decidim-admin/config/locales/en.yml +75 -20
  123. data/decidim-admin/config/locales/es.yml +77 -22
  124. data/decidim-admin/config/locales/eu.yml +191 -16
  125. data/decidim-admin/config/locales/fi.yml +0 -29
  126. data/decidim-admin/config/routes.rb +1 -1
  127. data/decidim-admin/lib/decidim/admin/test/manage_attachments_examples.rb +11 -11
  128. data/decidim-admin/spec/commands/deliver_newsletter_spec.rb +4 -1
  129. data/decidim-admin/spec/commands/update_participatory_process_spec.rb +117 -0
  130. data/decidim-admin/spec/features/admin_invite_spec.rb +5 -1
  131. data/decidim-admin/spec/features/admin_manages_feature_permissions_spec.rb +1 -1
  132. data/decidim-admin/spec/features/admin_manages_features_spec.rb +10 -10
  133. data/decidim-admin/spec/features/admin_manages_newsletters_spec.rb +11 -9
  134. data/decidim-admin/spec/features/admin_manages_organization_admins_spec.rb +8 -5
  135. data/decidim-admin/spec/features/admin_manages_organization_scopes_spec.rb +7 -6
  136. data/decidim-admin/spec/features/admin_manages_organization_spec.rb +14 -0
  137. data/decidim-admin/spec/features/admin_manages_participatory_process_groups_spec.rb +6 -6
  138. data/decidim-admin/spec/features/admin_manages_participatory_processes_spec.rb +27 -5
  139. data/decidim-admin/spec/features/admin_manages_user_groups_spec.rb +1 -1
  140. data/decidim-admin/spec/features/participatory_process_admin_manages_participatory_process_admins_spec.rb +2 -2
  141. data/decidim-admin/spec/features/static_pages_spec.rb +9 -7
  142. data/decidim-admin/spec/jobs/newsletter_job_spec.rb +2 -0
  143. data/decidim-admin/spec/queries/process_admin_roles_for_process_spec.rb +4 -3
  144. data/decidim-admin/spec/shared/manage_process_admins_examples.rb +31 -8
  145. data/decidim-admin/spec/shared/manage_process_attachments_examples.rb +1 -1
  146. data/decidim-admin/spec/shared/manage_process_categories_examples.rb +11 -26
  147. data/decidim-admin/spec/shared/manage_process_steps_examples.rb +8 -23
  148. data/decidim-admin/spec/shared/manage_processes_examples.rb +5 -33
  149. data/decidim-admin/spec/support/processes_menu_links_helpers.rb +1 -1
  150. data/decidim-admin/yarn.lock +4 -0
  151. data/decidim-api/app/controllers/decidim/api/application_controller.rb +2 -1
  152. data/decidim-budgets/app/controllers/decidim/budgets/admin/projects_controller.rb +1 -1
  153. data/decidim-budgets/app/controllers/decidim/budgets/line_items_controller.rb +21 -15
  154. data/decidim-budgets/app/views/decidim/budgets/admin/projects/_form.html.erb +34 -24
  155. data/decidim-budgets/app/views/decidim/budgets/admin/projects/edit.html.erb +3 -5
  156. data/decidim-budgets/app/views/decidim/budgets/admin/projects/index.html.erb +52 -34
  157. data/decidim-budgets/app/views/decidim/budgets/admin/projects/new.html.erb +4 -5
  158. data/decidim-budgets/app/views/decidim/budgets/projects/_filters.html.erb +1 -1
  159. data/decidim-budgets/config/i18n-tasks.yml +1 -0
  160. data/decidim-budgets/config/locales/ca.yml +5 -0
  161. data/decidim-budgets/config/locales/en.yml +5 -0
  162. data/decidim-budgets/config/locales/es.yml +5 -0
  163. data/decidim-budgets/config/locales/eu.yml +27 -0
  164. data/decidim-budgets/spec/features/orders_spec.rb +22 -0
  165. data/decidim-budgets/spec/shared/manage_attachments_examples.rb +1 -1
  166. data/decidim-budgets/spec/shared/manage_projects_examples.rb +10 -8
  167. data/decidim-comments/README.md +33 -0
  168. data/decidim-comments/app/assets/javascripts/decidim/comments/bundle.js +0 -0
  169. data/decidim-comments/app/assets/javascripts/decidim/comments/comments.js.erb +2 -0
  170. data/decidim-comments/app/frontend/application/{apollo_client.js → apollo_client.ts} +5 -5
  171. data/decidim-comments/app/frontend/application/application.component.test.tsx +36 -0
  172. data/decidim-comments/app/frontend/application/application.component.tsx +37 -0
  173. data/decidim-comments/app/frontend/application/icon.component.test.tsx +49 -0
  174. data/decidim-comments/app/frontend/application/icon.component.tsx +35 -0
  175. data/decidim-comments/app/frontend/comments/{add_comment_form.component.test.jsx → add_comment_form.component.test.tsx} +98 -92
  176. data/decidim-comments/app/frontend/comments/{add_comment_form.component.jsx → add_comment_form.component.tsx} +152 -153
  177. data/decidim-comments/app/frontend/comments/{comment.component.test.jsx → comment.component.test.tsx} +59 -71
  178. data/decidim-comments/app/frontend/comments/{comment.component.jsx → comment.component.tsx} +114 -116
  179. data/decidim-comments/app/frontend/comments/comment_order_selector.component.test.tsx +21 -0
  180. data/decidim-comments/app/frontend/comments/comment_order_selector.component.tsx +88 -0
  181. data/decidim-comments/app/frontend/comments/comment_thread.component.test.tsx +65 -0
  182. data/decidim-comments/app/frontend/comments/comment_thread.component.tsx +70 -0
  183. data/decidim-comments/app/frontend/comments/{comments.component.test.jsx → comments.component.test.tsx} +38 -81
  184. data/decidim-comments/app/frontend/comments/{comments.component.jsx → comments.component.tsx} +49 -63
  185. data/decidim-comments/app/frontend/comments/down_vote_button.component.test.tsx +39 -0
  186. data/decidim-comments/app/frontend/comments/down_vote_button.component.tsx +89 -0
  187. data/decidim-comments/app/frontend/comments/up_vote_button.component.test.tsx +39 -0
  188. data/decidim-comments/app/frontend/comments/up_vote_button.component.tsx +89 -0
  189. data/decidim-comments/app/frontend/comments/vote_button.component.tsx +36 -0
  190. data/decidim-comments/app/frontend/comments/{vote_button_component.test.jsx → vote_button_component.test.tsx} +16 -20
  191. data/decidim-comments/app/frontend/entry.ts +19 -0
  192. data/decidim-comments/app/frontend/{comments → fragments}/add_comment_form_commentable.fragment.graphql +1 -1
  193. data/decidim-comments/app/frontend/{comments → fragments}/add_comment_form_session.fragment.graphql +1 -1
  194. data/decidim-comments/app/frontend/{comments → fragments}/comment.fragment.graphql +3 -1
  195. data/decidim-comments/app/frontend/{comments → fragments}/comment_data.fragment.graphql +6 -3
  196. data/decidim-comments/app/frontend/{comments → fragments}/comment_thread.fragment.graphql +3 -1
  197. data/decidim-comments/app/frontend/{comments/down_vote.fragment.graphql → fragments/down_vote_button.fragment.graphql} +2 -2
  198. data/decidim-comments/app/frontend/{comments/up_vote.fragment.graphql → fragments/up_vote_button.fragment.graphql} +2 -2
  199. data/decidim-comments/app/frontend/{comments/add_comment_form.mutation.graphql → mutations/add_comment.mutation.graphql} +3 -1
  200. data/decidim-comments/app/frontend/{comments → mutations}/down_vote.mutation.graphql +3 -1
  201. data/decidim-comments/app/frontend/{comments → mutations}/up_vote.mutation.graphql +3 -1
  202. data/decidim-comments/app/frontend/{comments → queries}/comments.query.graphql +4 -1
  203. data/decidim-comments/app/frontend/support/{asset_url.js → asset_url.ts} +1 -1
  204. data/decidim-comments/app/frontend/support/{generate_comments_data.js → generate_comments_data.ts} +11 -6
  205. data/decidim-comments/app/frontend/support/{generate_user_data.js → generate_user_data.ts} +2 -2
  206. data/decidim-comments/app/frontend/support/{generate_user_group_data.js → generate_user_group_data.ts} +2 -2
  207. data/decidim-comments/app/frontend/support/graphql_transformer.js +32 -0
  208. data/decidim-comments/app/frontend/support/load_translations.ts +44 -0
  209. data/decidim-comments/app/frontend/support/{require_all.js → require_all.ts} +1 -1
  210. data/decidim-comments/app/frontend/support/{resolve_graphql_query.js → resolve_graphql_query.ts} +7 -7
  211. data/decidim-comments/app/frontend/support/schema.ts +119 -0
  212. data/decidim-comments/config/locales/eu.yml +29 -5
  213. data/decidim-dev/Rakefile +2 -0
  214. data/decidim-dev/config/locales/eu.yml +1 -1
  215. data/decidim-dev/decidim-dev.gemspec +1 -1
  216. data/decidim-dev/lib/decidim/dev/test/rspec_support/capybara.rb +1 -4
  217. data/decidim-dev/lib/decidim/dev/test/rspec_support/feature.rb +1 -0
  218. data/decidim-dev/lib/decidim/dev/test/rspec_support/helpers.rb +1 -1
  219. data/decidim-dev/lib/decidim/dev/test/rspec_support/phantomjs_polyfills/phantomjs-shim.js +215 -0
  220. data/decidim-dev/lib/decidim/dev/test/rspec_support/translation_helpers.rb +1 -1
  221. data/decidim-dev/lib/generators/decidim/dummy_generator.rb +5 -0
  222. data/decidim-meetings/app/controllers/decidim/meetings/admin/application_controller.rb +1 -1
  223. data/decidim-meetings/app/views/decidim/meetings/admin/meeting_closes/_form.html.erb +30 -19
  224. data/decidim-meetings/app/views/decidim/meetings/admin/meeting_closes/edit.html.erb +3 -5
  225. data/decidim-meetings/app/views/decidim/meetings/admin/meetings/_form.html.erb +46 -35
  226. data/decidim-meetings/app/views/decidim/meetings/admin/meetings/edit.html.erb +5 -6
  227. data/decidim-meetings/app/views/decidim/meetings/admin/meetings/index.html.erb +72 -51
  228. data/decidim-meetings/app/views/decidim/meetings/admin/meetings/new.html.erb +4 -6
  229. data/decidim-meetings/app/views/decidim/meetings/meetings/_filters.html.erb +1 -1
  230. data/decidim-meetings/config/locales/ca.yml +2 -1
  231. data/decidim-meetings/config/locales/en.yml +2 -1
  232. data/decidim-meetings/config/locales/es.yml +2 -1
  233. data/decidim-meetings/config/locales/eu.yml +25 -5
  234. data/decidim-meetings/config/locales/fi.yml +0 -1
  235. data/decidim-meetings/spec/shared/manage_attachments_examples.rb +1 -1
  236. data/decidim-meetings/spec/shared/manage_meetings_examples.rb +18 -16
  237. data/decidim-pages/app/views/decidim/pages/admin/pages/_form.html.erb +10 -3
  238. data/decidim-pages/app/views/decidim/pages/admin/pages/edit.html.erb +3 -5
  239. data/decidim-pages/config/locales/eu.yml +4 -2
  240. data/decidim-pages/spec/features/admin_spec.rb +1 -1
  241. data/decidim-proposals/app/controllers/decidim/proposals/admin/proposals_controller.rb +1 -1
  242. data/decidim-proposals/app/views/decidim/proposals/admin/proposal_answers/edit.html.erb +14 -8
  243. data/decidim-proposals/app/views/decidim/proposals/admin/proposals/_form.html.erb +28 -20
  244. data/decidim-proposals/app/views/decidim/proposals/admin/proposals/index.html.erb +60 -43
  245. data/decidim-proposals/app/views/decidim/proposals/admin/proposals/new.html.erb +3 -5
  246. data/decidim-proposals/app/views/decidim/proposals/proposals/_filters.html.erb +1 -1
  247. data/decidim-proposals/config/locales/ca.yml +3 -0
  248. data/decidim-proposals/config/locales/en.yml +4 -1
  249. data/decidim-proposals/config/locales/es.yml +3 -0
  250. data/decidim-proposals/config/locales/eu.yml +42 -19
  251. data/decidim-proposals/config/locales/fi.yml +0 -1
  252. data/decidim-proposals/spec/shared/manage_proposals_examples.rb +15 -13
  253. data/decidim-results/README.md +1 -1
  254. data/decidim-results/app/controllers/decidim/results/admin/results_controller.rb +1 -1
  255. data/decidim-results/app/views/decidim/results/admin/results/_form.html.erb +30 -21
  256. data/decidim-results/app/views/decidim/results/admin/results/edit.html.erb +4 -5
  257. data/decidim-results/app/views/decidim/results/admin/results/index.html.erb +40 -25
  258. data/decidim-results/app/views/decidim/results/admin/results/new.html.erb +4 -5
  259. data/decidim-results/app/views/decidim/results/results/_filters.html.erb +1 -1
  260. data/decidim-results/config/locales/ca.yml +2 -0
  261. data/decidim-results/config/locales/en.yml +2 -0
  262. data/decidim-results/config/locales/es.yml +2 -0
  263. data/decidim-results/config/locales/eu.yml +22 -4
  264. data/decidim-results/spec/shared/manage_results_examples.rb +10 -8
  265. data/decidim-system/config/locales/eu.yml +60 -2
  266. data/lib/generators/decidim/app_generator.rb +0 -4
  267. data/lib/generators/decidim/install_generator.rb +0 -4
  268. data/lib/generators/decidim/templates/README.md.erb +18 -18
  269. data/package.json +47 -22
  270. data/tsconfig.json +17 -0
  271. data/tslint.json +12 -0
  272. data/webpack.config.js +8 -6
  273. data/webpack.d.ts +5 -0
  274. data/yarn.lock +1461 -781
  275. metadata +119 -83
  276. data/decidim-admin/app/assets/stylesheets/decidim/admin/_actions.scss +0 -8
  277. data/decidim-admin/app/assets/stylesheets/decidim/admin/_forms.scss +0 -10
  278. data/decidim-admin/app/assets/stylesheets/decidim/admin/_foundation_and_overrides.scss +0 -53
  279. data/decidim-admin/app/assets/stylesheets/decidim/admin/_icons.scss +0 -9
  280. data/decidim-admin/app/assets/stylesheets/decidim/admin/_layout.scss +0 -27
  281. data/decidim-admin/app/assets/stylesheets/decidim/admin/_settings.scss +0 -566
  282. data/decidim-admin/app/assets/stylesheets/decidim/admin/_tables.scss +0 -21
  283. data/decidim-admin/app/views/layouts/decidim/admin/_login_items.html.erb +0 -8
  284. data/decidim-admin/app/views/layouts/decidim/admin/_sidebar.html.erb +0 -22
  285. data/decidim-comments/app/frontend/application/application.component.jsx +0 -37
  286. data/decidim-comments/app/frontend/application/application.component.test.jsx +0 -33
  287. data/decidim-comments/app/frontend/application/icon.component.jsx +0 -26
  288. data/decidim-comments/app/frontend/application/icon.component.test.jsx +0 -53
  289. data/decidim-comments/app/frontend/comments/comment_order_selector.component.jsx +0 -72
  290. data/decidim-comments/app/frontend/comments/comment_order_selector.component.test.jsx +0 -20
  291. data/decidim-comments/app/frontend/comments/comment_thread.component.jsx +0 -75
  292. data/decidim-comments/app/frontend/comments/comment_thread.component.test.jsx +0 -83
  293. data/decidim-comments/app/frontend/comments/down_vote_button.component.jsx +0 -98
  294. data/decidim-comments/app/frontend/comments/down_vote_button.component.test.jsx +0 -48
  295. data/decidim-comments/app/frontend/comments/featured_comment.component.jsx +0 -23
  296. data/decidim-comments/app/frontend/comments/featured_comment.component.test.jsx +0 -15
  297. data/decidim-comments/app/frontend/comments/up_vote_button.component.jsx +0 -98
  298. data/decidim-comments/app/frontend/comments/up_vote_button.component.test.jsx +0 -48
  299. data/decidim-comments/app/frontend/comments/vote_button.component.jsx +0 -32
  300. data/decidim-comments/app/frontend/entry.js +0 -17
  301. data/decidim-comments/app/frontend/entry.test.js +0 -31
  302. data/decidim-comments/app/frontend/support/load_translations.js +0 -23
  303. data/decidim-comments/app/frontend/support/stub_component.js +0 -29
  304. data/decidim-dev/lib/decidim/dev/test/rspec_support/phantomjs_polyfills/bind-polyfill.js +0 -18
  305. data/decidim-dev/lib/decidim/dev/test/rspec_support/phantomjs_polyfills/object-assign-polyfill.js +0 -24
  306. data/karma.conf.js +0 -45
  307. data/lib/generators/decidim/review_app_generator.rb +0 -53
  308. data/lib/generators/decidim/templates/app.json.erb +0 -16
@@ -1,130 +1,118 @@
1
- /* eslint-disable no-unused-expressions */
2
- import { shallow, mount } from 'enzyme';
3
- import { filter } from 'graphql-anywhere';
4
- import gql from 'graphql-tag';
1
+ import { mount, shallow } from "enzyme";
2
+ import * as $ from "jquery";
3
+ import * as React from "react";
5
4
 
6
- import Comment from './comment.component';
7
- import AddCommentForm from './add_comment_form.component';
8
- import UpVoteButton from './up_vote_button.component';
9
- import DownVoteButton from './down_vote_button.component';
5
+ import { CommentFragment } from "../support/schema";
6
+ import AddCommentForm from "./add_comment_form.component";
7
+ import Comment from "./comment.component";
8
+ import DownVoteButton from "./down_vote_button.component";
9
+ import UpVoteButton from "./up_vote_button.component";
10
10
 
11
- import commentFragment from './comment.fragment.graphql';
12
- import commentDataFragment from './comment_data.fragment.graphql';
13
- import upVoteFragment from './up_vote.fragment.graphql';
14
- import downVoteFragment from './down_vote.fragment.graphql';
11
+ import generateCommentsData from "../support/generate_comments_data";
12
+ import generateUserData from "../support/generate_user_data";
15
13
 
16
- import stubComponent from '../support/stub_component';
17
- import generateCommentsData from '../support/generate_comments_data';
18
- import generateUserData from '../support/generate_user_data';
14
+ import { loadLocaleTranslations } from "../support/load_translations";
19
15
 
20
16
  describe("<Comment />", () => {
21
- let comment = {};
22
- let session = null;
23
-
24
- stubComponent(AddCommentForm);
25
- stubComponent(UpVoteButton);
26
- stubComponent(DownVoteButton);
17
+ let comment: CommentFragment;
18
+ let session: any = null;
27
19
 
28
20
  beforeEach(() => {
21
+ loadLocaleTranslations("en");
29
22
  let commentsData = generateCommentsData(1);
30
23
  commentsData[0].comments = generateCommentsData(3);
31
24
 
32
- const fragment = gql`
33
- ${commentFragment}
34
- ${commentDataFragment}
35
- ${upVoteFragment}
36
- ${downVoteFragment}
37
- `;
38
-
39
- comment = filter(fragment, commentsData[0]);
25
+ comment = commentsData[0];
40
26
  session = {
41
- user: generateUserData()
42
- }
27
+ user: generateUserData(),
28
+ };
29
+
30
+ window.$ = $;
43
31
  });
44
32
 
45
33
  it("should render an article with class comment", () => {
46
34
  const wrapper = shallow(<Comment comment={comment} session={session} />);
47
- expect(wrapper.find('article.comment')).to.present();
35
+ expect(wrapper.find("article.comment").exists()).toBeTruthy();
48
36
  });
49
37
 
50
38
  it("should render a time tag with comment's created at", () => {
51
39
  const wrapper = shallow(<Comment comment={comment} session={session} />);
52
- expect(wrapper.find('time')).to.have.text(comment.created_at);
40
+ expect(wrapper.find("time").prop("dateTime")).toEqual(comment.createdAt);
53
41
  });
54
42
 
55
43
  it("should render author's name in a link with class author__name", () => {
56
44
  const wrapper = shallow(<Comment comment={comment} session={session} />);
57
- expect(wrapper.find('a.author__name')).to.have.text(comment.author.name);
45
+ expect(wrapper.find("a.author__name").text()).toEqual(comment.author.name);
58
46
  });
59
47
 
60
48
  it("should render author's avatar as a image tag", () => {
61
49
  const wrapper = shallow(<Comment comment={comment} session={session} />);
62
- expect(wrapper.find('a.author__avatar img')).to.have.attr('src').equal(comment.author.avatarUrl);
50
+ expect(wrapper.find("a.author__avatar img").prop("src")).toEqual(comment.author.avatarUrl);
63
51
  });
64
52
 
65
53
  it("should render comment's body on a div with class comment__content", () => {
66
54
  const wrapper = shallow(<Comment comment={comment} session={session} />);
67
- expect(wrapper.find('div.comment__content')).to.have.text(comment.body);
55
+ expect(wrapper.find("div.comment__content").text()).toEqual(comment.body);
68
56
  });
69
57
 
70
58
  it("should initialize with a state property showReplyForm as false", () => {
71
59
  const wrapper = shallow(<Comment comment={comment} session={session} />);
72
- expect(wrapper).to.have.state('showReplyForm', false);
60
+ expect(wrapper.state()).toHaveProperty("showReplyForm", false);
73
61
  });
74
62
 
75
63
  it("should render a AddCommentForm component with the correct props when clicking the reply button", () => {
76
64
  const wrapper = shallow(<Comment comment={comment} session={session} />);
77
- expect(wrapper.find(AddCommentForm)).not.to.be.present();
78
- wrapper.find('button.comment__reply').simulate('click');
79
- expect(wrapper.find(AddCommentForm)).to.have.prop('session').deep.equal(session);
80
- expect(wrapper.find(AddCommentForm)).to.have.prop('commentable').deep.equal(comment);
81
- expect(wrapper.find(AddCommentForm)).to.have.prop('showTitle').equal(false);
82
- expect(wrapper.find(AddCommentForm)).to.have.prop('submitButtonClassName').equal('button small hollow');
65
+ expect(wrapper.find(AddCommentForm).exists()).toBeFalsy();
66
+ wrapper.find("button.comment__reply").simulate("click");
67
+ expect(wrapper.find(AddCommentForm).prop("session")).toEqual(session);
68
+ expect(wrapper.find(AddCommentForm).prop("commentable")).toEqual(comment);
69
+ expect(wrapper.find(AddCommentForm).prop("showTitle")).toBeFalsy();
70
+ expect(wrapper.find(AddCommentForm).prop("submitButtonClassName")).toEqual("button small hollow");
83
71
  });
84
72
 
85
73
  it("should not render the additional reply button if the parent comment has no comments and isRootcomment", () => {
86
74
  comment.hasComments = false;
87
- const wrapper = shallow(<Comment comment={comment} session={session} isRootComment />);
88
- expect(wrapper.find('div.comment__additionalreply')).not.to.be.present();
75
+ const wrapper = shallow(<Comment comment={comment} session={session} isRootComment={true} />);
76
+ expect(wrapper.find("div.comment__additionalreply").exists()).toBeFalsy();
89
77
  });
90
78
 
91
- it("should not render the additional reply button if the parent comment has comments and not isRootcomment", () => {
79
+ it("should not render the additional reply button if the parent comment has comments and not isRootcomment", () => {
92
80
  comment.hasComments = true;
93
81
  const wrapper = shallow(<Comment comment={comment} session={session} />);
94
- expect(wrapper.find('div.comment__additionalreply')).not.to.be.present();
82
+ expect(wrapper.find("div.comment__additionalreply").exists()).toBeFalsy();
95
83
  });
96
84
 
97
85
  it("should render the additional reply button if the parent comment has comments and isRootcomment", () => {
98
86
  comment.hasComments = true;
99
- const wrapper = shallow(<Comment comment={comment} session={session} isRootComment />);
100
- expect(wrapper.find('div.comment__additionalreply')).to.be.present();
87
+ const wrapper = shallow(<Comment comment={comment} session={session} isRootComment={true} />);
88
+ expect(wrapper.find("div.comment__additionalreply").exists()).toBeTruthy();
101
89
  });
102
90
 
103
91
  it("should render comment's comments as a separate Comment components", () => {
104
- const wrapper = shallow(<Comment comment={comment} session={session} votable />);
92
+ const wrapper = shallow(<Comment comment={comment} session={session} votable={true} />);
105
93
  wrapper.find(Comment).forEach((node, idx) => {
106
- expect(node).to.have.prop("comment").deep.equal(comment.comments[idx]);
107
- expect(node).to.have.prop("session").deep.equal(session);
108
- expect(node).to.have.prop("articleClassName").equal("comment comment--nested")
109
- expect(node).to.have.prop("votable").equal(true);
94
+ expect(node.prop("comment")).toEqual(comment.comments[idx]);
95
+ expect(node.prop("session")).toEqual(session);
96
+ expect(node.prop("articleClassName")).toEqual("comment comment--nested");
97
+ expect(node.prop("votable")).toBeTruthy();
110
98
  });
111
99
  });
112
100
 
113
101
  it("should render comment's comments with articleClassName as 'comment comment--nested comment--nested--alt' when articleClassName is 'comment comment--nested'", () => {
114
102
  const wrapper = shallow(<Comment comment={comment} session={session} articleClassName="comment comment--nested" />);
115
103
  wrapper.find(Comment).forEach((node) => {
116
- expect(node).to.have.prop("articleClassName").equal("comment comment--nested comment--nested--alt")
104
+ expect(node.prop("articleClassName")).toEqual("comment comment--nested comment--nested--alt");
117
105
  });
118
106
  });
119
107
 
120
108
  it("should have a default prop articleClassName with value 'comment'", () => {
121
109
  const wrapper = mount(<Comment comment={comment} session={session} />);
122
- expect(wrapper).to.have.prop("articleClassName").equal("comment");
110
+ expect(wrapper.prop("articleClassName")).toEqual("comment");
123
111
  });
124
112
 
125
113
  it("should have a default prop isRootComment with value false", () => {
126
114
  const wrapper = mount(<Comment comment={comment} session={session} />);
127
- expect(wrapper).to.have.prop("isRootComment").equal(false);
115
+ expect(wrapper.prop("isRootComment")).toBeFalsy();
128
116
  });
129
117
 
130
118
  describe("when the comment cannot accept new comments", () => {
@@ -134,9 +122,9 @@ describe("<Comment />", () => {
134
122
 
135
123
  it("should not render the reply button", () => {
136
124
  const wrapper = shallow(<Comment comment={comment} session={session} />);
137
- expect(wrapper.find('button.comment__reply')).not.to.be.present();
125
+ expect(wrapper.find("button.comment__reply").exists()).toBeFalsy();
138
126
  });
139
- })
127
+ });
140
128
 
141
129
  describe("when user is not logged in", () => {
142
130
  beforeEach(() => {
@@ -145,49 +133,49 @@ describe("<Comment />", () => {
145
133
 
146
134
  it("should not render reply button", () => {
147
135
  const wrapper = shallow(<Comment comment={comment} session={session} />);
148
- expect(wrapper.find('button.comment__reply')).not.to.be.present();
136
+ expect(wrapper.find("button.comment__reply").exists()).toBeFalsy();
149
137
  });
150
138
 
151
139
  it("should not render the flag modal", () => {
152
140
  const wrapper = shallow(<Comment comment={comment} session={session} />);
153
- expect(wrapper.find('.flag-modal')).not.to.be.present();
141
+ expect(wrapper.find(".flag-modal").exists()).toBeFalsy();
154
142
  });
155
143
  });
156
144
 
157
145
  it("should render a 'in favor' badge if comment's alignment is 1", () => {
158
146
  comment.alignment = 1;
159
147
  const wrapper = shallow(<Comment comment={comment} session={session} />);
160
- expect(wrapper.find('span.success.label')).to.have.text('In favor');
148
+ expect(wrapper.find("span.success.label").text()).toEqual("In favor");
161
149
  });
162
150
 
163
151
  it("should render a 'against' badge if comment's alignment is -1", () => {
164
152
  comment.alignment = -1;
165
153
  const wrapper = shallow(<Comment comment={comment} session={session} />);
166
- expect(wrapper.find('span.alert.label')).to.have.text('Against');
154
+ expect(wrapper.find("span.alert.label").text()).toEqual("Against");
167
155
  });
168
156
 
169
157
  it("should render the flag modal", () => {
170
158
  const wrapper = shallow(<Comment comment={comment} session={session} />);
171
- expect(wrapper.find('.flag-modal')).to.be.present();
159
+ expect(wrapper.find(".flag-modal").exists()).toBeTruthy();
172
160
  });
173
161
 
174
162
  describe("when user has already reported the comment", () => {
175
163
  it("should not render the flag form", () => {
176
164
  comment.alreadyReported = true;
177
165
  const wrapper = shallow(<Comment comment={comment} session= {session} />);
178
- expect(wrapper.find('.flag-modal form')).not.to.be.present();
166
+ expect(wrapper.find(".flag-modal form").exists()).toBeFalsy();
179
167
  });
180
168
  });
181
169
 
182
170
  describe("when the comment is votable", () => {
183
171
  it("should render an UpVoteButton component", () => {
184
- const wrapper = shallow(<Comment comment={comment} session={session} votable />);
185
- expect(wrapper.find(UpVoteButton)).to.have.prop("comment").deep.equal(comment);
186
- })
172
+ const wrapper = shallow(<Comment comment={comment} session={session} votable={true} />);
173
+ expect(wrapper.find(UpVoteButton).prop("comment")).toEqual(comment);
174
+ });
187
175
 
188
176
  it("should render an DownVoteButton component", () => {
189
- const wrapper = shallow(<Comment comment={comment} session={session} votable />);
190
- expect(wrapper.find(DownVoteButton)).to.have.prop("comment").deep.equal(comment);
191
- })
177
+ const wrapper = shallow(<Comment comment={comment} session={session} votable={true} />);
178
+ expect(wrapper.find(DownVoteButton).prop("comment")).toEqual(comment);
179
+ });
192
180
  });
193
181
  });
@@ -1,44 +1,66 @@
1
- /* eslint-disable max-lines, camelcase */
2
- import { Component, PropTypes } from 'react';
3
- import { propType } from 'graphql-anywhere';
4
- import gql from 'graphql-tag';
5
- import moment from 'moment';
6
- import { I18n } from 'react-i18nify';
7
- import classnames from 'classnames';
8
-
9
- import AddCommentForm from './add_comment_form.component';
10
- import UpVoteButton from './up_vote_button.component';
11
- import DownVoteButton from './down_vote_button.component';
12
- import Icon from '../application/icon.component';
13
-
14
- import commentFragment from './comment.fragment.graphql';
15
- import commentDataFragment from './comment_data.fragment.graphql';
1
+ import * as classnames from "classnames";
2
+ import * as moment from "moment";
3
+ import * as React from "react";
4
+
5
+ import Icon from "../application/icon.component";
6
+
7
+ import AddCommentForm from "./add_comment_form.component";
8
+ import DownVoteButton from "./down_vote_button.component";
9
+ import UpVoteButton from "./up_vote_button.component";
10
+
11
+ import {
12
+ AddCommentFormSessionFragment,
13
+ CommentFragment,
14
+ } from "../support/schema";
15
+
16
+ const { I18n } = require("react-i18nify");
17
+
18
+ interface CommentProps {
19
+ comment: CommentFragment;
20
+ session: AddCommentFormSessionFragment & {
21
+ user: any;
22
+ } | null;
23
+ articleClassName?: string;
24
+ isRootComment?: boolean;
25
+ votable?: boolean;
26
+ }
27
+
28
+ interface CommentState {
29
+ showReplyForm: boolean;
30
+ }
16
31
 
17
32
  /**
18
33
  * A single comment component with the author info and the comment's body
19
34
  * @class
20
35
  * @augments Component
21
36
  */
22
- class Comment extends Component {
23
- constructor(props) {
37
+ class Comment extends React.Component<CommentProps, CommentState> {
38
+ public static defaultProps: any = {
39
+ articleClassName: "comment",
40
+ isRootComment: false,
41
+ session: null,
42
+ votable: false,
43
+ };
44
+
45
+ constructor(props: CommentProps) {
24
46
  super(props);
25
47
 
26
48
  this.state = {
27
- showReplyForm: false
49
+ showReplyForm: false,
28
50
  };
29
51
  }
30
52
 
31
- componentDidMount() {
32
- if ($(document).foundation) {
53
+ public componentDidMount() {
54
+ if (window.$(document).foundation) {
33
55
  const { comment: { id } } = this.props;
34
- $(`#flagModalComment${id}`).foundation();
56
+ window.$(`#flagModalComment${id}`).foundation();
35
57
  }
36
58
  }
37
59
 
38
- render() {
60
+ public render(): JSX.Element {
39
61
  const { session, comment: { id, author, body, createdAt }, articleClassName } = this.props;
40
62
  const formattedCreatedAt = ` ${moment(createdAt).format("LLL")}`;
41
- let modalName = 'loginModal';
63
+ let modalName = "loginModal";
42
64
 
43
65
  if (session && session.user) {
44
66
  modalName = `flagModalComment${id}`;
@@ -58,8 +80,8 @@ class Comment extends Component {
58
80
  </div>
59
81
  </div>
60
82
  <div className="author-data__extra">
61
- <button type="button" title={ I18n.t("components.comment.report.title") } data-open={modalName}>
62
- <Icon name="icon-flag" iconExtraClassName="icon--small"></Icon>
83
+ <button type="button" title={I18n.t("components.comment.report.title")} data-open={modalName}>
84
+ <Icon name="icon-flag" iconExtraClassName="icon--small" />
63
85
  </button>
64
86
  {this._renderFlagModal()}
65
87
  </div>
@@ -67,8 +89,8 @@ class Comment extends Component {
67
89
  </div>
68
90
  <div className="comment__content">
69
91
  <p>
70
- { this._renderAlignmentBadge() }
71
- { body }
92
+ {this._renderAlignmentBadge()}
93
+ {body}
72
94
  </p>
73
95
  </div>
74
96
  <div className="comment__footer">
@@ -82,23 +104,27 @@ class Comment extends Component {
82
104
  );
83
105
  }
84
106
 
107
+ private toggleReplyForm = () => {
108
+ const { showReplyForm } = this.state;
109
+ this.setState({ showReplyForm: !showReplyForm });
110
+ }
111
+
85
112
  /**
86
113
  * Render reply button if user can reply the comment
87
114
  * @private
88
115
  * @returns {Void|DOMElement} - Render the reply button or not if user can reply
89
116
  */
90
- _renderReplyButton() {
117
+ private _renderReplyButton() {
91
118
  const { comment: { acceptsNewComments }, session } = this.props;
92
- const { showReplyForm } = this.state;
93
119
 
94
120
  if (session && acceptsNewComments) {
95
121
  return (
96
122
  <button
97
123
  className="comment__reply muted-link"
98
124
  aria-controls="comment1-reply"
99
- onClick={() => this.setState({ showReplyForm: !showReplyForm })}
125
+ onClick={this.toggleReplyForm}
100
126
  >
101
- { I18n.t("components.comment.reply") }
127
+ {I18n.t("components.comment.reply")}
102
128
  </button>
103
129
  );
104
130
  }
@@ -106,14 +132,13 @@ class Comment extends Component {
106
132
  return <span>&nbsp;</span>;
107
133
  }
108
134
 
109
- /**
135
+ /**
110
136
  * Render additional reply button if user can reply the comment at the bottom of a conversation
111
137
  * @private
112
138
  * @returns {Void|DOMElement} - Render the reply button or not if user can reply
113
139
  */
114
- _renderAdditionalReplyButton() {
140
+ private _renderAdditionalReplyButton() {
115
141
  const { comment: { acceptsNewComments, hasComments }, session, isRootComment } = this.props;
116
- const { showReplyForm } = this.state;
117
142
 
118
143
  if (session && acceptsNewComments) {
119
144
  if (hasComments && isRootComment) {
@@ -122,9 +147,9 @@ class Comment extends Component {
122
147
  <button
123
148
  className="comment__reply muted-link"
124
149
  aria-controls="comment1-reply"
125
- onClick={() => this.setState({ showReplyForm: !showReplyForm })}
150
+ onClick={this.toggleReplyForm}
126
151
  >
127
- { I18n.t("components.comment.reply") }
152
+ {I18n.t("components.comment.reply")}
128
153
  </button>
129
154
  </div>
130
155
  );
@@ -138,7 +163,7 @@ class Comment extends Component {
138
163
  * @private
139
164
  * @returns {Void|DOMElement} - Render the upVote and downVote buttons or not
140
165
  */
141
- _renderVoteButtons() {
166
+ private _renderVoteButtons() {
142
167
  const { comment, votable } = this.props;
143
168
 
144
169
  if (votable) {
@@ -158,11 +183,11 @@ class Comment extends Component {
158
183
  * @private
159
184
  * @returns {Void|DomElement} - A wrapper element with comment's comments inside
160
185
  */
161
- _renderReplies() {
186
+ private _renderReplies() {
162
187
  const { comment: { id, hasComments, comments }, session, votable, articleClassName } = this.props;
163
- let replyArticleClassName = 'comment comment--nested';
188
+ let replyArticleClassName = "comment comment--nested";
164
189
 
165
- if (articleClassName === 'comment comment--nested') {
190
+ if (articleClassName === "comment comment--nested") {
166
191
  replyArticleClassName = `${replyArticleClassName} comment--nested--alt`;
167
192
  }
168
193
 
@@ -170,7 +195,7 @@ class Comment extends Component {
170
195
  return (
171
196
  <div>
172
197
  {
173
- comments.map((reply) => (
198
+ comments.map((reply: CommentFragment) => (
174
199
  <Comment
175
200
  key={`comment_${id}_reply_${reply.id}`}
176
201
  comment={reply}
@@ -192,19 +217,19 @@ class Comment extends Component {
192
217
  * @private
193
218
  * @returns {Void|ReactElement} - Render the AddCommentForm component or not
194
219
  */
195
- _renderReplyForm() {
220
+ private _renderReplyForm() {
196
221
  const { session, comment } = this.props;
197
222
  const { showReplyForm } = this.state;
198
223
 
199
- if (showReplyForm) {
224
+ if (session && showReplyForm) {
200
225
  return (
201
226
  <AddCommentForm
202
227
  session={session}
203
228
  commentable={comment}
204
229
  showTitle={false}
205
230
  submitButtonClassName="button small hollow"
206
- onCommentAdded={() => this.setState({ showReplyForm: false })}
207
- autoFocus
231
+ onCommentAdded={this.toggleReplyForm}
232
+ autoFocus={true}
208
233
  />
209
234
  );
210
235
  }
@@ -217,25 +242,25 @@ class Comment extends Component {
217
242
  * @private
218
243
  * @returns {Void|DOMElement} - The alignment's badge or not
219
244
  */
220
- _renderAlignmentBadge() {
245
+ private _renderAlignmentBadge() {
221
246
  const { comment: { alignment } } = this.props;
222
- const spanClassName = classnames('label', {
247
+ const spanClassName = classnames("label", {
223
248
  success: alignment === 1,
224
- alert: alignment === -1
249
+ alert: alignment === -1,
225
250
  });
226
251
 
227
- let label = '';
252
+ let label = "";
228
253
 
229
254
  if (alignment === 1) {
230
- label = I18n.t('components.comment.alignment.in_favor');
255
+ label = I18n.t("components.comment.alignment.in_favor");
231
256
  } else {
232
- label = I18n.t('components.comment.alignment.against');
257
+ label = I18n.t("components.comment.alignment.against");
233
258
  }
234
259
 
235
260
  if (alignment === 1 || alignment === -1) {
236
261
  return (
237
262
  <span>
238
- <span className={spanClassName}>{ label }</span>
263
+ <span className={spanClassName}>{label}</span>
239
264
  &nbsp;
240
265
  </span>
241
266
  );
@@ -249,20 +274,25 @@ class Comment extends Component {
249
274
  * @private
250
275
  * @return {Void|DOMElement} - The comment's report modal or not.
251
276
  */
252
- _renderFlagModal() {
277
+ private _renderFlagModal() {
253
278
  const { session, comment: { id, sgid, alreadyReported } } = this.props;
254
279
  const authenticityToken = this._getAuthenticityToken();
255
280
 
281
+ const closeModal = () => {
282
+ window.$(`#flagModalComment${id}`).foundation("close");
283
+ };
284
+
256
285
  if (session && session.user) {
257
286
  return (
258
- <div className="reveal flag-modal" id={`flagModalComment${id}`} data-reveal>
287
+ <div className="reveal flag-modal" id={`flagModalComment${id}`} data-reveal={true}>
259
288
  <div className="reveal__header">
260
- <h3 className="reveal__title">{ I18n.t("components.comment.report.title") }</h3>
289
+ <h3 className="reveal__title">{I18n.t("components.comment.report.title")}</h3>
261
290
  <button
262
291
  className="close-button"
263
- aria-label={ I18n.t("components.comment.report.close") }
292
+ aria-label={I18n.t("components.comment.report.close")}
264
293
  type="button"
265
- onClick={() => $(`#flagModalComment${id}`).foundation('close')}>
294
+ onClick={closeModal}
295
+ >
266
296
  <span aria-hidden="true">&times;</span>
267
297
  </button>
268
298
  </div>
@@ -270,31 +300,33 @@ class Comment extends Component {
270
300
  (() => {
271
301
  if (alreadyReported) {
272
302
  return (
273
- <p key={`already-reported-comment-${id}`}>{ I18n.t("components.comment.report.already_reported") }</p>
303
+ <p key={`already-reported-comment-${id}`}>{I18n.t("components.comment.report.already_reported")}</p>
274
304
  );
275
305
  }
276
306
  return [
277
- <p key={`report-description-comment-${id}`}>{ I18n.t("components.comment.report.description") }</p>,
278
- <form key={`report-form-comment-${id}`} method="post" action={`/report?sgid=${sgid}`}>
279
- <input type="hidden" name="authenticity_token" value={authenticityToken} />
280
- <label htmlFor={`report_comment_${id}_reason_spam`}>
281
- <input type="radio" value="spam" name="report[reason]" id={`report_comment_${id}_reason_spam`} defaultChecked />
282
- { I18n.t("components.comment.report.reasons.spam") }
283
- </label>
284
- <label htmlFor={`report_comment_${id}_reason_offensive`}>
285
- <input type="radio" value="offensive" name="report[reason]" id={`report_comment_${id}_reason_offensive`} />
286
- { I18n.t("components.comment.report.reasons.offensive") }
287
- </label>
288
- <label htmlFor={`report_comment_${id}_reason_does_not_belong`}>
289
- <input type="radio" value="does_not_belong" name="report[reason]" id={`report_comment_${id}_reason_does_not_belong`} />
290
- { I18n.t("components.comment.report.reasons.does_not_belong", { organization_name: session.user.organizationName }) }
291
- </label>
292
- <label htmlFor={`report_comment_${id}_details`}>
293
- { I18n.t("components.comment.report.details") }
294
- <textarea rows="4" name="report[details]" id={`report_comment_${id}_details`} />
295
- </label>
296
- <button type="submit" name="commit" className="button">{ I18n.t("components.comment.report.action") }</button>
297
- </form>
307
+ <p key={`report-description-comment-${id}`}>{I18n.t("components.comment.report.description")}</p>,
308
+ (
309
+ <form key={`report-form-comment-${id}`} method="post" action={`/report?sgid=${sgid}`}>
310
+ <input type="hidden" name="authenticity_token" value={authenticityToken} />
311
+ <label htmlFor={`report_comment_${id}_reason_spam`}>
312
+ <input type="radio" value="spam" name="report[reason]" id={`report_comment_${id}_reason_spam`} defaultChecked={true} />
313
+ {I18n.t("components.comment.report.reasons.spam")}
314
+ </label>
315
+ <label htmlFor={`report_comment_${id}_reason_offensive`}>
316
+ <input type="radio" value="offensive" name="report[reason]" id={`report_comment_${id}_reason_offensive`} />
317
+ {I18n.t("components.comment.report.reasons.offensive")}
318
+ </label>
319
+ <label htmlFor={`report_comment_${id}_reason_does_not_belong`}>
320
+ <input type="radio" value="does_not_belong" name="report[reason]" id={`report_comment_${id}_reason_does_not_belong`} />
321
+ {I18n.t("components.comment.report.reasons.does_not_belong", { organization_name: session.user.organizationName })}
322
+ </label>
323
+ <label htmlFor={`report_comment_${id}_details`}>
324
+ {I18n.t("components.comment.report.details")}
325
+ <textarea rows={4} name="report[details]" id={`report_comment_${id}_details`} />
326
+ </label>
327
+ <button type="submit" name="commit" className="button">{I18n.t("components.comment.report.action")}</button>
328
+ </form>
329
+ ),
298
330
  ];
299
331
  })()
300
332
  }
@@ -309,44 +341,10 @@ class Comment extends Component {
309
341
  * Get Rails authenticity token so we can send requests through the report forms.
310
342
  * @private
311
343
  * @return {string} - The current authenticity token.
312
- */
313
- _getAuthenticityToken() {
314
- return $('meta[name="csrf-token"]').attr('content');
344
+ */
345
+ private _getAuthenticityToken() {
346
+ return window.$('meta[name="csrf-token"]').attr("content");
315
347
  }
316
348
  }
317
349
 
318
- Comment.fragments = {
319
- comment: gql`
320
- ${commentFragment}
321
- ${commentDataFragment}
322
- ${UpVoteButton.fragments.comment}
323
- ${DownVoteButton.fragments.comment}
324
- `,
325
- commentData: gql`
326
- ${commentDataFragment}
327
- ${UpVoteButton.fragments.comment}
328
- ${DownVoteButton.fragments.comment}
329
- `
330
- };
331
-
332
- Comment.propTypes = {
333
- comment: PropTypes.oneOfType([
334
- propType(Comment.fragments.comment).isRequired,
335
- propType(Comment.fragments.commentData).isRequired
336
- ]).isRequired,
337
- session: PropTypes.shape({
338
- user: PropTypes.any.isRequired
339
- }),
340
- articleClassName: PropTypes.string.isRequired,
341
- isRootComment: PropTypes.bool,
342
- votable: PropTypes.bool
343
- };
344
-
345
- Comment.defaultProps = {
346
- articleClassName: 'comment',
347
- isRootComment: false,
348
- session: null,
349
- votable: false
350
- };
351
-
352
350
  export default Comment;