decidim-collaborative_texts 0.31.0.rc1

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 (159) hide show
  1. checksums.yaml +7 -0
  2. data/README.md +24 -0
  3. data/Rakefile +3 -0
  4. data/app/cells/decidim/collaborative_texts/document_cell.rb +23 -0
  5. data/app/cells/decidim/collaborative_texts/document_l_cell.rb +15 -0
  6. data/app/commands/decidim/collaborative_texts/admin/create_document.rb +25 -0
  7. data/app/commands/decidim/collaborative_texts/admin/publish_document.rb +52 -0
  8. data/app/commands/decidim/collaborative_texts/admin/unpublish_document.rb +44 -0
  9. data/app/commands/decidim/collaborative_texts/admin/update_document.rb +101 -0
  10. data/app/commands/decidim/collaborative_texts/admin/update_document_settings.rb +13 -0
  11. data/app/commands/decidim/collaborative_texts/create_suggestion.rb +28 -0
  12. data/app/commands/decidim/collaborative_texts/rollout.rb +50 -0
  13. data/app/controllers/concerns/decidim/collaborative_texts/admin/filterable.rb +23 -0
  14. data/app/controllers/decidim/collaborative_texts/admin/application_controller.rb +15 -0
  15. data/app/controllers/decidim/collaborative_texts/admin/documents_controller.rb +142 -0
  16. data/app/controllers/decidim/collaborative_texts/application_controller.rb +14 -0
  17. data/app/controllers/decidim/collaborative_texts/documents_controller.rb +57 -0
  18. data/app/controllers/decidim/collaborative_texts/suggestions_controller.rb +55 -0
  19. data/app/events/decidim/collaborative_texts/suggestion_accepted_event.rb +6 -0
  20. data/app/forms/decidim/collaborative_texts/admin/document_form.rb +29 -0
  21. data/app/forms/decidim/collaborative_texts/rollout_form.rb +26 -0
  22. data/app/forms/decidim/collaborative_texts/suggestion_form.rb +42 -0
  23. data/app/helpers/decidim/collaborative_texts/application_helper.rb +20 -0
  24. data/app/models/decidim/collaborative_texts/application_record.rb +10 -0
  25. data/app/models/decidim/collaborative_texts/document.rb +78 -0
  26. data/app/models/decidim/collaborative_texts/suggestion.rb +36 -0
  27. data/app/models/decidim/collaborative_texts/version.rb +35 -0
  28. data/app/packs/entrypoints/decidim_collaborative_texts.js +7 -0
  29. data/app/packs/images/decidim/collaborative_texts/decidim_collaborative_texts.svg +1 -0
  30. data/app/packs/src/decidim/collaborative_texts/document.js +168 -0
  31. data/app/packs/src/decidim/collaborative_texts/editor.js +80 -0
  32. data/app/packs/src/decidim/collaborative_texts/init_documents.js +27 -0
  33. data/app/packs/src/decidim/collaborative_texts/manager.js +106 -0
  34. data/app/packs/src/decidim/collaborative_texts/selection.js +106 -0
  35. data/app/packs/src/decidim/collaborative_texts/suggestion.js +243 -0
  36. data/app/packs/src/decidim/collaborative_texts/suggestions_list.js +103 -0
  37. data/app/packs/src/decidim/collaborative_texts/test/document.test.js +83 -0
  38. data/app/packs/src/decidim/collaborative_texts/test/manager.test.js +149 -0
  39. data/app/packs/src/decidim/collaborative_texts/test/selection.test.js +125 -0
  40. data/app/packs/src/decidim/collaborative_texts/test/suggestions.test.js +233 -0
  41. data/app/packs/src/decidim/collaborative_texts/test/toc.test.js +70 -0
  42. data/app/packs/src/decidim/collaborative_texts/toc.js +48 -0
  43. data/app/packs/stylesheets/decidim/collaborative_texts/collaborative_texts.scss +287 -0
  44. data/app/permissions/decidim/collaborative_texts/admin/permissions.rb +28 -0
  45. data/app/permissions/decidim/collaborative_texts/permissions.rb +36 -0
  46. data/app/presenters/decidim/collaborative_texts/admin_log/document_presenter.rb +54 -0
  47. data/app/presenters/decidim/collaborative_texts/admin_log/suggestion_presenter.rb +62 -0
  48. data/app/presenters/decidim/collaborative_texts/admin_log/suggestion_resource_presenter.rb +20 -0
  49. data/app/presenters/decidim/collaborative_texts/admin_log/version_presenter.rb +53 -0
  50. data/app/presenters/decidim/collaborative_texts/official_author_presenter.rb +11 -0
  51. data/app/presenters/decidim/collaborative_texts/suggestion_presenter.rb +57 -0
  52. data/app/views/decidim/collaborative_texts/admin/documents/_actions.html.erb +82 -0
  53. data/app/views/decidim/collaborative_texts/admin/documents/_document-tr.html.erb +15 -0
  54. data/app/views/decidim/collaborative_texts/admin/documents/_documents-thead.html.erb +7 -0
  55. data/app/views/decidim/collaborative_texts/admin/documents/_draft_options.html.erb +6 -0
  56. data/app/views/decidim/collaborative_texts/admin/documents/_form.html.erb +16 -0
  57. data/app/views/decidim/collaborative_texts/admin/documents/_non_draft_options.html.erb +9 -0
  58. data/app/views/decidim/collaborative_texts/admin/documents/_versions.html.erb +18 -0
  59. data/app/views/decidim/collaborative_texts/admin/documents/edit.html.erb +33 -0
  60. data/app/views/decidim/collaborative_texts/admin/documents/edit_settings.html.erb +18 -0
  61. data/app/views/decidim/collaborative_texts/admin/documents/index.html.erb +32 -0
  62. data/app/views/decidim/collaborative_texts/admin/documents/manage_trash.html.erb +19 -0
  63. data/app/views/decidim/collaborative_texts/admin/documents/new.html.erb +18 -0
  64. data/app/views/decidim/collaborative_texts/admin/settings/_form.html.erb +9 -0
  65. data/app/views/decidim/collaborative_texts/documents/_editor_template.html.erb +15 -0
  66. data/app/views/decidim/collaborative_texts/documents/_manager.html.erb +9 -0
  67. data/app/views/decidim/collaborative_texts/documents/_suggestions_box_item_template.html.erb +33 -0
  68. data/app/views/decidim/collaborative_texts/documents/_suggestions_box_template.html.erb +20 -0
  69. data/app/views/decidim/collaborative_texts/documents/index.html.erb +29 -0
  70. data/app/views/decidim/collaborative_texts/documents/show.html.erb +70 -0
  71. data/config/assets.rb +8 -0
  72. data/config/locales/am-ET.yml +1 -0
  73. data/config/locales/ar.yml +1 -0
  74. data/config/locales/bg.yml +1 -0
  75. data/config/locales/bn-BD.yml +1 -0
  76. data/config/locales/bs-BA.yml +1 -0
  77. data/config/locales/ca-IT.yml +154 -0
  78. data/config/locales/ca.yml +154 -0
  79. data/config/locales/cs.yml +122 -0
  80. data/config/locales/da.yml +1 -0
  81. data/config/locales/de.yml +154 -0
  82. data/config/locales/el.yml +1 -0
  83. data/config/locales/en.yml +154 -0
  84. data/config/locales/eo.yml +1 -0
  85. data/config/locales/es-MX.yml +154 -0
  86. data/config/locales/es-PY.yml +154 -0
  87. data/config/locales/es.yml +154 -0
  88. data/config/locales/et.yml +1 -0
  89. data/config/locales/eu.yml +154 -0
  90. data/config/locales/fa-IR.yml +1 -0
  91. data/config/locales/fi-plain.yml +154 -0
  92. data/config/locales/fi.yml +154 -0
  93. data/config/locales/fr-CA.yml +125 -0
  94. data/config/locales/fr.yml +125 -0
  95. data/config/locales/ga-IE.yml +1 -0
  96. data/config/locales/gl.yml +1 -0
  97. data/config/locales/gn-PY.yml +1 -0
  98. data/config/locales/he-IL.yml +1 -0
  99. data/config/locales/hr.yml +1 -0
  100. data/config/locales/hu.yml +1 -0
  101. data/config/locales/id-ID.yml +1 -0
  102. data/config/locales/is-IS.yml +1 -0
  103. data/config/locales/it.yml +1 -0
  104. data/config/locales/ja.yml +153 -0
  105. data/config/locales/ka-GE.yml +1 -0
  106. data/config/locales/kaa.yml +1 -0
  107. data/config/locales/ko.yml +1 -0
  108. data/config/locales/lb.yml +1 -0
  109. data/config/locales/lo-LA.yml +1 -0
  110. data/config/locales/lt.yml +1 -0
  111. data/config/locales/lv.yml +1 -0
  112. data/config/locales/mt.yml +1 -0
  113. data/config/locales/nl.yml +1 -0
  114. data/config/locales/no.yml +6 -0
  115. data/config/locales/oc-FR.yml +1 -0
  116. data/config/locales/om-ET.yml +1 -0
  117. data/config/locales/pl.yml +1 -0
  118. data/config/locales/pt-BR.yml +1 -0
  119. data/config/locales/pt.yml +1 -0
  120. data/config/locales/ro-RO.yml +89 -0
  121. data/config/locales/ru.yml +1 -0
  122. data/config/locales/si-LK.yml +1 -0
  123. data/config/locales/sk.yml +1 -0
  124. data/config/locales/sl.yml +1 -0
  125. data/config/locales/so-SO.yml +1 -0
  126. data/config/locales/sq-AL.yml +1 -0
  127. data/config/locales/sr-CS.yml +1 -0
  128. data/config/locales/sv.yml +117 -0
  129. data/config/locales/sw-KE.yml +1 -0
  130. data/config/locales/th-TH.yml +1 -0
  131. data/config/locales/ti-ER.yml +1 -0
  132. data/config/locales/tr-TR.yml +69 -0
  133. data/config/locales/uk.yml +1 -0
  134. data/config/locales/val-ES.yml +1 -0
  135. data/config/locales/vi.yml +1 -0
  136. data/config/locales/zh-CN.yml +1 -0
  137. data/config/locales/zh-TW.yml +1 -0
  138. data/db/migrate/20250205215038_create_decidim_collaborative_texts_documents.rb +16 -0
  139. data/db/migrate/20250213113536_create_collaborative_texts_versions.rb +13 -0
  140. data/db/migrate/20250227204839_create_collaborative_texts_suggestions.rb +13 -0
  141. data/db/migrate/20250312140133_add_counter_caches_to_collaborative_texts_documents.rb +13 -0
  142. data/db/migrate/20250408205231_add_counter_caches_to_collaborative_text_versions.rb +8 -0
  143. data/decidim-collaborative_texts.gemspec +36 -0
  144. data/lib/decidim/api/document_input_filter.rb +29 -0
  145. data/lib/decidim/api/document_input_sort.rb +14 -0
  146. data/lib/decidim/api/document_type.rb +31 -0
  147. data/lib/decidim/api/documents_type.rb +39 -0
  148. data/lib/decidim/api/suggestion_type.rb +18 -0
  149. data/lib/decidim/api/version_type.rb +21 -0
  150. data/lib/decidim/collaborative_texts/admin.rb +10 -0
  151. data/lib/decidim/collaborative_texts/admin_engine.rb +34 -0
  152. data/lib/decidim/collaborative_texts/api.rb +12 -0
  153. data/lib/decidim/collaborative_texts/component.rb +54 -0
  154. data/lib/decidim/collaborative_texts/engine.rb +28 -0
  155. data/lib/decidim/collaborative_texts/seeds.rb +117 -0
  156. data/lib/decidim/collaborative_texts/test/factories.rb +80 -0
  157. data/lib/decidim/collaborative_texts/version.rb +9 -0
  158. data/lib/decidim/collaborative_texts.rb +13 -0
  159. metadata +233 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: cebf8aafaaf331e3c5bc7afbc800b34301731a03a87b8e4fe4f83947803a4fa5
4
+ data.tar.gz: b43b11d0431395a03ce9cc86613fe251e017e2abad0ec4f4a4a410e548aceac4
5
+ SHA512:
6
+ metadata.gz: ffc6eadae13b4b104fc799c10a01f3b4edd69b73935bf329a935ec7399aae055f67cd1614d28c12dc9e593edaa97e1b853f64aa8c8626a8fbad4003bde4a0203
7
+ data.tar.gz: 13bf2903c624058f03fbc4f2dde15f8180646c6dba273d80207f8c34f502cdd5a0244eb07a85467dfdcb85e4cc4037ea72e0c658b8a906bed5d3118affdea012
data/README.md ADDED
@@ -0,0 +1,24 @@
1
+ # Decidim::CollaborativeTexts
2
+
3
+ The Decidim::CollaborativeTexts is a component that allows users to collaboratively create and amend texts through the use of suggestions and comments.
4
+
5
+ > **WARNING**
6
+ > This module is under development and is not ready for usage yet.
7
+
8
+ ## Installation
9
+
10
+ In order to install use this module, you need at least Decidim 0.31 to be installed.
11
+
12
+ To install this module, run in your console:
13
+
14
+ ```bash
15
+ bundle add decidim-collaborative_texts
16
+ ```
17
+
18
+ ## Contributing
19
+
20
+ See [Decidim](https://github.com/decidim/decidim).
21
+
22
+ ## License
23
+
24
+ See [Decidim](https://github.com/decidim/decidim).
data/Rakefile ADDED
@@ -0,0 +1,3 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "decidim/dev/common_rake"
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "cell/partial"
4
+
5
+ module Decidim
6
+ module CollaborativeTexts
7
+ # This cell renders the document card for an instance of a Document
8
+ # the default size is the List Card (:l)
9
+ class DocumentCell < Decidim::ViewModel
10
+ include Cell::ViewModel::Partial
11
+
12
+ def show
13
+ cell card_size, model, options
14
+ end
15
+
16
+ private
17
+
18
+ def card_size
19
+ "decidim/collaborative_texts/document_l"
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module CollaborativeTexts
5
+ # This cell renders the List (:l) post card
6
+ # for a given instance of a Post
7
+ class DocumentLCell < Decidim::CardLCell
8
+ private
9
+
10
+ def has_description?
11
+ false
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module CollaborativeTexts
5
+ module Admin
6
+ # This command is executed when the user creates a Document from the admin
7
+ # panel.
8
+ class CreateDocument < Decidim::Commands::CreateResource
9
+ fetch_form_attributes :title, :body, :coauthorships, :component
10
+
11
+ private
12
+
13
+ def resource_class = Decidim::CollaborativeTexts::Document
14
+
15
+ def extra_params
16
+ {
17
+ extra: {
18
+ body: form.body
19
+ }
20
+ }
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,52 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module CollaborativeTexts
5
+ module Admin
6
+ # This command is executed when the user publishes an
7
+ # existing collaborative text document.
8
+ class PublishDocument < Decidim::Command
9
+ # Public: Initializes the command.
10
+ #
11
+ # document - Decidim::CollaborativeTexts::Document
12
+ # current_user - the user performing the action
13
+ def initialize(document, current_user)
14
+ @document = document
15
+ @current_user = current_user
16
+ end
17
+
18
+ # Executes the command. Broadcasts these events:
19
+ #
20
+ # - :ok when everything is valid.
21
+ # - :invalid if the form was not valid and we could not proceed.
22
+ #
23
+ # Returns nothing.
24
+ def call
25
+ return broadcast(:invalid) if document.published?
26
+
27
+ transaction do
28
+ publish_document
29
+ end
30
+
31
+ broadcast(:ok, document)
32
+ end
33
+
34
+ private
35
+
36
+ attr_reader :document, :current_user
37
+
38
+ def publish_document
39
+ @document = Decidim.traceability.perform_action!(
40
+ :publish,
41
+ document,
42
+ current_user,
43
+ visibility: "all"
44
+ ) do
45
+ document.publish!
46
+ document
47
+ end
48
+ end
49
+ end
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,44 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module CollaborativeTexts
5
+ module Admin
6
+ # This command is executed when the user unpublishes an
7
+ # existing collaborative text document.
8
+ class UnpublishDocument < Decidim::Command
9
+ # Public: Initializes the command.
10
+ #
11
+ # document - Decidim::CollaborativeTexts::Document
12
+ # current_user - the user performing the action
13
+ def initialize(document, current_user)
14
+ @document = document
15
+ @current_user = current_user
16
+ end
17
+
18
+ # Executes the command. Broadcasts these events:
19
+ #
20
+ # - :ok when everything is valid.
21
+ # - :invalid if the form was not valid and we could not proceed.
22
+ #
23
+ # Returns nothing.
24
+ def call
25
+ return broadcast(:invalid) unless document.published?
26
+
27
+ @document = Decidim.traceability.perform_action!(
28
+ :unpublish,
29
+ document,
30
+ current_user
31
+ ) do
32
+ document.unpublish!
33
+ document
34
+ end
35
+ broadcast(:ok, document)
36
+ end
37
+
38
+ private
39
+
40
+ attr_reader :document, :current_user
41
+ end
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,101 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module CollaborativeTexts
5
+ module Admin
6
+ # This command is executed when the user changes a Document from the admin
7
+ # panel.
8
+ class UpdateDocument < Decidim::Commands::UpdateResource
9
+ protected
10
+
11
+ def update_resource
12
+ # Attributes to the model Document
13
+ update_document_record!
14
+ # As traceability might not understand the (delegated) body attribute, we save it separately
15
+ if create_new_version?
16
+ create_draft_version!
17
+ else
18
+ update_version_record!
19
+ end
20
+ end
21
+
22
+ def create_new_version?
23
+ @create_new_version ||= resource.has_suggestions? && form.draft?
24
+ end
25
+
26
+ def update_document_record!
27
+ return unless form.title != resource.title || form.accepting_suggestions != resource.accepting_suggestions
28
+
29
+ # this is a safe-guard in case there are no coauthors
30
+ resource.coauthorships = form.coauthorships if resource.coauthorships.blank?
31
+
32
+ Decidim.traceability.update!(
33
+ resource,
34
+ current_user,
35
+ {
36
+ title: form.title,
37
+ accepting_suggestions: form.accepting_suggestions
38
+ },
39
+ **extra_document_params
40
+ )
41
+ end
42
+
43
+ # When the document is not a draft or it has no suggestions, we just update the current version
44
+ def update_version_record!
45
+ attributes = { draft: form.draft? }
46
+ attributes[:body] = form.body unless resource.has_suggestions?
47
+ Decidim.traceability.update!(
48
+ resource.current_version,
49
+ current_user,
50
+ attributes,
51
+ **extra_version_params
52
+ )
53
+ end
54
+
55
+ # A new version is necessary when the document has suggestions and we want a draft (so we can edit it)
56
+ # If we allow to edit a version with suggestions all the reference nodes to the DOM will be out of sync
57
+ # Note that we do not update the body in purpose, as it is edition is disabled in the UI
58
+ def create_draft_version!
59
+ Decidim.traceability.create!(
60
+ Decidim::CollaborativeTexts::Version,
61
+ current_user,
62
+ { document: resource, body: resource.body, draft: true },
63
+ **extra_version_params
64
+ )
65
+ end
66
+
67
+ def extra_document_params
68
+ {
69
+ extra: {
70
+ version_id: resource.current_version&.id,
71
+ version_number: current_version_number
72
+ }
73
+ }
74
+ end
75
+
76
+ def extra_version_params
77
+ {
78
+ extra: {
79
+ document_id: resource.id,
80
+ title: resource.title,
81
+ version_number: current_version_number
82
+ },
83
+ resource: {
84
+ title: resource.title
85
+ },
86
+ participatory_space: {
87
+ title: resource.participatory_space.title
88
+ }
89
+ }
90
+ end
91
+
92
+ def current_version_number
93
+ @current_version_number ||= begin
94
+ num = resource.current_version&.version_number || 1
95
+ create_new_version? ? num + 1 : num
96
+ end
97
+ end
98
+ end
99
+ end
100
+ end
101
+ end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module CollaborativeTexts
5
+ module Admin
6
+ # This command is executed when the user changes a Document from the admin
7
+ # panel.
8
+ class UpdateDocumentSettings < Decidim::Commands::UpdateResource
9
+ fetch_form_attributes :announcement
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,28 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module CollaborativeTexts
5
+ # This command is executed when the user creates a Document from the admin
6
+ # panel.
7
+ class CreateSuggestion < Decidim::Commands::CreateResource
8
+ fetch_form_attributes :author, :document_version, :changeset
9
+
10
+ private
11
+
12
+ def resource_class = Decidim::CollaborativeTexts::Suggestion
13
+
14
+ def extra_params
15
+ {
16
+ extra: {
17
+ participatory_space: {
18
+ title: form.document&.participatory_space&.title
19
+ },
20
+ resource: {
21
+ title: form.document&.title
22
+ }
23
+ }
24
+ }
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,50 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module CollaborativeTexts
5
+ # This command is executed when the user creates a Document from the admin
6
+ # panel.
7
+ class Rollout < Decidim::Commands::CreateResource
8
+ fetch_form_attributes :body, :document, :draft
9
+
10
+ # 1: add accepted suggestions authors as co-authors
11
+ # 2: transfer non-accepted suggestions to the new version
12
+ def run_after_hooks
13
+ process_accepted_suggestions
14
+ return if form.draft?
15
+
16
+ move_pending_suggestions
17
+ end
18
+
19
+ private
20
+
21
+ def resource_class = Decidim::CollaborativeTexts::Version
22
+
23
+ # move pending suggestions to the new version
24
+ # rubocop:disable Rails/SkipsModelValidations
25
+ def move_pending_suggestions
26
+ return if form.pending_suggestions.empty?
27
+
28
+ form.pending_suggestions.update_all(document_version_id: resource.id)
29
+ end
30
+ # rubocop:enable Rails/SkipsModelValidations
31
+
32
+ # Add as co-authors and change the status of the suggestions to accepted
33
+ def process_accepted_suggestions
34
+ affected_users = []
35
+ form.accepted_suggestions.each do |suggestion|
36
+ suggestion.accepted!
37
+ resource.document.add_coauthor suggestion.author
38
+ affected_users << suggestion.author
39
+ end
40
+
41
+ Decidim::EventsManager.publish(
42
+ event: "decidim.events.collaborative_texts.suggestion_accepted",
43
+ event_class: Decidim::CollaborativeTexts::SuggestionAcceptedEvent,
44
+ resource: resource.document,
45
+ affected_users: affected_users.uniq
46
+ )
47
+ end
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "active_support/concern"
4
+
5
+ module Decidim
6
+ module CollaborativeTexts
7
+ module Admin
8
+ module Filterable
9
+ extend ActiveSupport::Concern
10
+
11
+ included do
12
+ include Decidim::Admin::Filterable
13
+
14
+ private
15
+
16
+ def base_query
17
+ collection
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module CollaborativeTexts
5
+ module Admin
6
+ # This controller is the abstract class from which all other controllers of
7
+ # this engine inherit.
8
+ #
9
+ # Note that it inherits from `Decidim::Components::BaseController`, which
10
+ # override its layout and provide all kinds of useful methods.
11
+ class ApplicationController < Decidim::Admin::Components::BaseController
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,142 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module CollaborativeTexts
5
+ module Admin
6
+ class DocumentsController < Admin::ApplicationController
7
+ include Decidim::CollaborativeTexts::Admin::Filterable
8
+ include Decidim::Admin::HasTrashableResources
9
+
10
+ helper_method :documents, :document
11
+
12
+ def index
13
+ enforce_permission_to :read, :collaborative_text
14
+ end
15
+
16
+ def new
17
+ enforce_permission_to :create, :collaborative_text
18
+ @form = form(DocumentForm).instance
19
+ end
20
+
21
+ def create
22
+ enforce_permission_to :create, :collaborative_text
23
+ @form = form(DocumentForm).from_params(params)
24
+
25
+ CreateDocument.call(@form) do
26
+ on(:ok) do
27
+ flash[:notice] = I18n.t("documents.create.success", scope: "decidim.collaborative_texts.admin")
28
+ redirect_to documents_path
29
+ end
30
+
31
+ on(:invalid) do
32
+ flash.now[:alert] = I18n.t("documents.create.invalid", scope: "decidim.collaborative_texts.admin")
33
+ render action: "new", status: :unprocessable_entity
34
+ end
35
+ end
36
+ end
37
+
38
+ def edit
39
+ enforce_permission_to(:update, :collaborative_text, document:)
40
+ @form = form(DocumentForm).from_model(document)
41
+ end
42
+
43
+ def update
44
+ enforce_permission_to(:update, :collaborative_text, document:)
45
+ @form = form(DocumentForm).from_params(params)
46
+
47
+ UpdateDocument.call(@form, document) do
48
+ on(:ok) do
49
+ flash[:notice] = I18n.t("documents.update.success", scope: "decidim.collaborative_texts.admin")
50
+ redirect_to documents_path
51
+ end
52
+
53
+ on(:invalid) do
54
+ flash.now[:alert] = I18n.t("documents.update.invalid", scope: "decidim.collaborative_texts.admin")
55
+ # This is a safe-guard in case there is no body coming from the POST request (as this attribute is read-only in certain cases)
56
+ @form.body = document.body if @form.body.blank?
57
+ render action: "edit", status: :unprocessable_entity
58
+ end
59
+ end
60
+ end
61
+
62
+ def edit_settings
63
+ enforce_permission_to(:update, :collaborative_text, document:)
64
+ @form = form(Admin::DocumentForm).from_model(document)
65
+ end
66
+
67
+ def update_settings
68
+ enforce_permission_to(:update, :collaborative_text, document:)
69
+ @form = form(Admin::DocumentForm).from_params(params)
70
+
71
+ UpdateDocumentSettings.call(@form, document) do
72
+ on(:ok) do
73
+ flash[:notice] = I18n.t("documents.update_settings.success", scope: "decidim.collaborative_texts.admin")
74
+ redirect_to documents_path
75
+ end
76
+
77
+ on(:invalid) do
78
+ flash.now[:alert] = I18n.t("documents.update_settings.invalid", scope: "decidim.collaborative_texts.admin")
79
+ render action: "edit_settings", status: :unprocessable_entity
80
+ end
81
+ end
82
+ end
83
+
84
+ def publish
85
+ enforce_permission_to(:update, :collaborative_text, document:)
86
+ Decidim::CollaborativeTexts::Admin::PublishDocument.call(document, current_user) do
87
+ on(:ok) do
88
+ flash[:notice] = I18n.t("documents.publish.success", scope: "decidim.collaborative_texts.admin")
89
+ redirect_to documents_path
90
+ end
91
+
92
+ on(:invalid) do
93
+ flash.now[:alert] = I18n.t("documents.publish.invalid", scope: "decidim.collaborative_texts.admin")
94
+ render action: "index", status: :unprocessable_entity
95
+ end
96
+ end
97
+ end
98
+
99
+ def unpublish
100
+ enforce_permission_to(:update, :collaborative_text, document:)
101
+ Decidim::CollaborativeTexts::Admin::UnpublishDocument.call(document, current_user) do
102
+ on(:ok) do
103
+ flash[:notice] = I18n.t("documents.unpublish.success", scope: "decidim.collaborative_texts.admin")
104
+ redirect_to documents_path
105
+ end
106
+
107
+ on(:invalid) do
108
+ flash.now[:alert] = I18n.t("documents.unpublish.invalid", scope: "decidim.collaborative_texts.admin")
109
+ render action: "index", status: :unprocessable_entity
110
+ end
111
+ end
112
+ end
113
+
114
+ private
115
+
116
+ def trashable_deleted_resource_type
117
+ :document
118
+ end
119
+
120
+ def trashable_deleted_resource
121
+ @trashable_deleted_resource ||= collection.with_deleted.find_by(id: params[:id])
122
+ end
123
+
124
+ def trashable_deleted_collection
125
+ @trashable_deleted_collection = filtered_collection.only_deleted.deleted_at_desc
126
+ end
127
+
128
+ def documents
129
+ @documents ||= filtered_collection
130
+ end
131
+
132
+ def document
133
+ @document ||= collection.find(params[:id])
134
+ end
135
+
136
+ def collection
137
+ @collection ||= Document.where(component: current_component)
138
+ end
139
+ end
140
+ end
141
+ end
142
+ end
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module CollaborativeTexts
5
+ # This controller is the abstract class from which all other controllers of
6
+ # this engine inherit.
7
+ #
8
+ # Note that it inherits from `Decidim::Components::Basecontroller`, which
9
+ # override its layout and provide all kinds of useful methods.
10
+ class ApplicationController < Decidim::Components::BaseController
11
+ helper Decidim::CollaborativeTexts::ApplicationHelper
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,57 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module CollaborativeTexts
5
+ class DocumentsController < Decidim::CollaborativeTexts::ApplicationController
6
+ include Decidim::Paginable
7
+ include Decidim::FormFactory
8
+ include Decidim::AjaxPermissionHandler
9
+
10
+ helper_method :documents, :document, :paginate_documents
11
+
12
+ def index; end
13
+
14
+ def show
15
+ raise ActionController::RoutingError, "Not Found" unless document
16
+ end
17
+
18
+ # roll out a new version of the document (only admins)
19
+ def update
20
+ enforce_permission_to(:rollout, :collaborative_text, document:)
21
+
22
+ @form = form(RolloutForm).from_params(params, document:)
23
+ Rollout.call(@form) do
24
+ on(:ok) do
25
+ render json: { redirect: @form.draft? ? presenter.edit : presenter.path }
26
+ end
27
+
28
+ on(:invalid) do
29
+ render json: { message: I18n.t("document.rollout.invalid", scope: "decidim.collaborative_texts", errors: @form.errors.full_messages) }, status: :unprocessable_entity
30
+ end
31
+ end
32
+ end
33
+
34
+ private
35
+
36
+ def document
37
+ @document ||= documents.find(params[:id])
38
+ end
39
+
40
+ def presenter
41
+ @presenter ||= Decidim::ResourceLocatorPresenter.new(document)
42
+ end
43
+
44
+ def documents
45
+ @documents ||= if current_user&.admin?
46
+ Document.where(component: current_component)
47
+ else
48
+ Document.published.where(component: current_component)
49
+ end
50
+ end
51
+
52
+ def paginate_documents
53
+ @paginate_documents ||= paginate(documents.enabled_desc)
54
+ end
55
+ end
56
+ end
57
+ end