decidim-proposals 0.9.3 → 0.10.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +18 -1
- data/app/assets/config/admin/decidim_proposals_manifest.js +1 -0
- data/app/assets/javascripts/decidim/proposals/admin/proposals.es6 +113 -0
- data/app/assets/javascripts/decidim/proposals/identity_selector_dialog.js.es6 +56 -0
- data/app/commands/decidim/proposals/admin/answer_proposal.rb +11 -5
- data/app/commands/decidim/proposals/admin/create_proposal.rb +25 -3
- data/app/commands/decidim/proposals/admin/create_proposal_note.rb +13 -8
- data/app/commands/decidim/proposals/admin/import_proposals.rb +83 -0
- data/app/commands/decidim/proposals/admin/update_proposal_category.rb +68 -0
- data/app/commands/decidim/proposals/create_proposal.rb +0 -12
- data/app/commands/decidim/proposals/endorse_proposal.rb +56 -0
- data/app/commands/decidim/proposals/publish_proposal.rb +60 -0
- data/app/commands/decidim/proposals/unendorse_proposal.rb +40 -0
- data/app/commands/decidim/proposals/update_proposal.rb +3 -3
- data/app/commands/decidim/proposals/vote_proposal.rb +1 -1
- data/app/commands/decidim/proposals/withdraw_proposal.rb +1 -1
- data/app/controllers/decidim/proposals/admin/proposal_answers_controller.rb +1 -1
- data/app/controllers/decidim/proposals/admin/proposal_notes_controller.rb +2 -2
- data/app/controllers/decidim/proposals/admin/proposals_controller.rb +50 -1
- data/app/controllers/decidim/proposals/admin/proposals_imports_controller.rb +35 -0
- data/app/controllers/decidim/proposals/proposal_endorsements_controller.rb +56 -0
- data/app/controllers/decidim/proposals/proposals_controller.rb +82 -9
- data/app/events/decidim/proposals/admin/update_proposal_category_event.rb +11 -0
- data/app/events/decidim/proposals/creation_enabled_event.rb +8 -0
- data/app/events/decidim/proposals/endorsing_enabled_event.rb +8 -0
- data/app/events/decidim/proposals/proposal_endorsed_event.rb +29 -0
- data/app/events/decidim/proposals/publish_proposal_event.rb +21 -0
- data/app/events/decidim/proposals/voting_enabled_event.rb +8 -0
- data/app/forms/decidim/proposals/admin/proposal_form.rb +9 -2
- data/app/forms/decidim/proposals/admin/proposals_import_form.rb +60 -0
- data/app/forms/decidim/proposals/proposal_form.rb +16 -5
- data/app/helpers/decidim/proposals/application_helper.rb +1 -0
- data/app/helpers/decidim/proposals/proposal_endorsements_helper.rb +117 -0
- data/app/helpers/decidim/proposals/proposal_votes_helper.rb +13 -6
- data/app/helpers/decidim/proposals/proposal_wizard_helper.rb +105 -0
- data/app/jobs/decidim/proposals/settings_change_job.rb +48 -0
- data/app/models/decidim/proposals/abilities/current_user_ability.rb +30 -8
- data/app/models/decidim/proposals/proposal.rb +38 -38
- data/app/models/decidim/proposals/proposal_endorsement.rb +31 -0
- data/app/models/decidim/proposals/proposal_note.rb +7 -0
- data/app/presenters/decidim/proposals/admin_log/proposal_note_presenter.rb +39 -0
- data/app/presenters/decidim/proposals/admin_log/proposal_presenter.rb +47 -0
- data/app/presenters/decidim/proposals/admin_log/value_types/proposal_state_presenter.rb +16 -0
- data/app/queries/decidim/proposals/similar_proposals.rb +53 -0
- data/app/types/decidim/proposals/proposal_type.rb +34 -0
- data/app/types/decidim/proposals/proposals_type.rb +34 -0
- data/app/views/decidim/participatory_processes/participatory_process_groups/_highlighted_proposals.html.erb +8 -0
- data/app/views/decidim/participatory_processes/participatory_process_groups/_proposal.html.erb +27 -0
- data/app/views/decidim/participatory_spaces/_highlighted_proposals.html.erb +10 -0
- data/app/views/decidim/participatory_spaces/_proposal.html.erb +27 -0
- data/app/views/decidim/proposals/admin/proposals/_bulk-actions.html.erb +15 -0
- data/app/views/decidim/proposals/admin/proposals/_js-callout.html.erb +6 -0
- data/app/views/decidim/proposals/admin/proposals/_proposal-tr.html.erb +63 -0
- data/app/views/decidim/proposals/admin/proposals/index.html.erb +12 -73
- data/app/views/decidim/proposals/admin/proposals/update_category.js.erb +25 -0
- data/app/views/decidim/proposals/admin/proposals_imports/new.html.erb +28 -0
- data/app/views/decidim/proposals/proposal_endorsements/_identity.html.erb +4 -0
- data/app/views/decidim/proposals/proposal_endorsements/identities.html.erb +12 -0
- data/app/views/decidim/proposals/proposal_endorsements/update_buttons_and_counters.js.erb +9 -0
- data/app/views/decidim/proposals/proposals/_endorsement_button.html.erb +11 -0
- data/app/views/decidim/proposals/proposals/_endorsement_identities_cabin.html.erb +13 -0
- data/app/views/decidim/proposals/proposals/_endorsement_xxs.html.erb +9 -0
- data/app/views/decidim/proposals/proposals/_endorsements_card_row.html.erb +22 -0
- data/app/views/decidim/proposals/proposals/_endorsements_count.html.erb +5 -0
- data/app/views/decidim/proposals/proposals/_endorsements_listing.html.erb +34 -0
- data/app/views/decidim/proposals/proposals/_proposal.html.erb +2 -2
- data/app/views/decidim/proposals/proposals/_proposal_preview.html.erb +36 -0
- data/app/views/decidim/proposals/proposals/_proposal_similar.html.erb +21 -0
- data/app/views/decidim/proposals/proposals/_vote_button.html.erb +8 -8
- data/app/views/decidim/proposals/proposals/_votes_count.html.erb +23 -6
- data/app/views/decidim/proposals/proposals/_voting_rules.html.erb +7 -3
- data/app/views/decidim/proposals/proposals/_wizard_aside.html.erb +16 -0
- data/app/views/decidim/proposals/proposals/_wizard_header.html.erb +31 -0
- data/app/views/decidim/proposals/proposals/compare.html.erb +19 -0
- data/app/views/decidim/proposals/proposals/edit_draft.html.erb +55 -0
- data/app/views/decidim/proposals/proposals/new.html.erb +7 -20
- data/app/views/decidim/proposals/proposals/preview.html.erb +18 -0
- data/app/views/decidim/proposals/proposals/show.html.erb +13 -4
- data/config/locales/ca.yml +156 -15
- data/config/locales/en.yml +156 -15
- data/config/locales/es.yml +157 -16
- data/config/locales/eu.yml +151 -7
- data/config/locales/fi.yml +151 -7
- data/config/locales/fr.yml +153 -9
- data/config/locales/gl.yml +151 -7
- data/config/locales/it.yml +151 -7
- data/config/locales/nl.yml +151 -7
- data/config/locales/pl.yml +148 -22
- data/config/locales/pt-BR.yml +151 -7
- data/config/locales/pt.yml +151 -7
- data/config/locales/ru.yml +0 -9
- data/config/locales/sv.yml +151 -7
- data/config/locales/uk.yml +87 -13
- data/db/migrate/20170307085300_migrate_proposal_reports_data_to_reports.rb +1 -1
- data/db/migrate/20171201115434_create_proposal_endorsements.rb +16 -0
- data/db/migrate/20171201122623_add_counter_cache_endorsements_to_proposals.rb +8 -0
- data/db/migrate/20171212102250_enable_pg_extensions.rb +7 -0
- data/db/migrate/20171220084719_add_published_at_to_proposals.rb +14 -0
- data/lib/decidim/proposals.rb +15 -0
- data/lib/decidim/proposals/admin_engine.rb +8 -0
- data/lib/decidim/proposals/commentable_proposal.rb +39 -0
- data/lib/decidim/proposals/engine.rb +69 -1
- data/lib/decidim/proposals/feature.rb +51 -6
- data/lib/decidim/proposals/test/factories.rb +78 -2
- data/lib/decidim/proposals/version.rb +1 -1
- metadata +76 -20
- data/app/events/decidim/proposals/create_proposal_event.rb +0 -9
@@ -35,7 +35,6 @@ module Decidim
|
|
35
35
|
transaction do
|
36
36
|
create_proposal
|
37
37
|
create_attachment if process_attachments?
|
38
|
-
send_notification
|
39
38
|
end
|
40
39
|
|
41
40
|
broadcast(:ok, proposal)
|
@@ -43,17 +42,6 @@ module Decidim
|
|
43
42
|
|
44
43
|
private
|
45
44
|
|
46
|
-
def send_notification
|
47
|
-
return if proposal.author.blank?
|
48
|
-
|
49
|
-
Decidim::EventsManager.publish(
|
50
|
-
event: "decidim.events.proposals.proposal_created",
|
51
|
-
event_class: Decidim::Proposals::CreateProposalEvent,
|
52
|
-
resource: proposal,
|
53
|
-
recipient_ids: proposal.author.followers.pluck(:id)
|
54
|
-
)
|
55
|
-
end
|
56
|
-
|
57
45
|
attr_reader :form, :proposal, :attachment
|
58
46
|
|
59
47
|
def create_proposal
|
@@ -0,0 +1,56 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Decidim
|
4
|
+
module Proposals
|
5
|
+
# A command with all the business logic when a user endorses a proposal.
|
6
|
+
class EndorseProposal < Rectify::Command
|
7
|
+
# Public: Initializes the command.
|
8
|
+
#
|
9
|
+
# proposal - A Decidim::Proposals::Proposal object.
|
10
|
+
# current_user - The current user.
|
11
|
+
# current_group_id- (optional) The current_grup that is endorsing the Proposal.
|
12
|
+
def initialize(proposal, current_user, current_group_id = nil)
|
13
|
+
@proposal = proposal
|
14
|
+
@current_user = current_user
|
15
|
+
@current_group_id = current_group_id
|
16
|
+
end
|
17
|
+
|
18
|
+
# Executes the command. Broadcasts these events:
|
19
|
+
#
|
20
|
+
# - :ok when everything is valid, together with the proposal vote.
|
21
|
+
# - :invalid if the form wasn't valid and we couldn't proceed.
|
22
|
+
#
|
23
|
+
# Returns nothing.
|
24
|
+
def call
|
25
|
+
endorsement = build_proposal_endorsement
|
26
|
+
if endorsement.save
|
27
|
+
notify_endorser_followers
|
28
|
+
broadcast(:ok, endorsement)
|
29
|
+
else
|
30
|
+
broadcast(:invalid)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
private
|
35
|
+
|
36
|
+
def build_proposal_endorsement
|
37
|
+
endorsement = @proposal.endorsements.build(author: @current_user)
|
38
|
+
endorsement.user_group = @current_user.user_groups.verified.find(@current_group_id) if @current_group_id.present?
|
39
|
+
endorsement
|
40
|
+
end
|
41
|
+
|
42
|
+
def notify_endorser_followers
|
43
|
+
recipient_ids = @current_user.followers.pluck(:id)
|
44
|
+
Decidim::EventsManager.publish(
|
45
|
+
event: "decidim.events.proposals.proposal_endorsed",
|
46
|
+
event_class: Decidim::Proposals::ProposalEndorsedEvent,
|
47
|
+
resource: @proposal,
|
48
|
+
recipient_ids: recipient_ids.uniq,
|
49
|
+
extra: {
|
50
|
+
endorser_id: @current_user.id
|
51
|
+
}
|
52
|
+
)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Decidim
|
4
|
+
module Proposals
|
5
|
+
# A command with all the business logic when a user publishes a draft proposal.
|
6
|
+
class PublishProposal < Rectify::Command
|
7
|
+
# Public: Initializes the command.
|
8
|
+
#
|
9
|
+
# proposal - The proposal to publish.
|
10
|
+
# current_user - The current user.
|
11
|
+
def initialize(proposal, current_user)
|
12
|
+
@proposal = proposal
|
13
|
+
@current_user = current_user
|
14
|
+
end
|
15
|
+
|
16
|
+
# Executes the command. Broadcasts these events:
|
17
|
+
#
|
18
|
+
# - :ok when everything is valid and the proposal is published.
|
19
|
+
# - :invalid if the proposal's author is not the current user.
|
20
|
+
#
|
21
|
+
# Returns nothing.
|
22
|
+
def call
|
23
|
+
return broadcast(:invalid) if @proposal.author != @current_user
|
24
|
+
|
25
|
+
transaction do
|
26
|
+
@proposal.update published_at: Time.current
|
27
|
+
send_notification
|
28
|
+
send_notification_to_participatory_space
|
29
|
+
end
|
30
|
+
|
31
|
+
broadcast(:ok, @proposal)
|
32
|
+
end
|
33
|
+
|
34
|
+
private
|
35
|
+
|
36
|
+
def send_notification
|
37
|
+
return if @proposal.author.blank?
|
38
|
+
|
39
|
+
Decidim::EventsManager.publish(
|
40
|
+
event: "decidim.events.proposals.proposal_published",
|
41
|
+
event_class: Decidim::Proposals::PublishProposalEvent,
|
42
|
+
resource: @proposal,
|
43
|
+
recipient_ids: @proposal.author.followers.pluck(:id)
|
44
|
+
)
|
45
|
+
end
|
46
|
+
|
47
|
+
def send_notification_to_participatory_space
|
48
|
+
Decidim::EventsManager.publish(
|
49
|
+
event: "decidim.events.proposals.proposal_published",
|
50
|
+
event_class: Decidim::Proposals::PublishProposalEvent,
|
51
|
+
resource: @proposal,
|
52
|
+
recipient_ids: @proposal.participatory_space.followers.pluck(:id) - @proposal.author.followers.pluck(:id),
|
53
|
+
extra: {
|
54
|
+
participatory_space: true
|
55
|
+
}
|
56
|
+
)
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Decidim
|
4
|
+
module Proposals
|
5
|
+
# A command with all the business logic when a user or organization unendorses a proposal.
|
6
|
+
class UnendorseProposal < Rectify::Command
|
7
|
+
# Public: Initializes the command.
|
8
|
+
#
|
9
|
+
# proposal - A Decidim::Proposals::Proposal object.
|
10
|
+
# current_user - The current user.
|
11
|
+
# current_group- (optional) The current_group that is unendorsing from the Proposal.
|
12
|
+
def initialize(proposal, current_user, current_group = nil)
|
13
|
+
@proposal = proposal
|
14
|
+
@current_user = current_user
|
15
|
+
@current_group = current_group
|
16
|
+
end
|
17
|
+
|
18
|
+
# Executes the command. Broadcasts these events:
|
19
|
+
#
|
20
|
+
# - :ok when everything is valid, together with the proposal.
|
21
|
+
# - :invalid if the form wasn't valid and we couldn't proceed.
|
22
|
+
#
|
23
|
+
# Returns nothing.
|
24
|
+
def call
|
25
|
+
destroy_proposal_endorsement
|
26
|
+
broadcast(:ok, @proposal)
|
27
|
+
end
|
28
|
+
|
29
|
+
private
|
30
|
+
|
31
|
+
def destroy_proposal_endorsement
|
32
|
+
query = @proposal.endorsements.where(
|
33
|
+
author: @current_user,
|
34
|
+
decidim_user_group_id: @current_group&.id
|
35
|
+
)
|
36
|
+
query.destroy_all
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -38,7 +38,7 @@ module Decidim
|
|
38
38
|
attr_reader :form, :proposal, :current_user
|
39
39
|
|
40
40
|
def update_proposal
|
41
|
-
@proposal.
|
41
|
+
@proposal.update!(
|
42
42
|
title: form.title,
|
43
43
|
body: form.body,
|
44
44
|
category: form.category,
|
@@ -72,11 +72,11 @@ module Decidim
|
|
72
72
|
end
|
73
73
|
|
74
74
|
def current_user_proposals
|
75
|
-
Proposal.where(author: current_user, feature: form.current_feature).where.not(id: proposal.id)
|
75
|
+
Proposal.where(author: current_user, feature: form.current_feature).published.where.not(id: proposal.id)
|
76
76
|
end
|
77
77
|
|
78
78
|
def user_group_proposals
|
79
|
-
Proposal.where(user_group: user_group, feature: form.current_feature).where.not(id: proposal.id)
|
79
|
+
Proposal.where(user_group: user_group, feature: form.current_feature).published.where.not(id: proposal.id)
|
80
80
|
end
|
81
81
|
end
|
82
82
|
end
|
@@ -20,7 +20,7 @@ module Decidim
|
|
20
20
|
#
|
21
21
|
# Returns nothing.
|
22
22
|
def call
|
23
|
-
return broadcast(:invalid) if @proposal.maximum_votes_reached?
|
23
|
+
return broadcast(:invalid) if @proposal.maximum_votes_reached? && !@proposal.can_accumulate_supports_beyond_threshold
|
24
24
|
|
25
25
|
build_proposal_vote
|
26
26
|
return broadcast(:invalid) unless vote.valid?
|
@@ -16,7 +16,7 @@ module Decidim
|
|
16
16
|
authorize! :create, ProposalNote
|
17
17
|
@form = form(ProposalNoteForm).from_params(params)
|
18
18
|
|
19
|
-
CreateProposalNote.call(@form, proposal
|
19
|
+
CreateProposalNote.call(@form, proposal) do
|
20
20
|
on(:ok) do
|
21
21
|
flash[:notice] = I18n.t("proposal_notes.create.success", scope: "decidim.proposals.admin")
|
22
22
|
redirect_to proposal_proposal_notes_path(proposal_id: proposal.id)
|
@@ -32,7 +32,7 @@ module Decidim
|
|
32
32
|
private
|
33
33
|
|
34
34
|
def proposal
|
35
|
-
@
|
35
|
+
@proposal ||= Proposal.where(feature: current_feature).find(params[:proposal_id])
|
36
36
|
end
|
37
37
|
end
|
38
38
|
end
|
@@ -32,10 +32,39 @@ module Decidim
|
|
32
32
|
end
|
33
33
|
end
|
34
34
|
|
35
|
+
def update_category
|
36
|
+
authorize! :update, Proposal
|
37
|
+
@proposal_ids = params[:proposal_ids]
|
38
|
+
|
39
|
+
Admin::UpdateProposalCategory.call(params[:category][:id], params[:proposal_ids]) do
|
40
|
+
on(:invalid_category) do
|
41
|
+
flash.now[:error] = I18n.t(
|
42
|
+
"proposals.update_category.select_a_category",
|
43
|
+
scope: "decidim.proposals.admin"
|
44
|
+
)
|
45
|
+
end
|
46
|
+
|
47
|
+
on(:invalid_proposal_ids) do
|
48
|
+
flash.now[:alert] = I18n.t(
|
49
|
+
"proposals.update_category.select_a_proposal",
|
50
|
+
scope: "decidim.proposals.admin"
|
51
|
+
)
|
52
|
+
end
|
53
|
+
|
54
|
+
on(:update_proposals_category) do
|
55
|
+
flash.now[:notice] = update_proposals_category_response_successful @response
|
56
|
+
flash.now[:alert] = update_proposals_category_response_errored @response
|
57
|
+
end
|
58
|
+
respond_to do |format|
|
59
|
+
format.js
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
35
64
|
private
|
36
65
|
|
37
66
|
def query
|
38
|
-
@query ||= Proposal.where(feature: current_feature).ransack(params[:q])
|
67
|
+
@query ||= Proposal.where(feature: current_feature).published.ransack(params[:q])
|
39
68
|
end
|
40
69
|
|
41
70
|
def proposals
|
@@ -45,6 +74,26 @@ module Decidim
|
|
45
74
|
def proposal
|
46
75
|
@proposal ||= Proposal.where(feature: current_feature).find(params[:id])
|
47
76
|
end
|
77
|
+
|
78
|
+
def update_proposals_category_response_successful(response)
|
79
|
+
return if response[:successful].blank?
|
80
|
+
I18n.t(
|
81
|
+
"proposals.update_category.success",
|
82
|
+
category: response[:category_name],
|
83
|
+
proposals: response[:successful].to_sentence,
|
84
|
+
scope: "decidim.proposals.admin"
|
85
|
+
)
|
86
|
+
end
|
87
|
+
|
88
|
+
def update_proposals_category_response_errored(response)
|
89
|
+
return if response[:errored].blank?
|
90
|
+
I18n.t(
|
91
|
+
"proposals.update_category.invalid",
|
92
|
+
category: response[:category_name],
|
93
|
+
proposals: response[:errored].to_sentence,
|
94
|
+
scope: "decidim.proposals.admin"
|
95
|
+
)
|
96
|
+
end
|
48
97
|
end
|
49
98
|
end
|
50
99
|
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Decidim
|
4
|
+
module Proposals
|
5
|
+
module Admin
|
6
|
+
class ProposalsImportsController < Admin::ApplicationController
|
7
|
+
def new
|
8
|
+
authorize! :manage, current_feature
|
9
|
+
|
10
|
+
@form = form(Admin::ProposalsImportForm).instance
|
11
|
+
end
|
12
|
+
|
13
|
+
def create
|
14
|
+
authorize! :manage, current_feature
|
15
|
+
|
16
|
+
@form = form(Admin::ProposalsImportForm).from_params(params)
|
17
|
+
|
18
|
+
authorize! :manage, @form.origin_feature
|
19
|
+
|
20
|
+
Admin::ImportProposals.call(@form) do
|
21
|
+
on(:ok) do |proposals|
|
22
|
+
flash[:notice] = I18n.t("proposals_imports.create.success", scope: "decidim.proposals.admin", number: proposals.length)
|
23
|
+
redirect_to EngineRouter.admin_proxy(current_feature).root_path
|
24
|
+
end
|
25
|
+
|
26
|
+
on(:invalid) do
|
27
|
+
flash.now[:alert] = I18n.t("proposals_imports.create.invalid", scope: "decidim.proposals.admin")
|
28
|
+
render action: "new"
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Decidim
|
4
|
+
module Proposals
|
5
|
+
# Exposes the proposal endorsement resource so that users can endorse proposals.
|
6
|
+
class ProposalEndorsementsController < Decidim::Proposals::ApplicationController
|
7
|
+
helper_method :proposal
|
8
|
+
|
9
|
+
before_action :authenticate_user!
|
10
|
+
|
11
|
+
def create
|
12
|
+
authorize! :endorse, proposal
|
13
|
+
@from_proposals_list = params[:from_proposals_list] == "true"
|
14
|
+
user_group_id = params[:user_group_id]
|
15
|
+
|
16
|
+
EndorseProposal.call(proposal, current_user, user_group_id) do
|
17
|
+
on(:ok) do
|
18
|
+
proposal.reload
|
19
|
+
render :update_buttons_and_counters
|
20
|
+
end
|
21
|
+
|
22
|
+
on(:invalid) do
|
23
|
+
render json: { error: I18n.t("proposal_endorsements.create.error", scope: "decidim.proposals") }, status: 422
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def destroy
|
29
|
+
authorize! :unendorse, proposal
|
30
|
+
@from_proposals_list = params[:from_proposals_list] == "true"
|
31
|
+
user_group_id = params[:user_group_id]
|
32
|
+
user_group = current_user.user_groups.verified.find(user_group_id) if user_group_id
|
33
|
+
|
34
|
+
UnendorseProposal.call(proposal, current_user, user_group) do
|
35
|
+
on(:ok) do
|
36
|
+
proposal.reload
|
37
|
+
render :update_buttons_and_counters
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def identities
|
43
|
+
authorize! :endorse, proposal
|
44
|
+
|
45
|
+
@user_verified_groups = current_user.user_groups.verified
|
46
|
+
render :identities, layout: false
|
47
|
+
end
|
48
|
+
|
49
|
+
private
|
50
|
+
|
51
|
+
def proposal
|
52
|
+
@proposal ||= Proposal.where(feature: current_feature).find(params[:proposal_id])
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
@@ -5,6 +5,7 @@ module Decidim
|
|
5
5
|
# Exposes the proposal resource so users can view and create them.
|
6
6
|
class ProposalsController < Decidim::Proposals::ApplicationController
|
7
7
|
helper Decidim::WidgetUrlsHelper
|
8
|
+
helper ProposalWizardHelper
|
8
9
|
include FormFactory
|
9
10
|
include FilterResource
|
10
11
|
include Orderable
|
@@ -12,10 +13,12 @@ module Decidim
|
|
12
13
|
|
13
14
|
helper_method :geocoded_proposals
|
14
15
|
before_action :authenticate_user!, only: [:new, :create]
|
16
|
+
before_action :ensure_is_draft, only: [:compare, :preview, :publish, :edit_draft, :update_draft]
|
15
17
|
|
16
18
|
def index
|
17
19
|
@proposals = search
|
18
20
|
.results
|
21
|
+
.published
|
19
22
|
.not_hidden
|
20
23
|
.includes(:author)
|
21
24
|
.includes(:category)
|
@@ -35,27 +38,32 @@ module Decidim
|
|
35
38
|
end
|
36
39
|
|
37
40
|
def show
|
38
|
-
@proposal = Proposal.not_hidden.where(feature: current_feature).find(params[:id])
|
41
|
+
@proposal = Proposal.published.not_hidden.where(feature: current_feature).find(params[:id])
|
39
42
|
@report_form = form(Decidim::ReportForm).from_params(reason: "spam")
|
40
43
|
end
|
41
44
|
|
42
45
|
def new
|
43
46
|
authorize! :create, Proposal
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
47
|
+
@step = :step_1
|
48
|
+
if proposal_draft.present?
|
49
|
+
redirect_to edit_draft_proposal_path proposal_draft.id
|
50
|
+
else
|
51
|
+
@form = form(ProposalForm).from_params(
|
52
|
+
attachment: form(AttachmentForm).from_params({})
|
53
|
+
)
|
54
|
+
end
|
48
55
|
end
|
49
56
|
|
50
57
|
def create
|
51
58
|
authorize! :create, Proposal
|
52
|
-
|
59
|
+
@step = :step_1
|
53
60
|
@form = form(ProposalForm).from_params(params)
|
54
61
|
|
55
62
|
CreateProposal.call(@form, current_user) do
|
56
63
|
on(:ok) do |proposal|
|
57
64
|
flash[:notice] = I18n.t("proposals.create.success", scope: "decidim")
|
58
|
-
|
65
|
+
compare_path = Decidim::ResourceLocatorPresenter.new(proposal).path + "/compare"
|
66
|
+
redirect_to compare_path
|
59
67
|
end
|
60
68
|
|
61
69
|
on(:invalid) do
|
@@ -65,8 +73,64 @@ module Decidim
|
|
65
73
|
end
|
66
74
|
end
|
67
75
|
|
76
|
+
def compare
|
77
|
+
@step = :step_2
|
78
|
+
@similar_proposals ||= Decidim::Proposals::SimilarProposals
|
79
|
+
.for(current_feature, @proposal)
|
80
|
+
.all
|
81
|
+
|
82
|
+
if @similar_proposals.blank?
|
83
|
+
flash[:notice] = I18n.t("proposals.proposals.compare.no_similars_found", scope: "decidim")
|
84
|
+
redirect_to preview_proposal_path(@proposal)
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
def preview
|
89
|
+
@step = :step_3
|
90
|
+
end
|
91
|
+
|
92
|
+
def publish
|
93
|
+
@step = :step_3
|
94
|
+
PublishProposal.call(@proposal, current_user) do
|
95
|
+
on(:ok) do |proposal|
|
96
|
+
flash[:notice] = I18n.t("proposals.publish.success", scope: "decidim")
|
97
|
+
redirect_to proposal_path(proposal)
|
98
|
+
end
|
99
|
+
|
100
|
+
on(:invalid) do
|
101
|
+
flash.now[:alert] = I18n.t("proposals.publish.error", scope: "decidim")
|
102
|
+
render :edit_draft
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
def edit_draft
|
108
|
+
@step = :step_1
|
109
|
+
authorize! :edit, Proposal
|
110
|
+
|
111
|
+
@form = form(ProposalForm).from_model(@proposal)
|
112
|
+
end
|
113
|
+
|
114
|
+
def update_draft
|
115
|
+
@step = :step_1
|
116
|
+
authorize! :edit, @proposal
|
117
|
+
|
118
|
+
@form = form(ProposalForm).from_params(params)
|
119
|
+
UpdateProposal.call(@form, current_user, @proposal) do
|
120
|
+
on(:ok) do |proposal|
|
121
|
+
flash[:notice] = I18n.t("proposals.update_draft.success", scope: "decidim")
|
122
|
+
redirect_to preview_proposal_path(proposal)
|
123
|
+
end
|
124
|
+
|
125
|
+
on(:invalid) do
|
126
|
+
flash.now[:alert] = I18n.t("proposals.update_draft.error", scope: "decidim")
|
127
|
+
render :edit_draft
|
128
|
+
end
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
68
132
|
def edit
|
69
|
-
@proposal = Proposal.not_hidden.where(feature: current_feature).find(params[:id])
|
133
|
+
@proposal = Proposal.published.not_hidden.where(feature: current_feature).find(params[:id])
|
70
134
|
authorize! :edit, @proposal
|
71
135
|
|
72
136
|
@form = form(ProposalForm).from_model(@proposal)
|
@@ -91,7 +155,7 @@ module Decidim
|
|
91
155
|
end
|
92
156
|
|
93
157
|
def withdraw
|
94
|
-
@proposal = Proposal.not_hidden.where(feature: current_feature).find(params[:id])
|
158
|
+
@proposal = Proposal.published.not_hidden.where(feature: current_feature).find(params[:id])
|
95
159
|
authorize! :withdraw, @proposal
|
96
160
|
|
97
161
|
WithdrawProposal.call(@proposal, current_user) do
|
@@ -127,6 +191,15 @@ module Decidim
|
|
127
191
|
related_to: ""
|
128
192
|
}
|
129
193
|
end
|
194
|
+
|
195
|
+
def proposal_draft
|
196
|
+
Proposal.not_hidden.where(feature: current_feature).find_by(published_at: nil)
|
197
|
+
end
|
198
|
+
|
199
|
+
def ensure_is_draft
|
200
|
+
@proposal = Proposal.not_hidden.where(feature: current_feature).find(params[:id])
|
201
|
+
redirect_to Decidim::ResourceLocatorPresenter.new(@proposal).path unless @proposal.draft?
|
202
|
+
end
|
130
203
|
end
|
131
204
|
end
|
132
205
|
end
|