decidim-proposals 0.8.4 → 0.9.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.
- checksums.yaml +5 -5
- data/README.md +1 -1
- data/app/assets/config/decidim_proposals_manifest.css +3 -1
- data/app/assets/javascripts/decidim/proposals/add_proposal.js.es6 +0 -2
- data/app/assets/stylesheets/decidim/proposals/social_share.css.scss +8 -5
- data/app/commands/decidim/proposals/admin/answer_proposal.rb +32 -0
- data/app/commands/decidim/proposals/admin/create_proposal_note.rb +47 -0
- data/app/commands/decidim/proposals/create_proposal.rb +12 -0
- data/app/commands/decidim/proposals/withdraw_proposal.rb +37 -0
- data/app/controllers/decidim/proposals/admin/proposal_notes_controller.rb +40 -0
- data/app/controllers/decidim/proposals/admin/proposals_controller.rb +6 -2
- data/app/controllers/decidim/proposals/proposals_controller.rb +20 -5
- data/app/events/decidim/proposals/accepted_proposal_event.rb +9 -0
- data/app/events/decidim/proposals/create_proposal_event.rb +9 -0
- data/app/events/decidim/proposals/evaluating_proposal_event.rb +8 -0
- data/app/events/decidim/proposals/rejected_proposal_event.rb +9 -0
- data/app/forms/decidim/proposals/admin/proposal_form.rb +12 -12
- data/app/forms/decidim/proposals/admin/proposal_note_form.rb +16 -0
- data/app/forms/decidim/proposals/proposal_form.rb +11 -11
- data/app/helpers/decidim/proposals/application_helper.rb +2 -0
- data/app/models/decidim/proposals/abilities/admin_ability.rb +1 -0
- data/app/models/decidim/proposals/abilities/current_user_ability.rb +8 -0
- data/app/models/decidim/proposals/abilities/participatory_process_admin_ability.rb +1 -0
- data/app/models/decidim/proposals/proposal.rb +30 -9
- data/app/models/decidim/proposals/proposal_note.rb +13 -0
- data/app/presenters/decidim/proposals/official_author_presenter.rb +34 -0
- data/app/presenters/decidim/proposals/proposal_presenter.rb +20 -0
- data/app/services/decidim/proposals/proposal_search.rb +4 -2
- data/app/views/decidim/proposals/admin/proposal_answers/edit.html.erb +1 -0
- data/app/views/decidim/proposals/admin/proposal_notes/_form.html.erb +8 -0
- data/app/views/decidim/proposals/admin/proposal_notes/_proposal_notes.html.erb +45 -0
- data/app/views/decidim/proposals/admin/proposal_notes/index.html.erb +3 -0
- data/app/views/decidim/proposals/admin/proposals/_form.html.erb +1 -1
- data/app/views/decidim/proposals/admin/proposals/index.html.erb +60 -8
- data/app/views/decidim/proposals/admin/shared/_info_proposal.html.erb +20 -0
- data/app/views/decidim/proposals/proposals/_filters.html.erb +1 -1
- data/app/views/decidim/proposals/proposals/_linked_proposals.html.erb +11 -8
- data/app/views/decidim/proposals/proposals/_proposal.html.erb +5 -2
- data/app/views/decidim/proposals/proposals/_proposal_badge.html.erb +3 -0
- data/app/views/decidim/proposals/proposals/_vote_button.html.erb +3 -3
- data/app/views/decidim/proposals/proposals/edit.html.erb +2 -2
- data/app/views/decidim/proposals/proposals/index.html.erb +6 -2
- data/app/views/decidim/proposals/proposals/new.html.erb +2 -2
- data/app/views/decidim/proposals/proposals/show.html.erb +8 -4
- data/config/locales/ca.yml +46 -7
- data/config/locales/en.yml +46 -6
- data/config/locales/es.yml +46 -7
- data/config/locales/eu.yml +46 -7
- data/config/locales/fi.yml +58 -19
- data/config/locales/fr.yml +53 -14
- data/config/locales/gl.yml +231 -0
- data/config/locales/it.yml +46 -7
- data/config/locales/nl.yml +46 -7
- data/config/locales/pl.yml +46 -7
- data/config/locales/pt-BR.yml +231 -0
- data/config/locales/pt.yml +48 -9
- data/config/locales/ru.yml +7 -7
- data/config/locales/sv.yml +231 -0
- data/config/locales/uk.yml +7 -7
- data/db/migrate/20170215132030_add_reference_to_proposals.rb +5 -1
- data/db/migrate/20180111110204_create_decidim_proposal_notes.rb +15 -0
- data/db/migrate/20180115155220_add_index_created_at_proposal_notes.rb +7 -0
- data/lib/decidim/proposals/admin_engine.rb +1 -0
- data/lib/decidim/proposals/engine.rb +4 -0
- data/lib/decidim/proposals/feature.rb +21 -6
- data/lib/decidim/proposals/test/factories.rb +10 -0
- data/lib/decidim/proposals/version.rb +1 -1
- metadata +60 -27
- data/app/views/decidim/proposals/proposals/_author.html.erb +0 -23
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: e91f7c5944cada8255ade51d10276d5c666db13515a2dba890ffa2415d4777bf
|
4
|
+
data.tar.gz: 94b46b9d2df7e575e7c5fb7c466a4388bb31d7d99a0242bcb5033ea17cf1796c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: '0805a7c4f5b29dc9592ccbd5d818768ad3300dbd7666de2dbe4955a7aa6458031fa6e0efc969bb9f59a37ac15fbd44d790d6e0466bc72a4b574c30a468e25578'
|
7
|
+
data.tar.gz: 56d62ad991804d97365baa634e9ad8e7e7350d2f6fe910ec1459e0af8e8f5ccf75d56011da21f8dc439400a6a8b18c9b8d4a412cad1ed997ec400d3739e957a1
|
data/README.md
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# Decidim::Proposals
|
2
2
|
|
3
|
-
The Proposals module adds one of the main features of Decidim: allows users to contribute to a
|
3
|
+
The Proposals module adds one of the main features of Decidim: allows users to contribute to a participatory process by creating proposals.
|
4
4
|
|
5
5
|
## Usage
|
6
6
|
|
@@ -1,19 +1,22 @@
|
|
1
|
-
|
1
|
+
/*
|
2
|
+
*= require social-share-button
|
3
|
+
*/
|
4
|
+
|
2
5
|
$size: 45px;
|
3
6
|
|
4
|
-
.share-link:hover
|
7
|
+
.share-link:hover{
|
5
8
|
text-decoration: underline;
|
6
9
|
cursor: pointer;
|
7
10
|
}
|
8
11
|
|
9
|
-
.social-share-button
|
12
|
+
.social-share-button{
|
10
13
|
display: inline-block;
|
11
14
|
vertical-align: top;
|
12
|
-
|
15
|
+
|
16
|
+
.ssb-icon{
|
13
17
|
margin-right: 5px;
|
14
18
|
background-size: $size $size;
|
15
19
|
height: $size;
|
16
20
|
width: $size;
|
17
21
|
}
|
18
22
|
}
|
19
|
-
|
@@ -24,6 +24,8 @@ module Decidim
|
|
24
24
|
return broadcast(:invalid) if form.invalid?
|
25
25
|
|
26
26
|
answer_proposal
|
27
|
+
notify_followers
|
28
|
+
|
27
29
|
broadcast(:ok)
|
28
30
|
end
|
29
31
|
|
@@ -38,6 +40,36 @@ module Decidim
|
|
38
40
|
answered_at: Time.current
|
39
41
|
)
|
40
42
|
end
|
43
|
+
|
44
|
+
def notify_followers
|
45
|
+
return if (proposal.previous_changes.keys & %w(state)).empty?
|
46
|
+
|
47
|
+
if proposal.accepted?
|
48
|
+
publish_event(
|
49
|
+
"decidim.events.proposals.proposal_accepted",
|
50
|
+
Decidim::Proposals::AcceptedProposalEvent
|
51
|
+
)
|
52
|
+
elsif proposal.rejected?
|
53
|
+
publish_event(
|
54
|
+
"decidim.events.proposals.proposal_rejected",
|
55
|
+
Decidim::Proposals::RejectedProposalEvent
|
56
|
+
)
|
57
|
+
elsif proposal.evaluating?
|
58
|
+
publish_event(
|
59
|
+
"decidim.events.proposals.proposal_evaluating",
|
60
|
+
Decidim::Proposals::EvaluatingProposalEvent
|
61
|
+
)
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
def publish_event(event, event_class)
|
66
|
+
Decidim::EventsManager.publish(
|
67
|
+
event: event,
|
68
|
+
event_class: event_class,
|
69
|
+
resource: proposal,
|
70
|
+
recipient_ids: proposal.followers.pluck(:id)
|
71
|
+
)
|
72
|
+
end
|
41
73
|
end
|
42
74
|
end
|
43
75
|
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Decidim
|
4
|
+
module Proposals
|
5
|
+
module Admin
|
6
|
+
# A command with all the business logic when an admin creates a private note proposal.
|
7
|
+
class CreateProposalNote < Rectify::Command
|
8
|
+
# Public: Initializes the command.
|
9
|
+
#
|
10
|
+
# form - A form object with the params.
|
11
|
+
# current_user - The current user.
|
12
|
+
# proposal - the proposal to relate.
|
13
|
+
def initialize(form, proposal, current_user)
|
14
|
+
@form = form
|
15
|
+
@proposal = proposal
|
16
|
+
@current_user = current_user
|
17
|
+
end
|
18
|
+
|
19
|
+
# Executes the command. Broadcasts these events:
|
20
|
+
#
|
21
|
+
# - :ok when everything is valid, together with the note proposal.
|
22
|
+
# - :invalid if the form wasn't valid and we couldn't proceed.
|
23
|
+
#
|
24
|
+
# Returns nothing.
|
25
|
+
def call
|
26
|
+
return broadcast(:invalid) if form.invalid?
|
27
|
+
|
28
|
+
create_proposal_note
|
29
|
+
|
30
|
+
broadcast(:ok, proposal_note)
|
31
|
+
end
|
32
|
+
|
33
|
+
private
|
34
|
+
|
35
|
+
attr_reader :form, :proposal_note
|
36
|
+
|
37
|
+
def create_proposal_note
|
38
|
+
@proposal_note = ProposalNote.create!(
|
39
|
+
body: form.body,
|
40
|
+
proposal: @proposal,
|
41
|
+
author: @current_user
|
42
|
+
)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -35,6 +35,7 @@ module Decidim
|
|
35
35
|
transaction do
|
36
36
|
create_proposal
|
37
37
|
create_attachment if process_attachments?
|
38
|
+
send_notification
|
38
39
|
end
|
39
40
|
|
40
41
|
broadcast(:ok, proposal)
|
@@ -42,6 +43,17 @@ module Decidim
|
|
42
43
|
|
43
44
|
private
|
44
45
|
|
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
|
+
|
45
57
|
attr_reader :form, :proposal, :attachment
|
46
58
|
|
47
59
|
def create_proposal
|
@@ -0,0 +1,37 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Decidim
|
4
|
+
module Proposals
|
5
|
+
# A command with all the business logic when a user withdraws a new proposal.
|
6
|
+
class WithdrawProposal < Rectify::Command
|
7
|
+
# Public: Initializes the command.
|
8
|
+
#
|
9
|
+
# proposal - The proposal to withdraw.
|
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, together with the proposal.
|
19
|
+
# - :invalid if the proposal already has supports or does not belong to current user.
|
20
|
+
#
|
21
|
+
# Returns nothing.
|
22
|
+
def call
|
23
|
+
return broadcast(:invalid) if @proposal.votes.any?
|
24
|
+
|
25
|
+
change_proposal_state_to_withdrawn
|
26
|
+
|
27
|
+
broadcast(:ok, @proposal)
|
28
|
+
end
|
29
|
+
|
30
|
+
private
|
31
|
+
|
32
|
+
def change_proposal_state_to_withdrawn
|
33
|
+
@proposal.update_attributes state: "withdrawn"
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Decidim
|
4
|
+
module Proposals
|
5
|
+
module Admin
|
6
|
+
# This controller allows admins to make private notes on proposals in a participatory process.
|
7
|
+
class ProposalNotesController < Admin::ApplicationController
|
8
|
+
helper_method :proposal
|
9
|
+
|
10
|
+
def index
|
11
|
+
authorize! :create, ProposalNote
|
12
|
+
@form = form(ProposalNoteForm).instance
|
13
|
+
end
|
14
|
+
|
15
|
+
def create
|
16
|
+
authorize! :create, ProposalNote
|
17
|
+
@form = form(ProposalNoteForm).from_params(params)
|
18
|
+
|
19
|
+
CreateProposalNote.call(@form, proposal, current_user) do
|
20
|
+
on(:ok) do
|
21
|
+
flash[:notice] = I18n.t("proposals.create.success", scope: "decidim")
|
22
|
+
redirect_to proposal_proposal_notes_path(proposal_id: proposal.id)
|
23
|
+
end
|
24
|
+
|
25
|
+
on(:invalid) do
|
26
|
+
flash.now[:alert] = I18n.t("proposals.create.error", scope: "decidim")
|
27
|
+
render :index
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
private
|
33
|
+
|
34
|
+
def proposal
|
35
|
+
@proposals ||= Proposal.where(feature: current_feature).find(params[:proposal_id])
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -6,7 +6,7 @@ module Decidim
|
|
6
6
|
# This controller allows admins to manage proposals in a participatory process.
|
7
7
|
class ProposalsController < Admin::ApplicationController
|
8
8
|
helper Proposals::ApplicationHelper
|
9
|
-
helper_method :proposals
|
9
|
+
helper_method :proposals, :query
|
10
10
|
|
11
11
|
def new
|
12
12
|
authorize! :create, Proposal
|
@@ -34,8 +34,12 @@ module Decidim
|
|
34
34
|
|
35
35
|
private
|
36
36
|
|
37
|
+
def query
|
38
|
+
@query ||= Proposal.where(feature: current_feature).ransack(params[:q])
|
39
|
+
end
|
40
|
+
|
37
41
|
def proposals
|
38
|
-
@proposals ||=
|
42
|
+
@proposals ||= query.result.page(params[:page]).per(15)
|
39
43
|
end
|
40
44
|
|
41
45
|
def proposal
|
@@ -55,7 +55,7 @@ module Decidim
|
|
55
55
|
CreateProposal.call(@form, current_user) do
|
56
56
|
on(:ok) do |proposal|
|
57
57
|
flash[:notice] = I18n.t("proposals.create.success", scope: "decidim")
|
58
|
-
redirect_to
|
58
|
+
redirect_to Decidim::ResourceLocatorPresenter.new(proposal).path
|
59
59
|
end
|
60
60
|
|
61
61
|
on(:invalid) do
|
@@ -77,16 +77,31 @@ module Decidim
|
|
77
77
|
authorize! :edit, @proposal
|
78
78
|
|
79
79
|
@form = form(ProposalForm).from_params(params)
|
80
|
-
|
81
80
|
UpdateProposal.call(@form, current_user, @proposal) do
|
82
81
|
on(:ok) do |proposal|
|
83
82
|
flash[:notice] = I18n.t("proposals.update.success", scope: "decidim")
|
84
|
-
redirect_to
|
83
|
+
redirect_to Decidim::ResourceLocatorPresenter.new(proposal).path
|
85
84
|
end
|
86
85
|
|
87
86
|
on(:invalid) do
|
88
87
|
flash.now[:alert] = I18n.t("proposals.update.error", scope: "decidim")
|
89
|
-
render :
|
88
|
+
render :edit
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
def withdraw
|
94
|
+
@proposal = Proposal.not_hidden.where(feature: current_feature).find(params[:id])
|
95
|
+
authorize! :withdraw, @proposal
|
96
|
+
|
97
|
+
WithdrawProposal.call(@proposal, current_user) do
|
98
|
+
on(:ok) do |_proposal|
|
99
|
+
flash[:notice] = I18n.t("proposals.update.success", scope: "decidim")
|
100
|
+
redirect_to Decidim::ResourceLocatorPresenter.new(@proposal).path
|
101
|
+
end
|
102
|
+
on(:invalid) do
|
103
|
+
flash[:alert] = I18n.t("proposals.update.error", scope: "decidim")
|
104
|
+
redirect_to Decidim::ResourceLocatorPresenter.new(@proposal).path
|
90
105
|
end
|
91
106
|
end
|
92
107
|
end
|
@@ -107,7 +122,7 @@ module Decidim
|
|
107
122
|
origin: "all",
|
108
123
|
activity: "",
|
109
124
|
category_id: "",
|
110
|
-
state: "
|
125
|
+
state: "not_withdrawn",
|
111
126
|
scope_id: nil,
|
112
127
|
related_to: ""
|
113
128
|
}
|
@@ -20,8 +20,9 @@ module Decidim
|
|
20
20
|
validates :address, geocoding: true, if: -> { current_feature.settings.geocoding_enabled? }
|
21
21
|
validates :category, presence: true, if: ->(form) { form.category_id.present? }
|
22
22
|
validates :scope, presence: true, if: ->(form) { form.scope_id.present? }
|
23
|
+
validate { errors.add(:scope_id, :invalid) if current_participatory_space&.scope && !current_participatory_space&.scope&.ancestor_of?(scope) }
|
23
24
|
|
24
|
-
delegate :categories, to: :current_feature
|
25
|
+
delegate :categories, to: :current_feature
|
25
26
|
|
26
27
|
def map_model(model)
|
27
28
|
return unless model.categorization
|
@@ -29,28 +30,27 @@ module Decidim
|
|
29
30
|
self.category_id = model.categorization.decidim_category_id
|
30
31
|
end
|
31
32
|
|
32
|
-
def organization_scopes
|
33
|
-
current_organization.scopes
|
34
|
-
end
|
35
|
-
|
36
|
-
def process_scope
|
37
|
-
current_feature.participatory_space.scope
|
38
|
-
end
|
39
|
-
|
40
33
|
alias feature current_feature
|
41
34
|
|
42
35
|
# Finds the Category from the category_id.
|
43
36
|
#
|
44
37
|
# Returns a Decidim::Category
|
45
38
|
def category
|
46
|
-
@category ||= categories.
|
39
|
+
@category ||= categories.find_by(id: category_id)
|
47
40
|
end
|
48
41
|
|
49
|
-
# Finds the Scope from the
|
42
|
+
# Finds the Scope from the given decidim_scope_id, uses participatory space scope if missing.
|
50
43
|
#
|
51
44
|
# Returns a Decidim::Scope
|
52
45
|
def scope
|
53
|
-
@scope ||=
|
46
|
+
@scope ||= @scope_id ? current_feature.scopes.find_by(id: @scope_id) : current_participatory_space&.scope
|
47
|
+
end
|
48
|
+
|
49
|
+
# Scope identifier
|
50
|
+
#
|
51
|
+
# Returns the scope identifier related to the proposal
|
52
|
+
def scope_id
|
53
|
+
@scope_id || scope&.id
|
54
54
|
end
|
55
55
|
end
|
56
56
|
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Decidim
|
4
|
+
module Proposals
|
5
|
+
module Admin
|
6
|
+
# A form object to be used when admin users want to create a proposal.
|
7
|
+
class ProposalNoteForm < Decidim::Form
|
8
|
+
mimic :proposal_note
|
9
|
+
|
10
|
+
attribute :body, String
|
11
|
+
|
12
|
+
validates :body, presence: true
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|