decidim-proposals 0.11.2 → 0.12.0.pre
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/endorsers_list/show.erb +18 -0
- data/app/cells/decidim/proposals/endorsers_list_cell.rb +30 -0
- data/app/cells/decidim/proposals/proposal_cell.rb +55 -0
- data/app/cells/decidim/proposals/proposal_m/footer.erb +23 -0
- data/app/cells/decidim/proposals/proposal_m/tags.erb +1 -0
- data/app/cells/decidim/proposals/proposal_m_cell.rb +74 -0
- data/app/cells/decidim/proposals/proposal_tags/show.erb +25 -0
- data/app/cells/decidim/proposals/proposal_tags_cell.rb +30 -0
- data/app/controllers/decidim/proposals/admin/proposal_answers_controller.rb +2 -2
- data/app/controllers/decidim/proposals/admin/proposal_notes_controller.rb +2 -2
- data/app/controllers/decidim/proposals/admin/proposals_controller.rb +3 -3
- data/app/controllers/decidim/proposals/admin/proposals_imports_controller.rb +2 -4
- data/app/controllers/decidim/proposals/application_controller.rb +0 -3
- data/app/controllers/decidim/proposals/proposal_endorsements_controller.rb +3 -3
- data/app/controllers/decidim/proposals/proposal_votes_controller.rb +2 -2
- data/app/controllers/decidim/proposals/proposals_controller.rb +11 -10
- data/app/forms/decidim/proposals/admin/proposal_form.rb +10 -0
- data/app/forms/decidim/proposals/proposal_form.rb +10 -0
- data/app/helpers/decidim/proposals/application_helper.rb +1 -24
- data/app/helpers/decidim/proposals/proposal_cells_helper.rb +67 -0
- data/app/helpers/decidim/proposals/proposal_votes_helper.rb +1 -1
- data/app/models/decidim/proposals/proposal.rb +22 -2
- data/app/permissions/decidim/proposals/admin/permissions.rb +52 -0
- data/app/permissions/decidim/proposals/permissions.rb +108 -0
- data/app/services/decidim/proposals/proposal_search.rb +2 -0
- data/app/types/decidim/proposals/proposal_type.rb +5 -5
- data/app/views/decidim/participatory_processes/participatory_process_groups/_proposal.html.erb +1 -27
- data/app/views/decidim/participatory_spaces/_proposal.html.erb +1 -27
- data/app/views/decidim/proposals/admin/proposal_notes/_proposal_notes.html.erb +1 -1
- data/app/views/decidim/proposals/admin/proposals/_bulk-actions.html.erb +3 -3
- data/app/views/decidim/proposals/admin/proposals/_proposal-tr.html.erb +3 -3
- data/app/views/decidim/proposals/admin/proposals/index.html.erb +1 -1
- data/app/views/decidim/proposals/proposal_endorsements/_identity.html.erb +2 -1
- data/app/views/decidim/proposals/proposal_widgets/show.html.erb +1 -1
- data/app/views/decidim/proposals/proposals/_endorsements_card_row.html.erb +2 -2
- data/app/views/decidim/proposals/proposals/_filters.html.erb +1 -1
- data/app/views/decidim/proposals/proposals/_linked_proposals.html.erb +7 -6
- data/app/views/decidim/proposals/proposals/_proposal.html.erb +1 -32
- data/app/views/decidim/proposals/proposals/_proposal_preview.html.erb +1 -36
- data/app/views/decidim/proposals/proposals/_proposal_similar.html.erb +6 -5
- data/app/views/decidim/proposals/proposals/_vote_button.html.erb +28 -10
- data/app/views/decidim/proposals/proposals/_votes_count.html.erb +14 -28
- data/app/views/decidim/proposals/proposals/complete.html.erb +10 -3
- data/app/views/decidim/proposals/proposals/index.html.erb +1 -1
- data/app/views/decidim/proposals/proposals/show.html.erb +7 -21
- data/config/locales/ca.yml +43 -15
- data/config/locales/en.yml +43 -15
- data/config/locales/es.yml +42 -14
- data/config/locales/eu.yml +42 -14
- data/config/locales/fi.yml +42 -14
- data/config/locales/fr.yml +42 -14
- data/config/locales/gl.yml +42 -14
- data/config/locales/it.yml +42 -14
- data/config/locales/nl.yml +42 -14
- data/config/locales/pl.yml +52 -14
- data/config/locales/pt-BR.yml +42 -14
- data/config/locales/pt.yml +42 -14
- data/config/locales/ru.yml +49 -17
- data/config/locales/sv.yml +42 -14
- data/config/locales/uk.yml +53 -15
- data/db/migrate/{20171212102250_enable_pg_extensions.rb → 20171212102250_enable_pg_trgm_extension_for_proposals.rb} +1 -1
- data/db/migrate/20180516131201_index_proposals_as_searchable_resources.rb +24 -0
- data/lib/decidim/proposals/admin_engine.rb +0 -10
- data/lib/decidim/proposals/component.rb +4 -1
- data/lib/decidim/proposals/engine.rb +8 -6
- data/lib/decidim/proposals/test/factories.rb +1 -0
- data/lib/decidim/proposals/version.rb +1 -1
- data/lib/decidim/proposals.rb +1 -0
- metadata +61 -28
- data/app/models/decidim/proposals/abilities/admin_ability.rb +0 -42
- data/app/models/decidim/proposals/abilities/current_user_ability.rb +0 -113
- data/app/models/decidim/proposals/abilities/participatory_process_admin_ability.rb +0 -48
- data/app/models/decidim/proposals/abilities/participatory_process_moderator_ability.rb +0 -19
- data/app/views/decidim/proposals/proposals/_identities_listing.html.erb +0 -30
- data/app/views/decidim/proposals/proposals/_identity_xxs.html.erb +0 -8
- data/app/views/decidim/proposals/proposals/_tags.html.erb +0 -25
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2384c4b531953a2fd808d55b6d7fbc1fc4af2a4cd2a0f8c0935cd3358201870a
|
4
|
+
data.tar.gz: 83edd0b0d7ee83bc2ae14aef758bb4ab4380342cfc82b32bd7039ecbf5330491
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: eb153981a26cdf7530da2420db8092e2916b851b65edd01a25c2125dd8f70026a2650dd1137e24841378a6c030932347f80250c15511cee79513f1429000383b
|
7
|
+
data.tar.gz: 83f36e6351ae01cf77748bf9bbabf842b1383954836a968f52655c6bdeb1328d59fc748616f28a8ad9b25a150bd05735fc13914a94bc2902b80e36cbfd1d7bdd
|
@@ -0,0 +1,18 @@
|
|
1
|
+
<div class="section">
|
2
|
+
<a name="list-of-endorsements"></a>
|
3
|
+
<div class="row">
|
4
|
+
<div class="columns large-12">
|
5
|
+
<h4 class="section-heading"><%= t("decidim.proposals.proposals.show.endorsements_list") %></h4>
|
6
|
+
</div>
|
7
|
+
<div class="columns large-12">
|
8
|
+
<%= cell(
|
9
|
+
"decidim/collapsible_list",
|
10
|
+
endorsers,
|
11
|
+
cell_name: "decidim/author",
|
12
|
+
cell_options: { extra_classes: ["author-data--small"] },
|
13
|
+
hidden_elements_count_i18n_key: "decidim.proposals.proposals.show.hidden_endorsers_count",
|
14
|
+
size: :small
|
15
|
+
) %>
|
16
|
+
</div>
|
17
|
+
</div>
|
18
|
+
</div>
|
@@ -0,0 +1,30 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "cell/partial"
|
4
|
+
|
5
|
+
module Decidim
|
6
|
+
module Proposals
|
7
|
+
# This cell renders the list of endorsers for the given Proposal.
|
8
|
+
#
|
9
|
+
# Example:
|
10
|
+
#
|
11
|
+
# cell("decidim/proposals/endorsers_list", my_proposal)
|
12
|
+
class EndorsersListCell < Decidim::ViewModel
|
13
|
+
include ProposalCellsHelper
|
14
|
+
|
15
|
+
def show
|
16
|
+
return unless endorsers.any?
|
17
|
+
render
|
18
|
+
end
|
19
|
+
|
20
|
+
private
|
21
|
+
|
22
|
+
# Finds the correct author for each endorsement.
|
23
|
+
#
|
24
|
+
# Returns an Array of presented Users/UserGroups
|
25
|
+
def endorsers
|
26
|
+
@endorsers ||= model.endorsements.for_listing.map { |identity| present(identity.normalized_author) }
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "cell/partial"
|
4
|
+
|
5
|
+
module Decidim
|
6
|
+
module Proposals
|
7
|
+
# This cell renders the proposal card for an instance of a Proposal
|
8
|
+
# the default size is the Medium Card (:m)
|
9
|
+
class ProposalCell < Decidim::ViewModel
|
10
|
+
include ProposalCellsHelper
|
11
|
+
include Cell::ViewModel::Partial
|
12
|
+
include Messaging::ConversationHelper
|
13
|
+
|
14
|
+
delegate :user_signed_in?, to: :parent_controller
|
15
|
+
|
16
|
+
def show
|
17
|
+
cell card_size, model, @options
|
18
|
+
end
|
19
|
+
|
20
|
+
private
|
21
|
+
|
22
|
+
def current_user
|
23
|
+
context[:current_user]
|
24
|
+
end
|
25
|
+
|
26
|
+
def card_size
|
27
|
+
"decidim/proposals/proposal_m"
|
28
|
+
end
|
29
|
+
|
30
|
+
def resource_path
|
31
|
+
resource_locator(model).path
|
32
|
+
end
|
33
|
+
|
34
|
+
def current_participatory_space
|
35
|
+
model.component.participatory_space
|
36
|
+
end
|
37
|
+
|
38
|
+
def component_name
|
39
|
+
translated_attribute current_component.name
|
40
|
+
end
|
41
|
+
|
42
|
+
def component_type_name
|
43
|
+
model.class.model_name.human
|
44
|
+
end
|
45
|
+
|
46
|
+
def participatory_space_name
|
47
|
+
translated_attribute current_participatory_space.title
|
48
|
+
end
|
49
|
+
|
50
|
+
def participatory_space_type_name
|
51
|
+
translated_attribute current_participatory_space.model_name.human
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
<% if has_link_to_resource? %>
|
2
|
+
<div class="card__footer">
|
3
|
+
<div class="card__support">
|
4
|
+
<% if actionable? %>
|
5
|
+
<% if !current_settings.votes_hidden? %>
|
6
|
+
<%= cell(
|
7
|
+
"decidim/progress_bar",
|
8
|
+
progress_bar_progress,
|
9
|
+
total: progress_bar_total,
|
10
|
+
units_name: "decidim.proposals.proposals.votes_count.count",
|
11
|
+
element_id: "proposal-#{model.id}-votes-count",
|
12
|
+
subtitle_text: progress_bar_subtitle_text,
|
13
|
+
small: true
|
14
|
+
) %>
|
15
|
+
<% end %>
|
16
|
+
<%= render partial: "decidim/proposals/proposals/vote_button.html", locals: { proposal: model, from_proposals_list: true } %>
|
17
|
+
<% else %>
|
18
|
+
<div class="card__support__data"></div>
|
19
|
+
<%= link_to t("decidim.proposals.proposals.proposal.view_proposal"), resource_path, class: "card__button button--sc light button small secondary" %>
|
20
|
+
<% end %>
|
21
|
+
</div>
|
22
|
+
</div>
|
23
|
+
<% end %>
|
@@ -0,0 +1 @@
|
|
1
|
+
<%= render partial: "decidim/shared/tags.html", locals: { resource: model, tags_class_extra: "tags--proposal" } %>
|
@@ -0,0 +1,74 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "cell/partial"
|
4
|
+
|
5
|
+
module Decidim
|
6
|
+
module Proposals
|
7
|
+
# This cell renders a proposal with its M-size card.
|
8
|
+
class ProposalMCell < Decidim::CardMCell
|
9
|
+
include ProposalCellsHelper
|
10
|
+
|
11
|
+
def badge
|
12
|
+
render if has_badge?
|
13
|
+
end
|
14
|
+
|
15
|
+
private
|
16
|
+
|
17
|
+
def has_state?
|
18
|
+
model.published?
|
19
|
+
end
|
20
|
+
|
21
|
+
def has_badge?
|
22
|
+
answered? || withdrawn?
|
23
|
+
end
|
24
|
+
|
25
|
+
def has_link_to_resource?
|
26
|
+
model.published?
|
27
|
+
end
|
28
|
+
|
29
|
+
def description
|
30
|
+
truncate(model.body, length: 100)
|
31
|
+
end
|
32
|
+
|
33
|
+
def badge_classes
|
34
|
+
return super unless options[:full_badge]
|
35
|
+
state_classes.concat(["label", "proposal-status"]).join(" ")
|
36
|
+
end
|
37
|
+
|
38
|
+
def statuses
|
39
|
+
return [:creation_date, :endorsements_count, :comments_count] unless has_link_to_resource?
|
40
|
+
[:creation_date, :follow, :endorsements_count, :comments_count]
|
41
|
+
end
|
42
|
+
|
43
|
+
def endorsements_count_status
|
44
|
+
return endorsements_count unless has_link_to_resource?
|
45
|
+
|
46
|
+
link_to resource_path do
|
47
|
+
endorsements_count
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
def endorsements_count
|
52
|
+
with_tooltip t("decidim.proposals.models.proposal.fields.endorsements") do
|
53
|
+
icon("bullhorn", class: "icon--small") + " " + model.proposal_endorsements_count.to_s
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
def progress_bar_progress
|
58
|
+
model.proposal_votes_count || 0
|
59
|
+
end
|
60
|
+
|
61
|
+
def progress_bar_total
|
62
|
+
model.maximum_votes || 0
|
63
|
+
end
|
64
|
+
|
65
|
+
def progress_bar_subtitle_text
|
66
|
+
if progress_bar_progress >= progress_bar_total
|
67
|
+
t("decidim.proposals.proposals.votes_count.most_popular_proposal")
|
68
|
+
else
|
69
|
+
t("decidim.proposals.proposals.votes_count.need_more_votes")
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
<figure>
|
2
|
+
<figcaption class="text-uppercase">
|
3
|
+
<strong>
|
4
|
+
<%= t("filed_as", scope: "decidim.proposals.proposals.tags") %>
|
5
|
+
</strong>
|
6
|
+
</figcaption>
|
7
|
+
|
8
|
+
<ul>
|
9
|
+
<% if category.present? %>
|
10
|
+
<li>
|
11
|
+
<%= link_to translated_attribute(category.name), resource_locator(model).index(filter: { category_id: category.id }) %>
|
12
|
+
<% if previous_category.present? && show_previous_category? %>
|
13
|
+
|
14
|
+
<small class="text-small">
|
15
|
+
<%= t("changed_from", scope: "decidim.proposals.proposals.tags", previous_category: "#{previous_category.translated_name}").html_safe %>
|
16
|
+
</small>
|
17
|
+
<% end %>
|
18
|
+
</li>
|
19
|
+
<% end %>
|
20
|
+
|
21
|
+
<% if has_visible_scopes?(model) %>
|
22
|
+
<li><%= link_to translated_attribute(scope.name), resource_locator(model).index(filter: { scope_id: [scope.id] }) %></li>
|
23
|
+
<% end %>
|
24
|
+
</ul>
|
25
|
+
</figure>
|
@@ -0,0 +1,30 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "cell/partial"
|
4
|
+
|
5
|
+
module Decidim
|
6
|
+
module Proposals
|
7
|
+
# This cell renders the tags for a proposal.
|
8
|
+
class ProposalTagsCell < Decidim::ViewModel
|
9
|
+
include ProposalCellsHelper
|
10
|
+
|
11
|
+
property :category
|
12
|
+
property :previous_category
|
13
|
+
property :scope
|
14
|
+
|
15
|
+
def show
|
16
|
+
render if has_category_or_scopes?
|
17
|
+
end
|
18
|
+
|
19
|
+
private
|
20
|
+
|
21
|
+
def show_previous_category?
|
22
|
+
options[:show_previous_category].to_s != "false"
|
23
|
+
end
|
24
|
+
|
25
|
+
def has_category_or_scopes?
|
26
|
+
category.present? || has_visible_scopes?(model)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -8,12 +8,12 @@ module Decidim
|
|
8
8
|
helper_method :proposal
|
9
9
|
|
10
10
|
def edit
|
11
|
-
|
11
|
+
enforce_permission_to :create, :proposal_answer
|
12
12
|
@form = form(Admin::ProposalAnswerForm).from_model(proposal)
|
13
13
|
end
|
14
14
|
|
15
15
|
def update
|
16
|
-
|
16
|
+
enforce_permission_to :create, :proposal_answer
|
17
17
|
@form = form(Admin::ProposalAnswerForm).from_params(params)
|
18
18
|
|
19
19
|
Admin::AnswerProposal.call(@form, proposal) do
|
@@ -8,12 +8,12 @@ module Decidim
|
|
8
8
|
helper_method :proposal
|
9
9
|
|
10
10
|
def index
|
11
|
-
|
11
|
+
enforce_permission_to :create, :proposal_note
|
12
12
|
@form = form(ProposalNoteForm).instance
|
13
13
|
end
|
14
14
|
|
15
15
|
def create
|
16
|
-
|
16
|
+
enforce_permission_to :create, :proposal_note
|
17
17
|
@form = form(ProposalNoteForm).from_params(params)
|
18
18
|
|
19
19
|
CreateProposalNote.call(@form, proposal) do
|
@@ -9,14 +9,14 @@ module Decidim
|
|
9
9
|
helper_method :proposals, :query
|
10
10
|
|
11
11
|
def new
|
12
|
-
|
12
|
+
enforce_permission_to :create, :proposal
|
13
13
|
@form = form(Admin::ProposalForm).from_params(
|
14
14
|
attachment: form(AttachmentForm).from_params({})
|
15
15
|
)
|
16
16
|
end
|
17
17
|
|
18
18
|
def create
|
19
|
-
|
19
|
+
enforce_permission_to :create, :proposal
|
20
20
|
@form = form(Admin::ProposalForm).from_params(params)
|
21
21
|
|
22
22
|
Admin::CreateProposal.call(@form) do
|
@@ -33,7 +33,7 @@ module Decidim
|
|
33
33
|
end
|
34
34
|
|
35
35
|
def update_category
|
36
|
-
|
36
|
+
enforce_permission_to :update, :proposal_category
|
37
37
|
@proposal_ids = params[:proposal_ids]
|
38
38
|
|
39
39
|
Admin::UpdateProposalCategory.call(params[:category][:id], params[:proposal_ids]) do
|
@@ -5,18 +5,16 @@ module Decidim
|
|
5
5
|
module Admin
|
6
6
|
class ProposalsImportsController < Admin::ApplicationController
|
7
7
|
def new
|
8
|
-
|
8
|
+
enforce_permission_to :import, :proposals
|
9
9
|
|
10
10
|
@form = form(Admin::ProposalsImportForm).instance
|
11
11
|
end
|
12
12
|
|
13
13
|
def create
|
14
|
-
|
14
|
+
enforce_permission_to :import, :proposals
|
15
15
|
|
16
16
|
@form = form(Admin::ProposalsImportForm).from_params(params)
|
17
17
|
|
18
|
-
authorize! :manage, @form.origin_component
|
19
|
-
|
20
18
|
Admin::ImportProposals.call(@form) do
|
21
19
|
on(:ok) do |proposals|
|
22
20
|
flash[:notice] = I18n.t("proposals_imports.create.success", scope: "decidim.proposals.admin", number: proposals.length)
|
@@ -9,11 +9,8 @@ module Decidim
|
|
9
9
|
# override its layout and provide all kinds of useful methods.
|
10
10
|
class ApplicationController < Decidim::Components::BaseController
|
11
11
|
helper Decidim::Messaging::ConversationHelper
|
12
|
-
|
13
12
|
helper_method :proposal_limit_reached?
|
14
13
|
|
15
|
-
private
|
16
|
-
|
17
14
|
def proposal_limit
|
18
15
|
return nil if component_settings.proposal_limit.zero?
|
19
16
|
component_settings.proposal_limit
|
@@ -9,7 +9,7 @@ module Decidim
|
|
9
9
|
before_action :authenticate_user!
|
10
10
|
|
11
11
|
def create
|
12
|
-
|
12
|
+
enforce_permission_to :endorse, :proposal, proposal: proposal
|
13
13
|
@from_proposals_list = params[:from_proposals_list] == "true"
|
14
14
|
user_group_id = params[:user_group_id]
|
15
15
|
|
@@ -26,7 +26,7 @@ module Decidim
|
|
26
26
|
end
|
27
27
|
|
28
28
|
def destroy
|
29
|
-
|
29
|
+
enforce_permission_to :unendorse, :proposal, proposal: proposal
|
30
30
|
@from_proposals_list = params[:from_proposals_list] == "true"
|
31
31
|
user_group_id = params[:user_group_id]
|
32
32
|
user_group = current_user.user_groups.verified.find(user_group_id) if user_group_id
|
@@ -40,7 +40,7 @@ module Decidim
|
|
40
40
|
end
|
41
41
|
|
42
42
|
def identities
|
43
|
-
|
43
|
+
enforce_permission_to :endorse, :proposal, proposal: proposal
|
44
44
|
|
45
45
|
@user_verified_groups = current_user.user_groups.verified
|
46
46
|
render :identities, layout: false
|
@@ -11,7 +11,7 @@ module Decidim
|
|
11
11
|
before_action :authenticate_user!
|
12
12
|
|
13
13
|
def create
|
14
|
-
|
14
|
+
enforce_permission_to :vote, :proposal, proposal: proposal
|
15
15
|
@from_proposals_list = params[:from_proposals_list] == "true"
|
16
16
|
|
17
17
|
VoteProposal.call(proposal, current_user) do
|
@@ -27,7 +27,7 @@ module Decidim
|
|
27
27
|
end
|
28
28
|
|
29
29
|
def destroy
|
30
|
-
|
30
|
+
enforce_permission_to :unvote, :proposal, proposal: proposal
|
31
31
|
@from_proposals_list = params[:from_proposals_list] == "true"
|
32
32
|
|
33
33
|
UnvoteProposal.call(proposal, current_user) do
|
@@ -43,7 +43,7 @@ module Decidim
|
|
43
43
|
end
|
44
44
|
|
45
45
|
def new
|
46
|
-
|
46
|
+
enforce_permission_to :create, :proposal
|
47
47
|
@step = :step_1
|
48
48
|
if proposal_draft.present?
|
49
49
|
redirect_to edit_draft_proposal_path(proposal_draft, component_id: proposal_draft.component.id, question_slug: proposal_draft.component.participatory_space.slug)
|
@@ -53,7 +53,7 @@ module Decidim
|
|
53
53
|
end
|
54
54
|
|
55
55
|
def create
|
56
|
-
|
56
|
+
enforce_permission_to :create, :proposal
|
57
57
|
@step = :step_3
|
58
58
|
@form = form(ProposalForm).from_params(params)
|
59
59
|
|
@@ -85,8 +85,9 @@ module Decidim
|
|
85
85
|
end
|
86
86
|
|
87
87
|
def complete
|
88
|
-
|
88
|
+
enforce_permission_to :create, :proposal
|
89
89
|
@step = :step_3
|
90
|
+
|
90
91
|
if params[:proposal].present?
|
91
92
|
params[:proposal][:attachment] = form(AttachmentForm).from_params({})
|
92
93
|
@form = form(ProposalForm).from_params(params)
|
@@ -118,14 +119,14 @@ module Decidim
|
|
118
119
|
|
119
120
|
def edit_draft
|
120
121
|
@step = :step_3
|
121
|
-
|
122
|
+
enforce_permission_to :edit, :proposal, proposal: @proposal
|
122
123
|
|
123
124
|
@form = form(ProposalForm).from_model(@proposal)
|
124
125
|
end
|
125
126
|
|
126
127
|
def update_draft
|
127
128
|
@step = :step_1
|
128
|
-
|
129
|
+
enforce_permission_to :edit, :proposal, proposal: @proposal
|
129
130
|
|
130
131
|
@form = form(ProposalForm).from_params(params)
|
131
132
|
UpdateProposal.call(@form, current_user, @proposal) do
|
@@ -142,7 +143,7 @@ module Decidim
|
|
142
143
|
end
|
143
144
|
|
144
145
|
def destroy_draft
|
145
|
-
|
146
|
+
enforce_permission_to :edit, :proposal, proposal: @proposal
|
146
147
|
|
147
148
|
DestroyProposal.call(@proposal, current_user) do
|
148
149
|
on(:ok) do
|
@@ -159,14 +160,14 @@ module Decidim
|
|
159
160
|
|
160
161
|
def edit
|
161
162
|
@proposal = Proposal.published.not_hidden.where(component: current_component).find(params[:id])
|
162
|
-
|
163
|
+
enforce_permission_to :edit, :proposal, proposal: @proposal
|
163
164
|
|
164
165
|
@form = form(ProposalForm).from_model(@proposal)
|
165
166
|
end
|
166
167
|
|
167
168
|
def update
|
168
169
|
@proposal = Proposal.not_hidden.where(component: current_component).find(params[:id])
|
169
|
-
|
170
|
+
enforce_permission_to :edit, :proposal, proposal: @proposal
|
170
171
|
|
171
172
|
@form = form(ProposalForm).from_params(params)
|
172
173
|
UpdateProposal.call(@form, current_user, @proposal) do
|
@@ -184,7 +185,7 @@ module Decidim
|
|
184
185
|
|
185
186
|
def withdraw
|
186
187
|
@proposal = Proposal.published.not_hidden.where(component: current_component).find(params[:id])
|
187
|
-
|
188
|
+
enforce_permission_to :withdraw, :proposal, proposal: @proposal
|
188
189
|
|
189
190
|
WithdrawProposal.call(@proposal, current_user) do
|
190
191
|
on(:ok) do |_proposal|
|
@@ -214,7 +215,7 @@ module Decidim
|
|
214
215
|
origin: "all",
|
215
216
|
activity: "",
|
216
217
|
category_id: "",
|
217
|
-
state: "
|
218
|
+
state: "except_rejected",
|
218
219
|
scope_id: nil,
|
219
220
|
related_to: ""
|
220
221
|
}
|
@@ -23,6 +23,8 @@ module Decidim
|
|
23
23
|
|
24
24
|
validate :scope_belongs_to_participatory_space_scope
|
25
25
|
|
26
|
+
validate :notify_missing_attachment_if_errored
|
27
|
+
|
26
28
|
delegate :categories, to: :current_component
|
27
29
|
|
28
30
|
def map_model(model)
|
@@ -59,6 +61,14 @@ module Decidim
|
|
59
61
|
def scope_belongs_to_participatory_space_scope
|
60
62
|
errors.add(:scope_id, :invalid) if current_participatory_space.out_of_scope?(scope)
|
61
63
|
end
|
64
|
+
|
65
|
+
# This method will add an error to the `attachment` field only if there's
|
66
|
+
# any error in any other field. This is needed because when the form has
|
67
|
+
# an error, the attachment is lost, so we need a way to inform the user of
|
68
|
+
# this problem.
|
69
|
+
def notify_missing_attachment_if_errored
|
70
|
+
errors.add(:attachment, :needs_to_be_reattached) if errors.any? && attachment.present?
|
71
|
+
end
|
62
72
|
end
|
63
73
|
end
|
64
74
|
end
|
@@ -26,6 +26,8 @@ module Decidim
|
|
26
26
|
validate :proposal_length
|
27
27
|
validate :scope_belongs_to_participatory_space_scope
|
28
28
|
|
29
|
+
validate :notify_missing_attachment_if_errored
|
30
|
+
|
29
31
|
delegate :categories, to: :current_component
|
30
32
|
|
31
33
|
def map_model(model)
|
@@ -72,6 +74,14 @@ module Decidim
|
|
72
74
|
def scope_belongs_to_participatory_space_scope
|
73
75
|
errors.add(:scope_id, :invalid) if current_participatory_space.out_of_scope?(scope)
|
74
76
|
end
|
77
|
+
|
78
|
+
# This method will add an error to the `attachment` field only if there's
|
79
|
+
# any error in any other field. This is needed because when the form has
|
80
|
+
# an error, the attachment is lost, so we need a way to inform the user of
|
81
|
+
# this problem.
|
82
|
+
def notify_missing_attachment_if_errored
|
83
|
+
errors.add(:attachment, :needs_to_be_reattached) if errors.any? && attachment.present?
|
84
|
+
end
|
75
85
|
end
|
76
86
|
end
|
77
87
|
end
|
@@ -74,7 +74,7 @@ module Decidim
|
|
74
74
|
|
75
75
|
def follow_button_for(model)
|
76
76
|
if current_user
|
77
|
-
render partial: "decidim/shared/follow_button", locals: { followable: model }
|
77
|
+
render partial: "decidim/shared/follow_button.html", locals: { followable: model }
|
78
78
|
else
|
79
79
|
content_tag(:p, class: "mt-s mb-none") do
|
80
80
|
t("decidim.proposals.proposals.show.sign_in_or_up",
|
@@ -83,29 +83,6 @@ module Decidim
|
|
83
83
|
end
|
84
84
|
end
|
85
85
|
end
|
86
|
-
|
87
|
-
# Public - A widget that lists all identities in an xxs card format.
|
88
|
-
# Shows the first 5 identities and hides the rest, but presents a 'see all'
|
89
|
-
# button to make the rest of identities visible.
|
90
|
-
#
|
91
|
-
# @param identities: The list of identities. Each item must have a user_group or author method.
|
92
|
-
# @param widget_id: Mandatory when placing more than 1 widget in a page, optional otherwise. Is the id
|
93
|
-
# uniquely identify this widget in the page.
|
94
|
-
#
|
95
|
-
def identities_list_xxs(identities, widget_id = "identities-xxs")
|
96
|
-
widget_ids = {
|
97
|
-
ellipsis: "#{widget_id}-ellipsis",
|
98
|
-
remaining_identities: "#{widget_id}-remaining-identities",
|
99
|
-
see_all_identities: "#{widget_id}-see-all-identities"
|
100
|
-
}
|
101
|
-
render partial: "identities_listing", locals: { identities: identities, widget_ids: widget_ids }
|
102
|
-
end
|
103
|
-
|
104
|
-
def identities_xxs(identities)
|
105
|
-
identities.collect do |identity|
|
106
|
-
render partial: "identity_xxs", locals: { identity: identity.normalized_author }
|
107
|
-
end.join(", ").html_safe
|
108
|
-
end
|
109
86
|
end
|
110
87
|
end
|
111
88
|
end
|
@@ -0,0 +1,67 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Decidim
|
4
|
+
module Proposals
|
5
|
+
# Custom helpers, scoped to the proposals engine.
|
6
|
+
#
|
7
|
+
module ProposalCellsHelper
|
8
|
+
include Decidim::Proposals::ApplicationHelper
|
9
|
+
include Decidim::Proposals::Engine.routes.url_helpers
|
10
|
+
include Decidim::LayoutHelper
|
11
|
+
include Decidim::ApplicationHelper
|
12
|
+
include Decidim::TranslationsHelper
|
13
|
+
include Decidim::ResourceReferenceHelper
|
14
|
+
include Decidim::TranslatableAttributes
|
15
|
+
include Decidim::CardHelper
|
16
|
+
|
17
|
+
delegate :title, :state, :answered?, :withdrawn?, to: :model
|
18
|
+
|
19
|
+
def actionable?
|
20
|
+
proposals_controller? && index_action? && current_settings.votes_enabled? && !model.draft?
|
21
|
+
end
|
22
|
+
|
23
|
+
def proposals_controller?
|
24
|
+
context[:controller].class.to_s == "Decidim::Proposals::ProposalsController"
|
25
|
+
end
|
26
|
+
|
27
|
+
def index_action?
|
28
|
+
context[:controller].action_name == "index"
|
29
|
+
end
|
30
|
+
|
31
|
+
def current_settings
|
32
|
+
model.component.current_settings
|
33
|
+
end
|
34
|
+
|
35
|
+
def component_settings
|
36
|
+
model.component.settings
|
37
|
+
end
|
38
|
+
|
39
|
+
def current_component
|
40
|
+
model.component
|
41
|
+
end
|
42
|
+
|
43
|
+
def from_context
|
44
|
+
@options[:from]
|
45
|
+
end
|
46
|
+
|
47
|
+
def badge_name
|
48
|
+
humanize_proposal_state state
|
49
|
+
end
|
50
|
+
|
51
|
+
def state_classes
|
52
|
+
case state
|
53
|
+
when "accepted"
|
54
|
+
["success"]
|
55
|
+
when "rejected"
|
56
|
+
["alert"]
|
57
|
+
when "evaluating"
|
58
|
+
["warning"]
|
59
|
+
when "withdrawn"
|
60
|
+
["alert"]
|
61
|
+
else
|
62
|
+
["muted"]
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|