decidim-proposals 0.28.5 → 0.29.0.rc1
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 +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/show.erb +11 -11
- 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 +18 -19
- 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 +4 -6
- 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 +38 -39
- data/app/events/decidim/proposals/proposal_state_changed_event.rb +37 -0
- data/app/forms/decidim/proposals/admin/proposal_answer_form.rb +8 -4
- data/app/forms/decidim/proposals/admin/proposal_form.rb +1 -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/map_helper.rb +1 -1
- 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 +83 -29
- 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/permissions/decidim/proposals/permissions.rb +3 -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 -3
- data/app/services/decidim/proposals/proposal_builder.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 +2 -2
- 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 +6 -12
- 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 +11 -7
- 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/index.html.erb +1 -1
- data/app/views/decidim/proposals/proposals/index.js.erb +0 -12
- 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/preview.html.erb +1 -1
- data/app/views/decidim/proposals/proposals/show.html.erb +3 -3
- data/config/locales/ar.yml +9 -115
- data/config/locales/bg.yml +117 -111
- data/config/locales/ca.yml +86 -83
- data/config/locales/cs.yml +65 -127
- data/config/locales/de.yml +128 -125
- data/config/locales/el.yml +8 -121
- data/config/locales/en.yml +110 -107
- data/config/locales/es-MX.yml +85 -82
- data/config/locales/es-PY.yml +88 -85
- data/config/locales/es.yml +83 -80
- data/config/locales/eu.yml +166 -170
- data/config/locales/fi-plain.yml +90 -87
- data/config/locales/fi.yml +139 -136
- data/config/locales/fr-CA.yml +92 -87
- data/config/locales/fr.yml +83 -78
- data/config/locales/ga-IE.yml +1 -27
- data/config/locales/gl.yml +11 -107
- data/config/locales/he-IL.yml +0 -17
- data/config/locales/hu.yml +18 -90
- data/config/locales/id-ID.yml +6 -106
- data/config/locales/is-IS.yml +8 -33
- data/config/locales/it.yml +14 -103
- data/config/locales/ja.yml +117 -112
- data/config/locales/lb.yml +1 -0
- data/config/locales/lt.yml +6 -123
- data/config/locales/lv.yml +4 -101
- data/config/locales/nl.yml +11 -102
- data/config/locales/no.yml +7 -108
- data/config/locales/pl.yml +110 -115
- data/config/locales/pt-BR.yml +10 -84
- data/config/locales/pt.yml +9 -109
- data/config/locales/ro-RO.yml +15 -117
- data/config/locales/ru.yml +9 -53
- data/config/locales/sk.yml +5 -109
- data/config/locales/sl.yml +4 -0
- data/config/locales/sv.yml +142 -337
- data/config/locales/tr-TR.yml +64 -108
- data/config/locales/uk.yml +11 -55
- data/config/locales/zh-CN.yml +5 -100
- data/config/locales/zh-TW.yml +8 -119
- 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 +3 -3
- data/lib/decidim/api/proposal_type.rb +4 -13
- data/lib/decidim/api/proposals_type.rb +3 -1
- 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 +8 -9
- data/lib/decidim/proposals/seeds.rb +60 -51
- data/lib/decidim/proposals/test/factories.rb +69 -14
- data/lib/decidim/proposals/version.rb +1 -1
- data/lib/decidim/proposals.rb +84 -12
- data/lib/tasks/proposals/upgrade/{decdim_proposals_upgrade_tasks.rake → decidim_proposals_upgrade_tasks.rake} +0 -13
- metadata +51 -40
- 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/services/decidim/proposals/collaborative_draft_diff_renderer.rb +0 -22
- 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/config/locales/bn-BD.yml +0 -1
- data/config/locales/bs-BA.yml +0 -100
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
|
@@ -11,21 +11,21 @@
|
|
11
11
|
<% end %>
|
12
12
|
</div>
|
13
13
|
|
14
|
-
<div class="flex items-center justify-between space-x-6">
|
15
|
-
<span class="content-block__span flex-shrink-0">
|
16
|
-
<%= t("decidim.participatory_spaces.highlighted_proposals.last") %>
|
17
|
-
</span>
|
18
|
-
<% if single_component? %>
|
19
|
-
<%= link_to decidim_proposals.new_proposal_path, class: "button button__xs md:button__lg button__secondary" do %>
|
20
|
-
<span class="text-center"><%= t("decidim.proposals.actions.new") %></span>
|
21
|
-
<%= icon "add-line" %>
|
22
|
-
<% end %>
|
23
|
-
<% end %>
|
24
|
-
</div>
|
25
14
|
<div class="flex items-start justify-between">
|
26
15
|
<div class="grow space-y-6">
|
16
|
+
<span class="content-block__span">
|
17
|
+
<%= t("decidim.participatory_spaces.highlighted_proposals.last") %>
|
18
|
+
</span>
|
19
|
+
|
27
20
|
<% proposals_to_render.each do |p| %>
|
28
21
|
<%= card_for p, link_whole_card: true, title_tag: :h3, **options.slice(:show_space) %>
|
29
22
|
<% end %>
|
30
23
|
</div>
|
24
|
+
|
25
|
+
<% if single_component? %>
|
26
|
+
<%= link_to decidim_proposals.new_proposal_path, class: "button button__sm md:button__lg button__secondary" do %>
|
27
|
+
<span><%= t("decidim.proposals.actions.new") %></span>
|
28
|
+
<%= icon "add-line" %>
|
29
|
+
<% end %>
|
30
|
+
<% end %>
|
31
31
|
</div>
|
@@ -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
|
@@ -7,8 +7,6 @@ module Decidim
|
|
7
7
|
# This cell renders the List (:l) proposal card
|
8
8
|
# for an instance of a Proposal
|
9
9
|
class ProposalLCell < Decidim::CardLCell
|
10
|
-
delegate :component_settings, to: :controller
|
11
|
-
|
12
10
|
alias proposal model
|
13
11
|
|
14
12
|
def title
|
@@ -22,24 +20,25 @@ module Decidim
|
|
22
20
|
end
|
23
21
|
|
24
22
|
def cache_hash
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
hash <<
|
36
|
-
hash << model
|
37
|
-
hash << Digest::MD5.hexdigest(model.authors.map(&:cache_key_with_version).to_s)
|
38
|
-
hash << (model.must_render_translation?(model.organization) ? 1 : 0) if model.respond_to?(:must_render_translation?)
|
39
|
-
hash << model.component.participatory_space.active_step.id if model.component.participatory_space.try(:active_step)
|
40
|
-
|
41
|
-
hash.join(Decidim.cache_key_separator)
|
23
|
+
hash = []
|
24
|
+
hash << I18n.locale.to_s
|
25
|
+
hash << model.cache_key_with_version
|
26
|
+
hash << model.proposal_votes_count
|
27
|
+
hash << model.endorsements_count
|
28
|
+
hash << model.comments_count
|
29
|
+
hash << Digest::MD5.hexdigest(model.component.cache_key_with_version)
|
30
|
+
hash << Digest::MD5.hexdigest(resource_image_path) if resource_image_path
|
31
|
+
hash << render_space? ? 1 : 0
|
32
|
+
if current_user
|
33
|
+
hash << current_user.cache_key_with_version
|
34
|
+
hash << current_user.follows?(model) ? 1 : 0
|
42
35
|
end
|
36
|
+
hash << model.follows_count
|
37
|
+
hash << Digest::MD5.hexdigest(model.authors.map(&:cache_key_with_version).to_s)
|
38
|
+
hash << (model.must_render_translation?(model.organization) ? 1 : 0) if model.respond_to?(:must_render_translation?)
|
39
|
+
hash << model.component.participatory_space.active_step.id if model.component.participatory_space.try(:active_step)
|
40
|
+
|
41
|
+
hash.join(Decidim.cache_key_separator)
|
43
42
|
end
|
44
43
|
end
|
45
44
|
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
|
@@ -58,9 +58,6 @@ module Decidim
|
|
58
58
|
action_user: form.current_user
|
59
59
|
)
|
60
60
|
@attached_to = @proposal
|
61
|
-
Decidim.traceability.perform_action!(:publish, @proposal, form.current_user, visibility: "all") do
|
62
|
-
@proposal.update!(published_at: Time.current)
|
63
|
-
end
|
64
61
|
end
|
65
62
|
|
66
63
|
def attributes
|
@@ -75,11 +72,12 @@ module Decidim
|
|
75
72
|
address: form.address,
|
76
73
|
latitude: form.latitude,
|
77
74
|
longitude: form.longitude,
|
78
|
-
created_in_meeting: form.created_in_meeting
|
75
|
+
created_in_meeting: form.created_in_meeting,
|
76
|
+
published_at: Time.current
|
79
77
|
}
|
80
78
|
end
|
81
79
|
|
82
|
-
def
|
80
|
+
def link_author_meeting
|
83
81
|
proposal.link_resources(form.author, "proposals_from_meeting")
|
84
82
|
end
|
85
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
|
|