decidim-enhanced_textwork 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (441) hide show
  1. checksums.yaml +7 -0
  2. data/README.md +64 -0
  3. data/Rakefile +3 -0
  4. data/app/cells/decidim/enhanced_textwork/amendment/show.erb +14 -0
  5. data/app/cells/decidim/enhanced_textwork/amendment_cell.rb +39 -0
  6. data/app/cells/decidim/enhanced_textwork/collaborative_draft_cell.rb +49 -0
  7. data/app/cells/decidim/enhanced_textwork/collaborative_draft_link_to_paragraph/show.erb +13 -0
  8. data/app/cells/decidim/enhanced_textwork/collaborative_draft_link_to_paragraph_cell.rb +57 -0
  9. data/app/cells/decidim/enhanced_textwork/collaborative_draft_m/footer.erb +6 -0
  10. data/app/cells/decidim/enhanced_textwork/collaborative_draft_m/tags.erb +1 -0
  11. data/app/cells/decidim/enhanced_textwork/collaborative_draft_m_cell.rb +44 -0
  12. data/app/cells/decidim/enhanced_textwork/collaborative_drafts/reported_content/show.erb +3 -0
  13. data/app/cells/decidim/enhanced_textwork/collaborative_drafts/reported_content_cell.rb +15 -0
  14. data/app/cells/decidim/enhanced_textwork/comments/show.erb +33 -0
  15. data/app/cells/decidim/enhanced_textwork/comments_cell.rb +8 -0
  16. data/app/cells/decidim/enhanced_textwork/content_blocks/highlighted_paragraphs/elements.erb +5 -0
  17. data/app/cells/decidim/enhanced_textwork/content_blocks/highlighted_paragraphs/heading.erb +1 -0
  18. data/app/cells/decidim/enhanced_textwork/content_blocks/highlighted_paragraphs_cell.rb +19 -0
  19. data/app/cells/decidim/enhanced_textwork/cost_report/show.erb +35 -0
  20. data/app/cells/decidim/enhanced_textwork/cost_report_cell.rb +42 -0
  21. data/app/cells/decidim/enhanced_textwork/highlighted_paragraphs/show.erb +3 -0
  22. data/app/cells/decidim/enhanced_textwork/highlighted_paragraphs_cell.rb +25 -0
  23. data/app/cells/decidim/enhanced_textwork/highlighted_paragraphs_for_component/show.erb +19 -0
  24. data/app/cells/decidim/enhanced_textwork/highlighted_paragraphs_for_component_cell.rb +41 -0
  25. data/app/cells/decidim/enhanced_textwork/irreversible_action_modal/show.erb +27 -0
  26. data/app/cells/decidim/enhanced_textwork/irreversible_action_modal_cell.rb +80 -0
  27. data/app/cells/decidim/enhanced_textwork/paragraph_activity_cell.rb +35 -0
  28. data/app/cells/decidim/enhanced_textwork/paragraph_cell.rb +53 -0
  29. data/app/cells/decidim/enhanced_textwork/paragraph_link_to_collaborative_draft_cell.rb +26 -0
  30. data/app/cells/decidim/enhanced_textwork/paragraph_link_to_rejected_emendation/show.erb +9 -0
  31. data/app/cells/decidim/enhanced_textwork/paragraph_link_to_rejected_emendation_cell.rb +34 -0
  32. data/app/cells/decidim/enhanced_textwork/paragraph_linked_resources/show.erb +9 -0
  33. data/app/cells/decidim/enhanced_textwork/paragraph_linked_resources_cell.rb +14 -0
  34. data/app/cells/decidim/enhanced_textwork/paragraph_m/footer.erb +26 -0
  35. data/app/cells/decidim/enhanced_textwork/paragraph_m/tags.erb +1 -0
  36. data/app/cells/decidim/enhanced_textwork/paragraph_m_cell.rb +152 -0
  37. data/app/cells/decidim/enhanced_textwork/paragraph_tags/show.erb +33 -0
  38. data/app/cells/decidim/enhanced_textwork/paragraph_tags_cell.rb +35 -0
  39. data/app/cells/decidim/enhanced_textwork/paragraphs_picker/paragraphs.erb +12 -0
  40. data/app/cells/decidim/enhanced_textwork/paragraphs_picker/show.erb +14 -0
  41. data/app/cells/decidim/enhanced_textwork/paragraphs_picker_cell.rb +72 -0
  42. data/app/cells/decidim/enhanced_textwork/participatory_text_paragraph/buttons.erb +33 -0
  43. data/app/cells/decidim/enhanced_textwork/participatory_text_paragraph/show.erb +38 -0
  44. data/app/cells/decidim/enhanced_textwork/participatory_text_paragraph_cell.rb +104 -0
  45. data/app/cells/decidim/enhanced_textwork/reported_content/show.erb +4 -0
  46. data/app/cells/decidim/enhanced_textwork/reported_content_cell.rb +13 -0
  47. data/app/commands/decidim/enhanced_textwork/accept_access_to_collaborative_draft.rb +70 -0
  48. data/app/commands/decidim/enhanced_textwork/admin/answer_paragraph.rb +74 -0
  49. data/app/commands/decidim/enhanced_textwork/admin/assign_paragraphs_to_valuator.rb +61 -0
  50. data/app/commands/decidim/enhanced_textwork/admin/create_paragraph.rb +97 -0
  51. data/app/commands/decidim/enhanced_textwork/admin/create_paragraph_note.rb +67 -0
  52. data/app/commands/decidim/enhanced_textwork/admin/destroy_paragraph.rb +32 -0
  53. data/app/commands/decidim/enhanced_textwork/admin/discard_participatory_text.rb +40 -0
  54. data/app/commands/decidim/enhanced_textwork/admin/import_from_editor_participatory_text.rb +53 -0
  55. data/app/commands/decidim/enhanced_textwork/admin/import_paragraphs.rb +101 -0
  56. data/app/commands/decidim/enhanced_textwork/admin/import_participatory_text.rb +55 -0
  57. data/app/commands/decidim/enhanced_textwork/admin/merge_paragraphs.rb +69 -0
  58. data/app/commands/decidim/enhanced_textwork/admin/notify_paragraph_answer.rb +85 -0
  59. data/app/commands/decidim/enhanced_textwork/admin/publish_answers.rb +67 -0
  60. data/app/commands/decidim/enhanced_textwork/admin/publish_participatory_text.rb +81 -0
  61. data/app/commands/decidim/enhanced_textwork/admin/split_paragraphs.rb +67 -0
  62. data/app/commands/decidim/enhanced_textwork/admin/unassign_paragraphs_from_valuator.rb +62 -0
  63. data/app/commands/decidim/enhanced_textwork/admin/update_paragraph.rb +86 -0
  64. data/app/commands/decidim/enhanced_textwork/admin/update_paragraph_category.rb +68 -0
  65. data/app/commands/decidim/enhanced_textwork/admin/update_paragraph_scope.rb +75 -0
  66. data/app/commands/decidim/enhanced_textwork/admin/update_participatory_text.rb +68 -0
  67. data/app/commands/decidim/enhanced_textwork/create_collaborative_draft.rb +81 -0
  68. data/app/commands/decidim/enhanced_textwork/create_paragraph.rb +106 -0
  69. data/app/commands/decidim/enhanced_textwork/destroy_paragraph.rb +33 -0
  70. data/app/commands/decidim/enhanced_textwork/gallery_methods.rb +18 -0
  71. data/app/commands/decidim/enhanced_textwork/hashtags_methods.rb +36 -0
  72. data/app/commands/decidim/enhanced_textwork/publish_collaborative_draft.rb +93 -0
  73. data/app/commands/decidim/enhanced_textwork/publish_paragraph.rb +105 -0
  74. data/app/commands/decidim/enhanced_textwork/reject_access_to_collaborative_draft.rb +62 -0
  75. data/app/commands/decidim/enhanced_textwork/request_access_to_collaborative_draft.rb +49 -0
  76. data/app/commands/decidim/enhanced_textwork/unvote_paragraph.rb +65 -0
  77. data/app/commands/decidim/enhanced_textwork/update_collaborative_draft.rb +63 -0
  78. data/app/commands/decidim/enhanced_textwork/update_paragraph.rb +135 -0
  79. data/app/commands/decidim/enhanced_textwork/vote_paragraph.rb +77 -0
  80. data/app/commands/decidim/enhanced_textwork/withdraw_collaborative_draft.rb +65 -0
  81. data/app/commands/decidim/enhanced_textwork/withdraw_paragraph.rb +50 -0
  82. data/app/controllers/concerns/decidim/enhanced_textwork/admin/filterable.rb +82 -0
  83. data/app/controllers/concerns/decidim/enhanced_textwork/admin/picker.rb +21 -0
  84. data/app/controllers/concerns/decidim/enhanced_textwork/collaborative_orderable.rb +42 -0
  85. data/app/controllers/concerns/decidim/enhanced_textwork/orderable.rb +78 -0
  86. data/app/controllers/decidim/enhanced_textwork/admin/application_controller.rb +16 -0
  87. data/app/controllers/decidim/enhanced_textwork/admin/paragraph_answers_controller.rb +50 -0
  88. data/app/controllers/decidim/enhanced_textwork/admin/paragraph_notes_controller.rb +39 -0
  89. data/app/controllers/decidim/enhanced_textwork/admin/paragraphs_controller.rb +237 -0
  90. data/app/controllers/decidim/enhanced_textwork/admin/paragraphs_imports_controller.rb +33 -0
  91. data/app/controllers/decidim/enhanced_textwork/admin/paragraphs_merges_controller.rb +30 -0
  92. data/app/controllers/decidim/enhanced_textwork/admin/paragraphs_splits_controller.rb +30 -0
  93. data/app/controllers/decidim/enhanced_textwork/admin/participatory_texts_controller.rb +128 -0
  94. data/app/controllers/decidim/enhanced_textwork/admin/valuation_assignments_controller.rb +58 -0
  95. data/app/controllers/decidim/enhanced_textwork/application_controller.rb +31 -0
  96. data/app/controllers/decidim/enhanced_textwork/collaborative_draft_collaborator_requests_controller.rb +53 -0
  97. data/app/controllers/decidim/enhanced_textwork/collaborative_drafts_controller.rb +161 -0
  98. data/app/controllers/decidim/enhanced_textwork/paragraph_votes_controller.rb +65 -0
  99. data/app/controllers/decidim/enhanced_textwork/paragraphs_controller.rb +316 -0
  100. data/app/controllers/decidim/enhanced_textwork/versions_controller.rb +21 -0
  101. data/app/controllers/decidim/enhanced_textwork/widgets_controller.rb +19 -0
  102. data/app/events/decidim/enhanced_textwork/accepted_paragraph_event.rb +17 -0
  103. data/app/events/decidim/enhanced_textwork/admin/paragraph_note_created_event.rb +27 -0
  104. data/app/events/decidim/enhanced_textwork/admin/update_paragraph_category_event.rb +11 -0
  105. data/app/events/decidim/enhanced_textwork/admin/update_paragraph_scope_event.rb +11 -0
  106. data/app/events/decidim/enhanced_textwork/collaborative_draft_access_accepted_event.rb +8 -0
  107. data/app/events/decidim/enhanced_textwork/collaborative_draft_access_rejected_event.rb +8 -0
  108. data/app/events/decidim/enhanced_textwork/collaborative_draft_access_request_event.rb +27 -0
  109. data/app/events/decidim/enhanced_textwork/collaborative_draft_access_requested_event.rb +8 -0
  110. data/app/events/decidim/enhanced_textwork/collaborative_draft_access_requester_accepted_event.rb +8 -0
  111. data/app/events/decidim/enhanced_textwork/collaborative_draft_access_requester_rejected_event.rb +8 -0
  112. data/app/events/decidim/enhanced_textwork/collaborative_draft_withdrawn_event.rb +29 -0
  113. data/app/events/decidim/enhanced_textwork/creation_enabled_event.rb +8 -0
  114. data/app/events/decidim/enhanced_textwork/endorsing_enabled_event.rb +8 -0
  115. data/app/events/decidim/enhanced_textwork/evaluating_paragraph_event.rb +11 -0
  116. data/app/events/decidim/enhanced_textwork/paragraph_endorsed_event.rb +33 -0
  117. data/app/events/decidim/enhanced_textwork/paragraph_mentioned_event.rb +21 -0
  118. data/app/events/decidim/enhanced_textwork/publish_paragraph_event.rb +25 -0
  119. data/app/events/decidim/enhanced_textwork/rejected_paragraph_event.rb +17 -0
  120. data/app/events/decidim/enhanced_textwork/voting_enabled_event.rb +8 -0
  121. data/app/forms/decidim/enhanced_textwork/accept_access_to_collaborative_draft_form.rb +10 -0
  122. data/app/forms/decidim/enhanced_textwork/access_to_collaborative_draft_form.rb +33 -0
  123. data/app/forms/decidim/enhanced_textwork/admin/import_editor_participatory_text_form.rb +35 -0
  124. data/app/forms/decidim/enhanced_textwork/admin/import_participatory_text_form.rb +68 -0
  125. data/app/forms/decidim/enhanced_textwork/admin/paragraph_answer_form.rb +44 -0
  126. data/app/forms/decidim/enhanced_textwork/admin/paragraph_base_form.rb +137 -0
  127. data/app/forms/decidim/enhanced_textwork/admin/paragraph_form.rb +32 -0
  128. data/app/forms/decidim/enhanced_textwork/admin/paragraph_note_form.rb +16 -0
  129. data/app/forms/decidim/enhanced_textwork/admin/paragraphs_fork_form.rb +63 -0
  130. data/app/forms/decidim/enhanced_textwork/admin/paragraphs_import_form.rb +67 -0
  131. data/app/forms/decidim/enhanced_textwork/admin/paragraphs_merge_form.rb +13 -0
  132. data/app/forms/decidim/enhanced_textwork/admin/paragraphs_split_form.rb +12 -0
  133. data/app/forms/decidim/enhanced_textwork/admin/participatory_text_paragraph_form.rb +20 -0
  134. data/app/forms/decidim/enhanced_textwork/admin/preview_participatory_text_form.rb +21 -0
  135. data/app/forms/decidim/enhanced_textwork/admin/valuation_assignment_form.rb +37 -0
  136. data/app/forms/decidim/enhanced_textwork/collaborative_draft_form.rb +20 -0
  137. data/app/forms/decidim/enhanced_textwork/paragraph_form.rb +126 -0
  138. data/app/forms/decidim/enhanced_textwork/paragraph_wizard_create_step_form.rb +41 -0
  139. data/app/forms/decidim/enhanced_textwork/reject_access_to_collaborative_draft_form.rb +9 -0
  140. data/app/forms/decidim/enhanced_textwork/request_access_to_collaborative_draft_form.rb +20 -0
  141. data/app/helpers/decidim/enhanced_textwork/admin/filterable_helper.rb +17 -0
  142. data/app/helpers/decidim/enhanced_textwork/admin/paragraph_bulk_actions_helper.rb +35 -0
  143. data/app/helpers/decidim/enhanced_textwork/admin/paragraph_rankings_helper.rb +63 -0
  144. data/app/helpers/decidim/enhanced_textwork/admin/paragraphs_helper.rb +144 -0
  145. data/app/helpers/decidim/enhanced_textwork/admin/paragraphs_picker_helper.rb +30 -0
  146. data/app/helpers/decidim/enhanced_textwork/application_helper.rb +191 -0
  147. data/app/helpers/decidim/enhanced_textwork/collaborative_draft_cells_helper.rb +48 -0
  148. data/app/helpers/decidim/enhanced_textwork/collaborative_draft_helper.rb +29 -0
  149. data/app/helpers/decidim/enhanced_textwork/control_version_helper.rb +12 -0
  150. data/app/helpers/decidim/enhanced_textwork/map_helper.rb +48 -0
  151. data/app/helpers/decidim/enhanced_textwork/paragraph_cells_helper.rb +75 -0
  152. data/app/helpers/decidim/enhanced_textwork/paragraph_votes_helper.rb +103 -0
  153. data/app/helpers/decidim/enhanced_textwork/paragraph_wizard_helper.rb +140 -0
  154. data/app/helpers/decidim/enhanced_textwork/paragraphs_helper.rb +63 -0
  155. data/app/helpers/decidim/enhanced_textwork/participatory_texts_helper.rb +49 -0
  156. data/app/jobs/decidim/enhanced_textwork/notify_paragraphs_mentioned_job.rb +27 -0
  157. data/app/jobs/decidim/enhanced_textwork/settings_change_job.rb +50 -0
  158. data/app/models/decidim/enhanced_textwork/application_record.rb +10 -0
  159. data/app/models/decidim/enhanced_textwork/collaborative_draft.rb +73 -0
  160. data/app/models/decidim/enhanced_textwork/collaborative_draft_collaborator_request.rb +13 -0
  161. data/app/models/decidim/enhanced_textwork/paragraph.rb +411 -0
  162. data/app/models/decidim/enhanced_textwork/paragraph_note.rb +20 -0
  163. data/app/models/decidim/enhanced_textwork/paragraph_vote.rb +50 -0
  164. data/app/models/decidim/enhanced_textwork/participatory_text.rb +16 -0
  165. data/app/models/decidim/enhanced_textwork/valuation_assignment.rb +24 -0
  166. data/app/packs/documents/decidim/enhanced_textwork/participatory_texts/participatory_text.md +52 -0
  167. data/app/packs/documents/decidim/enhanced_textwork/participatory_texts/participatory_text.odt +0 -0
  168. data/app/packs/entrypoints/decidim_enhanced_textwork.js +17 -0
  169. data/app/packs/entrypoints/decidim_enhanced_textwork_admin.js +3 -0
  170. data/app/packs/images/decidim/enhanced_textwork/decidim_paragraphs.svg +1 -0
  171. data/app/packs/images/decidim/gamification/badges/decidim_gamification_badges_accepted_paragraphs.svg +1 -0
  172. data/app/packs/images/decidim/gamification/badges/decidim_gamification_badges_paragraph_votes.svg +1 -0
  173. data/app/packs/images/decidim/gamification/badges/decidim_gamification_badges_paragraphs.svg +1 -0
  174. data/app/packs/src/decidim/enhanced_textwork/add_paragraph.js +49 -0
  175. data/app/packs/src/decidim/enhanced_textwork/admin/paragraphs.js +143 -0
  176. data/app/packs/src/decidim/enhanced_textwork/admin/paragraphs_form.js +29 -0
  177. data/app/packs/src/decidim/enhanced_textwork/admin/paragraphs_picker.js +35 -0
  178. data/app/packs/src/decidim/enhanced_textwork/toggle_element.js +21 -0
  179. data/app/packs/src/decidim/enhanced_textwork/utils.js +11 -0
  180. data/app/packs/stylesheets/decidim/enhanced_textwork/_paragraphs.scss +208 -0
  181. data/app/packs/stylesheets/decidim/enhanced_textwork/paragraphs/_preview.scss +3 -0
  182. data/app/permissions/decidim/enhanced_textwork/admin/permissions.rb +147 -0
  183. data/app/permissions/decidim/enhanced_textwork/permissions.rb +163 -0
  184. data/app/presenters/decidim/enhanced_textwork/admin_log/paragraph_note_presenter.rb +39 -0
  185. data/app/presenters/decidim/enhanced_textwork/admin_log/paragraph_presenter.rb +51 -0
  186. data/app/presenters/decidim/enhanced_textwork/admin_log/valuation_assignment_presenter.rb +51 -0
  187. data/app/presenters/decidim/enhanced_textwork/admin_log/value_types/paragraph_state_presenter.rb +17 -0
  188. data/app/presenters/decidim/enhanced_textwork/admin_log/value_types/paragraph_title_body_presenter.rb +23 -0
  189. data/app/presenters/decidim/enhanced_textwork/admin_log/value_types/valuator_role_user_presenter.rb +19 -0
  190. data/app/presenters/decidim/enhanced_textwork/collaborative_draft_presenter.rb +25 -0
  191. data/app/presenters/decidim/enhanced_textwork/log/resource_presenter.rb +22 -0
  192. data/app/presenters/decidim/enhanced_textwork/log/valuation_assignment_presenter.rb +22 -0
  193. data/app/presenters/decidim/enhanced_textwork/official_author_presenter.rb +14 -0
  194. data/app/presenters/decidim/enhanced_textwork/paragraph_presenter.rb +146 -0
  195. data/app/queries/decidim/enhanced_textwork/filtered_paragraphs.rb +37 -0
  196. data/app/queries/decidim/enhanced_textwork/metrics/accepted_paragraphs_metric_manage.rb +32 -0
  197. data/app/queries/decidim/enhanced_textwork/metrics/endorsements_metric_manage.rb +58 -0
  198. data/app/queries/decidim/enhanced_textwork/metrics/paragraph_followers_metric_measure.rb +58 -0
  199. data/app/queries/decidim/enhanced_textwork/metrics/paragraph_participants_metric_measure.rb +74 -0
  200. data/app/queries/decidim/enhanced_textwork/metrics/paragraphs_metric_manage.rb +48 -0
  201. data/app/queries/decidim/enhanced_textwork/metrics/votes_metric_manage.rb +52 -0
  202. data/app/queries/decidim/enhanced_textwork/similar_paragraphs.rb +67 -0
  203. data/app/services/decidim/enhanced_textwork/collaborative_draft_search.rb +59 -0
  204. data/app/services/decidim/enhanced_textwork/diff_renderer.rb +74 -0
  205. data/app/services/decidim/enhanced_textwork/paragraph_builder.rb +132 -0
  206. data/app/services/decidim/enhanced_textwork/paragraph_search.rb +85 -0
  207. data/app/validators/paragraph_length_validator.rb +40 -0
  208. data/app/views/decidim/enhanced_textwork/admin/paragraph_answers/_form.html.erb +35 -0
  209. data/app/views/decidim/enhanced_textwork/admin/paragraph_notes/_form.html.erb +8 -0
  210. data/app/views/decidim/enhanced_textwork/admin/paragraph_notes/_paragraph_notes.html.erb +45 -0
  211. data/app/views/decidim/enhanced_textwork/admin/paragraphs/_bulk-actions.html.erb +33 -0
  212. data/app/views/decidim/enhanced_textwork/admin/paragraphs/_form.html.erb +101 -0
  213. data/app/views/decidim/enhanced_textwork/admin/paragraphs/_js-callout.html.erb +6 -0
  214. data/app/views/decidim/enhanced_textwork/admin/paragraphs/_paragraph-tr.html.erb +76 -0
  215. data/app/views/decidim/enhanced_textwork/admin/paragraphs/bulk_actions/_assign_to_valuator.html.erb +15 -0
  216. data/app/views/decidim/enhanced_textwork/admin/paragraphs/bulk_actions/_dropdown.html.erb +56 -0
  217. data/app/views/decidim/enhanced_textwork/admin/paragraphs/bulk_actions/_merge.html.erb +15 -0
  218. data/app/views/decidim/enhanced_textwork/admin/paragraphs/bulk_actions/_publish_answers.html.erb +14 -0
  219. data/app/views/decidim/enhanced_textwork/admin/paragraphs/bulk_actions/_recategorize.html.erb +15 -0
  220. data/app/views/decidim/enhanced_textwork/admin/paragraphs/bulk_actions/_scope-change.html.erb +25 -0
  221. data/app/views/decidim/enhanced_textwork/admin/paragraphs/bulk_actions/_split.html.erb +15 -0
  222. data/app/views/decidim/enhanced_textwork/admin/paragraphs/bulk_actions/_unassign_from_valuator.html.erb +15 -0
  223. data/app/views/decidim/enhanced_textwork/admin/paragraphs/edit.html.erb +7 -0
  224. data/app/views/decidim/enhanced_textwork/admin/paragraphs/index.html.erb +84 -0
  225. data/app/views/decidim/enhanced_textwork/admin/paragraphs/new.html.erb +7 -0
  226. data/app/views/decidim/enhanced_textwork/admin/paragraphs/publish_answers.js.erb +12 -0
  227. data/app/views/decidim/enhanced_textwork/admin/paragraphs/show.html.erb +186 -0
  228. data/app/views/decidim/enhanced_textwork/admin/paragraphs/update_category.js.erb +26 -0
  229. data/app/views/decidim/enhanced_textwork/admin/paragraphs/update_scope.js.erb +27 -0
  230. data/app/views/decidim/enhanced_textwork/admin/paragraphs_imports/new.html.erb +37 -0
  231. data/app/views/decidim/enhanced_textwork/admin/participatory_texts/_article-preview.html.erb +16 -0
  232. data/app/views/decidim/enhanced_textwork/admin/participatory_texts/_bulk-actions.html.erb +3 -0
  233. data/app/views/decidim/enhanced_textwork/admin/participatory_texts/index.html.erb +55 -0
  234. data/app/views/decidim/enhanced_textwork/admin/participatory_texts/new_editor.html.erb +39 -0
  235. data/app/views/decidim/enhanced_textwork/admin/participatory_texts/new_import.html.erb +39 -0
  236. data/app/views/decidim/enhanced_textwork/collaborative_drafts/_accept_request_access_form.html.erb +8 -0
  237. data/app/views/decidim/enhanced_textwork/collaborative_drafts/_collaborative_drafts.html.erb +16 -0
  238. data/app/views/decidim/enhanced_textwork/collaborative_drafts/_collaborator_requests.html.erb +20 -0
  239. data/app/views/decidim/enhanced_textwork/collaborative_drafts/_count.html.erb +1 -0
  240. data/app/views/decidim/enhanced_textwork/collaborative_drafts/_edit_form_fields.html.erb +83 -0
  241. data/app/views/decidim/enhanced_textwork/collaborative_drafts/_filters.html.erb +32 -0
  242. data/app/views/decidim/enhanced_textwork/collaborative_drafts/_filters_small_view.html.erb +18 -0
  243. data/app/views/decidim/enhanced_textwork/collaborative_drafts/_new_collaborative_draft_button.html.erb +11 -0
  244. data/app/views/decidim/enhanced_textwork/collaborative_drafts/_reject_request_access_form.html.erb +10 -0
  245. data/app/views/decidim/enhanced_textwork/collaborative_drafts/_request_access_form.html.erb +7 -0
  246. data/app/views/decidim/enhanced_textwork/collaborative_drafts/_wizard_aside.html.erb +13 -0
  247. data/app/views/decidim/enhanced_textwork/collaborative_drafts/_wizard_header.html.erb +14 -0
  248. data/app/views/decidim/enhanced_textwork/collaborative_drafts/edit.html.erb +31 -0
  249. data/app/views/decidim/enhanced_textwork/collaborative_drafts/index.html.erb +23 -0
  250. data/app/views/decidim/enhanced_textwork/collaborative_drafts/index.js.erb +10 -0
  251. data/app/views/decidim/enhanced_textwork/collaborative_drafts/new.html.erb +24 -0
  252. data/app/views/decidim/enhanced_textwork/collaborative_drafts/show.html.erb +128 -0
  253. data/app/views/decidim/enhanced_textwork/paragraph_votes/update_buttons_and_counters.js.erb +41 -0
  254. data/app/views/decidim/enhanced_textwork/paragraphs/_count.html.erb +1 -0
  255. data/app/views/decidim/enhanced_textwork/paragraphs/_dynamic_map_instructions.html.erb +4 -0
  256. data/app/views/decidim/enhanced_textwork/paragraphs/_edit_form_fields.html.erb +115 -0
  257. data/app/views/decidim/enhanced_textwork/paragraphs/_endorsements_card_row.html.erb +0 -0
  258. data/app/views/decidim/enhanced_textwork/paragraphs/_filters.html.erb +48 -0
  259. data/app/views/decidim/enhanced_textwork/paragraphs/_filters_small_view.html.erb +18 -0
  260. data/app/views/decidim/enhanced_textwork/paragraphs/_linked_paragraphs.html.erb +34 -0
  261. data/app/views/decidim/enhanced_textwork/paragraphs/_paragraph.html.erb +1 -0
  262. data/app/views/decidim/enhanced_textwork/paragraphs/_paragraph_badge.html.erb +3 -0
  263. data/app/views/decidim/enhanced_textwork/paragraphs/_paragraph_similar.html.erb +22 -0
  264. data/app/views/decidim/enhanced_textwork/paragraphs/_paragraphs.html.erb +46 -0
  265. data/app/views/decidim/enhanced_textwork/paragraphs/_remaining_votes_count.html.erb +3 -0
  266. data/app/views/decidim/enhanced_textwork/paragraphs/_vote_button.html.erb +61 -0
  267. data/app/views/decidim/enhanced_textwork/paragraphs/_votes_count.html.erb +18 -0
  268. data/app/views/decidim/enhanced_textwork/paragraphs/_voting_rules.html.erb +50 -0
  269. data/app/views/decidim/enhanced_textwork/paragraphs/_wizard_aside.html.erb +20 -0
  270. data/app/views/decidim/enhanced_textwork/paragraphs/_wizard_header.html.erb +42 -0
  271. data/app/views/decidim/enhanced_textwork/paragraphs/compare.html.erb +23 -0
  272. data/app/views/decidim/enhanced_textwork/paragraphs/complete.html.erb +24 -0
  273. data/app/views/decidim/enhanced_textwork/paragraphs/edit.html.erb +31 -0
  274. data/app/views/decidim/enhanced_textwork/paragraphs/edit_draft.html.erb +26 -0
  275. data/app/views/decidim/enhanced_textwork/paragraphs/index.html.erb +56 -0
  276. data/app/views/decidim/enhanced_textwork/paragraphs/index.js.erb +10 -0
  277. data/app/views/decidim/enhanced_textwork/paragraphs/new.html.erb +38 -0
  278. data/app/views/decidim/enhanced_textwork/paragraphs/participatory_texts/_index.html.erb +20 -0
  279. data/app/views/decidim/enhanced_textwork/paragraphs/participatory_texts/_overview.html.erb +35 -0
  280. data/app/views/decidim/enhanced_textwork/paragraphs/participatory_texts/_paragraph_vote_button.html.erb +53 -0
  281. data/app/views/decidim/enhanced_textwork/paragraphs/participatory_texts/_paragraph_vote_button_chevron.html.erb +72 -0
  282. data/app/views/decidim/enhanced_textwork/paragraphs/participatory_texts/_paragraph_votes_count.html.erb +41 -0
  283. data/app/views/decidim/enhanced_textwork/paragraphs/participatory_texts/_view_index.html.erb +10 -0
  284. data/app/views/decidim/enhanced_textwork/paragraphs/participatory_texts/participatory_text.html.erb +29 -0
  285. data/app/views/decidim/enhanced_textwork/paragraphs/preview.html.erb +41 -0
  286. data/app/views/decidim/enhanced_textwork/paragraphs/show.html.erb +143 -0
  287. data/app/views/decidim/enhanced_textwork/versions/index.html.erb +16 -0
  288. data/app/views/decidim/enhanced_textwork/versions/show.html.erb +18 -0
  289. data/config/assets.rb +10 -0
  290. data/config/locales/de.yml +927 -0
  291. data/config/locales/en.yml +967 -0
  292. data/config/locales/todo/am-ET.yml +1 -0
  293. data/config/locales/todo/ar-SA.yml +801 -0
  294. data/config/locales/todo/ar.yml +791 -0
  295. data/config/locales/todo/bg-BG.yml +237 -0
  296. data/config/locales/todo/bg.yml +238 -0
  297. data/config/locales/todo/ca.yml +908 -0
  298. data/config/locales/todo/cs-CZ.yml +787 -0
  299. data/config/locales/todo/cs.yml +969 -0
  300. data/config/locales/todo/da-DK.yml +1 -0
  301. data/config/locales/todo/da.yml +1 -0
  302. data/config/locales/todo/el-GR.yml +1 -0
  303. data/config/locales/todo/el.yml +848 -0
  304. data/config/locales/todo/eo-UY.yml +1 -0
  305. data/config/locales/todo/eo.yml +1 -0
  306. data/config/locales/todo/es-MX.yml +908 -0
  307. data/config/locales/todo/es-PY.yml +908 -0
  308. data/config/locales/todo/es.yml +908 -0
  309. data/config/locales/todo/et-EE.yml +1 -0
  310. data/config/locales/todo/et.yml +1 -0
  311. data/config/locales/todo/eu.yml +717 -0
  312. data/config/locales/todo/fi-pl.yml +763 -0
  313. data/config/locales/todo/fi-plain.yml +920 -0
  314. data/config/locales/todo/fi.yml +920 -0
  315. data/config/locales/todo/fr-CA.yml +936 -0
  316. data/config/locales/todo/fr-LU.yml +903 -0
  317. data/config/locales/todo/fr.yml +936 -0
  318. data/config/locales/todo/ga-IE.yml +275 -0
  319. data/config/locales/todo/gl.yml +808 -0
  320. data/config/locales/todo/hr-HR.yml +1 -0
  321. data/config/locales/todo/hr.yml +1 -0
  322. data/config/locales/todo/hu.yml +847 -0
  323. data/config/locales/todo/id-ID.yml +704 -0
  324. data/config/locales/todo/is-IS.yml +269 -0
  325. data/config/locales/todo/is.yml +274 -0
  326. data/config/locales/todo/it.yml +908 -0
  327. data/config/locales/todo/ja.yml +922 -0
  328. data/config/locales/todo/ko-KR.yml +1 -0
  329. data/config/locales/todo/ko.yml +1 -0
  330. data/config/locales/todo/lb-LU.yml +1 -0
  331. data/config/locales/todo/lb.yml +40 -0
  332. data/config/locales/todo/lt-LT.yml +1 -0
  333. data/config/locales/todo/lt.yml +1 -0
  334. data/config/locales/todo/lv.yml +838 -0
  335. data/config/locales/todo/mt-MT.yml +1 -0
  336. data/config/locales/todo/mt.yml +1 -0
  337. data/config/locales/todo/nl.yml +882 -0
  338. data/config/locales/todo/no.yml +770 -0
  339. data/config/locales/todo/om-ET.yml +1 -0
  340. data/config/locales/todo/pl.yml +927 -0
  341. data/config/locales/todo/pt-BR.yml +908 -0
  342. data/config/locales/todo/pt.yml +945 -0
  343. data/config/locales/todo/ro-RO.yml +886 -0
  344. data/config/locales/todo/ru.yml +379 -0
  345. data/config/locales/todo/si-LK.yml +1 -0
  346. data/config/locales/todo/sk-SK.yml +896 -0
  347. data/config/locales/todo/sk.yml +851 -0
  348. data/config/locales/todo/sl.yml +26 -0
  349. data/config/locales/todo/so-SO.yml +1 -0
  350. data/config/locales/todo/sr-CS.yml +125 -0
  351. data/config/locales/todo/sv.yml +908 -0
  352. data/config/locales/todo/sw-KE.yml +1 -0
  353. data/config/locales/todo/ti-ER.yml +1 -0
  354. data/config/locales/todo/tr-TR.yml +890 -0
  355. data/config/locales/todo/uk.yml +379 -0
  356. data/config/locales/todo/vi-VN.yml +1 -0
  357. data/config/locales/todo/vi.yml +1 -0
  358. data/config/locales/todo/zh-CN.yml +857 -0
  359. data/config/locales/todo/zh-TW.yml +1 -0
  360. data/db/migrate/20161212110850_create_decidim_paragraphs.rb +16 -0
  361. data/db/migrate/20170112115253_create_paragraph_votes.rb +14 -0
  362. data/db/migrate/20170113114245_add_enhanced_textwork_text_search_indexes.rb +8 -0
  363. data/db/migrate/20170118120151_add_counter_cache_votes_to_paragraphs.rb +7 -0
  364. data/db/migrate/20170120151202_add_user_group_id_to_paragraphs.rb +7 -0
  365. data/db/migrate/20170131092413_add_answers_to_paragraphs.rb +9 -0
  366. data/db/migrate/20170205082832_add_index_to_decidim_enhanced_textwork_paragraphs_paragraph_votes_count.rb +9 -0
  367. data/db/migrate/20170215113152_create_paragraph_reports.rb +16 -0
  368. data/db/migrate/20170215131720_add_report_count_to_paragraphs.rb +7 -0
  369. data/db/migrate/20170215132030_add_reference_to_paragraphs.rb +13 -0
  370. data/db/migrate/20170220152416_add_hidden_at_to_paragraphs.rb +7 -0
  371. data/db/migrate/20170228105156_add_geolocalization_fields_to_paragraphs.rb +9 -0
  372. data/db/migrate/20170307085300_migrate_paragraph_reports_data_to_reports.rb +24 -0
  373. data/db/migrate/20170410073742_remove_not_null_reference_paragraphs.rb +7 -0
  374. data/db/migrate/20170612101809_migrate_paragraphs_category.rb +15 -0
  375. data/db/migrate/20171201115434_create_paragraph_endorsements.rb +16 -0
  376. data/db/migrate/20171201122623_add_counter_cache_endorsements_to_paragraphs.rb +8 -0
  377. data/db/migrate/20171212102250_enable_pg_trgm_extension_for_paragraphs.rb +18 -0
  378. data/db/migrate/20171220084719_add_published_at_to_paragraphs.rb +14 -0
  379. data/db/migrate/20180111110204_create_decidim_paragraph_notes.rb +15 -0
  380. data/db/migrate/20180115155220_add_index_created_at_paragraph_notes.rb +7 -0
  381. data/db/migrate/20180305133811_rename_features_to_components_at_paragraphs.rb +11 -0
  382. data/db/migrate/20180326091532_create_decidim_enhanced_textwork_collaborative_drafts.rb +29 -0
  383. data/db/migrate/20180413135249_fix_nil_threshold_per_paragraph.rb +18 -0
  384. data/db/migrate/20180529101323_add_counter_cache_coauthorships_to_paragraphs.rb +8 -0
  385. data/db/migrate/20180529110230_move_enhanced_textwork_authorships_to_coauthorships.rb +28 -0
  386. data/db/migrate/20180529110830_remove_authorships_from_paragraphs.rb +8 -0
  387. data/db/migrate/20180613151121_create_enhanced_textwork_collaborative_draft_collaborator_requests.rb +12 -0
  388. data/db/migrate/20180711074134_add_enhanced_textwork_counter_cache_coauthorships_to_collaborative_drafts.rb +7 -0
  389. data/db/migrate/20180711075004_remove_index_counter_cache_coauthorships_to_paragraphs.rb +7 -0
  390. data/db/migrate/20180927111721_create_enhanced_textwork_participatory_texts.rb +13 -0
  391. data/db/migrate/20180930125321_add_participatory_text_level_to_paragraphs.rb +7 -0
  392. data/db/migrate/20180930125321_add_position_to_paragraphs.rb +7 -0
  393. data/db/migrate/20181003074440_fix_user_groups_ids_in_paragraphs_endorsements.rb +20 -0
  394. data/db/migrate/20181010114622_add_enhanced_textwork_temporary_votes.rb +9 -0
  395. data/db/migrate/20181016132225_add_enhanced_textwork_organization_as_author.rb +13 -0
  396. data/db/migrate/20181017084221_make_author_polymorhpic_for_paragraph_endorsements.rb +31 -0
  397. data/db/migrate/20181026073215_add_enhanced_textwork_created_in_meeting.rb +7 -0
  398. data/db/migrate/20190215113158_use_enhanced_textwork_md5_indexes.rb +17 -0
  399. data/db/migrate/20191206154128_add_endorsements_counter_cache_to_paragraphs.rb +7 -0
  400. data/db/migrate/20200120215928_move_paragraph_endorsements_to_core_endorsements.rb +54 -0
  401. data/db/migrate/20200120230130_drop_paragraph_endorsements.rb +8 -0
  402. data/db/migrate/20200203111239_add_paragraph_valuation_assignments.rb +12 -0
  403. data/db/migrate/20200210135152_add_costs_to_paragraphs.rb +9 -0
  404. data/db/migrate/20200212120110_sync_paragraphs_state_with_amendments_state.rb +28 -0
  405. data/db/migrate/20200227175922_add_state_published_at_to_paragraphs.rb +7 -0
  406. data/db/migrate/20200306123652_publish_existing_paragraphs_state.rb +15 -0
  407. data/db/migrate/20200708091228_move_paragraphs_fields_to_i18n.rb +86 -0
  408. data/db/migrate/20200730131631_move_paragraph_endorsed_event_notifications_to_resource_endorsed_event.rb +20 -0
  409. data/db/migrate/20200827154156_add_commentable_counter_cache_to_paragraphs.rb +12 -0
  410. data/db/migrate/20201002085508_fix_paragraphs_data.rb +36 -0
  411. data/db/migrate/20210127115628_fix_answered_paragraphs_after_copy.rb +14 -0
  412. data/db/migrate/20210310102839_add_followable_counter_cache_to_paragraphs.rb +16 -0
  413. data/db/migrate/20210310120812_add_enhanced_textwork_followable_counter_cache_to_collaborative_drafts.rb +16 -0
  414. data/db/migrate/20210318082934_fix_counters_for_copied_paragraphs.rb +19 -0
  415. data/lib/decidim/api/paragraph_input_filter.rb +29 -0
  416. data/lib/decidim/api/paragraph_input_sort.rb +20 -0
  417. data/lib/decidim/api/paragraph_type.rb +56 -0
  418. data/lib/decidim/api/paragraphs_type.rb +43 -0
  419. data/lib/decidim/content_parsers/paragraph_parser.rb +101 -0
  420. data/lib/decidim/content_renderers/paragraph_renderer.rb +33 -0
  421. data/lib/decidim/enhanced_textwork/admin.rb +10 -0
  422. data/lib/decidim/enhanced_textwork/admin_engine.rb +52 -0
  423. data/lib/decidim/enhanced_textwork/api.rb +10 -0
  424. data/lib/decidim/enhanced_textwork/commentable_collaborative_draft.rb +38 -0
  425. data/lib/decidim/enhanced_textwork/commentable_paragraph.rb +36 -0
  426. data/lib/decidim/enhanced_textwork/component.rb +448 -0
  427. data/lib/decidim/enhanced_textwork/doc_to_markdown.rb +50 -0
  428. data/lib/decidim/enhanced_textwork/engine.rb +204 -0
  429. data/lib/decidim/enhanced_textwork/html_to_markdown.rb +22 -0
  430. data/lib/decidim/enhanced_textwork/markdown_to_paragraphs.rb +153 -0
  431. data/lib/decidim/enhanced_textwork/odt_to_markdown.rb +46 -0
  432. data/lib/decidim/enhanced_textwork/paragraph_creator.rb +98 -0
  433. data/lib/decidim/enhanced_textwork/paragraph_serializer.rb +95 -0
  434. data/lib/decidim/enhanced_textwork/participatory_text_section.rb +21 -0
  435. data/lib/decidim/enhanced_textwork/test/capybara_paragraphs_picker.rb +59 -0
  436. data/lib/decidim/enhanced_textwork/test/factories.rb +492 -0
  437. data/lib/decidim/enhanced_textwork/valuatable.rb +21 -0
  438. data/lib/decidim/enhanced_textwork/version.rb +14 -0
  439. data/lib/decidim/enhanced_textwork.rb +58 -0
  440. data/lib/decidim/exporters/word.rb +309 -0
  441. metadata +704 -0
@@ -0,0 +1,204 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "decidim/core"
4
+
5
+ module Decidim
6
+ module EnhancedTextwork
7
+ # This is the engine that runs on the public interface of `decidim-paragraphs`.
8
+ # It mostly handles rendering the created page associated to a participatory
9
+ # process.
10
+ class Engine < ::Rails::Engine
11
+ isolate_namespace Decidim::EnhancedTextwork
12
+
13
+ routes do
14
+ resources :paragraphs, except: [:destroy] do
15
+ member do
16
+ get :compare
17
+ get :complete
18
+ get :edit_draft
19
+ patch :update_draft
20
+ get :preview
21
+ get :overview
22
+ post :publish
23
+ delete :destroy_draft
24
+ put :withdraw
25
+ end
26
+ resource :paragraph_vote, only: [:create, :destroy]
27
+ resource :widget, only: :show, path: "embed"
28
+ resources :versions, only: [:show, :index]
29
+ end
30
+ resources :collaborative_drafts, except: [:destroy] do
31
+ member do
32
+ post :request_access, controller: "collaborative_draft_collaborator_requests"
33
+ post :request_accept, controller: "collaborative_draft_collaborator_requests"
34
+ post :request_reject, controller: "collaborative_draft_collaborator_requests"
35
+ post :withdraw
36
+ post :publish
37
+ end
38
+ resources :versions, only: [:show, :index]
39
+ end
40
+ root to: "paragraphs#index"
41
+ end
42
+
43
+ initializer "decidim.content_processors" do |_app|
44
+ Decidim.configure do |config|
45
+ config.content_processors += [:paragraph]
46
+ end
47
+ end
48
+
49
+ initializer "decidim_enhanced_textwork.view_hooks" do
50
+ Decidim.view_hooks.register(:participatory_space_highlighted_elements, priority: Decidim::ViewHooks::MEDIUM_PRIORITY) do |view_context|
51
+ view_context.cell("decidim/enhanced_textwork/highlighted_paragraphs", view_context.current_participatory_space)
52
+ end
53
+ end
54
+
55
+ initializer "decidim_changes" do
56
+ config.to_prepare do
57
+ Decidim::SettingsChange.subscribe "surveys" do |changes|
58
+ Decidim::EnhancedTextwork::SettingsChangeJob.perform_later(
59
+ changes[:component_id],
60
+ changes[:previous_settings],
61
+ changes[:current_settings]
62
+ )
63
+ end
64
+ end
65
+ end
66
+
67
+ initializer "decidim_enhanced_textwork.mentions_listener" do
68
+ config.to_prepare do
69
+ Decidim::Comments::CommentCreation.subscribe do |data|
70
+ paragraphs = data.dig(:metadatas, :paragraph).try(:linked_paragraphs)
71
+ Decidim::EnhancedTextwork::NotifyParagraphsMentionedJob.perform_later(data[:comment_id], paragraphs) if paragraphs
72
+ end
73
+ end
74
+ end
75
+
76
+ # Subscribes to ActiveSupport::Notifications that may affect a Paragraph.
77
+ initializer "decidim_enhanced_textwork.subscribe_to_events" do
78
+ # when a paragraph is linked from a result
79
+ event_name = "decidim.resourceable.included_paragraphs.created"
80
+ ActiveSupport::Notifications.subscribe event_name do |_name, _started, _finished, _unique_id, data|
81
+ payload = data[:this]
82
+ if payload[:from_type] == Decidim::Accountability::Result.name && payload[:to_type] == Paragraph.name
83
+ paragraph = Paragraph.find(payload[:to_id])
84
+ paragraph.update(state: "accepted", state_published_at: Time.current)
85
+ end
86
+ end
87
+ end
88
+
89
+ initializer "decidim_enhanced_textwork.add_cells_view_paths" do
90
+ Cell::ViewModel.view_paths << File.expand_path("#{Decidim::EnhancedTextwork::Engine.root}/app/cells")
91
+ Cell::ViewModel.view_paths << File.expand_path("#{Decidim::EnhancedTextwork::Engine.root}/app/views") # for paragraph partials
92
+ end
93
+
94
+ initializer "decidim_enhanced_textwork.add_badges" do
95
+ Decidim::Gamification.register_badge(:paragraphs) do |badge|
96
+ badge.levels = [1, 5, 10, 30, 60]
97
+
98
+ badge.valid_for = [:user, :user_group]
99
+
100
+ badge.reset = lambda { |model|
101
+ case model
102
+ when User
103
+ Decidim::Coauthorship.where(
104
+ coauthorable_type: "Decidim::EnhancedTextwork::Paragraph",
105
+ author: model,
106
+ user_group: nil
107
+ ).count
108
+ when UserGroup
109
+ Decidim::Coauthorship.where(
110
+ coauthorable_type: "Decidim::EnhancedTextwork::Paragraph",
111
+ user_group: model
112
+ ).count
113
+ end
114
+ }
115
+ end
116
+
117
+ Decidim::Gamification.register_badge(:accepted_paragraphs) do |badge|
118
+ badge.levels = [1, 5, 15, 30, 50]
119
+
120
+ badge.valid_for = [:user, :user_group]
121
+
122
+ badge.reset = lambda { |model|
123
+ paragraph_ids = case model
124
+ when User
125
+ Decidim::Coauthorship.where(
126
+ coauthorable_type: "Decidim::EnhancedTextwork::Paragraph",
127
+ author: model,
128
+ user_group: nil
129
+ ).select(:coauthorable_id)
130
+ when UserGroup
131
+ Decidim::Coauthorship.where(
132
+ coauthorable_type: "Decidim::EnhancedTextwork::Paragraph",
133
+ user_group: model
134
+ ).select(:coauthorable_id)
135
+ end
136
+
137
+ Decidim::EnhancedTextwork::Paragraph.where(id: paragraph_ids).accepted.count
138
+ }
139
+ end
140
+
141
+ Decidim::Gamification.register_badge(:paragraph_votes) do |badge|
142
+ badge.levels = [5, 15, 50, 100, 500]
143
+
144
+ badge.reset = lambda { |user|
145
+ Decidim::EnhancedTextwork::ParagraphVote.where(author: user).select(:decidim_paragraph_id).distinct.count
146
+ }
147
+ end
148
+ end
149
+
150
+ initializer "decidim_enhanced_textwork.register_metrics" do
151
+ Decidim.metrics_registry.register(:paragraphs) do |metric_registry|
152
+ metric_registry.manager_class = "Decidim::EnhancedTextwork::Metrics::ParagraphsMetricManage"
153
+
154
+ metric_registry.settings do |settings|
155
+ settings.attribute :highlighted, type: :boolean, default: true
156
+ settings.attribute :scopes, type: :array, default: %w(home participatory_process)
157
+ settings.attribute :weight, type: :integer, default: 2
158
+ settings.attribute :stat_block, type: :string, default: "medium"
159
+ end
160
+ end
161
+
162
+ Decidim.metrics_registry.register(:accepted_paragraphs) do |metric_registry|
163
+ metric_registry.manager_class = "Decidim::EnhancedTextwork::Metrics::AcceptedParagraphsMetricManage"
164
+
165
+ metric_registry.settings do |settings|
166
+ settings.attribute :highlighted, type: :boolean, default: false
167
+ settings.attribute :scopes, type: :array, default: %w(home participatory_process)
168
+ settings.attribute :weight, type: :integer, default: 3
169
+ settings.attribute :stat_block, type: :string, default: "small"
170
+ end
171
+ end
172
+
173
+ Decidim.metrics_registry.register(:enhanced_textwork_votes) do |metric_registry|
174
+ metric_registry.manager_class = "Decidim::EnhancedTextwork::Metrics::VotesMetricManage"
175
+
176
+ metric_registry.settings do |settings|
177
+ settings.attribute :highlighted, type: :boolean, default: true
178
+ settings.attribute :scopes, type: :array, default: %w(home participatory_process)
179
+ settings.attribute :weight, type: :integer, default: 3
180
+ settings.attribute :stat_block, type: :string, default: "medium"
181
+ end
182
+ end
183
+
184
+ Decidim.metrics_registry.register(:enhanced_textwork_endorsements) do |metric_registry|
185
+ metric_registry.manager_class = "Decidim::EnhancedTextwork::Metrics::EndorsementsMetricManage"
186
+
187
+ metric_registry.settings do |settings|
188
+ settings.attribute :highlighted, type: :boolean, default: false
189
+ settings.attribute :scopes, type: :array, default: %w(participatory_process)
190
+ settings.attribute :weight, type: :integer, default: 4
191
+ settings.attribute :stat_block, type: :string, default: "medium"
192
+ end
193
+ end
194
+
195
+ Decidim.metrics_operation.register(:participants, :paragraphs) do |metric_operation|
196
+ metric_operation.manager_class = "Decidim::EnhancedTextwork::Metrics::ParagraphParticipantsMetricMeasure"
197
+ end
198
+ Decidim.metrics_operation.register(:followers, :paragraphs) do |metric_operation|
199
+ metric_operation.manager_class = "Decidim::EnhancedTextwork::Metrics::ParagraphFollowersMetricMeasure"
200
+ end
201
+ end
202
+ end
203
+ end
204
+ end
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "kramdown"
4
+
5
+ module Decidim
6
+ module EnhancedTextwork
7
+ # This class parses a participatory text document from quill editor in markdown
8
+ #
9
+ # This implementation uses Kramdown Base renderer.
10
+ #
11
+ class HtmlToMarkdown
12
+ # Public: Initializes the serializer with a paragraph.
13
+ def initialize(html)
14
+ @html = html
15
+ end
16
+
17
+ def to_md
18
+ ::Kramdown::Document.new(@html, input: "html").to_kramdown
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,153 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "redcarpet"
4
+
5
+ module Decidim
6
+ module EnhancedTextwork
7
+ # This class parses a participatory text document in markdown and
8
+ # produces Paragraphs in the form of sections and articles.
9
+ #
10
+ # This implementation uses Redcarpet Base renderer.
11
+ # Redcarpet::Render::Base performs a callback for every block it finds, what MarkdownToParagraphs
12
+ # does is to implement callbacks for the blocks which it is interested in performing some actions.
13
+ #
14
+ class MarkdownToParagraphs < ::Redcarpet::Render::Base
15
+ # Public: Initializes the serializer with a paragraph.
16
+ def initialize(component, current_user)
17
+ super()
18
+ @component = component
19
+ @current_user = current_user
20
+ @last_position = 0
21
+ @num_sections = 0
22
+ @list_items = []
23
+ end
24
+
25
+ def parse(document)
26
+ renderer = self
27
+ extensions = {
28
+ # no lax_spacing so that it is easier to group paragraphs in articles.
29
+ lax_spacing: false,
30
+ fenced_code_blocks: true,
31
+ autolink: true,
32
+ underline: true
33
+ }
34
+ parser = ::Redcarpet::Markdown.new(renderer, extensions)
35
+ parser.render(document)
36
+ end
37
+
38
+ ##########################################
39
+ # Redcarpet callbacks
40
+ ##########################################
41
+
42
+ # Block-level calls ######################
43
+
44
+ # Recarpet callback to process headers.
45
+ # Creates Paricipatory Text Paragraphs at Section and Subsection levels.
46
+ def header(title, level)
47
+ participatory_text_level = if level > 1
48
+ Decidim::EnhancedTextwork::ParticipatoryTextSection::LEVELS[:sub_section]
49
+ else
50
+ Decidim::EnhancedTextwork::ParticipatoryTextSection::LEVELS[:section]
51
+ end
52
+
53
+ create_paragraph(title, title, participatory_text_level)
54
+
55
+ @num_sections += 1
56
+ title
57
+ end
58
+
59
+ # Recarpet callback to process paragraphs.
60
+ # Creates Paricipatory Text Paragraphs at Article level.
61
+ def paragraph(text)
62
+ return if text.blank?
63
+
64
+ create_paragraph(
65
+ (@last_position + 1 - @num_sections).to_s,
66
+ text,
67
+ Decidim::EnhancedTextwork::ParticipatoryTextSection::LEVELS[:article]
68
+ )
69
+
70
+ text
71
+ end
72
+
73
+ # Render the list as a whole
74
+ def list(_contents, list_type)
75
+ return if @list_items.empty?
76
+
77
+ body = case list_type
78
+ when :ordered
79
+ @list_items.collect.with_index { |item, idx| "#{idx + 1}. #{item}\n" }.join
80
+ else
81
+ @list_items.collect { |item| "- #{item}\n" }.join
82
+ end
83
+ # reset items for the next list
84
+ @list_items = []
85
+ create_paragraph(
86
+ (@last_position + 1 - @num_sections).to_s,
87
+ body,
88
+ Decidim::EnhancedTextwork::ParticipatoryTextSection::LEVELS[:article]
89
+ )
90
+
91
+ body
92
+ end
93
+
94
+ # do not render list items, save them for rendering with the whole list
95
+ def list_item(text, _list_type)
96
+ @list_items << text.strip
97
+ nil
98
+ end
99
+
100
+ # Span-level calls #######################
101
+
102
+ def link(link, title, content)
103
+ attrs = %(href="#{link}")
104
+ attrs += %( title="#{title}") if title.present?
105
+ "<a #{attrs}>#{content}</a>"
106
+ end
107
+
108
+ def image(link, title, alt_text)
109
+ attrs = %(src="#{link}")
110
+ attrs += %( alt="#{alt_text}") if alt_text.present?
111
+ attrs += %( title="#{title}") if title.present?
112
+ "<img #{attrs}/>"
113
+ end
114
+
115
+ def emphasis(text)
116
+ "<em>#{text}</em>"
117
+ end
118
+
119
+ def double_emphasis(text)
120
+ "<strong>#{text}</strong>"
121
+ end
122
+
123
+ def underline(text)
124
+ "<u>#{text}</u>"
125
+ end
126
+
127
+ private
128
+
129
+ # Prevents PaperTrail from creating versions while producing paragraphs from a document.
130
+ # A first version will be created when publishing the Participatory Text.
131
+ def create_paragraph(title, body, participatory_text_level)
132
+ attributes = {
133
+ component: @component,
134
+ title: { I18n.locale => title },
135
+ body: { I18n.locale => body },
136
+ participatory_text_level: participatory_text_level
137
+ }
138
+
139
+ PaperTrail.request(enabled: false) do
140
+ paragraph = Decidim::EnhancedTextwork::ParagraphBuilder.create(
141
+ attributes: attributes,
142
+ author: @component.organization,
143
+ action_user: @current_user
144
+ )
145
+
146
+ @last_position = paragraph.position
147
+
148
+ paragraph
149
+ end
150
+ end
151
+ end
152
+ end
153
+ end
@@ -0,0 +1,46 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "doc2text"
4
+ require "tempfile"
5
+
6
+ module Decidim
7
+ module EnhancedTextwork
8
+ # This class parses a participatory text document in markdown and
9
+ # produces Paragraphs in the form of sections and articles.
10
+ #
11
+ # This implementation uses Redcarpet Base renderer.
12
+ # Redcarpet::Render::Base performs a callback for every block it finds, what MarkdownToParagraphs
13
+ # does is to implement callbacks for the blocks which it is interested in performing some actions.
14
+ #
15
+ class OdtToMarkdown
16
+ # Public: Initializes the serializer with a paragraph.
17
+ def initialize(doc)
18
+ @doc = doc
19
+ end
20
+
21
+ def to_md
22
+ doc_file = doc_to_tmp_file
23
+ md_file = transform_to_md_file(doc_file)
24
+ md_file.read
25
+ end
26
+
27
+ #-----------------------------------------------------
28
+
29
+ private
30
+
31
+ #-----------------------------------------------------
32
+
33
+ def doc_to_tmp_file
34
+ file = Tempfile.new("doc-to-markdown-odt", encoding: "ascii-8bit")
35
+ file.write(@doc)
36
+ file
37
+ end
38
+
39
+ def transform_to_md_file(doc_file)
40
+ md_file = Tempfile.new
41
+ Doc2Text::Odt::Document.parse_and_save doc_file, md_file
42
+ md_file
43
+ end
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,98 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module EnhancedTextwork
5
+ # This class is responsible for creating the imported paragraphs
6
+ # and must be included in paragraphs component's import manifest.
7
+ class ParagraphCreator < Decidim::Admin::Import::Creator
8
+ # Retuns the resource class to be created with the provided data.
9
+ def self.resource_klass
10
+ Decidim::EnhancedTextwork::Paragraph
11
+ end
12
+
13
+ # Produces a paragraph from parsed data
14
+ #
15
+ # Returns a paragraph
16
+ def produce
17
+ resource.add_coauthor(context[:current_user], user_group: context[:user_group])
18
+
19
+ resource
20
+ end
21
+
22
+ # Saves the paragraph
23
+ def finish!
24
+ super # resource.save!
25
+ notify(resource)
26
+ publish(resource)
27
+ end
28
+
29
+ private
30
+
31
+ attr_reader :context
32
+
33
+ def resource
34
+ @resource ||= Decidim::EnhancedTextwork::Paragraph.new(
35
+ category: category,
36
+ scope: scope,
37
+ title: title,
38
+ body: body,
39
+ component: component,
40
+ published_at: Time.current
41
+ )
42
+ end
43
+
44
+ def category
45
+ id = data.has_key?(:category) ? data[:category]["id"] : data[:"category/id"].to_i
46
+ Decidim::Category.find_by(id: id)
47
+ end
48
+
49
+ def scope
50
+ id = data.has_key?(:scope) ? data[:scope]["id"] : data[:"scope/id"].to_i
51
+ Decidim::Scope.find_by(id: id)
52
+ end
53
+
54
+ def title
55
+ locale_hasher("title", available_locales)
56
+ end
57
+
58
+ def body
59
+ locale_hasher("body", available_locales)
60
+ end
61
+
62
+ def available_locales
63
+ @available_locales ||= component.participatory_space.organization.available_locales
64
+ end
65
+
66
+ def component
67
+ context[:current_component]
68
+ end
69
+
70
+ def notify(paragraph)
71
+ return if paragraph.coauthorships.empty?
72
+
73
+ Decidim::EventsManager.publish(
74
+ event: "decidim.events.enhanced_textwork.paragraph_published",
75
+ event_class: Decidim::EnhancedTextwork::PublishParagraphEvent,
76
+ resource: paragraph,
77
+ followers: coauthors_followers(paragraph)
78
+ )
79
+ end
80
+
81
+ def publish(paragraph)
82
+ Decidim::EventsManager.publish(
83
+ event: "decidim.events.enhanced_textwork.paragraph_published",
84
+ event_class: Decidim::EnhancedTextwork::PublishParagraphEvent,
85
+ resource: paragraph,
86
+ followers: paragraph.participatory_space.followers - coauthors_followers(paragraph),
87
+ extra: {
88
+ participatory_space: true
89
+ }
90
+ )
91
+ end
92
+
93
+ def coauthors_followers(paragraph)
94
+ @coauthors_followers ||= paragraph.authors.flat_map(&:followers)
95
+ end
96
+ end
97
+ end
98
+ end
@@ -0,0 +1,95 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module EnhancedTextwork
5
+ # This class serializes a Paragraph so can be exported to CSV, JSON or other
6
+ # formats.
7
+ class ParagraphSerializer < Decidim::Exporters::Serializer
8
+ include Decidim::ApplicationHelper
9
+ include Decidim::ResourceHelper
10
+ include Decidim::TranslationsHelper
11
+
12
+ # Public: Initializes the serializer with a paragraph.
13
+ def initialize(paragraph)
14
+ @paragraph = paragraph
15
+ end
16
+
17
+ # Public: Exports a hash with the serialized data for this paragraph.
18
+ def serialize
19
+ {
20
+ id: paragraph.id,
21
+ category: {
22
+ id: paragraph.category.try(:id),
23
+ name: paragraph.category.try(:name) || empty_translatable
24
+ },
25
+ scope: {
26
+ id: paragraph.scope.try(:id),
27
+ name: paragraph.scope.try(:name) || empty_translatable
28
+ },
29
+ participatory_space: {
30
+ id: paragraph.participatory_space.id,
31
+ url: Decidim::ResourceLocatorPresenter.new(paragraph.participatory_space).url
32
+ },
33
+ component: { id: component.id },
34
+ title: paragraph.title,
35
+ body: paragraph.body,
36
+ state: paragraph.state.to_s,
37
+ reference: paragraph.reference,
38
+ answer: ensure_translatable(paragraph.answer),
39
+ supports: paragraph.paragraph_votes_count,
40
+ endorsements: {
41
+ total_count: paragraph.endorsements.count,
42
+ user_endorsements: user_endorsements
43
+ },
44
+ comments: paragraph.comments_count,
45
+ attachments: paragraph.attachments.count,
46
+ followers: paragraph.followers.count,
47
+ published_at: paragraph.published_at,
48
+ url: url,
49
+ meeting_urls: meetings,
50
+ related_paragraphs: related_paragraphs,
51
+ is_amend: paragraph.emendation?,
52
+ original_paragraph: {
53
+ title: paragraph&.amendable&.title,
54
+ url: original_paragraph_url
55
+ }
56
+ }
57
+ end
58
+
59
+ private
60
+
61
+ attr_reader :paragraph
62
+ alias resource paragraph
63
+
64
+ def component
65
+ paragraph.component
66
+ end
67
+
68
+ def meetings
69
+ paragraph.linked_resources(:meetings, "paragraphs_from_meeting").map do |meeting|
70
+ Decidim::ResourceLocatorPresenter.new(meeting).url
71
+ end
72
+ end
73
+
74
+ def related_paragraphs
75
+ paragraph.linked_resources(:paragraphs, "copied_from_component").map do |paragraph|
76
+ Decidim::ResourceLocatorPresenter.new(paragraph).url
77
+ end
78
+ end
79
+
80
+ def url
81
+ Decidim::ResourceLocatorPresenter.new(paragraph).url
82
+ end
83
+
84
+ def user_endorsements
85
+ paragraph.endorsements.for_listing.map { |identity| identity.normalized_author&.name }
86
+ end
87
+
88
+ def original_paragraph_url
89
+ return unless paragraph.emendation? && paragraph.amendable.present?
90
+
91
+ Decidim::ResourceLocatorPresenter.new(paragraph.amendable).url
92
+ end
93
+ end
94
+ end
95
+ end
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module EnhancedTextwork
5
+ # The data store for a Paragraph in the Decidim::EnhancedTextwork component.
6
+ module ParticipatoryTextSection
7
+ extend ActiveSupport::Concern
8
+
9
+ LEVELS = {
10
+ section: "section", sub_section: "sub-section", article: "article"
11
+ }.freeze
12
+
13
+ included do
14
+ # Public: is this section an :article?
15
+ def article?
16
+ participatory_text_level == LEVELS[:article]
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,59 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "decidim/dev/test/rspec_support/capybara_data_picker"
4
+
5
+ module Capybara
6
+ module EnhancedTextworkPicker
7
+ include DataPicker
8
+
9
+ RSpec::Matchers.define :have_paragraphs_picked do |expected|
10
+ match do |paragraphs_picker|
11
+ data_picker = paragraphs_picker.data_picker
12
+
13
+ expected.each do |paragraph|
14
+ expect(data_picker).to have_selector(".picker-values div input[value='#{paragraph.id}']", visible: :all)
15
+ expect(data_picker).to have_selector(:xpath, "//div[contains(@class,'picker-values')]/div/a[text()[contains(.,\"#{translated(paragraph.title)}\")]]")
16
+ end
17
+ end
18
+ end
19
+
20
+ RSpec::Matchers.define :have_paragraphs_not_picked do |expected|
21
+ match do |paragraphs_picker|
22
+ data_picker = paragraphs_picker.data_picker
23
+
24
+ expected.each do |paragraph|
25
+ expect(data_picker).not_to have_selector(".picker-values div input[value='#{paragraph.id}']", visible: :all)
26
+ expect(data_picker).not_to have_selector(:xpath, "//div[contains(@class,'picker-values')]/div/a[text()[contains(.,\"#{translated(paragraph.title)}\")]]")
27
+ end
28
+ end
29
+ end
30
+
31
+ def paragraphs_pick(paragraphs_picker, paragraphs)
32
+ data_picker = paragraphs_picker.data_picker
33
+
34
+ expect(data_picker).to have_selector(".picker-prompt")
35
+ data_picker.find(".picker-prompt").click
36
+
37
+ paragraphs.each do |paragraph|
38
+ data_picker_choose_value(paragraph.id)
39
+ end
40
+ data_picker_close
41
+
42
+ expect(paragraphs_picker).to have_paragraphs_picked(paragraphs)
43
+ end
44
+
45
+ def paragraphs_remove(paragraphs_picker, paragraphs)
46
+ data_picker = paragraphs_picker.data_picker
47
+
48
+ paragraphs.each do |paragraph|
49
+ data_picker.find("a", text: paragraph.title["en"]).find("span").click
50
+ end
51
+
52
+ expect(paragraphs_picker).to have_paragraphs_not_picked(paragraphs)
53
+ end
54
+ end
55
+ end
56
+
57
+ RSpec.configure do |config|
58
+ config.include Capybara::ParagraphsPicker, type: :system
59
+ end