decidim-proposals 0.12.2 → 0.13.0.pre1
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/app/cells/decidim/proposals/coauthorships_cell.rb +40 -0
- data/app/cells/decidim/proposals/proposal_m_cell.rb +5 -0
- data/app/commands/decidim/proposals/admin/import_proposals.rb +3 -0
- data/app/commands/decidim/proposals/admin/update_proposal_category.rb +2 -2
- data/app/commands/decidim/proposals/create_proposal.rb +3 -4
- data/app/commands/decidim/proposals/destroy_proposal.rb +1 -1
- data/app/commands/decidim/proposals/publish_proposal.rb +12 -4
- data/app/commands/decidim/proposals/update_proposal.rb +4 -4
- data/app/controllers/decidim/proposals/proposals_controller.rb +1 -2
- data/app/events/decidim/proposals/publish_proposal_event.rb +1 -1
- data/app/forms/decidim/proposals/proposal_form.rb +1 -1
- data/app/helpers/decidim/proposals/application_helper.rb +4 -0
- data/app/helpers/decidim/proposals/proposal_endorsements_helper.rb +16 -10
- data/app/jobs/decidim/proposals/notify_proposals_mentioned_job.rb +2 -2
- data/app/models/decidim/proposals/proposal.rb +19 -2
- data/app/permissions/decidim/proposals/permissions.rb +1 -1
- data/app/presenters/decidim/proposals/proposal_presenter.rb +6 -3
- data/app/services/decidim/proposals/proposal_search.rb +2 -2
- data/app/views/decidim/proposals/admin/proposals/_bulk-actions.html.erb +1 -1
- data/app/views/decidim/proposals/admin/proposals/index.html.erb +1 -1
- data/app/views/decidim/proposals/proposal_endorsements/update_buttons_and_counters.js.erb +1 -1
- data/app/views/decidim/proposals/proposals/_endorsements_card_row.html.erb +1 -1
- data/app/views/decidim/proposals/proposals/_proposal_similar.html.erb +1 -1
- data/app/views/decidim/proposals/proposals/show.html.erb +1 -1
- data/config/locales/ca.yml +6 -6
- data/config/locales/en.yml +6 -6
- data/config/locales/es-PY.yml +6 -6
- data/config/locales/es.yml +6 -6
- data/config/locales/eu.yml +6 -6
- data/config/locales/fi.yml +6 -6
- data/config/locales/fr.yml +76 -76
- data/config/locales/gl.yml +6 -6
- data/config/locales/it.yml +6 -6
- data/config/locales/nl.yml +5 -5
- data/config/locales/pl.yml +6 -6
- data/config/locales/pt-BR.yml +6 -6
- data/config/locales/pt.yml +6 -6
- data/config/locales/ru.yml +1 -2
- data/config/locales/sv.yml +6 -6
- data/config/locales/uk.yml +3 -3
- data/db/migrate/20180529101323_add_counter_cache_coauthorships_to_proposals.rb +8 -0
- data/db/migrate/20180529110230_move_authorships_to_coauthorships.rb +28 -0
- data/db/migrate/20180529110830_remove_authorships_from_proposals.rb +8 -0
- data/lib/decidim/proposals/component.rb +3 -2
- data/lib/decidim/proposals/proposal_serializer.rb +1 -1
- data/lib/decidim/proposals/test/factories.rb +17 -3
- data/lib/decidim/proposals/version.rb +1 -1
- metadata +40 -37
- data/app/views/decidim/proposals/proposals/_endorsements_count.html.erb +0 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2609298045f639a58aa4261912edf5bed42edd6f5f6565af65d277c829c3986a
|
4
|
+
data.tar.gz: add5696156559e7a28bb893977788628459f788c132f6c8b4ea2856c726978d5
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 80c6b74ae952eefbb30a6abe00d13a37d50b8143fd00d0ed9b9b4f9d8dfcadb8a360852bc2a616e41bb27e79d172e18bf8333fca462e2345e0cd93eccd8ca977
|
7
|
+
data.tar.gz: de47a3b699f8c2e3e549e60f330e0cacf79e6ebf8bd47cc2d37013b4c9d436b0ce3751250948ac64ae29be17334e36485291767884e955d97909f8b5b66a5ddf
|
@@ -0,0 +1,40 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Decidim
|
4
|
+
module Proposals
|
5
|
+
# This cell renders a collapsible list of the proposal coauthors.
|
6
|
+
#
|
7
|
+
# Available sizes:
|
8
|
+
# - `:small` => collapses after 3 elements.
|
9
|
+
# - `:default` => collapses after 7 elements. If not specified, this one is
|
10
|
+
# used.
|
11
|
+
#
|
12
|
+
# Example:
|
13
|
+
#
|
14
|
+
# cell("decidim/proposals/coauthorships", @proposal)
|
15
|
+
class CoauthorshipsCell < Decidim::ViewModel
|
16
|
+
include Decidim::ApplicationHelper
|
17
|
+
|
18
|
+
def show
|
19
|
+
if model.official?
|
20
|
+
cell "decidim/author", present(model).author, from: model
|
21
|
+
else
|
22
|
+
cell(
|
23
|
+
"decidim/collapsible_authors",
|
24
|
+
authors_for(model),
|
25
|
+
cell_name: "decidim/author",
|
26
|
+
cell_options: { extra_classes: ["author-data--small"] },
|
27
|
+
size: :small,
|
28
|
+
from: model
|
29
|
+
)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
private
|
34
|
+
|
35
|
+
def authors_for(coauthorable)
|
36
|
+
coauthorable.identities.map { |identity| present(identity) }
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -36,10 +36,15 @@ module Decidim
|
|
36
36
|
end
|
37
37
|
|
38
38
|
def statuses
|
39
|
+
return [:endorsements_count, :comments_count] if model.draft?
|
39
40
|
return [:creation_date, :endorsements_count, :comments_count] unless has_link_to_resource?
|
40
41
|
[:creation_date, :follow, :endorsements_count, :comments_count]
|
41
42
|
end
|
42
43
|
|
44
|
+
def creation_date_status
|
45
|
+
l(model.published_at.to_date, format: :decidim_short)
|
46
|
+
end
|
47
|
+
|
43
48
|
def endorsements_count_status
|
44
49
|
return endorsements_count unless has_link_to_resource?
|
45
50
|
|
@@ -52,6 +52,9 @@ module Decidim
|
|
52
52
|
proposal.save!
|
53
53
|
|
54
54
|
proposal.link_resources([original_proposal], "copied_from_component")
|
55
|
+
original_proposal.coauthorships.each do |coauthorship|
|
56
|
+
Decidim::Coauthorship.create(author: coauthorship.author, user_group: coauthorship.user_group, coauthorable: proposal)
|
57
|
+
end
|
55
58
|
end.compact
|
56
59
|
end
|
57
60
|
|
@@ -37,7 +37,7 @@ module Decidim
|
|
37
37
|
else
|
38
38
|
transaction do
|
39
39
|
update_proposal_category proposal
|
40
|
-
notify_author proposal if proposal.
|
40
|
+
notify_author proposal if proposal.coauthorships.any?
|
41
41
|
end
|
42
42
|
@response[:successful] << proposal.title
|
43
43
|
end
|
@@ -59,7 +59,7 @@ module Decidim
|
|
59
59
|
event: "decidim.events.proposals.proposal_update_category",
|
60
60
|
event_class: Decidim::Proposals::Admin::UpdateProposalCategoryEvent,
|
61
61
|
resource: proposal,
|
62
|
-
recipient_ids:
|
62
|
+
recipient_ids: proposal.coauthorships.pluck(:decidim_author_id)
|
63
63
|
)
|
64
64
|
end
|
65
65
|
end
|
@@ -50,13 +50,12 @@ module Decidim
|
|
50
50
|
body: form.body,
|
51
51
|
category: form.category,
|
52
52
|
scope: form.scope,
|
53
|
-
author: @current_user,
|
54
|
-
decidim_user_group_id: form.user_group_id,
|
55
53
|
component: form.component,
|
56
54
|
address: form.address,
|
57
55
|
latitude: form.latitude,
|
58
56
|
longitude: form.longitude
|
59
57
|
)
|
58
|
+
proposal.add_coauthor(@current_user, decidim_user_group_id: form.user_group_id)
|
60
59
|
end
|
61
60
|
|
62
61
|
def build_attachment
|
@@ -112,11 +111,11 @@ module Decidim
|
|
112
111
|
end
|
113
112
|
|
114
113
|
def current_user_proposals
|
115
|
-
Proposal.
|
114
|
+
Proposal.from_author(@current_user).where(component: form.current_component).except_withdrawn
|
116
115
|
end
|
117
116
|
|
118
117
|
def user_group_proposals
|
119
|
-
Proposal.
|
118
|
+
Proposal.from_user_group(@user_group).where(component: form.current_component).except_withdrawn
|
120
119
|
end
|
121
120
|
end
|
122
121
|
end
|
@@ -22,7 +22,7 @@ module Decidim
|
|
22
22
|
# Returns nothing.
|
23
23
|
def call
|
24
24
|
return broadcast(:invalid) unless @proposal.draft?
|
25
|
-
return broadcast(:invalid)
|
25
|
+
return broadcast(:invalid) unless @proposal.authored_by?(@current_user)
|
26
26
|
|
27
27
|
@proposal.destroy!
|
28
28
|
|
@@ -20,7 +20,7 @@ module Decidim
|
|
20
20
|
#
|
21
21
|
# Returns nothing.
|
22
22
|
def call
|
23
|
-
return broadcast(:invalid)
|
23
|
+
return broadcast(:invalid) unless @proposal.authored_by?(@current_user)
|
24
24
|
|
25
25
|
transaction do
|
26
26
|
@proposal.update published_at: Time.current
|
@@ -34,13 +34,13 @@ module Decidim
|
|
34
34
|
private
|
35
35
|
|
36
36
|
def send_notification
|
37
|
-
return if @proposal.
|
37
|
+
return if @proposal.coauthorships.empty?
|
38
38
|
|
39
39
|
Decidim::EventsManager.publish(
|
40
40
|
event: "decidim.events.proposals.proposal_published",
|
41
41
|
event_class: Decidim::Proposals::PublishProposalEvent,
|
42
42
|
resource: @proposal,
|
43
|
-
recipient_ids: @proposal
|
43
|
+
recipient_ids: coauthors_followers(@proposal)
|
44
44
|
)
|
45
45
|
end
|
46
46
|
|
@@ -49,12 +49,20 @@ module Decidim
|
|
49
49
|
event: "decidim.events.proposals.proposal_published",
|
50
50
|
event_class: Decidim::Proposals::PublishProposalEvent,
|
51
51
|
resource: @proposal,
|
52
|
-
recipient_ids: @proposal.participatory_space.followers.pluck(:id) - @proposal
|
52
|
+
recipient_ids: @proposal.participatory_space.followers.pluck(:id) - coauthors_followers(@proposal),
|
53
53
|
extra: {
|
54
54
|
participatory_space: true
|
55
55
|
}
|
56
56
|
)
|
57
57
|
end
|
58
|
+
|
59
|
+
def coauthors_followers(_proposal)
|
60
|
+
followers_ids = []
|
61
|
+
@proposal.authors.each do |author|
|
62
|
+
followers_ids += author.followers.pluck(:id)
|
63
|
+
end
|
64
|
+
followers_ids
|
65
|
+
end
|
58
66
|
end
|
59
67
|
end
|
60
68
|
end
|
@@ -43,12 +43,12 @@ module Decidim
|
|
43
43
|
body: form.body,
|
44
44
|
category: form.category,
|
45
45
|
scope: form.scope,
|
46
|
-
author: current_user,
|
47
|
-
decidim_user_group_id: user_group.try(:id),
|
48
46
|
address: form.address,
|
49
47
|
latitude: form.latitude,
|
50
48
|
longitude: form.longitude
|
51
49
|
)
|
50
|
+
@proposal.coauthorships.clear
|
51
|
+
@proposal.add_coauthor(current_user, decidim_user_group_id: user_group&.id)
|
52
52
|
end
|
53
53
|
|
54
54
|
def proposal_limit_reached?
|
@@ -72,11 +72,11 @@ module Decidim
|
|
72
72
|
end
|
73
73
|
|
74
74
|
def current_user_proposals
|
75
|
-
Proposal.where(
|
75
|
+
Proposal.from_author(current_user).where(component: form.current_component).published.where.not(id: proposal.id)
|
76
76
|
end
|
77
77
|
|
78
78
|
def user_group_proposals
|
79
|
-
Proposal.where(
|
79
|
+
Proposal.from_user_group(user_group).where(component: form.current_component).published.where.not(id: proposal.id)
|
80
80
|
end
|
81
81
|
end
|
82
82
|
end
|
@@ -20,7 +20,6 @@ module Decidim
|
|
20
20
|
.results
|
21
21
|
.published
|
22
22
|
.not_hidden
|
23
|
-
.includes(:author)
|
24
23
|
.includes(:category)
|
25
24
|
.includes(:scope)
|
26
25
|
|
@@ -222,7 +221,7 @@ module Decidim
|
|
222
221
|
end
|
223
222
|
|
224
223
|
def proposal_draft
|
225
|
-
Proposal.not_hidden.where(component: current_component
|
224
|
+
Proposal.from_all_user_identities(current_user).not_hidden.where(component: current_component).find_by(published_at: nil)
|
226
225
|
end
|
227
226
|
|
228
227
|
def ensure_is_draft
|
@@ -31,7 +31,7 @@ module Decidim
|
|
31
31
|
delegate :categories, to: :current_component
|
32
32
|
|
33
33
|
def map_model(model)
|
34
|
-
self.user_group_id = model.
|
34
|
+
self.user_group_id = model.user_groups.first&.id
|
35
35
|
return unless model.categorization
|
36
36
|
|
37
37
|
self.category_id = model.categorization.decidim_category_id
|
@@ -4,16 +4,6 @@ module Decidim
|
|
4
4
|
module Proposals
|
5
5
|
# Simple helper to handle markup variations for proposal endorsements partials
|
6
6
|
module ProposalEndorsementsHelper
|
7
|
-
# Returns the css classes used for proposal endorsements count in both proposals list and show pages
|
8
|
-
#
|
9
|
-
# from_proposals_list - A boolean to indicate if the template is rendered from the proposals list page
|
10
|
-
#
|
11
|
-
# Returns a hash with the css classes for the count number and label
|
12
|
-
def endorsements_count_classes(from_proposals_list)
|
13
|
-
return { number: "card__support__number", label: "" } if from_proposals_list
|
14
|
-
{ number: "extra__suport-number", label: "extra__suport-text" }
|
15
|
-
end
|
16
|
-
|
17
7
|
# Returns the css classes used for proposal endorsement button in both proposals list and show pages
|
18
8
|
#
|
19
9
|
# from_proposals_list - A boolean to indicate if the template is rendered from the proposals list page
|
@@ -116,6 +106,22 @@ module Decidim
|
|
116
106
|
render partial: "decidim/proposals/proposal_endorsements/identity", locals:
|
117
107
|
{ identity: presenter, selected: selected, current_endorsement_url: current_endorsement_url, http_method: http_method }
|
118
108
|
end
|
109
|
+
|
110
|
+
# Renders the counter of endorsements that appears in card at show Propoal.
|
111
|
+
def render_endorsements_count_card_part(proposal, fully_endorsed)
|
112
|
+
content = icon("bullhorn", class: "icon--small", aria_label: "Endorsements", role: "img")
|
113
|
+
content += proposal.proposal_endorsements_count.to_s
|
114
|
+
tag_params = { id: "proposal-#{proposal.id}-endorsements-count", class: "button small compact light button--sc button--shadow #{fully_endorsed ? "success" : "secondary"}" }
|
115
|
+
if proposal.proposal_endorsements_count.positive?
|
116
|
+
link_to "#list-of-endorsements", tag_params do
|
117
|
+
content
|
118
|
+
end
|
119
|
+
else
|
120
|
+
content_tag("div", tag_params) do
|
121
|
+
content
|
122
|
+
end
|
123
|
+
end
|
124
|
+
end
|
119
125
|
end
|
120
126
|
end
|
121
127
|
end
|
@@ -8,9 +8,9 @@ module Decidim
|
|
8
8
|
linked_proposals = proposal_metadata.linked_proposals
|
9
9
|
linked_proposals.each do |proposal_id|
|
10
10
|
proposal = Proposal.find(proposal_id)
|
11
|
-
next if proposal.
|
11
|
+
next if proposal.official?
|
12
12
|
|
13
|
-
recipient_ids =
|
13
|
+
recipient_ids = proposal.authors.pluck(:decidim_author_id)
|
14
14
|
Decidim::EventsManager.publish(
|
15
15
|
event: "decidim.events.proposals.proposal_mentioned",
|
16
16
|
event_class: Decidim::Proposals::ProposalMentionedEvent,
|
@@ -5,7 +5,7 @@ module Decidim
|
|
5
5
|
# The data store for a Proposal in the Decidim::Proposals component.
|
6
6
|
class Proposal < Proposals::ApplicationRecord
|
7
7
|
include Decidim::Resourceable
|
8
|
-
include Decidim::
|
8
|
+
include Decidim::Coauthorable
|
9
9
|
include Decidim::HasComponent
|
10
10
|
include Decidim::ScopableComponent
|
11
11
|
include Decidim::HasReference
|
@@ -18,6 +18,7 @@ module Decidim
|
|
18
18
|
include Decidim::Traceable
|
19
19
|
include Decidim::Loggable
|
20
20
|
include Decidim::Fingerprintable
|
21
|
+
include Decidim::DataPortability
|
21
22
|
|
22
23
|
fingerprint fields: [:title, :body]
|
23
24
|
|
@@ -60,6 +61,14 @@ module Decidim
|
|
60
61
|
Decidim::Proposals::AdminLog::ProposalPresenter
|
61
62
|
end
|
62
63
|
|
64
|
+
# Returns a collection scoped by user.
|
65
|
+
# Overrides this method in DataPortability to support Coauthorable.
|
66
|
+
def self.user_collection(user)
|
67
|
+
joins(:coauthorships)
|
68
|
+
.where("decidim_coauthorships.coauthorable_type = ?", name)
|
69
|
+
.where("decidim_coauthorships.decidim_author_id = ?", user.id)
|
70
|
+
end
|
71
|
+
|
63
72
|
# Public: Check if the user has voted the proposal.
|
64
73
|
#
|
65
74
|
# Returns Boolean.
|
@@ -124,7 +133,7 @@ module Decidim
|
|
124
133
|
|
125
134
|
# Public: Whether the proposal is official or not.
|
126
135
|
def official?
|
127
|
-
|
136
|
+
authors.empty?
|
128
137
|
end
|
129
138
|
|
130
139
|
# Public: The maximum amount of votes allowed for this proposal.
|
@@ -186,6 +195,14 @@ module Decidim
|
|
186
195
|
Arel.sql(query)
|
187
196
|
end
|
188
197
|
|
198
|
+
def self.export_serializer
|
199
|
+
Decidim::Proposals::ProposalSerializer
|
200
|
+
end
|
201
|
+
|
202
|
+
def self.data_portability_images(user)
|
203
|
+
user_collection(user).map { |p| p.attachments.collect(&:file_url) }
|
204
|
+
end
|
205
|
+
|
189
206
|
private
|
190
207
|
|
191
208
|
# Checks whether the proposal is inside the time window to be editable or not once published.
|
@@ -12,10 +12,13 @@ module Decidim
|
|
12
12
|
def author
|
13
13
|
@author ||= if official?
|
14
14
|
Decidim::Proposals::OfficialAuthorPresenter.new
|
15
|
-
elsif user_group
|
16
|
-
Decidim::UserGroupPresenter.new(user_group)
|
17
15
|
else
|
18
|
-
|
16
|
+
coauthorship = coauthorships.first
|
17
|
+
if coauthorship.user_group
|
18
|
+
Decidim::UserGroupPresenter.new(coauthorship.user_group)
|
19
|
+
else
|
20
|
+
Decidim::UserPresenter.new(coauthorship.author)
|
21
|
+
end
|
19
22
|
end
|
20
23
|
end
|
21
24
|
|
@@ -24,9 +24,9 @@ module Decidim
|
|
24
24
|
# The 'official' proposals doesn't have an author id
|
25
25
|
def search_origin
|
26
26
|
if origin == "official"
|
27
|
-
query.where(
|
27
|
+
query.where(coauthorships_count: 0)
|
28
28
|
elsif origin == "citizens"
|
29
|
-
query.where.not(
|
29
|
+
query.where.not(coauthorships_count: 0)
|
30
30
|
else # Assume 'all'
|
31
31
|
query
|
32
32
|
end
|
@@ -5,7 +5,7 @@
|
|
5
5
|
<%= link_to t("actions.import", scope: "decidim.proposals", name: t("models.proposal.name", scope: "decidim.proposals.admin")), new_proposals_import_path, class: "button tiny button--simple" if allowed_to? :import, :proposals %>
|
6
6
|
|
7
7
|
<% if allowed_to? :create, :proposal %>
|
8
|
-
<%= link_to t("actions.new", scope: "decidim.proposals"
|
8
|
+
<%= link_to t("actions.new", scope: "decidim.proposals"), new_proposal_path, class: "button tiny button--simple" %>
|
9
9
|
<% end %>
|
10
10
|
|
11
11
|
<%= export_dropdown %>
|
@@ -55,7 +55,7 @@
|
|
55
55
|
<% end %>
|
56
56
|
|
57
57
|
<th>
|
58
|
-
<%= sort_link(query, :
|
58
|
+
<%= sort_link(query, :published_at, t("models.proposal.fields.published_at", scope: "decidim.proposals") ) %>
|
59
59
|
</th>
|
60
60
|
|
61
61
|
<th class="actions"><%= t("actions.title", scope: "decidim.proposals") %></th>
|
@@ -10,7 +10,7 @@ function update_main_page_button() {
|
|
10
10
|
function update_identities_rows() {
|
11
11
|
<% fully_endorsed= fully_endorsed?(proposal, current_user) %>
|
12
12
|
var $proposalEndorsementsRowCount = $('#proposal-<%= proposal.id %>-endorsements-count');
|
13
|
-
morphdom($proposalEndorsementsRowCount[0], '<%= j(
|
13
|
+
morphdom($proposalEndorsementsRowCount[0], '<%= j(render_endorsements_count_card_part(proposal, fully_endorsed)).strip.html_safe %>');
|
14
14
|
var $proposalEndorsementsRowButton = $($('#select-identity-button')[0]);
|
15
15
|
<% if fully_endorsed %>
|
16
16
|
$proposalEndorsementsRowButton.addClass('success')
|
@@ -3,7 +3,7 @@
|
|
3
3
|
<% if endorsements_enabled? %>
|
4
4
|
<div class="column small-9 collapse">
|
5
5
|
<div class="button-group button-group--collapse button--nomargin small">
|
6
|
-
<%=
|
6
|
+
<%= render_endorsements_count_card_part(@proposal, fully_endorsed) %>
|
7
7
|
<% if current_settings.endorsements_blocked? || !current_component.participatory_space.can_participate?(current_user) %>
|
8
8
|
<%= content_tag :span, t(".endorse"), class: "card__button button #{endorsement_button_classes(false)} disabled", disabled: true, title: t(".endorse") %>
|
9
9
|
<% elsif current_user %>
|