decidim-proposals 0.28.2 → 0.29.0.rc1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +1 -18
- data/app/cells/decidim/proposals/cost_report_cell.rb +0 -3
- data/app/cells/decidim/proposals/highlighted_proposals_for_component_cell.rb +1 -1
- data/app/cells/decidim/proposals/participatory_text_proposal/buttons.erb +1 -1
- data/app/cells/decidim/proposals/participatory_text_proposal_cell.rb +2 -3
- data/app/cells/decidim/proposals/proposal_cell.rb +2 -0
- data/app/cells/decidim/proposals/proposal_g/show.erb +23 -0
- data/app/cells/decidim/proposals/proposal_g_cell.rb +48 -0
- data/app/cells/decidim/proposals/proposal_l_cell.rb +0 -2
- data/app/cells/decidim/proposals/proposal_metadata_cell.rb +23 -15
- data/app/commands/decidim/proposals/admin/answer_proposal.rb +2 -1
- data/app/commands/decidim/proposals/admin/assign_proposals_to_valuator.rb +7 -5
- data/app/commands/decidim/proposals/admin/create_proposal.rb +2 -2
- data/app/commands/decidim/proposals/admin/create_proposal_state.rb +15 -0
- data/app/commands/decidim/proposals/admin/destroy_proposal_state.rb +10 -0
- data/app/commands/decidim/proposals/admin/import_proposals.rb +10 -2
- data/app/commands/decidim/proposals/admin/notify_proposal_answer.rb +4 -21
- data/app/commands/decidim/proposals/admin/unassign_proposals_from_valuator.rb +6 -4
- data/app/commands/decidim/proposals/admin/update_proposal_state.rb +13 -0
- data/app/commands/decidim/proposals/create_proposal.rb +21 -2
- data/app/commands/decidim/proposals/update_proposal.rb +2 -2
- data/app/commands/decidim/proposals/vote_proposal.rb +1 -1
- data/app/commands/decidim/proposals/withdraw_proposal.rb +3 -7
- data/app/controllers/concerns/decidim/proposals/admin/filterable.rb +10 -22
- data/app/controllers/decidim/proposals/admin/proposal_states_controller.rb +86 -0
- data/app/controllers/decidim/proposals/admin/proposals_controller.rb +4 -0
- data/app/controllers/decidim/proposals/admin/valuation_assignments_controller.rb +8 -11
- data/app/controllers/decidim/proposals/proposals_controller.rb +30 -35
- data/app/events/decidim/proposals/proposal_state_changed_event.rb +37 -0
- data/app/forms/decidim/proposals/admin/proposal_answer_form.rb +5 -1
- data/app/forms/decidim/proposals/admin/proposal_state_form.rb +22 -0
- data/app/forms/decidim/proposals/admin/proposals_fork_form.rb +1 -1
- data/app/forms/decidim/proposals/admin/proposals_import_form.rb +1 -1
- data/app/forms/decidim/proposals/admin/valuation_assignment_form.rb +12 -14
- data/app/forms/decidim/proposals/proposal_form.rb +25 -4
- data/app/forms/decidim/proposals/reject_access_to_collaborative_draft_form.rb +1 -1
- data/app/forms/decidim/proposals/request_access_to_collaborative_draft_form.rb +1 -1
- data/app/helpers/decidim/proposals/admin/proposal_bulk_actions_helper.rb +7 -17
- data/app/helpers/decidim/proposals/admin/proposals_helper.rb +13 -89
- data/app/helpers/decidim/proposals/application_helper.rb +16 -10
- data/app/helpers/decidim/proposals/proposal_cells_helper.rb +6 -2
- data/app/helpers/decidim/proposals/proposal_votes_helper.rb +3 -3
- data/app/helpers/decidim/proposals/proposal_wizard_helper.rb +5 -8
- data/app/helpers/decidim/proposals/proposals_helper.rb +18 -24
- data/app/models/decidim/proposals/proposal.rb +78 -28
- data/app/models/decidim/proposals/proposal_state.rb +58 -0
- data/app/packs/documents/decidim/proposals/participatory_texts/participatory_text.md +1 -3
- data/app/packs/images/decidim/proposals/proposal-placeholder-card-g.svg +15 -0
- data/app/packs/src/decidim/proposals/add_proposal.js +2 -0
- data/app/packs/src/decidim/proposals/admin/proposals.js +43 -8
- data/app/packs/stylesheets/decidim/proposals/proposals.scss +39 -1
- data/app/permissions/decidim/proposals/admin/permissions.rb +16 -4
- data/app/presenters/decidim/proposals/admin_log/proposal_state_presenter.rb +21 -0
- data/app/presenters/decidim/proposals/proposal_presenter.rb +12 -3
- data/app/queries/decidim/proposals/metrics/endorsements_metric_manage.rb +1 -1
- data/app/queries/decidim/proposals/metrics/proposal_followers_metric_measure.rb +1 -1
- data/app/queries/decidim/proposals/metrics/proposal_participants_metric_measure.rb +4 -4
- data/app/queries/decidim/proposals/metrics/proposals_metric_manage.rb +1 -1
- data/app/queries/decidim/proposals/metrics/votes_metric_manage.rb +1 -1
- data/app/services/decidim/proposals/diff_renderer.rb +1 -1
- data/app/views/decidim/proposals/admin/imports/_proposals_fields.html.erb +1 -1
- data/app/views/decidim/proposals/admin/participatory_texts/index.html.erb +3 -2
- data/app/views/decidim/proposals/admin/proposal_answers/_form.html.erb +1 -1
- data/app/views/decidim/proposals/admin/proposal_notes/_proposal_notes.html.erb +3 -3
- data/app/views/decidim/proposals/admin/proposal_states/_form.html.erb +67 -0
- data/app/views/decidim/proposals/admin/proposal_states/edit.html.erb +18 -0
- data/app/views/decidim/proposals/admin/proposal_states/index.html.erb +50 -0
- data/app/views/decidim/proposals/admin/proposal_states/new.html.erb +18 -0
- data/app/views/decidim/proposals/admin/proposals/_bulk-actions.html.erb +0 -2
- data/app/views/decidim/proposals/admin/proposals/_form.html.erb +6 -6
- data/app/views/decidim/proposals/admin/proposals/_proposal-tr.html.erb +2 -2
- data/app/views/decidim/proposals/admin/proposals/bulk_actions/_assign_to_valuator.html.erb +11 -7
- data/app/views/decidim/proposals/admin/proposals/bulk_actions/_dropdown.html.erb +7 -5
- data/app/views/decidim/proposals/admin/proposals/bulk_actions/_merge.html.erb +2 -2
- data/app/views/decidim/proposals/admin/proposals/bulk_actions/_publish_answers.html.erb +2 -2
- data/app/views/decidim/proposals/admin/proposals/bulk_actions/_recategorize.html.erb +2 -2
- data/app/views/decidim/proposals/admin/proposals/bulk_actions/_scope-change.html.erb +2 -2
- data/app/views/decidim/proposals/admin/proposals/bulk_actions/_split.html.erb +2 -2
- data/app/views/decidim/proposals/admin/proposals/bulk_actions/_unassign_from_valuator.html.erb +11 -7
- data/app/views/decidim/proposals/admin/proposals/bulk_actions/_valuators_picker.html.erb +12 -0
- data/app/views/decidim/proposals/admin/proposals/index.html.erb +9 -5
- data/app/views/decidim/proposals/admin/proposals/publish_answers.js.erb +1 -1
- data/app/views/decidim/proposals/admin/proposals/show.html.erb +3 -2
- data/app/views/decidim/proposals/admin/proposals/update_attribute.js.erb +3 -3
- data/app/views/decidim/proposals/proposals/_edit_form_fields.html.erb +12 -5
- data/app/views/decidim/proposals/proposals/_proposal.html.erb +1 -1
- data/app/views/decidim/proposals/proposals/_proposal_aside.html.erb +1 -1
- data/app/views/decidim/proposals/proposals/_proposals.html.erb +9 -3
- data/app/views/decidim/proposals/proposals/_vote_button.html.erb +1 -1
- data/app/views/decidim/proposals/proposals/_voting_rules.html.erb +3 -3
- data/app/views/decidim/proposals/proposals/_wizard_header.html.erb +0 -1
- data/app/views/decidim/proposals/proposals/new.html.erb +2 -7
- data/app/views/decidim/proposals/proposals/participatory_texts/_proposal_vote_button.html.erb +4 -4
- data/app/views/decidim/proposals/proposals/participatory_texts/_proposal_votes_count.html.erb +8 -8
- data/app/views/decidim/proposals/proposals/show.html.erb +1 -1
- data/config/locales/ar.yml +5 -114
- data/config/locales/bg.yml +109 -106
- data/config/locales/ca.yml +80 -77
- data/config/locales/cs.yml +60 -119
- data/config/locales/de.yml +107 -104
- data/config/locales/el.yml +2 -118
- data/config/locales/en.yml +109 -106
- data/config/locales/es-MX.yml +82 -79
- data/config/locales/es-PY.yml +84 -81
- data/config/locales/es.yml +81 -78
- data/config/locales/eu.yml +100 -104
- data/config/locales/fi-plain.yml +87 -84
- data/config/locales/fi.yml +109 -106
- data/config/locales/fr-CA.yml +85 -82
- data/config/locales/fr.yml +77 -74
- data/config/locales/ga-IE.yml +1 -27
- data/config/locales/gl.yml +4 -104
- data/config/locales/he-IL.yml +0 -13
- data/config/locales/hu.yml +14 -88
- data/config/locales/id-ID.yml +1 -97
- data/config/locales/is-IS.yml +0 -33
- data/config/locales/it.yml +5 -96
- data/config/locales/ja.yml +108 -105
- data/config/locales/lb.yml +1 -0
- data/config/locales/lt.yml +2 -122
- data/config/locales/lv.yml +1 -96
- data/config/locales/nl.yml +5 -95
- data/config/locales/no.yml +2 -107
- data/config/locales/pl.yml +105 -113
- data/config/locales/pt-BR.yml +4 -81
- data/config/locales/pt.yml +4 -107
- data/config/locales/ro-RO.yml +5 -110
- data/config/locales/ru.yml +1 -53
- data/config/locales/sk.yml +1 -103
- data/config/locales/sv.yml +20 -103
- data/config/locales/tr-TR.yml +56 -103
- data/config/locales/uk.yml +2 -54
- data/config/locales/zh-CN.yml +1 -99
- data/config/locales/zh-TW.yml +2 -116
- data/db/migrate/20240110203500_add_withdrawn_at_field_to_proposals.rb +27 -0
- data/db/migrate/20240110203501_create_decidim_proposals_proposal_state.rb +14 -0
- data/db/migrate/20240110203502_add_state_id_to_decidim_proposals_proposals.rb +13 -0
- data/db/migrate/20240110203503_remove_state_from_decidim_proposals_proposals.rb +11 -0
- data/db/migrate/20240110203504_create_default_proposal_states.rb +31 -0
- data/db/migrate/20240209092404_change_color_fields_on_proposals_states.rb +54 -0
- data/decidim-proposals.gemspec +2 -2
- data/lib/decidim/api/proposal_type.rb +4 -0
- data/lib/decidim/proposals/admin_engine.rb +8 -0
- data/lib/decidim/proposals/admin_filter.rb +37 -0
- data/lib/decidim/proposals/component.rb +8 -5
- data/lib/decidim/proposals/engine.rb +1 -15
- data/lib/decidim/proposals/import/proposal_answer_creator.rb +6 -6
- data/lib/decidim/proposals/import/proposal_creator.rb +1 -1
- data/lib/decidim/proposals/markdown_to_proposals.rb +2 -8
- data/lib/decidim/proposals/proposal_serializer.rb +5 -3
- data/lib/decidim/proposals/seeds.rb +60 -51
- data/lib/decidim/proposals/test/factories.rb +64 -8
- data/lib/decidim/proposals/version.rb +1 -1
- data/lib/decidim/proposals.rb +84 -12
- data/lib/tasks/proposals/upgrade/decidim_proposals_upgrade_tasks.rake +32 -0
- metadata +49 -35
- data/app/events/decidim/proposals/accepted_proposal_event.rb +0 -17
- data/app/events/decidim/proposals/evaluating_proposal_event.rb +0 -11
- data/app/events/decidim/proposals/rejected_proposal_event.rb +0 -17
- data/app/forms/decidim/proposals/proposal_wizard_create_step_form.rb +0 -44
- data/app/queries/decidim/proposals/similar_proposals.rb +0 -67
- data/app/views/decidim/proposals/proposals/_endorsements_card_row.html.erb +0 -0
- data/app/views/decidim/proposals/proposals/_proposal_badge.html.erb +0 -3
- data/app/views/decidim/proposals/proposals/compare.html.erb +0 -24
- data/app/views/decidim/proposals/proposals/complete.html.erb +0 -31
- data/lib/tasks/proposals/upgrade/decdim_proposal_upgrade_tasks.rake +0 -34
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 22cc3e857b344169fadf51778fef41a0ea95d814e8855a90eb354d5b2bda88fe
|
4
|
+
data.tar.gz: 48d87bd26f7856a756da54a174edddc30c17a9330a7e5af07c808cdfac7adf36
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: be95b2675428571df7ad89af801ad8a988c7f616272386c9cd213644cf285596379079da03c178ccf83d867d1ee70ebff706fc3ce35632c3ced1feeeaef3cd94
|
7
|
+
data.tar.gz: 940ea09bddab76eeacc28e581e3f02ccc79a85a230226aa34dcbbaf3e414f38361f35851557d0c86025a4ab9380230edf79e738fac02054d1c0a5fcc3f2782c2
|
data/README.md
CHANGED
@@ -20,23 +20,6 @@ And then execute:
|
|
20
20
|
bundle
|
21
21
|
```
|
22
22
|
|
23
|
-
### Configuring Similarity
|
24
|
-
|
25
|
-
`pg_trgm` is a PostgreSQL extension providing simple fuzzy string matching used in the Proposal wizard to find similar published proposals (title and the body).
|
26
|
-
|
27
|
-
Create config variables in your app's `/config/initializers/decidim-proposals.rb`:
|
28
|
-
|
29
|
-
```ruby
|
30
|
-
Decidim::Proposals.configure do |config|
|
31
|
-
config.similarity_threshold = 0.25 # default value
|
32
|
-
config.similarity_limit = 10 # default value
|
33
|
-
end
|
34
|
-
```
|
35
|
-
|
36
|
-
`similarity_threshold`(real): Sets the current similarity threshold that is used by the % operator. The threshold must be between 0 and 1 (default is 0.3).
|
37
|
-
|
38
|
-
`similarity_limit`: number of maximum results.
|
39
|
-
|
40
23
|
## Global Search
|
41
24
|
|
42
25
|
This module includes the following models to Decidim's Global Search:
|
@@ -49,7 +32,7 @@ Participatory texts persist each section of the document in a Proposal.
|
|
49
32
|
|
50
33
|
When importing participatory texts all formats are first transformed into Markdown and is the markdown that is parsed and processed to generate the corresponding Proposals.
|
51
34
|
|
52
|
-
When processing participatory text documents three kinds of
|
35
|
+
When processing participatory text documents three kinds of sections are taken into account.
|
53
36
|
|
54
37
|
- Section: each "Title 1" in the document becomes a section.
|
55
38
|
- Subsection: the rest of the titles become subsections.
|
@@ -6,9 +6,6 @@ module Decidim
|
|
6
6
|
module Proposals
|
7
7
|
# This cell renders the cost report for a proposal.
|
8
8
|
class CostReportCell < Decidim::ViewModel
|
9
|
-
include ActionView::Helpers::NumberHelper
|
10
|
-
include Decidim::SanitizeHelper
|
11
|
-
include Decidim::LayoutHelper
|
12
9
|
include ProposalCellsHelper
|
13
10
|
|
14
11
|
private
|
@@ -35,7 +35,7 @@ module Decidim
|
|
35
35
|
end
|
36
36
|
|
37
37
|
def base_relation
|
38
|
-
Decidim::Proposals::Proposal.published.not_hidden.
|
38
|
+
Decidim::Proposals::Proposal.published.not_hidden.not_withdrawn.where(component: model)
|
39
39
|
end
|
40
40
|
|
41
41
|
def decidim_proposals
|
@@ -1,4 +1,4 @@
|
|
1
|
-
<% if
|
1
|
+
<% if amendment_creation_enabled? || visible_emendations.any? %>
|
2
2
|
<%= action_authorized_link_to :amend, amend_resource_path, resource: model, disabled: amend_button_disabled?, class: "proposal-participatory__button" do %>
|
3
3
|
<%= icon "chat-1-line" %>
|
4
4
|
<span><%= t("amend", scope: "decidim.proposals.participatory_text_proposal.buttons") %></span>
|
@@ -10,7 +10,6 @@ module Decidim
|
|
10
10
|
include ProposalCellsHelper
|
11
11
|
include Cell::ViewModel::Partial
|
12
12
|
include Messaging::ConversationHelper
|
13
|
-
include Decidim::SanitizeHelper
|
14
13
|
|
15
14
|
def show
|
16
15
|
render
|
@@ -69,12 +68,12 @@ module Decidim
|
|
69
68
|
@visible_emendations ||= model.visible_emendations_for(current_user)
|
70
69
|
end
|
71
70
|
|
72
|
-
def
|
71
|
+
def amendment_creation_enabled?
|
73
72
|
(current_component.settings.amendments_enabled? && current_settings.amendment_creation_enabled?)
|
74
73
|
end
|
75
74
|
|
76
75
|
def amend_button_disabled?
|
77
|
-
!
|
76
|
+
!amendment_creation_enabled?
|
78
77
|
end
|
79
78
|
end
|
80
79
|
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
<%= link_to resource_path, class: classes[:default], id: resource_id do %>
|
2
|
+
<div class="<%= classes[:img] %>">
|
3
|
+
<% if has_image? %>
|
4
|
+
<%= image_tag resource_image_path, alt: alt_title %>
|
5
|
+
<% else %>
|
6
|
+
<%= external_icon "media/images/proposal-placeholder-card-g.svg", class: "card__proposal-placeholder-g" %>
|
7
|
+
<% end %>
|
8
|
+
</div>
|
9
|
+
<div class="<%= classes[:text] %>">
|
10
|
+
<div class="card__grid-text-title">
|
11
|
+
<%= content_tag title_tag, title, class: title_class %>
|
12
|
+
<%= proposal_state_item[:text] if proposal_state_item.present? %>
|
13
|
+
</div>
|
14
|
+
|
15
|
+
<%= description if show_description? %>
|
16
|
+
|
17
|
+
<% if metadata_cell.present? %>
|
18
|
+
<div class="<%= classes[:metadata] %>">
|
19
|
+
<%= cell metadata_cell, resource, links: false, skip_state: true, **options %>
|
20
|
+
</div>
|
21
|
+
<% end %>
|
22
|
+
</div>
|
23
|
+
<% end %>
|
@@ -0,0 +1,48 @@
|
|
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 Grid Card (:g)
|
9
|
+
class ProposalGCell < Decidim::CardGCell
|
10
|
+
include Decidim::Proposals::ApplicationHelper
|
11
|
+
include Decidim::LayoutHelper
|
12
|
+
|
13
|
+
delegate :state_class, to: :metadata_cell_instance
|
14
|
+
|
15
|
+
def show
|
16
|
+
render
|
17
|
+
end
|
18
|
+
|
19
|
+
def title
|
20
|
+
present(model).title(html_escape: true)
|
21
|
+
end
|
22
|
+
|
23
|
+
def metadata_cell
|
24
|
+
"decidim/proposals/proposal_metadata"
|
25
|
+
end
|
26
|
+
|
27
|
+
def metadata_cell_instance
|
28
|
+
@metadata_cell_instance ||= cell("decidim/proposals/proposal_metadata", model)
|
29
|
+
end
|
30
|
+
|
31
|
+
def resource_image_path
|
32
|
+
model.attachments.first&.url
|
33
|
+
end
|
34
|
+
|
35
|
+
def proposal_state_item
|
36
|
+
return if model.state.blank?
|
37
|
+
|
38
|
+
@proposal_state_item ||= { text: content_tag(:span, humanize_proposal_state(model.state), class: "label #{state_class}") }
|
39
|
+
end
|
40
|
+
|
41
|
+
private
|
42
|
+
|
43
|
+
def classes
|
44
|
+
super.merge(metadata: "card__list-metadata")
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
@@ -15,9 +15,30 @@ module Decidim
|
|
15
15
|
end
|
16
16
|
|
17
17
|
def state_item
|
18
|
-
return if state.blank?
|
18
|
+
return if state.blank? || @options.fetch(:skip_state, false)
|
19
19
|
|
20
|
-
|
20
|
+
if model.withdrawn?
|
21
|
+
{ text: content_tag(:span, humanize_proposal_state(:withdrawn), class: "label alert") }
|
22
|
+
elsif model.emendation?
|
23
|
+
{ text: content_tag(:span, humanize_proposal_state(state), class: "label #{state_class}") }
|
24
|
+
else
|
25
|
+
{ text: content_tag(:span, translated_attribute(model.proposal_state&.title), class: "label", style: model.proposal_state.css_style) }
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def state_class
|
30
|
+
return "alert" if model.withdrawn?
|
31
|
+
|
32
|
+
case state
|
33
|
+
when "accepted"
|
34
|
+
"success"
|
35
|
+
when "rejected"
|
36
|
+
"alert"
|
37
|
+
when "evaluating"
|
38
|
+
"warning"
|
39
|
+
else
|
40
|
+
"muted"
|
41
|
+
end
|
21
42
|
end
|
22
43
|
|
23
44
|
private
|
@@ -43,19 +64,6 @@ module Decidim
|
|
43
64
|
icon: "account-circle-line"
|
44
65
|
}
|
45
66
|
end
|
46
|
-
|
47
|
-
def state_class
|
48
|
-
case state
|
49
|
-
when "accepted"
|
50
|
-
"success"
|
51
|
-
when "rejected", "withdrawn"
|
52
|
-
"alert"
|
53
|
-
when "evaluating"
|
54
|
-
"warning"
|
55
|
-
else
|
56
|
-
"muted"
|
57
|
-
end
|
58
|
-
end
|
59
67
|
end
|
60
68
|
end
|
61
69
|
end
|
@@ -44,7 +44,6 @@ module Decidim
|
|
44
44
|
form.current_user
|
45
45
|
) do
|
46
46
|
attributes = {
|
47
|
-
state: form.state,
|
48
47
|
answer: form.answer,
|
49
48
|
cost: form.cost,
|
50
49
|
cost_report: form.cost_report,
|
@@ -54,7 +53,9 @@ module Decidim
|
|
54
53
|
if form.state == "not_answered"
|
55
54
|
attributes[:answered_at] = nil
|
56
55
|
attributes[:state_published_at] = nil
|
56
|
+
proposal.proposal_state = nil
|
57
57
|
else
|
58
|
+
proposal.assign_state(form.state)
|
58
59
|
attributes[:answered_at] = Time.current
|
59
60
|
attributes[:state_published_at] = Time.current if !initial_has_state_published && form.publish_answer?
|
60
61
|
end
|
@@ -35,24 +35,26 @@ module Decidim
|
|
35
35
|
def assign_proposals
|
36
36
|
transaction do
|
37
37
|
form.proposals.flat_map do |proposal|
|
38
|
-
|
38
|
+
form.valuator_roles.each do |valuator_role|
|
39
|
+
find_assignment(proposal, valuator_role) || assign_proposal(proposal, valuator_role)
|
40
|
+
end
|
39
41
|
end
|
40
42
|
end
|
41
43
|
end
|
42
44
|
|
43
|
-
def find_assignment(proposal)
|
45
|
+
def find_assignment(proposal, valuator_role)
|
44
46
|
Decidim::Proposals::ValuationAssignment.find_by(
|
45
47
|
proposal:,
|
46
|
-
valuator_role:
|
48
|
+
valuator_role:
|
47
49
|
)
|
48
50
|
end
|
49
51
|
|
50
|
-
def assign_proposal(proposal)
|
52
|
+
def assign_proposal(proposal, valuator_role)
|
51
53
|
Decidim.traceability.create!(
|
52
54
|
Decidim::Proposals::ValuationAssignment,
|
53
55
|
form.current_user,
|
54
56
|
proposal:,
|
55
|
-
valuator_role:
|
57
|
+
valuator_role:
|
56
58
|
)
|
57
59
|
end
|
58
60
|
end
|
@@ -39,7 +39,7 @@ module Decidim
|
|
39
39
|
create_proposal
|
40
40
|
create_gallery if process_gallery?
|
41
41
|
create_attachment(weight: first_attachment_weight) if process_attachments?
|
42
|
-
|
42
|
+
link_author_meeting if form.created_in_meeting?
|
43
43
|
end
|
44
44
|
|
45
45
|
send_notification
|
@@ -77,7 +77,7 @@ module Decidim
|
|
77
77
|
}
|
78
78
|
end
|
79
79
|
|
80
|
-
def
|
80
|
+
def link_author_meeting
|
81
81
|
proposal.link_resources(form.author, "proposals_from_meeting")
|
82
82
|
end
|
83
83
|
|
@@ -0,0 +1,15 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Decidim
|
4
|
+
module Proposals
|
5
|
+
module Admin
|
6
|
+
class CreateProposalState < Decidim::Commands::CreateResource
|
7
|
+
fetch_form_attributes :title, :text_color, :bg_color, :announcement_title, :component
|
8
|
+
|
9
|
+
def resource_class
|
10
|
+
Decidim::Proposals::ProposalState
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -47,8 +47,14 @@ module Decidim
|
|
47
47
|
def proposals
|
48
48
|
@proposals = Decidim::Proposals::Proposal
|
49
49
|
.where(component: origin_component)
|
50
|
-
.where(state: @form.states)
|
51
50
|
@proposals = @proposals.where(scope: proposal_scopes) unless proposal_scopes.empty?
|
51
|
+
|
52
|
+
@proposals = if @form.states.include?("not_answered")
|
53
|
+
@proposals.not_answered.or(@proposals.where(id: @proposals.only_status(@form.states).pluck(:id)))
|
54
|
+
else
|
55
|
+
@proposals.only_status(@form.states)
|
56
|
+
end
|
57
|
+
|
52
58
|
@proposals
|
53
59
|
end
|
54
60
|
|
@@ -80,10 +86,12 @@ module Decidim
|
|
80
86
|
def proposal_answer_attributes(original_proposal)
|
81
87
|
return {} unless form.keep_answers
|
82
88
|
|
89
|
+
state = Decidim::Proposals::ProposalState.where(component: target_component, token: original_proposal.state).first
|
90
|
+
|
83
91
|
{
|
84
92
|
answer: original_proposal.answer,
|
85
93
|
answered_at: original_proposal.answered_at,
|
86
|
-
|
94
|
+
proposal_state: state,
|
87
95
|
state_published_at: original_proposal.state_published_at
|
88
96
|
}
|
89
97
|
end
|
@@ -11,7 +11,7 @@ module Decidim
|
|
11
11
|
# initial_state - The proposal state before the current process.
|
12
12
|
def initialize(proposal, initial_state)
|
13
13
|
@proposal = proposal
|
14
|
-
@initial_state = initial_state
|
14
|
+
@initial_state = initial_state
|
15
15
|
end
|
16
16
|
|
17
17
|
# Executes the command. Broadcasts these events:
|
@@ -42,28 +42,11 @@ module Decidim
|
|
42
42
|
end
|
43
43
|
|
44
44
|
def notify_followers
|
45
|
-
if proposal.
|
46
|
-
publish_event(
|
47
|
-
"decidim.events.proposals.proposal_accepted",
|
48
|
-
Decidim::Proposals::AcceptedProposalEvent
|
49
|
-
)
|
50
|
-
elsif proposal.rejected?
|
51
|
-
publish_event(
|
52
|
-
"decidim.events.proposals.proposal_rejected",
|
53
|
-
Decidim::Proposals::RejectedProposalEvent
|
54
|
-
)
|
55
|
-
elsif proposal.evaluating?
|
56
|
-
publish_event(
|
57
|
-
"decidim.events.proposals.proposal_evaluating",
|
58
|
-
Decidim::Proposals::EvaluatingProposalEvent
|
59
|
-
)
|
60
|
-
end
|
61
|
-
end
|
45
|
+
return if proposal.state == "not_answered"
|
62
46
|
|
63
|
-
def publish_event(event, event_class)
|
64
47
|
Decidim::EventsManager.publish(
|
65
|
-
event
|
66
|
-
event_class
|
48
|
+
event: "decidim.events.proposals.proposal_state_changed",
|
49
|
+
event_class: Decidim::Proposals::ProposalStateChangedEvent,
|
67
50
|
resource: proposal,
|
68
51
|
affected_users: proposal.notifiable_identities,
|
69
52
|
followers: proposal.followers - proposal.notifiable_identities
|
@@ -33,16 +33,18 @@ module Decidim
|
|
33
33
|
def unassign_proposals
|
34
34
|
transaction do
|
35
35
|
form.proposals.flat_map do |proposal|
|
36
|
-
|
37
|
-
|
36
|
+
form.valuator_roles.each do |valuator_role|
|
37
|
+
assignment = find_assignment(proposal, valuator_role)
|
38
|
+
unassign(assignment) if assignment
|
39
|
+
end
|
38
40
|
end
|
39
41
|
end
|
40
42
|
end
|
41
43
|
|
42
|
-
def find_assignment(proposal)
|
44
|
+
def find_assignment(proposal, valuator_role)
|
43
45
|
Decidim::Proposals::ValuationAssignment.find_by(
|
44
46
|
proposal:,
|
45
|
-
valuator_role:
|
47
|
+
valuator_role:
|
46
48
|
)
|
47
49
|
end
|
48
50
|
|
@@ -0,0 +1,13 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Decidim
|
4
|
+
module Proposals
|
5
|
+
module Admin
|
6
|
+
class UpdateProposalState < Decidim::Commands::UpdateResource
|
7
|
+
include TranslatableAttributes
|
8
|
+
|
9
|
+
fetch_form_attributes :title, :text_color, :bg_color, :announcement_title, :component
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -4,6 +4,7 @@ module Decidim
|
|
4
4
|
module Proposals
|
5
5
|
# A command with all the business logic when a user creates a new proposal.
|
6
6
|
class CreateProposal < Decidim::Command
|
7
|
+
include ::Decidim::MultipleAttachmentsMethods
|
7
8
|
include HashtagsMethods
|
8
9
|
|
9
10
|
# Public: Initializes the command.
|
@@ -31,8 +32,14 @@ module Decidim
|
|
31
32
|
return broadcast(:invalid)
|
32
33
|
end
|
33
34
|
|
35
|
+
if process_attachments?
|
36
|
+
build_attachments
|
37
|
+
return broadcast(:invalid) if attachments_invalid?
|
38
|
+
end
|
39
|
+
|
34
40
|
with_events(with_transaction: true) do
|
35
41
|
create_proposal
|
42
|
+
create_attachments(first_weight: first_attachment_weight) if process_attachments?
|
36
43
|
end
|
37
44
|
|
38
45
|
broadcast(:ok, proposal)
|
@@ -74,8 +81,14 @@ module Decidim
|
|
74
81
|
},
|
75
82
|
component: form.component
|
76
83
|
)
|
84
|
+
|
85
|
+
proposal.category = form.category if form.category_id.present?
|
86
|
+
proposal.scope = form.scope if form.scope_id.present?
|
87
|
+
proposal.documents = form.documents if form.documents.present?
|
88
|
+
proposal.address = form.address if form.has_address? && !form.geocoded?
|
77
89
|
proposal.add_coauthor(@current_user, user_group:)
|
78
90
|
proposal.save!
|
91
|
+
@attached_to = proposal
|
79
92
|
proposal
|
80
93
|
end
|
81
94
|
end
|
@@ -104,11 +117,17 @@ module Decidim
|
|
104
117
|
end
|
105
118
|
|
106
119
|
def current_user_proposals
|
107
|
-
Proposal.from_author(@current_user).where(component: form.current_component)
|
120
|
+
Proposal.not_withdrawn.from_author(@current_user).where(component: form.current_component)
|
108
121
|
end
|
109
122
|
|
110
123
|
def user_group_proposals
|
111
|
-
Proposal.from_user_group(@user_group).where(component: form.current_component)
|
124
|
+
Proposal.not_withdrawn.from_user_group(@user_group).where(component: form.current_component)
|
125
|
+
end
|
126
|
+
|
127
|
+
def first_attachment_weight
|
128
|
+
return 1 if proposal.photos.count.zero?
|
129
|
+
|
130
|
+
proposal.photos.count
|
112
131
|
end
|
113
132
|
end
|
114
133
|
end
|
@@ -133,11 +133,11 @@ module Decidim
|
|
133
133
|
end
|
134
134
|
|
135
135
|
def current_user_proposals
|
136
|
-
Proposal.from_author(current_user).where(component: form.current_component).published.where.not(id: proposal.id).
|
136
|
+
Proposal.from_author(current_user).where(component: form.current_component).published.where.not(id: proposal.id).not_withdrawn
|
137
137
|
end
|
138
138
|
|
139
139
|
def user_group_proposals
|
140
|
-
Proposal.from_user_group(user_group).where(component: form.current_component).published.where.not(id: proposal.id).
|
140
|
+
Proposal.from_user_group(user_group).where(component: form.current_component).published.where.not(id: proposal.id).not_withdrawn
|
141
141
|
end
|
142
142
|
end
|
143
143
|
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? && !@proposal.
|
23
|
+
return broadcast(:invalid) if @proposal.maximum_votes_reached? && !@proposal.can_accumulate_votes_beyond_threshold
|
24
24
|
|
25
25
|
build_proposal_vote
|
26
26
|
return broadcast(:invalid) unless vote.valid?
|
@@ -16,14 +16,14 @@ module Decidim
|
|
16
16
|
# Executes the command. Broadcasts these events:
|
17
17
|
#
|
18
18
|
# - :ok when everything is valid, together with the proposal.
|
19
|
-
# - :
|
19
|
+
# - :has_votes if the proposal already has votes or does not belong to current user.
|
20
20
|
#
|
21
21
|
# Returns nothing.
|
22
22
|
def call
|
23
|
-
return broadcast(:
|
23
|
+
return broadcast(:has_votes) if @proposal.votes.any?
|
24
24
|
|
25
25
|
transaction do
|
26
|
-
|
26
|
+
@proposal.withdraw!
|
27
27
|
reject_emendations_if_any
|
28
28
|
end
|
29
29
|
|
@@ -32,10 +32,6 @@ module Decidim
|
|
32
32
|
|
33
33
|
private
|
34
34
|
|
35
|
-
def change_proposal_state_to_withdrawn
|
36
|
-
@proposal.update state: "withdrawn"
|
37
|
-
end
|
38
|
-
|
39
35
|
def reject_emendations_if_any
|
40
36
|
return if @proposal.emendations.empty?
|
41
37
|
|
@@ -13,6 +13,8 @@ module Decidim
|
|
13
13
|
|
14
14
|
private
|
15
15
|
|
16
|
+
delegate :filters, :dynamically_translated_filters, :filters_with_values, to: :filter_config
|
17
|
+
|
16
18
|
# Comment about participatory_texts_enabled.
|
17
19
|
def base_query
|
18
20
|
return collection.order(:position) if current_component.settings.participatory_texts_enabled?
|
@@ -30,32 +32,18 @@ module Decidim
|
|
30
32
|
:id_string_or_title_cont
|
31
33
|
end
|
32
34
|
|
33
|
-
def
|
34
|
-
|
35
|
-
:is_emendation_true,
|
36
|
-
:with_any_state,
|
37
|
-
:state_eq,
|
38
|
-
:scope_id_eq,
|
39
|
-
:category_id_eq,
|
40
|
-
:valuator_role_ids_has
|
41
|
-
]
|
35
|
+
def filter_config
|
36
|
+
@filter_config ||= Decidim::AdminFilter.new(:proposals).build_for(self)
|
42
37
|
end
|
43
38
|
|
44
|
-
def
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
with_any_state: %w(state_published state_not_published),
|
49
|
-
scope_id_eq: scope_ids_hash(scopes.top_level),
|
50
|
-
category_id_eq: category_ids_hash(categories.first_class),
|
51
|
-
valuator_role_ids_has: valuator_role_ids
|
52
|
-
}
|
39
|
+
def translated_state_eq(state)
|
40
|
+
return t("decidim.admin.filters.proposals.state_eq.values.withdrawn") if state == "withdrawn"
|
41
|
+
|
42
|
+
translated_attribute(ProposalState.where(component: current_component, token: state).first&.title)
|
53
43
|
end
|
54
44
|
|
55
|
-
|
56
|
-
|
57
|
-
def dynamically_translated_filters
|
58
|
-
[:scope_id_eq, :category_id_eq, :valuator_role_ids_has]
|
45
|
+
def state_eq_values
|
46
|
+
ProposalState.where(component: current_component).pluck(:token) + ["withdrawn"]
|
59
47
|
end
|
60
48
|
|
61
49
|
def valuator_role_ids
|