decidim 0.2.0 → 0.3.0

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 (322) hide show
  1. checksums.yaml +4 -4
  2. data/.circleci/config.yml +3 -1
  3. data/.codeclimate.yml +2 -3
  4. data/.rubocop.yml +1 -48
  5. data/.travis.yml +1 -0
  6. data/Dockerfile +1 -0
  7. data/Gemfile +1 -0
  8. data/Gemfile.lock +119 -115
  9. data/README.md +24 -9
  10. data/Rakefile +14 -10
  11. data/decidim-admin/app/assets/javascripts/decidim/admin/application.js.es6 +21 -9
  12. data/decidim-admin/app/assets/javascripts/decidim/admin/sort_list.component.js.es6 +35 -0
  13. data/decidim-admin/app/assets/stylesheets/decidim/admin/extra/_language-chooser.scss +4 -0
  14. data/decidim-admin/app/assets/stylesheets/decidim/admin/extra/_sort.scss +12 -0
  15. data/decidim-admin/app/controllers/decidim/admin/application_controller.rb +1 -0
  16. data/decidim-admin/app/controllers/decidim/admin/participatory_process_attachments_controller.rb +4 -0
  17. data/decidim-admin/app/helpers/decidim/admin/menu_helper.rb +0 -1
  18. data/decidim-admin/app/models/decidim/admin/participatory_process_user_role.rb +2 -2
  19. data/decidim-admin/app/views/decidim/admin/categories/index.html.erb +7 -1
  20. data/decidim-admin/app/views/decidim/admin/exports/_dropdown.html.erb +1 -1
  21. data/decidim-admin/app/views/decidim/admin/moderations/index.html.erb +6 -2
  22. data/decidim-admin/app/views/decidim/admin/participatory_process_steps/index.html.erb +1 -0
  23. data/decidim-admin/app/views/layouts/decidim/admin/_title_bar.html.erb +10 -0
  24. data/decidim-admin/bin/rails +3 -3
  25. data/decidim-admin/config/locales/ca.yml +3 -1
  26. data/decidim-admin/config/locales/en.yml +3 -1
  27. data/decidim-admin/config/locales/es.yml +3 -1
  28. data/decidim-admin/config/locales/eu.yml +0 -1
  29. data/decidim-admin/config/locales/fi.yml +0 -1
  30. data/decidim-admin/config/locales/fr.yml +0 -1
  31. data/decidim-admin/config/locales/it.yml +490 -0
  32. data/decidim-admin/db/migrate/20161102144648_add_admin_participatory_process_user_roles.rb +5 -3
  33. data/decidim-admin/db/migrate/20170128112958_change_user_groups_verified_to_timestamp.rb +2 -0
  34. data/decidim-admin/decidim-admin.gemspec +2 -1
  35. data/decidim-admin/lib/decidim/admin/engine.rb +1 -1
  36. data/decidim-admin/lib/decidim/admin/test/manage_attachments_examples.rb +3 -3
  37. data/decidim-admin/spec/commands/reject_user_group_spec.rb +2 -2
  38. data/decidim-admin/spec/features/admin_copy_participatory_process_spec.rb +2 -2
  39. data/decidim-admin/spec/features/admin_invite_spec.rb +1 -1
  40. data/decidim-admin/spec/features/admin_manages_features_spec.rb +2 -2
  41. data/decidim-admin/spec/features/admin_manages_newsletters_spec.rb +4 -4
  42. data/decidim-admin/spec/features/admin_manages_organization_spec.rb +6 -6
  43. data/decidim-admin/spec/features/admin_manages_participatory_process_groups_spec.rb +4 -4
  44. data/decidim-admin/spec/features/admin_manages_participatory_processes_spec.rb +4 -4
  45. data/decidim-admin/spec/features/static_pages_spec.rb +4 -4
  46. data/decidim-admin/spec/forms/organization_form_spec.rb +1 -1
  47. data/decidim-admin/spec/shared/manage_process_categories_examples.rb +44 -29
  48. data/decidim-admin/spec/shared/manage_process_steps_examples.rb +3 -3
  49. data/decidim-admin/spec/shared/manage_processes_examples.rb +1 -1
  50. data/decidim-admin/spec/shared/participatory_admin_shared_context.rb +3 -3
  51. data/decidim-admin/spec/spec_helper.rb +3 -2
  52. data/decidim-api/bin/rails +3 -3
  53. data/decidim-api/decidim-api.gemspec +2 -1
  54. data/decidim-api/lib/decidim/api/engine.rb +1 -1
  55. data/decidim-api/spec/spec_helper.rb +3 -2
  56. data/decidim-budgets/app/controllers/decidim/budgets/application_controller.rb +1 -1
  57. data/decidim-budgets/app/models/decidim/budgets/line_item.rb +1 -2
  58. data/decidim-budgets/app/models/decidim/budgets/order.rb +2 -2
  59. data/decidim-budgets/app/views/decidim/budgets/projects/_linked_projects.html.erb +1 -1
  60. data/decidim-budgets/bin/rails +3 -3
  61. data/decidim-budgets/config/locales/it.yml +126 -0
  62. data/decidim-budgets/db/migrate/20170127114122_create_projects.rb +2 -0
  63. data/decidim-budgets/db/migrate/20170130095615_create_orders.rb +2 -0
  64. data/decidim-budgets/db/migrate/20170130101825_create_line_items.rb +2 -0
  65. data/decidim-budgets/db/migrate/20170207101750_remove_short_description_from_decidim_projects.rb +2 -0
  66. data/decidim-budgets/db/migrate/20170215132708_add_reference_to_projects.rb +2 -0
  67. data/decidim-budgets/db/migrate/20170410074214_remove_not_null_reference_budgets.rb +2 -0
  68. data/decidim-budgets/db/migrate/20170612101846_migrate_projects_category.rb +15 -0
  69. data/decidim-budgets/decidim-budgets.gemspec +3 -1
  70. data/decidim-budgets/lib/decidim/budgets/feature.rb +2 -2
  71. data/decidim-budgets/spec/features/admin_manages_project_attachments_spec.rb +5 -3
  72. data/decidim-budgets/spec/features/admin_manages_projects_spec.rb +5 -7
  73. data/decidim-budgets/spec/features/process_admin_manages_project_attachments_spec.rb +4 -4
  74. data/decidim-budgets/spec/features/process_admin_manages_projects_spec.rb +5 -8
  75. data/decidim-budgets/spec/shared/manage_attachments_examples.rb +0 -4
  76. data/decidim-budgets/spec/shared/manage_projects_examples.rb +3 -3
  77. data/decidim-budgets/spec/spec_helper.rb +2 -1
  78. data/decidim-comments/app/assets/javascripts/decidim/comments/bundle.js +0 -0
  79. data/decidim-comments/app/commands/decidim/comments/create_comment.rb +2 -2
  80. data/decidim-comments/app/frontend/comments/add_comment_form.component.tsx +1 -0
  81. data/decidim-comments/app/frontend/comments/comment.component.test.tsx +12 -1
  82. data/decidim-comments/app/frontend/comments/comment.component.tsx +42 -4
  83. data/decidim-comments/app/frontend/comments/comment_thread.component.test.tsx +11 -0
  84. data/decidim-comments/app/frontend/comments/comment_thread.component.tsx +5 -1
  85. data/decidim-comments/app/frontend/fragments/comment_data.fragment.graphql +3 -0
  86. data/decidim-comments/app/frontend/support/generate_comments_data.ts +3 -0
  87. data/decidim-comments/app/frontend/support/schema.ts +18 -12
  88. data/decidim-comments/app/mailers/decidim/comments/comment_notification_mailer.rb +6 -4
  89. data/decidim-comments/app/models/decidim/comments/comment.rb +6 -4
  90. data/decidim-comments/app/models/decidim/comments/comment_vote.rb +1 -2
  91. data/decidim-comments/app/models/decidim/comments/seed.rb +5 -2
  92. data/decidim-comments/app/resolvers/decidim/comments/vote_comment_resolver.rb +3 -0
  93. data/decidim-comments/app/types/decidim/comments/commentable_interface.rb +3 -3
  94. data/decidim-comments/app/views/decidim/comments/comment_notification_mailer/comment_created.html.erb +1 -1
  95. data/decidim-comments/app/views/decidim/comments/comment_notification_mailer/reply_created.html.erb +1 -1
  96. data/decidim-comments/bin/rails +3 -3
  97. data/decidim-comments/config/locales/ca.yml +5 -0
  98. data/decidim-comments/config/locales/en.yml +5 -0
  99. data/decidim-comments/config/locales/es.yml +5 -0
  100. data/decidim-comments/config/locales/it.yml +65 -0
  101. data/decidim-comments/db/migrate/20161130143508_create_comments.rb +2 -0
  102. data/decidim-comments/db/migrate/20161214082645_add_depth_to_comments.rb +2 -0
  103. data/decidim-comments/db/migrate/20161216102820_add_alignment_to_comments.rb +2 -0
  104. data/decidim-comments/db/migrate/20161219150806_create_comment_votes.rb +3 -1
  105. data/decidim-comments/db/migrate/20170123102043_add_user_group_id_to_comments.rb +2 -0
  106. data/decidim-comments/db/migrate/20170504085413_add_root_commentable_to_comments.rb +2 -0
  107. data/decidim-comments/db/migrate/20170510091348_update_root_commentable_for_comments.rb +3 -2
  108. data/decidim-comments/db/migrate/20170510091409_set_root_commentable_null_constraints.rb +2 -0
  109. data/decidim-comments/decidim-comments.gemspec +2 -1
  110. data/decidim-comments/lib/decidim/comments/comment_serializer.rb +1 -1
  111. data/decidim-comments/lib/decidim/comments/commentable.rb +4 -4
  112. data/decidim-comments/spec/commands/create_comment_spec.rb +2 -2
  113. data/decidim-comments/spec/features/admin_manages_comments_spec.rb +4 -9
  114. data/decidim-comments/spec/features/process_admin_manages_comments_spec.rb +5 -11
  115. data/decidim-comments/spec/mailers/comment_notification_mailer_spec.rb +12 -7
  116. data/decidim-comments/spec/shared/author_localised_email.rb +26 -0
  117. data/decidim-comments/spec/spec_helper.rb +1 -1
  118. data/decidim-dev/config/locales/it.yml +9 -0
  119. data/decidim-dev/decidim-dev.gemspec +8 -3
  120. data/decidim-dev/lib/decidim/dev.rb +1 -8
  121. data/decidim-dev/lib/decidim/dev/railtie.rb +1 -1
  122. data/decidim-dev/lib/decidim/dev/test/base_spec_helper.rb +6 -4
  123. data/decidim-dev/lib/decidim/dev/test/rspec_support/capybara.rb +2 -2
  124. data/decidim-dev/lib/decidim/dev/test/rspec_support/feature.rb +4 -2
  125. data/decidim-dev/lib/decidim/dev/test/rspec_support/feature_context.rb +28 -8
  126. data/decidim-dev/lib/decidim/dev/test/rspec_support/translation_helpers.rb +7 -2
  127. data/decidim-dev/lib/decidim/dev/test/spec_helper.rb +2 -2
  128. data/decidim-dev/lib/generators/decidim/dummy_generator.rb +1 -1
  129. data/decidim-meetings/README.md +1 -1
  130. data/decidim-meetings/app/controllers/decidim/meetings/application_controller.rb +1 -1
  131. data/decidim-meetings/app/views/decidim/meetings/meetings/_linked_meetings.html.erb +1 -1
  132. data/decidim-meetings/bin/rails +3 -3
  133. data/decidim-meetings/config/locales/it.yml +87 -0
  134. data/decidim-meetings/db/migrate/20161130121354_create_meetings.rb +2 -0
  135. data/decidim-meetings/db/migrate/20170110142105_close_a_meeting.rb +2 -0
  136. data/decidim-meetings/db/migrate/20170123151650_add_latitude_and_longitude_to_meetings.rb +2 -0
  137. data/decidim-meetings/db/migrate/20170129153716_remove_short_description_from_meetings.rb +2 -0
  138. data/decidim-meetings/db/migrate/20170215132546_add_reference_to_meetings.rb +2 -0
  139. data/decidim-meetings/db/migrate/20170410074252_remove_not_null_reference_meetings.rb +2 -0
  140. data/decidim-meetings/db/migrate/20170612101925_migrate_meetings_category.rb +15 -0
  141. data/decidim-meetings/decidim-meetings.gemspec +3 -1
  142. data/decidim-meetings/lib/decidim/meetings/feature.rb +2 -2
  143. data/decidim-meetings/spec/features/admin_manages_meetings_attachments_spec.rb +5 -1
  144. data/decidim-meetings/spec/features/admin_manages_meetings_spec.rb +5 -7
  145. data/decidim-meetings/spec/features/explore_meetings_spec.rb +32 -6
  146. data/decidim-meetings/spec/features/process_admin_manages_meetings_attachments_spec.rb +4 -2
  147. data/decidim-meetings/spec/features/process_admin_manages_meetings_spec.rb +5 -8
  148. data/decidim-meetings/spec/shared/manage_attachments_examples.rb +0 -3
  149. data/decidim-meetings/spec/shared/manage_meetings_examples.rb +11 -11
  150. data/decidim-meetings/spec/spec_helper.rb +2 -1
  151. data/decidim-pages/bin/rails +3 -3
  152. data/decidim-pages/config/locales/it.yml +22 -0
  153. data/decidim-pages/db/migrate/20161116121353_create_decidim_pages.rb +2 -0
  154. data/decidim-pages/db/migrate/20161214150429_add_commentable_to_pages.rb +2 -0
  155. data/decidim-pages/db/migrate/20170110145040_remove_commentable_flag_from_pages.rb +2 -0
  156. data/decidim-pages/db/migrate/20170220091402_remove_page_feature_titles.rb +2 -0
  157. data/decidim-pages/decidim-pages.gemspec +3 -1
  158. data/decidim-pages/spec/features/admin_spec.rb +1 -1
  159. data/decidim-pages/spec/spec_helper.rb +2 -3
  160. data/decidim-proposals/app/commands/decidim/proposals/unvote_proposal.rb +34 -0
  161. data/decidim-proposals/app/commands/decidim/proposals/vote_proposal.rb +39 -0
  162. data/decidim-proposals/app/controllers/concerns/decidim/proposals/orderable.rb +7 -3
  163. data/decidim-proposals/app/controllers/decidim/proposals/proposal_votes_controller.rb +18 -8
  164. data/decidim-proposals/app/models/decidim/proposals/proposal.rb +3 -3
  165. data/decidim-proposals/app/models/decidim/proposals/proposal_vote.rb +0 -1
  166. data/decidim-proposals/app/views/decidim/proposals/proposals/_author.html.erb +23 -0
  167. data/decidim-proposals/app/views/decidim/proposals/proposals/_linked_proposals.html.erb +2 -2
  168. data/decidim-proposals/app/views/decidim/proposals/proposals/_proposal.html.erb +1 -9
  169. data/decidim-proposals/app/views/decidim/proposals/proposals/_vote_button.html.erb +2 -6
  170. data/decidim-proposals/app/views/decidim/proposals/proposals/new.html.erb +1 -1
  171. data/decidim-proposals/app/views/decidim/proposals/proposals/show.html.erb +1 -11
  172. data/decidim-proposals/bin/rails +3 -3
  173. data/decidim-proposals/config/locales/ca.yml +6 -0
  174. data/decidim-proposals/config/locales/en.yml +6 -0
  175. data/decidim-proposals/config/locales/es.yml +6 -0
  176. data/decidim-proposals/config/locales/eu.yml +0 -2
  177. data/decidim-proposals/config/locales/fi.yml +0 -2
  178. data/decidim-proposals/config/locales/fr.yml +0 -2
  179. data/decidim-proposals/config/locales/it.yml +147 -0
  180. data/decidim-proposals/db/migrate/20161212110850_create_decidim_proposals.rb +2 -0
  181. data/decidim-proposals/db/migrate/20170112115253_create_proposal_votes.rb +3 -1
  182. data/decidim-proposals/db/migrate/20170113114245_add_text_search_indexes.rb +2 -0
  183. data/decidim-proposals/db/migrate/20170118120151_add_counter_cache_votes_to_proposals.rb +2 -0
  184. data/decidim-proposals/db/migrate/20170120151202_add_user_group_id_to_proposals.rb +2 -0
  185. data/decidim-proposals/db/migrate/20170131092413_add_answers_to_proposals.rb +2 -0
  186. data/decidim-proposals/db/migrate/20170205082832_add_index_to_decidim_proposals_proposals_proposal_votes_count.rb +2 -0
  187. data/decidim-proposals/db/migrate/20170215113152_create_proposal_reports.rb +2 -0
  188. data/decidim-proposals/db/migrate/20170215131720_add_report_count_to_proposals.rb +2 -0
  189. data/decidim-proposals/db/migrate/20170215132030_add_reference_to_proposals.rb +2 -0
  190. data/decidim-proposals/db/migrate/20170220152416_add_hidden_at_to_proposals.rb +2 -0
  191. data/decidim-proposals/db/migrate/20170228105156_add_geolocalization_fields_to_proposals.rb +2 -0
  192. data/decidim-proposals/db/migrate/20170307085300_migrate_proposal_reports_data_to_reports.rb +8 -10
  193. data/decidim-proposals/db/migrate/20170410073742_remove_not_null_reference_proposals.rb +2 -0
  194. data/decidim-proposals/db/migrate/20170612101809_migrate_proposals_category.rb +15 -0
  195. data/decidim-proposals/decidim-proposals.gemspec +4 -2
  196. data/decidim-proposals/lib/decidim/proposals/feature.rb +5 -1
  197. data/decidim-proposals/lib/decidim/proposals/proposal_serializer.rb +1 -6
  198. data/decidim-proposals/spec/commands/decidim/proposals/unvote_proposal_spec.rb +26 -0
  199. data/decidim-proposals/spec/commands/decidim/proposals/vote_proposal_spec.rb +47 -0
  200. data/decidim-proposals/spec/features/admin_manages_proposals_spec.rb +6 -11
  201. data/decidim-proposals/spec/features/process_admin_manages_proposals_spec.rb +6 -12
  202. data/decidim-proposals/spec/features/proposals_spec.rb +38 -12
  203. data/decidim-proposals/spec/shared/manage_proposals_examples.rb +3 -6
  204. data/decidim-proposals/spec/spec_helper.rb +2 -1
  205. data/decidim-results/app/controllers/decidim/results/application_controller.rb +1 -1
  206. data/decidim-results/app/views/decidim/results/results/_linked_results.html.erb +1 -1
  207. data/decidim-results/bin/rails +3 -3
  208. data/decidim-results/config/locales/it.yml +78 -0
  209. data/decidim-results/db/migrate/20170116104125_create_results.rb +2 -0
  210. data/decidim-results/db/migrate/20170129164553_remove_short_description_from_results.rb +2 -0
  211. data/decidim-results/db/migrate/20170215132624_add_reference_to_results.rb +2 -0
  212. data/decidim-results/db/migrate/20170410074358_remove_not_null_reference_results.rb +2 -0
  213. data/decidim-results/db/migrate/20170612101951_migrate_results_category.rb +15 -0
  214. data/decidim-results/decidim-results.gemspec +3 -1
  215. data/decidim-results/spec/features/admin_manages_results_spec.rb +5 -7
  216. data/decidim-results/spec/features/process_admin_manages_results_spec.rb +5 -8
  217. data/decidim-results/spec/shared/manage_results_examples.rb +3 -3
  218. data/decidim-results/spec/spec_helper.rb +2 -1
  219. data/decidim-surveys/README.md +24 -0
  220. data/decidim-surveys/Rakefile +3 -0
  221. data/decidim-surveys/app/assets/config/admin/decidim_surveys_manifest.js +1 -0
  222. data/decidim-surveys/app/assets/images/decidim/surveys/icon.svg +1 -0
  223. data/decidim-surveys/app/assets/javascripts/decidim/surveys/admin/auto_label_by_position.component.js.es6 +33 -0
  224. data/decidim-surveys/app/assets/javascripts/decidim/surveys/admin/dynamic_fields.component.js.es6 +95 -0
  225. data/decidim-surveys/app/assets/javascripts/decidim/surveys/admin/surveys.js.es6 +85 -0
  226. data/decidim-surveys/app/assets/stylesheets/decidim/surveys/surveys.scss +9 -0
  227. data/decidim-surveys/app/commands/decidim/surveys/admin/update_survey.rb +65 -0
  228. data/decidim-surveys/app/commands/decidim/surveys/answer_survey.rb +43 -0
  229. data/decidim-surveys/app/commands/decidim/surveys/create_survey.rb +19 -0
  230. data/decidim-surveys/app/controllers/decidim/surveys/admin/application_controller.rb +15 -0
  231. data/decidim-surveys/app/controllers/decidim/surveys/admin/surveys_controller.rb +55 -0
  232. data/decidim-surveys/app/controllers/decidim/surveys/application_controller.rb +13 -0
  233. data/decidim-surveys/app/controllers/decidim/surveys/surveys_controller.rb +39 -0
  234. data/decidim-surveys/app/forms/decidim/surveys/admin/survey_form.rb +19 -0
  235. data/decidim-surveys/app/forms/decidim/surveys/admin/survey_question_answer_option_form.rb +15 -0
  236. data/decidim-surveys/app/forms/decidim/surveys/admin/survey_question_form.rb +24 -0
  237. data/decidim-surveys/app/forms/decidim/surveys/survey_answer_form.rb +36 -0
  238. data/decidim-surveys/app/forms/decidim/surveys/survey_form.rb +22 -0
  239. data/decidim-surveys/app/helpers/decidim/surveys/admin/application_helper.rb +39 -0
  240. data/decidim-surveys/app/models/decidim/surveys/abilities/admin_user.rb +34 -0
  241. data/decidim-surveys/app/models/decidim/surveys/abilities/current_user.rb +47 -0
  242. data/decidim-surveys/app/models/decidim/surveys/abilities/process_admin_user.rb +44 -0
  243. data/decidim-surveys/app/models/decidim/surveys/application_record.rb +10 -0
  244. data/decidim-surveys/app/models/decidim/surveys/survey.rb +25 -0
  245. data/decidim-surveys/app/models/decidim/surveys/survey_answer.rb +27 -0
  246. data/decidim-surveys/app/models/decidim/surveys/survey_question.rb +18 -0
  247. data/decidim-surveys/app/queries/decidim/surveys/survey_user_answers.rb +28 -0
  248. data/decidim-surveys/app/views/decidim/surveys/admin/surveys/_answer_option.html.erb +23 -0
  249. data/decidim-surveys/app/views/decidim/surveys/admin/surveys/_form.html.erb +47 -0
  250. data/decidim-surveys/app/views/decidim/surveys/admin/surveys/_question.html.erb +57 -0
  251. data/decidim-surveys/app/views/decidim/surveys/admin/surveys/edit.html.erb +7 -0
  252. data/decidim-surveys/app/views/decidim/surveys/surveys/show.html.erb +102 -0
  253. data/decidim-surveys/bin/rails +15 -0
  254. data/decidim-surveys/config/i18n-tasks.yml +11 -0
  255. data/decidim-surveys/config/locales/ca.yml +69 -0
  256. data/decidim-surveys/config/locales/en.yml +73 -0
  257. data/decidim-surveys/config/locales/es.yml +69 -0
  258. data/decidim-surveys/config/locales/eu.yml +5 -0
  259. data/decidim-surveys/config/locales/fi.yml +5 -0
  260. data/decidim-surveys/config/locales/fr.yml +5 -0
  261. data/decidim-surveys/config/locales/it.yml +5 -0
  262. data/decidim-surveys/config/locales/nl.yml +5 -0
  263. data/decidim-surveys/db/migrate/20170511092231_create_decidim_surveys.rb +15 -0
  264. data/decidim-surveys/db/migrate/20170515090916_create_decidim_survey_questions.rb +12 -0
  265. data/decidim-surveys/db/migrate/20170515144119_create_decidim_survey_answers.rb +14 -0
  266. data/decidim-surveys/db/migrate/20170518085302_add_position_to_surveys_questions.rb +7 -0
  267. data/decidim-surveys/db/migrate/20170522075938_add_mandatory_to_surveys_questions.rb +7 -0
  268. data/decidim-surveys/db/migrate/20170524122229_add_question_type_to_surveys_questions.rb +7 -0
  269. data/decidim-surveys/db/migrate/20170525132233_add_answer_options_to_surveys_questions.rb +7 -0
  270. data/decidim-surveys/decidim-surveys.gemspec +22 -0
  271. data/decidim-surveys/lib/decidim/surveys.rb +14 -0
  272. data/decidim-surveys/lib/decidim/surveys/admin.rb +10 -0
  273. data/decidim-surveys/lib/decidim/surveys/admin_engine.rb +34 -0
  274. data/decidim-surveys/lib/decidim/surveys/engine.rb +25 -0
  275. data/decidim-surveys/lib/decidim/surveys/feature.rb +85 -0
  276. data/decidim-surveys/lib/decidim/surveys/survey_user_answers_serializer.rb +23 -0
  277. data/decidim-surveys/lib/decidim/surveys/test/factories.rb +39 -0
  278. data/decidim-surveys/spec/commands/decidim/surveys/admin/update_survey_spec.rb +147 -0
  279. data/decidim-surveys/spec/commands/decidim/surveys/answer_survey_spec.rb +71 -0
  280. data/decidim-surveys/spec/commands/decidim/surveys/create_survey_spec.rb +44 -0
  281. data/decidim-surveys/spec/factories.rb +3 -0
  282. data/decidim-surveys/spec/features/admin_manages_surveys_spec.rb +13 -0
  283. data/decidim-surveys/spec/features/process_admin_manages_surveys_spec.rb +13 -0
  284. data/decidim-surveys/spec/features/survey_spec.rb +235 -0
  285. data/decidim-surveys/spec/forms/decidim/surveys/admin/survey_form_spec.rb +64 -0
  286. data/decidim-surveys/spec/forms/decidim/surveys/admin/survey_question_form_spec.rb +36 -0
  287. data/decidim-surveys/spec/forms/decidim/surveys/survey_answer_form_spec.rb +36 -0
  288. data/decidim-surveys/spec/forms/decidim/surveys/survey_form_spec.rb +32 -0
  289. data/decidim-surveys/spec/models/decidim/surveys/abilities/admin_user_spec.rb +22 -0
  290. data/decidim-surveys/spec/models/decidim/surveys/abilities/current_user_spec.rb +19 -0
  291. data/decidim-surveys/spec/models/decidim/surveys/abilities/process_admin_user_spec.rb +23 -0
  292. data/decidim-surveys/spec/models/decidim/surveys/survey_answer_spec.rb +55 -0
  293. data/decidim-surveys/spec/models/decidim/surveys/survey_question_spec.rb +19 -0
  294. data/decidim-surveys/spec/models/decidim/surveys/survey_spec.rb +65 -0
  295. data/decidim-surveys/spec/queries/decidim/surveys/survey_user_answers_spec.rb +21 -0
  296. data/decidim-surveys/spec/services/decidim/surveys/surveys/survey_user_answer_serializer_spec.rb +34 -0
  297. data/decidim-surveys/spec/shared/edit_survey_examples.rb +213 -0
  298. data/decidim-surveys/spec/shared/export_survey_user_answers_examples.rb +47 -0
  299. data/decidim-surveys/spec/spec_helper.rb +4 -0
  300. data/decidim-system/app/controllers/decidim/system/devise/passwords_controller.rb +2 -0
  301. data/decidim-system/app/helpers/decidim/system/menu_helper.rb +0 -1
  302. data/decidim-system/bin/rails +3 -3
  303. data/decidim-system/config/locales/it.yml +66 -0
  304. data/decidim-system/db/migrate/20160919105637_devise_create_decidim_admins.rb +2 -0
  305. data/decidim-system/decidim-system.gemspec +2 -1
  306. data/decidim-system/spec/spec_helper.rb +3 -2
  307. data/decidim.gemspec +5 -4
  308. data/docs/geocoding.md +2 -2
  309. data/docs/how_to_create_a_plugin.md +11 -11
  310. data/lib/decidim.rb +1 -0
  311. data/lib/generators/decidim/app_generator.rb +3 -2
  312. data/lib/generators/decidim/demo_generator.rb +1 -1
  313. data/lib/generators/decidim/docker_generator.rb +2 -2
  314. data/lib/generators/decidim/install_generator.rb +3 -6
  315. data/lib/generators/decidim/templates/initializer.rb +2 -2
  316. metadata +130 -47
  317. data/decidim-admin/app/assets/javascripts/decidim/admin/sort_steps.js.es6 +0 -30
  318. data/decidim-budgets/spec/shared/admin_shared_context.rb +0 -13
  319. data/decidim-comments/spec/shared/admin_shared_context.rb +0 -13
  320. data/decidim-meetings/spec/shared/admin_shared_context.rb +0 -13
  321. data/decidim-proposals/spec/shared/admin_shared_context.rb +0 -13
  322. data/decidim-results/spec/shared/admin_shared_context.rb +0 -13
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- ENV["ENGINE_NAME"] = File.dirname(File.dirname(__FILE__)).split("/").last
3
+ ENV["ENGINE_NAME"] = File.dirname(__dir__).split("/").last
4
+
4
5
  require "decidim/dev/test/base_spec_helper"
@@ -43,9 +43,9 @@ module Decidim
43
43
 
44
44
  def send_notification_to_author
45
45
  if @comment.depth.positive? && @commentable.author.replies_notifications?
46
- CommentNotificationMailer.reply_created(@author, @comment, @commentable, @comment.root_commentable).deliver_later
46
+ CommentNotificationMailer.reply_created(@comment, @commentable, @comment.root_commentable).deliver_later
47
47
  elsif @comment.depth.zero? && @commentable.author.comments_notifications?
48
- CommentNotificationMailer.comment_created(@author, @comment, @commentable).deliver_later
48
+ CommentNotificationMailer.comment_created(@comment, @commentable).deliver_later
49
49
  end
50
50
  end
51
51
 
@@ -360,6 +360,7 @@ const AddCommentFormWithMutation = graphql(addCommentMutation, {
360
360
  __typename: "User",
361
361
  name: ownProps.session.user.name,
362
362
  avatarUrl: ownProps.session.user.avatarUrl,
363
+ deleted: false,
363
364
  },
364
365
  comments: [],
365
366
  hasComments: false,
@@ -45,6 +45,17 @@ describe("<Comment />", () => {
45
45
  expect(wrapper.find("a.author__name").text()).toEqual(comment.author.name);
46
46
  });
47
47
 
48
+ describe("when the author's account has been deleted", () => {
49
+ beforeEach(() => {
50
+ comment.author.deleted = true;
51
+ });
52
+
53
+ it("should render 'Deleted user' inside a badge", () => {
54
+ const wrapper = shallow(<Comment comment={comment} session={session} />);
55
+ expect(wrapper.find("span.label.label--small.label--basic").text()).toEqual("Deleted user");
56
+ });
57
+ });
58
+
48
59
  it("should render author's avatar as a image tag", () => {
49
60
  const wrapper = shallow(<Comment comment={comment} session={session} />);
50
61
  expect(wrapper.find("a.author__avatar img").prop("src")).toEqual(comment.author.avatarUrl);
@@ -145,7 +156,7 @@ describe("<Comment />", () => {
145
156
  it("should render a 'in favor' badge if comment's alignment is 1", () => {
146
157
  comment.alignment = 1;
147
158
  const wrapper = shallow(<Comment comment={comment} session={session} />);
148
- expect(wrapper.find("span.success.label").text()).toEqual("In favor");
159
+ expect(wrapper.find("span.alignment.label").text()).toEqual("In favor");
149
160
  });
150
161
 
151
162
  it("should render a 'against' badge if comment's alignment is -1", () => {
@@ -42,6 +42,8 @@ class Comment extends React.Component<CommentProps, CommentState> {
42
42
  votable: false,
43
43
  };
44
44
 
45
+ public commentNode: HTMLElement;
46
+
45
47
  constructor(props: CommentProps) {
46
48
  super(props);
47
49
 
@@ -51,12 +53,37 @@ class Comment extends React.Component<CommentProps, CommentState> {
51
53
  }
52
54
 
53
55
  public componentDidMount() {
56
+ const { comment: { id } } = this.props;
57
+ const hash = document.location.hash;
58
+ const regex = new RegExp(`#comment_${id}`);
59
+
60
+ function scrollTo(element: Element, to: number, duration: number) {
61
+ if (duration <= 0) {
62
+ return;
63
+ }
64
+ const difference = to - element.scrollTop;
65
+ const perTick = difference / duration * 10;
66
+
67
+ setTimeout(() => {
68
+ element.scrollTop = element.scrollTop + perTick;
69
+ if (element.scrollTop === to) {
70
+ return;
71
+ }
72
+ scrollTo(element, to, duration - 10);
73
+ }, 10);
74
+ }
75
+
76
+ if (regex.test(hash)) {
77
+ scrollTo(document.body, this.commentNode.offsetTop, 200);
78
+ }
79
+
54
80
  if (window.$(document).foundation) {
55
- const { comment: { id } } = this.props;
56
81
  window.$(`#flagModalComment${id}`).foundation();
57
82
  }
58
83
  }
59
84
 
85
+ public getNodeReference = (commentNode: HTMLElement) => this.commentNode = commentNode;
86
+
60
87
  public render(): JSX.Element {
61
88
  const { session, comment: { id, author, body, createdAt }, articleClassName } = this.props;
62
89
  const formattedCreatedAt = ` ${moment(createdAt).format("LLL")}`;
@@ -67,7 +94,7 @@ class Comment extends React.Component<CommentProps, CommentState> {
67
94
  }
68
95
 
69
96
  return (
70
- <article id={`comment_${id}`} className={articleClassName}>
97
+ <article id={`comment_${id}`} className={articleClassName} ref={this.getNodeReference}>
71
98
  <div className="comment__header">
72
99
  <div className="author-data">
73
100
  <div className="author-data__main">
@@ -75,7 +102,18 @@ class Comment extends React.Component<CommentProps, CommentState> {
75
102
  <a className="author__avatar">
76
103
  <img src={author.avatarUrl} alt="author-avatar" />
77
104
  </a>
78
- <a className="author__name">{author.name}</a>
105
+ { author.deleted ?
106
+ <span className="label label--small label--basic">{I18n.t("components.comment.deleted_user")}</span> :
107
+ <a className="author__name">{author.name}</a>
108
+ }
109
+ { !author.isUser && author.isVerified &&
110
+ <span>
111
+ &nbsp;
112
+ <span className="label success label--small">
113
+ {I18n.t("components.comment.verified_user_group")}
114
+ </span>
115
+ </span>
116
+ }
79
117
  <time dateTime={createdAt}>{formattedCreatedAt}</time>
80
118
  </div>
81
119
  </div>
@@ -244,7 +282,7 @@ class Comment extends React.Component<CommentProps, CommentState> {
244
282
  */
245
283
  private _renderAlignmentBadge() {
246
284
  const { comment: { alignment } } = this.props;
247
- const spanClassName = classnames("label", {
285
+ const spanClassName = classnames("label alignment", {
248
286
  success: alignment === 1,
249
287
  alert: alignment === -1,
250
288
  });
@@ -39,6 +39,17 @@ describe("<CommentThread />", () => {
39
39
  const wrapper = shallow(<CommentThread comment={comment} session={session} />);
40
40
  expect(wrapper.find("h6.comment-thread__title").text()).toContain(`Conversation with ${comment.author.name}`);
41
41
  });
42
+
43
+ describe("when the author's account has been deleted", () => {
44
+ beforeEach(() => {
45
+ comment.author.deleted = true;
46
+ });
47
+
48
+ it("should render a h6 comment-thread__title with 'Deleted user'", () => {
49
+ const wrapper = shallow(<CommentThread comment={comment} session={session} />);
50
+ expect(wrapper.find("h6.comment-thread__title").text()).toContain("Conversation with Deleted user");
51
+ });
52
+ });
42
53
  });
43
54
 
44
55
  describe("should render a Comment", () => {
@@ -58,7 +58,11 @@ class CommentThread extends React.Component<CommentThreadProps, undefined> {
58
58
  if (hasComments) {
59
59
  return (
60
60
  <h6 className="comment-thread__title">
61
- {I18n.t("components.comment_thread.title", { authorName: author.name })}
61
+ {
62
+ author.deleted ?
63
+ I18n.t("components.comment_thread.title", { authorName: I18n.t("components.comment.deleted_user") }) :
64
+ I18n.t("components.comment_thread.title", { authorName: author.name })
65
+ }
62
66
  </h6>
63
67
  );
64
68
  }
@@ -10,6 +10,9 @@ fragment CommentData on Comment {
10
10
  author {
11
11
  name
12
12
  avatarUrl
13
+ isVerified
14
+ isUser
15
+ deleted
13
16
  }
14
17
  hasComments
15
18
  acceptsNewComments
@@ -19,6 +19,9 @@ const generateCommentsData = (num = 1) => {
19
19
  author: {
20
20
  name: name.findName(),
21
21
  avatarUrl: image.imageUrl(),
22
+ isVerified: Math.random() >= 0.5,
23
+ isUser: Math.random() >= 0.5,
24
+ deleted: false,
22
25
  },
23
26
  hasComments: false,
24
27
  comments: [],
@@ -59,11 +59,11 @@ export interface GetCommentsQuery {
59
59
  } | null,
60
60
  } | null;
61
61
  commentable: AddCommentFormCommentableFragment & {
62
- // Wether the object can have new comments or not
62
+ // Whether the object can have new comments or not
63
63
  acceptsNewComments: boolean,
64
- // Wether the object comments have alignment or not
64
+ // Whether the object comments have alignment or not
65
65
  commentsHaveAlignment: boolean,
66
- // Wether the object comments have votes or not
66
+ // Whether the object comments have votes or not
67
67
  commentsHaveVotes: boolean,
68
68
  comments: Array< CommentThreadFragment & CommentFragment & CommentDataFragment & UpVoteButtonFragment & DownVoteButtonFragment & {
69
69
  // The Comment's unique ID
@@ -89,6 +89,14 @@ export interface AddCommentFormSessionFragment {
89
89
  } >;
90
90
  }
91
91
 
92
+ export interface CommentFragment extends CommentDataFragment, UpVoteButtonFragment, DownVoteButtonFragment {
93
+ comments: Array< CommentDataFragment & UpVoteButtonFragment & DownVoteButtonFragment & {
94
+ comments: Array< CommentDataFragment & UpVoteButtonFragment & DownVoteButtonFragment & {
95
+ comments: Array<CommentDataFragment & UpVoteButtonFragment & DownVoteButtonFragment>,
96
+ } >,
97
+ } >;
98
+ }
99
+
92
100
  export interface CommentDataFragment extends UpVoteButtonFragment, DownVoteButtonFragment {
93
101
  // The Comment's unique ID
94
102
  id: string;
@@ -106,10 +114,16 @@ export interface CommentDataFragment extends UpVoteButtonFragment, DownVoteButto
106
114
  name: string,
107
115
  // The author's avatar url
108
116
  avatarUrl: string,
117
+ // Whether the author is verified or not
118
+ isVerified: boolean,
119
+ // Whether the author is a user or another kind of author (User Group)
120
+ isUser: boolean,
121
+ // Whether the author's account has been deleted or not
122
+ deleted: boolean,
109
123
  };
110
124
  // Check if the commentable has comments
111
125
  hasComments: boolean;
112
- // Wether the object can have new comments or not
126
+ // Whether the object can have new comments or not
113
127
  acceptsNewComments: boolean;
114
128
  // The comment's alignment. Can be 0 (neutral), 1 (in favor) or -1 (against)'
115
129
  alignment: number | null;
@@ -122,14 +136,6 @@ export interface CommentThreadFragment extends CommentFragment, CommentDataFragm
122
136
  hasComments: boolean;
123
137
  }
124
138
 
125
- export interface CommentFragment extends CommentDataFragment, UpVoteButtonFragment, DownVoteButtonFragment {
126
- comments: Array< CommentDataFragment & UpVoteButtonFragment & DownVoteButtonFragment & {
127
- comments: Array< CommentDataFragment & UpVoteButtonFragment & DownVoteButtonFragment & {
128
- comments: Array<CommentDataFragment & UpVoteButtonFragment & DownVoteButtonFragment>,
129
- } >,
130
- } >;
131
- }
132
-
133
139
  export interface DownVoteButtonFragment {
134
140
  // The Comment's unique ID
135
141
  id: string;
@@ -9,21 +9,23 @@ module Decidim
9
9
 
10
10
  helper_method :commentable_title
11
11
 
12
- def comment_created(user, comment, commentable)
13
- with_user(user) do
12
+ def comment_created(comment, commentable)
13
+ with_user(commentable.author) do
14
14
  @comment = comment
15
15
  @commentable = commentable
16
+ @locator = Decidim::ResourceLocatorPresenter.new(@commentable)
16
17
  @organization = commentable.organization
17
18
  subject = I18n.t("comment_created.subject", scope: "decidim.comments.mailer.comment_notification")
18
19
  mail(to: commentable.author.email, subject: subject)
19
20
  end
20
21
  end
21
22
 
22
- def reply_created(user, reply, comment, commentable)
23
- with_user(user) do
23
+ def reply_created(reply, comment, commentable)
24
+ with_user(comment.author) do
24
25
  @reply = reply
25
26
  @comment = comment
26
27
  @commentable = commentable
28
+ @locator = Decidim::ResourceLocatorPresenter.new(@commentable)
27
29
  @organization = commentable.organization
28
30
  subject = I18n.t("reply_created.subject", scope: "decidim.comments.mailer.comment_notification")
29
31
  mail(to: comment.author.email, subject: subject)
@@ -23,10 +23,12 @@ module Decidim
23
23
  has_many :up_votes, -> { where(weight: 1) }, foreign_key: "decidim_comment_id", class_name: "CommentVote", dependent: :destroy
24
24
  has_many :down_votes, -> { where(weight: -1) }, foreign_key: "decidim_comment_id", class_name: "CommentVote", dependent: :destroy
25
25
 
26
- validates :author, :commentable, :root_commentable, :body, presence: true
26
+ validates :body, presence: true
27
27
  validates :depth, numericality: { greater_than_or_equal_to: 0 }
28
28
  validates :alignment, inclusion: { in: [0, 1, -1] }
29
29
 
30
+ validates :body, length: { maximum: 500 }
31
+
30
32
  validate :commentable_can_have_comments
31
33
 
32
34
  before_save :compute_depth
@@ -52,9 +54,9 @@ module Decidim
52
54
  down_votes.any? { |vote| vote.author == user }
53
55
  end
54
56
 
55
- # Public: Overrides the `reported_content` Reportable concern method.
56
- def reported_content
57
- body
57
+ # Public: Overrides the `reported_content_url` Reportable concern method.
58
+ def reported_content_url
59
+ ResourceLocatorPresenter.new(root_commentable).url(anchor: "comment_#{id}")
58
60
  end
59
61
 
60
62
  private
@@ -8,8 +8,7 @@ module Decidim
8
8
  belongs_to :comment, foreign_key: "decidim_comment_id", class_name: "Comment"
9
9
  belongs_to :author, foreign_key: "decidim_author_id", class_name: "Decidim::User"
10
10
 
11
- validates :comment, presence: true, uniqueness: { scope: :author }
12
- validates :author, presence: true
11
+ validates :comment, uniqueness: { scope: :author }
13
12
  validates :weight, inclusion: { in: [-1, 1] }
14
13
  validate :author_and_comment_same_organization
15
14
 
@@ -15,12 +15,15 @@ module Decidim
15
15
  organization = resource.organization
16
16
 
17
17
  rand(1..5).times do
18
- random = rand(Decidim::User.count)
18
+ author = Decidim::User.where(organization: organization).all.sample
19
+ user_group = [true, false].sample ? author.user_groups.verified.sample : nil
20
+
19
21
  Comment.create(
20
22
  commentable: resource,
21
23
  root_commentable: resource,
22
24
  body: ::Faker::Lorem.sentence,
23
- author: Decidim::User.where(organization: organization).offset(random).first
25
+ author: author,
26
+ user_group: user_group
24
27
  )
25
28
  end
26
29
  end
@@ -14,6 +14,9 @@ module Decidim
14
14
  on(:ok) do |comment|
15
15
  return comment
16
16
  end
17
+ on(:invalid) do
18
+ return GraphQL::ExecutionError.new(I18n.t("votes.create.error", scope: "decidim.comments"))
19
+ end
17
20
  end
18
21
  end
19
22
  end
@@ -13,15 +13,15 @@ module Decidim
13
13
  property :commentable_type
14
14
  end
15
15
 
16
- field :acceptsNewComments, !types.Boolean, "Wether the object can have new comments or not" do
16
+ field :acceptsNewComments, !types.Boolean, "Whether the object can have new comments or not" do
17
17
  property :accepts_new_comments?
18
18
  end
19
19
 
20
- field :commentsHaveAlignment, !types.Boolean, "Wether the object comments have alignment or not" do
20
+ field :commentsHaveAlignment, !types.Boolean, "Whether the object comments have alignment or not" do
21
21
  property :comments_have_alignment?
22
22
  end
23
23
 
24
- field :commentsHaveVotes, !types.Boolean, "Wether the object comments have votes or not" do
24
+ field :commentsHaveVotes, !types.Boolean, "Whether the object comments have votes or not" do
25
25
  property :comments_have_votes?
26
26
  end
27
27
 
@@ -4,7 +4,7 @@
4
4
  <%=
5
5
  t(".new_comment_html", {
6
6
  commenter: @comment.author.name,
7
- commentable_link: link_to(commentable_title, decidim_resource_url(@commentable))
7
+ commentable_link: link_to(commentable_title, @locator.url(anchor: "comment_#{@comment.id}"))
8
8
  })
9
9
  %>
10
10
  </p>
@@ -4,7 +4,7 @@
4
4
  <%=
5
5
  t(".new_reply_html", {
6
6
  commenter: @reply.author.name,
7
- commentable_link: link_to(commentable_title, decidim_resource_url(@commentable))
7
+ commentable_link: link_to(commentable_title, @locator.url(anchor: "comment_#{@reply.id}"))
8
8
  })
9
9
  %>
10
10
  </p>
@@ -4,11 +4,11 @@
4
4
  # This command will automatically be run when you run "rails" with Rails gems
5
5
  # installed from the root of your application.
6
6
 
7
- ENGINE_ROOT = File.expand_path("../..", __FILE__)
8
- ENGINE_PATH = File.expand_path("../../lib/decidim/comments/engine", __FILE__)
7
+ ENGINE_ROOT = File.expand_path("..", __dir__)
8
+ ENGINE_PATH = File.expand_path("../lib/decidim/comments/engine", __dir__)
9
9
 
10
10
  # Set up gems listed in the Gemfile.
11
- ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile", __FILE__)
11
+ ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../Gemfile", __dir__)
12
12
  require "bundler/setup" if File.exist?(ENV["BUNDLE_GEMFILE"])
13
13
 
14
14
  require "rails/all"
@@ -19,6 +19,9 @@ ca:
19
19
  subject: Tens un nou comentari
20
20
  reply_created:
21
21
  subject: Tens una nova resposta del teu comentari
22
+ votes:
23
+ create:
24
+ error: Hi ha hagut errors en votar el comentari.
22
25
  components:
23
26
  add_comment_form:
24
27
  account_message: "<a href=\"%{sign_in_url}\">Entra amb el teu compte</a> o <a href=\"%{sign_up_url}\">registra't</a> per a deixar un comentari.\n"
@@ -37,6 +40,7 @@ ca:
37
40
  alignment:
38
41
  against: En contra
39
42
  in_favor: A favor
43
+ deleted_user: Usuari eliminat
40
44
  reply: Respondre
41
45
  report:
42
46
  action: Denuncia
@@ -49,6 +53,7 @@ ca:
49
53
  offensive: Conté racisme, sexisme, insults, atacs personals, amenaces de mort, peticions de suïcidi o qualsevol forma de discurs d'odi.
50
54
  spam: Conté "clickbait", publicitat o estafes.
51
55
  title: Denuncia un problema
56
+ verified_user_group: Organització verificada
52
57
  comment_order_selector:
53
58
  order:
54
59
  best_rated: Més ben valorats
@@ -20,6 +20,9 @@ en:
20
20
  subject: You have a new comment
21
21
  reply_created:
22
22
  subject: You have a new reply of your comment
23
+ votes:
24
+ create:
25
+ error: There's been errors when voting the comment.
23
26
  components:
24
27
  add_comment_form:
25
28
  account_message: '<a href="%{sign_in_url}">Sign in with your account</a> or <a href="%{sign_up_url}">sign up</a> to add your comment. '
@@ -38,6 +41,7 @@ en:
38
41
  alignment:
39
42
  against: Against
40
43
  in_favor: In favor
44
+ deleted_user: Deleted user
41
45
  reply: Reply
42
46
  report:
43
47
  action: Report
@@ -50,6 +54,7 @@ en:
50
54
  offensive: Contains racism, sexism, slurs, personal attacks, death threats, suicide requests or any form of hate speech.
51
55
  spam: Contains clickbait, advertising, scams or script bots.
52
56
  title: Report a problem
57
+ verified_user_group: Verified organization
53
58
  comment_order_selector:
54
59
  order:
55
60
  best_rated: Best rated