decidim-proposals 0.29.2 → 0.30.0.rc1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/app/cells/decidim/proposals/highlighted_proposals_for_component/show.erb +1 -1
- data/app/cells/decidim/proposals/highlighted_proposals_for_component_cell.rb +1 -1
- data/app/cells/decidim/proposals/participatory_text_proposal_cell.rb +1 -1
- data/app/cells/decidim/proposals/proposal_g/show.erb +13 -0
- data/app/cells/decidim/proposals/proposal_g_cell.rb +13 -0
- data/app/cells/decidim/proposals/proposal_history_cell.rb +107 -0
- data/app/cells/decidim/proposals/proposal_l/show.erb +37 -0
- data/app/cells/decidim/proposals/proposal_l_cell.rb +9 -0
- data/app/cells/decidim/proposals/proposal_metadata_cell.rb +2 -2
- data/app/cells/decidim/proposals/proposal_vote/show.erb +75 -0
- data/app/cells/decidim/proposals/proposal_vote_cell.rb +43 -0
- data/app/commands/decidim/proposals/accept_coauthorship.rb +62 -0
- data/app/commands/decidim/proposals/admin/assign_proposals_to_valuator.rb +14 -0
- data/app/commands/decidim/proposals/admin/create_proposal.rb +6 -14
- data/app/commands/decidim/proposals/admin/create_proposal_note.rb +20 -11
- data/app/commands/decidim/proposals/admin/import_proposals.rb +0 -5
- data/app/commands/decidim/proposals/admin/merge_proposals.rb +2 -2
- data/app/commands/decidim/proposals/admin/proposal_notes_methods.rb +48 -0
- data/app/commands/decidim/proposals/admin/reply_proposal_note.rb +92 -0
- data/app/commands/decidim/proposals/admin/split_proposals.rb +2 -2
- data/app/commands/decidim/proposals/admin/update_proposal.rb +10 -16
- data/app/commands/decidim/proposals/admin/update_proposal_taxonomies.rb +34 -0
- data/app/commands/decidim/proposals/cancel_coauthorship.rb +32 -0
- data/app/commands/decidim/proposals/create_collaborative_draft.rb +1 -2
- data/app/commands/decidim/proposals/create_proposal.rb +1 -2
- data/app/commands/decidim/proposals/invite_coauthor.rb +45 -0
- data/app/commands/decidim/proposals/publish_collaborative_draft.rb +1 -2
- data/app/commands/decidim/proposals/reject_coauthorship.rb +54 -0
- data/app/commands/decidim/proposals/update_collaborative_draft.rb +1 -2
- data/app/commands/decidim/proposals/update_proposal.rb +1 -2
- data/app/controllers/concerns/decidim/proposals/admin/filterable.rb +5 -1
- data/app/controllers/concerns/decidim/proposals/admin/needs_interpolations.rb +40 -0
- data/app/controllers/decidim/proposals/admin/proposal_answers_controller.rb +50 -2
- data/app/controllers/decidim/proposals/admin/proposal_notes_controller.rb +18 -0
- data/app/controllers/decidim/proposals/admin/proposals_controller.rb +41 -85
- data/app/controllers/decidim/proposals/collaborative_drafts_controller.rb +2 -4
- data/app/controllers/decidim/proposals/invite_coauthors_controller.rb +87 -0
- data/app/controllers/decidim/proposals/proposals_controller.rb +7 -32
- data/app/events/decidim/proposals/accepted_coauthorship_event.rb +8 -0
- data/app/events/decidim/proposals/admin/proposal_assigned_to_valuator_event.rb +27 -0
- data/app/events/decidim/proposals/admin/proposal_note_created_event.rb +5 -0
- data/app/events/decidim/proposals/coauthor_accepted_invite_event.rb +49 -0
- data/app/events/decidim/proposals/coauthor_invited_event.rb +45 -0
- data/app/events/decidim/proposals/coauthor_rejected_invite_event.rb +8 -0
- data/app/events/decidim/proposals/rejected_coauthorship_event.rb +8 -0
- data/app/events/decidim/proposals/update_proposal_taxonomies_event.rb +9 -0
- data/app/forms/decidim/proposals/admin/proposal_answer_form.rb +1 -0
- data/app/forms/decidim/proposals/admin/proposal_base_form.rb +3 -31
- data/app/forms/decidim/proposals/admin/proposal_form.rb +11 -6
- data/app/forms/decidim/proposals/admin/proposals_import_form.rb +0 -5
- data/app/forms/decidim/proposals/collaborative_draft_form.rb +0 -8
- data/app/forms/decidim/proposals/proposal_form.rb +5 -32
- data/app/helpers/decidim/proposals/admin/proposal_bulk_actions_helper.rb +25 -0
- data/app/helpers/decidim/proposals/admin/proposals_helper.rb +0 -1
- data/app/helpers/decidim/proposals/application_helper.rb +23 -14
- data/app/helpers/decidim/proposals/collaborative_draft_helper.rb +7 -7
- data/app/helpers/decidim/proposals/map_helper.rb +0 -18
- data/app/helpers/decidim/proposals/proposal_votes_helper.rb +15 -2
- data/app/jobs/decidim/proposals/admin/proposal_answer_job.rb +20 -0
- data/app/models/decidim/proposals/collaborative_draft.rb +10 -1
- data/app/models/decidim/proposals/proposal.rb +66 -5
- data/app/models/decidim/proposals/proposal_note.rb +11 -0
- data/app/models/decidim/proposals/proposal_state.rb +1 -1
- data/app/packs/entrypoints/decidim_proposals.js +1 -0
- data/app/packs/entrypoints/decidim_proposals_geocoding.js +2 -0
- data/app/packs/src/decidim/proposals/admin/proposals.js +16 -1
- data/app/packs/src/decidim/proposals/exit_handler.js +73 -0
- data/app/packs/stylesheets/decidim/proposals/proposals.scss +248 -3
- data/app/permissions/decidim/proposals/admin/permissions.rb +2 -5
- data/app/permissions/decidim/proposals/permissions.rb +42 -0
- data/app/presenters/decidim/proposals/admin_log/proposal_presenter.rb +1 -1
- data/app/presenters/decidim/proposals/proposal_presenter.rb +1 -1
- data/app/queries/decidim/proposals/filtered_proposals.rb +2 -2
- data/app/queries/decidim/proposals/metrics/accepted_proposals_metric_manage.rb +2 -2
- data/app/queries/decidim/proposals/metrics/endorsements_metric_manage.rb +10 -10
- data/app/queries/decidim/proposals/metrics/proposal_followers_metric_measure.rb +4 -4
- data/app/queries/decidim/proposals/metrics/proposal_participants_metric_measure.rb +6 -6
- data/app/queries/decidim/proposals/metrics/proposals_metric_manage.rb +6 -6
- data/app/queries/decidim/proposals/metrics/votes_metric_manage.rb +6 -6
- data/app/services/decidim/proposals/proposal_builder.rb +1 -1
- data/app/views/decidim/proposals/admin/proposal_notes/_form.html.erb +3 -3
- data/app/views/decidim/proposals/admin/proposal_notes/_proposal_note.html.erb +28 -0
- data/app/views/decidim/proposals/admin/proposal_notes/_proposal_note_reply.html.erb +9 -0
- data/app/views/decidim/proposals/admin/proposal_notes/_proposal_notes.html.erb +4 -28
- data/app/views/decidim/proposals/admin/proposal_states/_form.html.erb +1 -1
- data/app/views/decidim/proposals/admin/proposals/_actions.html.erb +21 -0
- data/app/views/decidim/proposals/admin/proposals/_bulk-actions.html.erb +3 -2
- data/app/views/decidim/proposals/admin/proposals/_form.html.erb +16 -23
- data/app/views/decidim/proposals/admin/proposals/_proposal-tr.html.erb +12 -28
- data/app/views/decidim/proposals/admin/proposals/_proposals-thead.html.erb +45 -0
- data/app/views/decidim/proposals/admin/proposals/bulk_actions/_apply_answer_template.html.erb +22 -0
- data/app/views/decidim/proposals/admin/proposals/bulk_actions/_dropdown.html.erb +15 -11
- data/app/views/decidim/proposals/admin/proposals/bulk_actions/_taxonomy_change.html.erb +23 -0
- data/app/views/decidim/proposals/admin/proposals/index.html.erb +17 -48
- data/app/views/decidim/proposals/admin/proposals/manage_trash.html.erb +18 -0
- data/app/views/decidim/proposals/admin/proposals/publish_answers.js.erb +1 -1
- data/app/views/decidim/proposals/admin/proposals/show.html.erb +10 -22
- data/app/views/decidim/proposals/admin/proposals/update_attribute.js.erb +1 -1
- data/app/views/decidim/proposals/admin/proposals_imports/new.html.erb +0 -3
- data/app/views/decidim/proposals/collaborative_drafts/_collaborative_actions.html.erb +9 -0
- data/app/views/decidim/proposals/collaborative_drafts/_collaborative_draft_aside.html.erb +0 -15
- data/app/views/decidim/proposals/collaborative_drafts/_edit_form_fields.html.erb +4 -6
- data/app/views/decidim/proposals/collaborative_drafts/index.html.erb +6 -2
- data/app/views/decidim/proposals/collaborative_drafts/show.html.erb +27 -11
- data/app/views/decidim/proposals/proposal_votes/update_buttons_and_counters.js.erb +29 -9
- data/app/views/decidim/proposals/proposals/_actions.html.erb +4 -7
- data/app/views/decidim/proposals/proposals/_edit_form_fields.html.erb +17 -22
- data/app/views/decidim/proposals/proposals/_exit_modal.html.erb +17 -0
- data/app/views/decidim/proposals/proposals/_notification_alert_box.html.erb +1 -0
- data/app/views/decidim/proposals/proposals/_proposal_actions.html.erb +19 -0
- data/app/views/decidim/proposals/proposals/_proposal_aside.html.erb +9 -32
- data/app/views/decidim/proposals/proposals/_proposal_voting_rules.html.erb +33 -0
- data/app/views/decidim/proposals/proposals/_remaining_votes_count.html.erb +2 -2
- data/app/views/decidim/proposals/proposals/_remaining_votes_notification.html.erb +12 -0
- data/app/views/decidim/proposals/proposals/_update_proposal_voting_rules.html.erb +6 -0
- data/app/views/decidim/proposals/proposals/_vote_button.html.erb +12 -8
- data/app/views/decidim/proposals/proposals/_votes_count.html.erb +2 -1
- data/app/views/decidim/proposals/proposals/_voting_rules.html.erb +1 -7
- data/app/views/decidim/proposals/proposals/index.html.erb +10 -18
- data/app/views/decidim/proposals/proposals/index.js.erb +1 -1
- data/app/views/decidim/proposals/proposals/participatory_texts/_proposal_vote_button.html.erb +3 -1
- data/app/views/decidim/proposals/proposals/show.html.erb +35 -15
- data/config/locales/ar.yml +18 -72
- data/config/locales/bg.yml +7 -89
- data/config/locales/bs-BA.yml +0 -13
- data/config/locales/ca.yml +212 -72
- data/config/locales/cs.yml +213 -73
- data/config/locales/de.yml +214 -75
- data/config/locales/el.yml +8 -82
- data/config/locales/en.yml +209 -69
- data/config/locales/es-MX.yml +213 -73
- data/config/locales/es-PY.yml +213 -73
- data/config/locales/es.yml +215 -75
- data/config/locales/eu.yml +217 -78
- data/config/locales/fi-plain.yml +216 -75
- data/config/locales/fi.yml +216 -75
- data/config/locales/fr-CA.yml +118 -87
- data/config/locales/fr.yml +118 -87
- data/config/locales/ga-IE.yml +0 -19
- data/config/locales/gl.yml +8 -43
- data/config/locales/hu.yml +6 -66
- data/config/locales/id-ID.yml +8 -40
- data/config/locales/is-IS.yml +0 -14
- data/config/locales/it.yml +8 -53
- data/config/locales/ja.yml +162 -87
- data/config/locales/lt.yml +8 -83
- data/config/locales/lv.yml +8 -50
- data/config/locales/nl.yml +6 -55
- data/config/locales/no.yml +8 -42
- data/config/locales/pl.yml +6 -88
- data/config/locales/pt-BR.yml +6 -74
- data/config/locales/pt.yml +8 -54
- data/config/locales/ro-RO.yml +10 -54
- data/config/locales/ru.yml +0 -18
- data/config/locales/sk.yml +8 -50
- data/config/locales/sr-CS.yml +0 -14
- data/config/locales/sv.yml +128 -85
- data/config/locales/tr-TR.yml +8 -51
- data/config/locales/uk.yml +0 -18
- data/config/locales/zh-CN.yml +8 -51
- data/config/locales/zh-TW.yml +8 -84
- data/db/migrate/20171220084719_add_published_at_to_proposals.rb +1 -1
- data/db/migrate/20181016132225_add_organization_as_author.rb +1 -1
- data/db/migrate/20200120215928_move_proposal_endorsements_to_core_endorsements.rb +1 -1
- data/db/migrate/20200827154156_add_commentable_counter_cache_to_proposals.rb +3 -3
- data/db/migrate/20210310102839_add_followable_counter_cache_to_proposals.rb +1 -1
- data/db/migrate/20240110203504_create_default_proposal_states.rb +1 -1
- data/db/migrate/20240404202756_add_valuation_assignments_count_to_decidim_proposals_proposals.rb +1 -1
- data/db/migrate/20240617091140_add_email_on_assigned_proposals_to_users.rb +7 -0
- data/db/migrate/20240617170052_add_parent_relation_to_decidim_proposal_notes.rb +7 -0
- data/db/migrate/20240828103755_add_deleted_at_to_decidim_proposals_proposals.rb +8 -0
- data/decidim-proposals.gemspec +1 -1
- data/lib/decidim/api/functions/proposal_finder_helper.rb +12 -0
- data/lib/decidim/api/functions/proposal_list_helper.rb +12 -0
- data/lib/decidim/api/proposal_type.rb +17 -25
- data/lib/decidim/api/proposals_type.rb +4 -19
- data/lib/decidim/proposals/admin_engine.rb +12 -3
- data/lib/decidim/proposals/admin_filter.rb +3 -6
- data/lib/decidim/proposals/component.rb +4 -5
- data/lib/decidim/proposals/download_your_data_proposal_serializer.rb +15 -0
- data/lib/decidim/proposals/engine.rb +5 -0
- data/lib/decidim/proposals/import/proposal_creator.rb +4 -4
- data/lib/decidim/proposals/proposal_serializer.rb +12 -29
- data/lib/decidim/proposals/seeds.rb +21 -17
- data/lib/decidim/proposals/test/factories.rb +2 -1
- data/lib/decidim/proposals/version.rb +1 -1
- data/lib/decidim/proposals.rb +4 -0
- metadata +65 -29
- data/app/commands/decidim/proposals/admin/update_proposal_category.rb +0 -70
- data/app/commands/decidim/proposals/admin/update_proposal_scope.rb +0 -75
- data/app/events/decidim/proposals/admin/update_proposal_category_event.rb +0 -11
- data/app/events/decidim/proposals/admin/update_proposal_scope_event.rb +0 -11
- data/app/views/decidim/proposals/admin/proposals/bulk_actions/_recategorize.html.erb +0 -15
- data/app/views/decidim/proposals/admin/proposals/bulk_actions/_scope-change.html.erb +0 -21
- data/app/views/decidim/proposals/collaborative_drafts/_actions.html.erb +0 -7
@@ -6,7 +6,9 @@ module Decidim
|
|
6
6
|
# This controller allows admins to manage proposals in a participatory process.
|
7
7
|
class ProposalsController < Admin::ApplicationController
|
8
8
|
include Decidim::ApplicationHelper
|
9
|
+
include Decidim::Admin::ComponentTaxonomiesHelper
|
9
10
|
include Decidim::Proposals::Admin::Filterable
|
11
|
+
include Decidim::Admin::HasTrashableResources
|
10
12
|
|
11
13
|
helper Proposals::ApplicationHelper
|
12
14
|
helper Decidim::Proposals::Admin::ProposalRankingsHelper
|
@@ -47,33 +49,45 @@ module Decidim
|
|
47
49
|
end
|
48
50
|
end
|
49
51
|
|
50
|
-
def
|
51
|
-
enforce_permission_to :update, :
|
52
|
+
def update_taxonomies
|
53
|
+
enforce_permission_to :update, :proposal_taxonomy
|
52
54
|
|
53
|
-
Admin::
|
54
|
-
on(:
|
55
|
-
flash
|
56
|
-
"proposals.
|
55
|
+
Admin::UpdateProposalTaxonomies.call(params[:taxonomies], proposal_ids, current_organization) do
|
56
|
+
on(:invalid_taxonomies) do
|
57
|
+
flash[:error] = I18n.t(
|
58
|
+
"proposals.update_taxonomies.select_a_taxonomy",
|
57
59
|
scope: "decidim.proposals.admin"
|
58
60
|
)
|
59
61
|
end
|
60
62
|
|
61
|
-
on(:
|
62
|
-
flash
|
63
|
-
"proposals.
|
63
|
+
on(:invalid_resources) do
|
64
|
+
flash[:alert] = I18n.t(
|
65
|
+
"proposals.update_taxonomies.select_a_proposal",
|
64
66
|
scope: "decidim.proposals.admin"
|
65
67
|
)
|
66
68
|
end
|
67
69
|
|
68
|
-
on(:
|
69
|
-
|
70
|
-
|
70
|
+
on(:update_resources_taxonomies) do |response|
|
71
|
+
if response[:successful].any?
|
72
|
+
flash[:notice] = t(
|
73
|
+
"proposals.update_taxonomies.success",
|
74
|
+
taxonomies: response[:taxonomies].map { |taxonomy| decidim_escape_translated(taxonomy.name) }.to_sentence,
|
75
|
+
proposals: response[:successful].map { |resource| decidim_escape_translated(resource.title) }.to_sentence,
|
76
|
+
scope: "decidim.proposals.admin"
|
77
|
+
)
|
78
|
+
end
|
79
|
+
if response[:errored].any?
|
80
|
+
flash[:alert] = t(
|
81
|
+
"proposals.update_taxonomies.invalid",
|
82
|
+
taxonomies: response[:taxonomies].map { |taxonomy| decidim_escape_translated(taxonomy.name) }.to_sentence,
|
83
|
+
proposals: response[:errored].map { |resource| decidim_escape_translated(resource.title) }.to_sentence,
|
84
|
+
scope: "decidim.proposals.admin"
|
85
|
+
)
|
86
|
+
end
|
71
87
|
end
|
72
88
|
end
|
73
89
|
|
74
|
-
|
75
|
-
format.js { render :update_attribute, locals: { form_selector: "#js-form-recategorize-projects", attribute_selector: "#category_id" } }
|
76
|
-
end
|
90
|
+
redirect_to proposals_path
|
77
91
|
end
|
78
92
|
|
79
93
|
def publish_answers
|
@@ -97,34 +111,6 @@ module Decidim
|
|
97
111
|
end
|
98
112
|
end
|
99
113
|
|
100
|
-
def update_scope
|
101
|
-
enforce_permission_to :update, :proposal_scope
|
102
|
-
|
103
|
-
Admin::UpdateProposalScope.call(params[:scope_id], proposal_ids) do
|
104
|
-
on(:invalid_scope) do
|
105
|
-
flash.now[:error] = t(
|
106
|
-
"proposals.update_scope.select_a_scope",
|
107
|
-
scope: "decidim.proposals.admin"
|
108
|
-
)
|
109
|
-
end
|
110
|
-
|
111
|
-
on(:invalid_proposal_ids) do
|
112
|
-
flash.now[:alert] = t(
|
113
|
-
"proposals.update_scope.select_a_proposal",
|
114
|
-
scope: "decidim.proposals.admin"
|
115
|
-
)
|
116
|
-
end
|
117
|
-
|
118
|
-
on(:update_proposals_scope) do
|
119
|
-
flash.now[:notice] = update_proposals_bulk_response_successful(@response, :scope)
|
120
|
-
flash.now[:alert] = update_proposals_bulk_response_errored(@response, :scope)
|
121
|
-
end
|
122
|
-
end
|
123
|
-
respond_to do |format|
|
124
|
-
format.js { render :update_attribute, locals: { form_selector: "#js-form-scope-change-projects", attribute_selector: "#scope_id" } }
|
125
|
-
end
|
126
|
-
end
|
127
|
-
|
128
114
|
def edit
|
129
115
|
enforce_permission_to(:edit, :proposal, proposal:)
|
130
116
|
@form = form(Admin::ProposalForm).from_model(proposal)
|
@@ -150,6 +136,18 @@ module Decidim
|
|
150
136
|
|
151
137
|
private
|
152
138
|
|
139
|
+
def trashable_deleted_resource_type
|
140
|
+
:proposal
|
141
|
+
end
|
142
|
+
|
143
|
+
def trashable_deleted_resource
|
144
|
+
@trashable_deleted_resource ||= collection.with_deleted.find_by(id: params[:id])
|
145
|
+
end
|
146
|
+
|
147
|
+
def trashable_deleted_collection
|
148
|
+
@trashable_deleted_collection = filtered_collection.only_deleted.deleted_at_desc
|
149
|
+
end
|
150
|
+
|
153
151
|
def collection
|
154
152
|
@collection ||= Proposal.where(component: current_component).not_hidden.published
|
155
153
|
end
|
@@ -166,48 +164,6 @@ module Decidim
|
|
166
164
|
@proposal_ids ||= params[:proposal_ids]
|
167
165
|
end
|
168
166
|
|
169
|
-
def update_proposals_bulk_response_successful(response, subject)
|
170
|
-
return if response[:successful].blank?
|
171
|
-
|
172
|
-
case subject
|
173
|
-
when :category
|
174
|
-
t(
|
175
|
-
"proposals.update_category.success",
|
176
|
-
subject_name: response[:subject_name],
|
177
|
-
proposals: response[:successful].to_sentence,
|
178
|
-
scope: "decidim.proposals.admin"
|
179
|
-
)
|
180
|
-
when :scope
|
181
|
-
t(
|
182
|
-
"proposals.update_scope.success",
|
183
|
-
subject_name: response[:subject_name],
|
184
|
-
proposals: response[:successful].to_sentence,
|
185
|
-
scope: "decidim.proposals.admin"
|
186
|
-
)
|
187
|
-
end
|
188
|
-
end
|
189
|
-
|
190
|
-
def update_proposals_bulk_response_errored(response, subject)
|
191
|
-
return if response[:errored].blank?
|
192
|
-
|
193
|
-
case subject
|
194
|
-
when :category
|
195
|
-
t(
|
196
|
-
"proposals.update_category.invalid",
|
197
|
-
subject_name: response[:subject_name],
|
198
|
-
proposals: response[:errored].to_sentence,
|
199
|
-
scope: "decidim.proposals.admin"
|
200
|
-
)
|
201
|
-
when :scope
|
202
|
-
t(
|
203
|
-
"proposals.update_scope.invalid",
|
204
|
-
subject_name: response[:subject_name],
|
205
|
-
proposals: response[:errored].to_sentence,
|
206
|
-
scope: "decidim.proposals.admin"
|
207
|
-
)
|
208
|
-
end
|
209
|
-
end
|
210
|
-
|
211
167
|
def form_presenter
|
212
168
|
@form_presenter ||= present(@form, presenter_class: Decidim::Proposals::ProposalPresenter)
|
213
169
|
end
|
@@ -27,8 +27,7 @@ module Decidim
|
|
27
27
|
@collaborative_drafts = search
|
28
28
|
.result
|
29
29
|
.not_hidden
|
30
|
-
.includes(:
|
31
|
-
.includes(:scope)
|
30
|
+
.includes(:taxonomies)
|
32
31
|
|
33
32
|
@collaborative_drafts = reorder(@collaborative_drafts)
|
34
33
|
@collaborative_drafts = paginate(@collaborative_drafts)
|
@@ -144,9 +143,8 @@ module Decidim
|
|
144
143
|
def default_filter_params
|
145
144
|
{
|
146
145
|
search_text_cont: "",
|
147
|
-
|
146
|
+
with_any_taxonomies: nil,
|
148
147
|
with_any_state: %w(open),
|
149
|
-
with_any_scope: nil,
|
150
148
|
related_to: ""
|
151
149
|
}
|
152
150
|
end
|
@@ -0,0 +1,87 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Decidim
|
4
|
+
module Proposals
|
5
|
+
class InviteCoauthorsController < Decidim::Proposals::ApplicationController
|
6
|
+
include Decidim::ControllerHelpers
|
7
|
+
|
8
|
+
helper_method :proposal
|
9
|
+
|
10
|
+
before_action :authenticate_user!
|
11
|
+
|
12
|
+
# author invites coauthor
|
13
|
+
def create
|
14
|
+
enforce_permission_to :invite, :proposal_coauthor_invites, { proposal:, coauthor: }
|
15
|
+
|
16
|
+
InviteCoauthor.call(proposal, coauthor) do
|
17
|
+
on(:ok) do
|
18
|
+
flash[:notice] = I18n.t("create.success", scope: "decidim.proposals.invite_coauthors", author_name: coauthor.name)
|
19
|
+
end
|
20
|
+
|
21
|
+
on(:invalid) do
|
22
|
+
flash[:alert] = I18n.t("create.error", scope: "decidim.proposals.invite_coauthors")
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
redirect_to Decidim::ResourceLocatorPresenter.new(proposal).path
|
27
|
+
end
|
28
|
+
|
29
|
+
# author cancels invitation
|
30
|
+
def cancel
|
31
|
+
enforce_permission_to :cancel, :proposal_coauthor_invites, { proposal:, coauthor: }
|
32
|
+
|
33
|
+
CancelCoauthorship.call(proposal, coauthor) do
|
34
|
+
on(:ok) do
|
35
|
+
flash[:notice] = I18n.t("cancel.success", scope: "decidim.proposals.invite_coauthors", author_name: coauthor.name)
|
36
|
+
end
|
37
|
+
|
38
|
+
on(:invalid) do
|
39
|
+
flash[:alert] = I18n.t("cancel.error", scope: "decidim.proposals.invite_coauthors")
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
redirect_to Decidim::ResourceLocatorPresenter.new(proposal).path
|
44
|
+
end
|
45
|
+
|
46
|
+
# coauthor accepts invitation
|
47
|
+
def update
|
48
|
+
enforce_permission_to :accept, :proposal_coauthor_invites, { proposal:, coauthor: }
|
49
|
+
|
50
|
+
AcceptCoauthorship.call(proposal, current_user) do
|
51
|
+
on(:ok) do
|
52
|
+
render json: { message: I18n.t("update.success", scope: "decidim.proposals.invite_coauthors") }
|
53
|
+
end
|
54
|
+
|
55
|
+
on(:invalid) do
|
56
|
+
render json: { message: I18n.t("update.error", scope: "decidim.proposals.invite_coauthors") }, status: :unprocessable_entity
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
# coauthor declines invitation
|
62
|
+
def destroy
|
63
|
+
enforce_permission_to :decline, :proposal_coauthor_invites, { proposal:, coauthor: }
|
64
|
+
|
65
|
+
RejectCoauthorship.call(proposal, current_user) do
|
66
|
+
on(:ok) do
|
67
|
+
render json: { message: I18n.t("destroy.success", scope: "decidim.proposals.invite_coauthors") }
|
68
|
+
end
|
69
|
+
|
70
|
+
on(:invalid) do
|
71
|
+
render json: { message: I18n.t("destroy.error", scope: "decidim.proposals.invite_coauthors") }, status: :unprocessable_entity
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
private
|
77
|
+
|
78
|
+
def coauthor
|
79
|
+
@coauthor ||= Decidim::User.find(params[:id])
|
80
|
+
end
|
81
|
+
|
82
|
+
def proposal
|
83
|
+
@proposal ||= Proposal.where(component: current_component).find(params[:proposal_id])
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
@@ -39,7 +39,7 @@ module Decidim
|
|
39
39
|
.published
|
40
40
|
.not_hidden
|
41
41
|
.only_amendables
|
42
|
-
.includes(:
|
42
|
+
.includes(:taxonomies, :attachments, :coauthorships)
|
43
43
|
.order(position: :asc)
|
44
44
|
render "decidim/proposals/proposals/participatory_texts/participatory_text"
|
45
45
|
else
|
@@ -202,9 +202,8 @@ module Decidim
|
|
202
202
|
search_text_cont: "",
|
203
203
|
with_any_origin: nil,
|
204
204
|
activity: "all",
|
205
|
-
|
205
|
+
with_any_taxonomies: nil,
|
206
206
|
with_any_state: default_states,
|
207
|
-
with_any_scope: nil,
|
208
207
|
related_to: "",
|
209
208
|
type: "all"
|
210
209
|
}
|
@@ -282,36 +281,12 @@ module Decidim
|
|
282
281
|
def tab_panel_items
|
283
282
|
@tab_panel_items ||= [
|
284
283
|
{
|
285
|
-
enabled: @proposal
|
286
|
-
id: "
|
287
|
-
text: t("decidim
|
288
|
-
icon: resource_type_icon_key("
|
284
|
+
enabled: ProposalHistoryCell.new(@proposal).render?,
|
285
|
+
id: "included_history",
|
286
|
+
text: t("decidim.history", scope: "activerecord.models", count: 2),
|
287
|
+
icon: resource_type_icon_key("history"),
|
289
288
|
method: :cell,
|
290
|
-
args: ["decidim/
|
291
|
-
},
|
292
|
-
{
|
293
|
-
enabled: @proposal.linked_resources(:results, "included_proposals").present?,
|
294
|
-
id: "included_results",
|
295
|
-
text: t("decidim/accountability/result", scope: "activerecord.models", count: 2),
|
296
|
-
icon: resource_type_icon_key("Decidim::Accountability::Result"),
|
297
|
-
method: :cell,
|
298
|
-
args: ["decidim/linked_resources_for", @proposal, { type: :results, link_name: "included_proposals" }]
|
299
|
-
},
|
300
|
-
{
|
301
|
-
enabled: @proposal.linked_resources(:meetings, "proposals_from_meeting").present?,
|
302
|
-
id: "included_meetings",
|
303
|
-
text: t("decidim/meetings/meeting", scope: "activerecord.models", count: 2),
|
304
|
-
icon: resource_type_icon_key("Decidim::Meetings::Meeting"),
|
305
|
-
method: :cell,
|
306
|
-
args: ["decidim/linked_resources_for", @proposal, { type: :meetings, link_name: "proposals_from_meeting" }]
|
307
|
-
},
|
308
|
-
{
|
309
|
-
enabled: @proposal.linked_resources(:proposals, "copied_from_component").present?,
|
310
|
-
id: "included_proposals",
|
311
|
-
text: t("decidim/proposals/proposal", scope: "activerecord.models", count: 2),
|
312
|
-
icon: resource_type_icon_key("Decidim::Proposals::Proposal"),
|
313
|
-
method: :cell,
|
314
|
-
args: ["decidim/linked_resources_for", @proposal, { type: :proposals, link_name: "copied_from_component" }]
|
289
|
+
args: ["decidim/proposals/proposal_history", @proposal]
|
315
290
|
}
|
316
291
|
] + attachments_tab_panel_items(@proposal)
|
317
292
|
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Decidim
|
4
|
+
module Proposals
|
5
|
+
module Admin
|
6
|
+
class ProposalAssignedToValuatorEvent < Decidim::Events::SimpleEvent
|
7
|
+
include Rails.application.routes.mounted_helpers
|
8
|
+
|
9
|
+
i18n_attributes :admin_proposal_info_url, :admin_proposal_info_path
|
10
|
+
|
11
|
+
def admin_proposal_info_path
|
12
|
+
ResourceLocatorPresenter.new(resource).show
|
13
|
+
end
|
14
|
+
|
15
|
+
def admin_proposal_info_url
|
16
|
+
send(resource.component.mounted_admin_engine).proposal_url(resource, resource.component.mounted_params)
|
17
|
+
end
|
18
|
+
|
19
|
+
private
|
20
|
+
|
21
|
+
def organization
|
22
|
+
@organization ||= component.participatory_space.organization
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -4,6 +4,7 @@ module Decidim
|
|
4
4
|
module Proposals
|
5
5
|
module Admin
|
6
6
|
class ProposalNoteCreatedEvent < Decidim::Events::SimpleEvent
|
7
|
+
include Decidim::Events::AuthorEvent
|
7
8
|
include Rails.application.routes.mounted_helpers
|
8
9
|
|
9
10
|
i18n_attributes :admin_proposal_info_url, :admin_proposal_info_path
|
@@ -18,6 +19,10 @@ module Decidim
|
|
18
19
|
|
19
20
|
private
|
20
21
|
|
22
|
+
def author
|
23
|
+
Decidim::User.find(extra[:note_author_id])
|
24
|
+
end
|
25
|
+
|
21
26
|
def organization
|
22
27
|
@organization ||= component.participatory_space.organization
|
23
28
|
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Decidim
|
4
|
+
module Proposals
|
5
|
+
class CoauthorAcceptedInviteEvent < Decidim::Events::BaseEvent
|
6
|
+
include Decidim::Events::NotificationEvent
|
7
|
+
include Decidim::Core::Engine.routes.url_helpers
|
8
|
+
|
9
|
+
def notification_title
|
10
|
+
I18n.t("notification_title", **i18n_options).html_safe
|
11
|
+
end
|
12
|
+
|
13
|
+
delegate :name, to: :author, prefix: true
|
14
|
+
delegate :name, to: :coauthor, prefix: true, allow_nil: true
|
15
|
+
|
16
|
+
def author_path
|
17
|
+
profile_path(author.nickname)
|
18
|
+
end
|
19
|
+
|
20
|
+
def coauthor_path
|
21
|
+
profile_path(coauthor.nickname) if coauthor
|
22
|
+
end
|
23
|
+
|
24
|
+
def author
|
25
|
+
resource.creator_author
|
26
|
+
end
|
27
|
+
|
28
|
+
def coauthor
|
29
|
+
@coauthor ||= Decidim::User.find_by(id: extra["coauthor_id"])
|
30
|
+
end
|
31
|
+
|
32
|
+
def i18n_scope
|
33
|
+
event_name
|
34
|
+
end
|
35
|
+
|
36
|
+
def i18n_options
|
37
|
+
{
|
38
|
+
scope: i18n_scope,
|
39
|
+
coauthor_name:,
|
40
|
+
coauthor_path:,
|
41
|
+
author_name:,
|
42
|
+
author_path:,
|
43
|
+
resource_path:,
|
44
|
+
resource_title:
|
45
|
+
}
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Decidim
|
4
|
+
module Proposals
|
5
|
+
class CoauthorInvitedEvent < Decidim::Events::SimpleEvent
|
6
|
+
include Decidim::Events::CoauthorEvent
|
7
|
+
include Decidim::Core::Engine.routes.url_helpers
|
8
|
+
|
9
|
+
def action_cell
|
10
|
+
"decidim/notification_actions/buttons" unless user_is_coauthor?
|
11
|
+
end
|
12
|
+
|
13
|
+
def action_data
|
14
|
+
[
|
15
|
+
{
|
16
|
+
i18n_label: "decidim.events.proposals.coauthor_invited.actions.accept",
|
17
|
+
url: invite_path,
|
18
|
+
icon: "check-line",
|
19
|
+
method: "patch"
|
20
|
+
},
|
21
|
+
{
|
22
|
+
i18n_label: "decidim.events.proposals.coauthor_invited.actions.decline",
|
23
|
+
url: invite_path,
|
24
|
+
icon: "close-circle-line",
|
25
|
+
method: "delete"
|
26
|
+
}
|
27
|
+
]
|
28
|
+
end
|
29
|
+
|
30
|
+
def resource_url
|
31
|
+
notifications_url(host: component.organization.host)
|
32
|
+
end
|
33
|
+
|
34
|
+
private
|
35
|
+
|
36
|
+
def invite_path
|
37
|
+
@invite_path ||= EngineRouter.main_proxy(component).proposal_invite_coauthor_path(proposal_id: resource, id: user.id)
|
38
|
+
end
|
39
|
+
|
40
|
+
def user_is_coauthor?
|
41
|
+
resource.authors.include?(user)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -8,14 +8,13 @@ module Decidim
|
|
8
8
|
include Decidim::TranslatableAttributes
|
9
9
|
include Decidim::AttachmentAttributes
|
10
10
|
include Decidim::ApplicationHelper
|
11
|
+
include Decidim::HasTaxonomyFormAttributes
|
11
12
|
|
12
13
|
mimic :proposal
|
13
14
|
|
14
15
|
attribute :address, String
|
15
16
|
attribute :latitude, Float
|
16
17
|
attribute :longitude, Float
|
17
|
-
attribute :category_id, Integer
|
18
|
-
attribute :scope_id, Integer
|
19
18
|
attribute :attachment, AttachmentForm
|
20
19
|
attribute :position, Integer
|
21
20
|
attribute :created_in_meeting, Boolean
|
@@ -25,46 +24,19 @@ module Decidim
|
|
25
24
|
attachments_attribute :photos
|
26
25
|
|
27
26
|
validates :address, geocoding: true, if: ->(form) { form.has_address? && !form.geocoded? }
|
28
|
-
validates :category, presence: true, if: ->(form) { form.category_id.present? }
|
29
|
-
validates :scope, presence: true, if: ->(form) { form.scope_id.present? }
|
30
|
-
validates :scope_id, scope_belongs_to_component: true, if: ->(form) { form.scope_id.present? }
|
31
27
|
validates :meeting_as_author, presence: true, if: ->(form) { form.created_in_meeting? }
|
32
28
|
|
33
29
|
validate :notify_missing_attachment_if_errored
|
34
30
|
|
35
|
-
delegate :categories, to: :current_component
|
36
|
-
|
37
31
|
def map_model(model)
|
38
32
|
body = translated_attribute(model.body)
|
39
33
|
@suggested_hashtags = Decidim::ContentRenderers::HashtagRenderer.new(body).extra_hashtags.map(&:name).map(&:downcase)
|
40
|
-
|
41
|
-
return unless model.categorization
|
42
|
-
|
43
|
-
self.category_id = model.categorization.decidim_category_id
|
44
|
-
self.scope_id = model.decidim_scope_id
|
45
34
|
end
|
46
35
|
|
47
36
|
alias component current_component
|
48
37
|
|
49
|
-
|
50
|
-
|
51
|
-
# Returns a Decidim::Category
|
52
|
-
def category
|
53
|
-
@category ||= categories.find_by(id: category_id)
|
54
|
-
end
|
55
|
-
|
56
|
-
# Finds the Scope from the given decidim_scope_id, uses participatory space scope if missing.
|
57
|
-
#
|
58
|
-
# Returns a Decidim::Scope
|
59
|
-
def scope
|
60
|
-
@scope ||= @attributes["scope_id"].value ? current_component.scopes.find_by(id: @attributes["scope_id"].value) : current_component.scope
|
61
|
-
end
|
62
|
-
|
63
|
-
# Scope identifier
|
64
|
-
#
|
65
|
-
# Returns the scope identifier related to the proposal
|
66
|
-
def scope_id
|
67
|
-
super || scope&.id
|
38
|
+
def participatory_space_manifest
|
39
|
+
@participatory_space_manifest ||= current_component.participatory_space.manifest.name
|
68
40
|
end
|
69
41
|
|
70
42
|
def geocoding_enabled?
|
@@ -6,27 +6,32 @@ module Decidim
|
|
6
6
|
# A form object to be used when admin users want to create a proposal.
|
7
7
|
class ProposalForm < Decidim::Proposals::Admin::ProposalBaseForm
|
8
8
|
include Decidim::HasUploadValidations
|
9
|
+
include Decidim::AttachmentAttributes
|
9
10
|
|
10
11
|
translatable_attribute :title, String do |field, _locale|
|
11
12
|
validates field, length: { in: 15..150 }, if: proc { |resource| resource.send(field).present? }
|
12
13
|
end
|
13
14
|
translatable_attribute :body, Decidim::Attributes::RichText
|
15
|
+
attribute :attachment, AttachmentForm
|
16
|
+
|
17
|
+
attachments_attribute :documents
|
14
18
|
|
15
19
|
validates :title, :body, translatable_presence: true
|
20
|
+
validates :title, :body, translated_etiquette: true
|
16
21
|
|
17
22
|
validate :notify_missing_attachment_if_errored
|
18
23
|
|
19
24
|
def map_model(model)
|
20
|
-
super
|
25
|
+
super
|
21
26
|
presenter = ProposalPresenter.new(model)
|
22
27
|
|
23
28
|
self.title = presenter.title(all_locales: title.is_a?(Hash))
|
24
29
|
self.body = presenter.editor_body(all_locales: body.is_a?(Hash))
|
25
|
-
self.
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
+
self.documents = model.attachments
|
31
|
+
end
|
32
|
+
|
33
|
+
def notify_missing_attachment_if_errored
|
34
|
+
errors.add(:add_documents, :needs_to_be_reattached) if errors.any? && add_documents.present?
|
30
35
|
end
|
31
36
|
end
|
32
37
|
end
|
@@ -14,7 +14,6 @@ module Decidim
|
|
14
14
|
attribute :keep_answers, Boolean
|
15
15
|
attribute :keep_authors, Boolean
|
16
16
|
attribute :states, Array
|
17
|
-
attribute :scope_ids, Array
|
18
17
|
|
19
18
|
validates :origin_component_id, :origin_component, :states, :current_component, presence: true
|
20
19
|
validates :import_proposals, allow_nil: false, acceptance: true
|
@@ -31,10 +30,6 @@ module Decidim
|
|
31
30
|
super.compact_blank
|
32
31
|
end
|
33
32
|
|
34
|
-
def scopes
|
35
|
-
Decidim::Scope.where(organization: current_organization, id: scope_ids)
|
36
|
-
end
|
37
|
-
|
38
33
|
def origin_component
|
39
34
|
@origin_component ||= origin_components.find_by(id: origin_component_id)
|
40
35
|
end
|
@@ -4,14 +4,6 @@ module Decidim
|
|
4
4
|
module Proposals
|
5
5
|
# A form object to be used when public users want to create a Collaborative Draft.
|
6
6
|
class CollaborativeDraftForm < Decidim::Proposals::ProposalForm
|
7
|
-
def map_model(model)
|
8
|
-
super
|
9
|
-
|
10
|
-
return unless model.categorization
|
11
|
-
|
12
|
-
self.category_id = model.categorization.decidim_category_id
|
13
|
-
end
|
14
|
-
|
15
7
|
def user_group
|
16
8
|
@user_group ||= Decidim::UserGroup.find user_group_id if user_group_id.present?
|
17
9
|
end
|