Skip to content

Commit 0af5a9a

Browse files
tramuntanaljmnzdztxusmicrostudi
authored
Generalize endorsements and apply to blog posts (decidim#5542)
* Generalize endorsements permissions and extract from proposals. * [WIP] Extracting Endorsable concern * [WIP] EndorseResource and UnendorseRerouce commands. * [WIP] EndorsementsController tests. * Add timestamps to decidim_endorsements db migration. * [I18N] Update yamls. * [WIP] Extract endorsements from proposals module. But keep funcionality for proposals. * [DOC] Update changelog upgrade notes. * Apply edlint.js style. * normalize i18n files. * [TEST|I18N] Pending development translations. * [TEST] Update factory modifications to not break other tests. * [TEST] Extract endorse_proposal_spec logic into system_endorse_resource_examples. * [TEST] Rename shared system example. * [REFACTOR] Separate logic and view in endorsement_buttons_cell#render_endorsements_button_card_part. * Get rid of Decidim::Proposals::ProposalEndorsement. * Remove uses of proposal_endorsement. * Remove legady proposal endorsements related exclude from i8n normalization. * Revert "Remove legady proposal endorsements related exclude from i8n normalization." * Update tests. * [TEST] Update endorsement permissions tests. * Do not remove dummy_resources.coauthorships_count column, as factories depend on that. * Extract endorser identities partial into a generic identities cell. (decidim#5564) * Extract endorser identities partial into a generic identities cell. Check if some already exists. * Remove Coauthorable to DummyResource * Complete documentation and small refactors to extract helpers to invoke the cells. * Update decidim-core/app/commands/decidim/endorse_resource.rb Co-Authored-By: Txus <[email protected]> * Update decidim-core/app/commands/decidim/endorse_resource.rb Co-Authored-By: Txus <[email protected]> * Update CHANGELOG.md Co-Authored-By: Txus <[email protected]> * Rubocopify. * Rubocopify again. * Provide migration to automatically move ProposalEndorsements into new decidim-core Endorsement db structures. * Update decidim-proposals/db/migrate/20200120215928_move_proposal_endorsements_to_core_endorsements.rb Co-Authored-By: Ivan Vergés <[email protected]> * Fix mispellings in MoveProposalEndorsementsToCoreEndorsements migration * Remove unneeded join clause in Proposal.newsletter_participant_ids(component) * Allow legacy data on rollback move ProposalEndorsements to Endorsements Allow to have rows in decidim_proposals_proposal_endorsements table when rolling back the MoveProposalEndorsementsToCoreEndorsements. Use #find_or_create_by just in case a migrated ProposalEndorsement is moved back to its original table. * [Feature] Make Blog Posts endorsable (decidim#5668) * Fix errors * CHANGELOG entry added * Review when creation_date and comments should be rendered * Refactor author cell * Model tests added * Remove deprecated proposal_endorsement factory. Co-authored-by: Oliver Valls <[email protected]> * Make blog posts followable (decidim#5690) * Make blog posts followable * Notify followers when creating new comment * Add CHANGELOG entry * Generalize follow button partial * Edit CHANGELOG entry * Fix proposal tests * Update tests after merging latest changes from develop * Update proposal_input_sort_spec when sorting by endorsement_count * Update changelog Co-authored-by: jarvisct <[email protected]> Co-authored-by: Txus <[email protected]> Co-authored-by: Ivan Vergés <[email protected]>
1 parent de58f62 commit 0af5a9a

File tree

100 files changed

+1985
-1378
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

100 files changed

+1985
-1378
lines changed

CHANGELOG.md

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,17 +4,25 @@
44

55
### Upgrade notes
66

7+
- **Endorsements**
8+
9+
This new version of Decidim has extracted the Endorsement feature into a generic concern that can now be applied to many resources.
10+
To keep current Decidim::Proposals::Proposal's endorsement information, endorsements are copied into the new `Decidim::Endorsable` tables and counter cache columns. This is done via migrations.
11+
12+
After this, `Decidim::Proposals::ProposalEndorsement` and the corresponding counter cache column in `decidim_proposals_proposal.proposal_endorsements_count` should be removed. To do so, Decidim will provide the corresponding migration in the next release.
13+
714
### Added
815

916
- **decidim-core**: Now messages inside conversations have their urls identified as links. [\#5755](https://github.com/decidim/decidim/pull/5755)
1017
- **decidim-core**: Support node.js semver rules for release candidates. [\#5828](https://github.com/decidim/decidim/pull/5828)
18+
- **decidim-proposals**, **decidim-core**, **decidim-blogs**: Extract proposals' endorsements into a polymorphic concern that can now be applied no any resource. It has, in turn, been aplied to blog posts. [\#5542](https://github.com/decidim/decidim/pull/5542)
1119

1220
### Changed
1321

1422
### Fixed
1523

16-
- **decidim-proposals**: Use simple_format to add a wrapper to proposals body [#5753](https://github.com/decidim/decidim/pull/5753)
17-
- **decidim-sortitions**: Fix incorrect proposals sortition. [\5620](https://github.com/decidim/decidim/pull/5620)
24+
- **decidim-proposals**: Use simple_format to add a wrapper to proposals body [\#5753](https://github.com/decidim/decidim/pull/5753)
25+
- **decidim-sortitions**: Fix incorrect proposals sortition. [\#5620](https://github.com/decidim/decidim/pull/5620)
1826
- **decidim-admin**: Fix: let components without step settings be added [\#5568](https://github.com/decidim/decidim/pull/5568)
1927
- **decidim-proposals**: Fix proposals that have their state not published [\#5832](https://github.com/decidim/decidim/pull/5832)
2028

decidim-blogs/app/cells/decidim/blogs/post_m_cell.rb

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,12 @@ class PostMCell < Decidim::CardMCell
1010
def has_actions?
1111
false
1212
end
13+
14+
def endorsements_count
15+
with_tooltip t("decidim.endorsable.endorsements") do
16+
icon("bullhorn", class: "icon--small") + " " + model.endorsements_count.to_s
17+
end
18+
end
1319
end
1420
end
1521
end

decidim-blogs/app/helpers/decidim/blogs/application_helper.rb

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ module ApplicationHelper
88
include PaginateHelper
99
include SanitizeHelper
1010
include Decidim::Blogs::PostsHelper
11+
include ::Decidim::EndorsableHelper
12+
include ::Decidim::FollowableHelper
1113
include Decidim::Comments::CommentsHelper
1214
end
1315
end

decidim-blogs/app/models/decidim/blogs/post.rb

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ class Post < Blogs::ApplicationRecord
1212
include Decidim::Authorable
1313
include Decidim::Comments::Commentable
1414
include Decidim::Searchable
15+
include Decidim::Endorsable
16+
include Decidim::Followable
1517
include Traceable
1618
include Loggable
1719

@@ -56,6 +58,10 @@ def official?
5658
def user_allowed_to_comment?(user)
5759
can_participate_in_space?(user)
5860
end
61+
62+
def users_to_notify_on_comment_created
63+
followers
64+
end
5965
end
6066
end
6167
end

decidim-blogs/app/views/decidim/blogs/posts/show.html.erb

Lines changed: 29 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -14,18 +14,39 @@
1414
blogpost: post
1515
)
1616
%>
17+
18+
<div class="row column view-header">
19+
<h2 class="heading2"><%= translated_attribute post.title %></h2>
20+
<%= cell "decidim/author", present(post.author), from: post %>
21+
</div>
1722
<div class="row">
18-
<div class="columns medium-7 mediumlarge-8">
19-
<div class="row column view-header">
20-
<h2 class="heading2"><%= translated_attribute post.title %></h2>
21-
<%= cell "decidim/author", present(post.author), from: post %>
22-
</div>
23+
<% if show_endorsements_card? %>
24+
<div class="columns section view-side mediumlarge-4 mediumlarge-push-8 large-3 large-push-9">
25+
<div class="card">
26+
<div class="card__content">
27+
<div class="row collapse buttons__row">
28+
<% if endorsements_enabled? %>
29+
<div class="column small-9 collapse">
30+
<%= endorsement_buttons_cell(post) %>
31+
</div>
32+
<% end %>
33+
<div class="column collapse <%= endorsements_enabled? ? "small-3" : "" %>">
34+
<%= link_to "#comments", class: "button small compact hollow secondary button--nomargin expanded" do %>
35+
<%= icon "comment-square", class: "icon--small", aria_label: t(".comments"), role: "img" %> <%= post.comments.count %>
36+
<% end %>
37+
</div>
38+
</div>
39+
<br>
40+
<%= follow_button_for(post) %>
41+
</div>
42+
</div>
43+
</div>
44+
<% end %>
45+
<div class="columns mediumlarge-8 mediumlarge-pull-4">
2346
<div class="section">
2447
<p><%= decidim_sanitize translated_attribute post.body %></p>
2548
</div>
26-
</div>
27-
<div id="most-commented" class="columns medium-5 mediumlarge-4 large-4">
28-
<%= render partial: "sidebar_blog", locals: { posts: posts_most_commented } %>
49+
<%= cell "decidim/endorsers_list", post %>
2950
</div>
3051
</div>
3152
<%= attachments_for post %>

decidim-blogs/config/locales/en.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ en:
4949
title: title
5050
posts:
5151
show:
52+
comments: Comments
5253
view: View
5354
sidebar_blog:
5455
comments: comments
@@ -64,6 +65,8 @@ en:
6465
step:
6566
announcement: Announcement
6667
comments_blocked: Comments blocked
68+
endorsements_blocked: Endorsements blocked
69+
endorsements_enabled: Endorsements enabled
6770
events:
6871
blogs:
6972
post_created:
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
# frozen_string_literal: true
2+
3+
class AddEndorsementsCounterCacheToBlogs < ActiveRecord::Migration[5.2]
4+
def change
5+
add_column :decidim_blogs_posts, :endorsements_count, :integer, null: false, default: 0
6+
end
7+
end

decidim-blogs/lib/decidim/blogs/component.rb

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@
1818
Decidim::Blogs::Post.where(component: components).count
1919
end
2020

21+
component.actions = %w(endorse vote create withdraw amend)
22+
2123
component.settings(:global) do |settings|
2224
settings.attribute :announcement, type: :text, translated: true, editor: true
2325
settings.attribute :comments_enabled, type: :boolean, default: true
@@ -26,11 +28,14 @@
2628
component.settings(:step) do |settings|
2729
settings.attribute :announcement, type: :text, translated: true, editor: true
2830
settings.attribute :comments_blocked, type: :boolean, default: false
31+
settings.attribute :endorsements_enabled, type: :boolean, default: true
32+
settings.attribute :endorsements_blocked, type: :boolean
2933
end
3034

3135
component.register_resource(:blogpost) do |resource|
3236
resource.model_class_name = "Decidim::Blogs::Post"
3337
resource.card = "decidim/blogs/post"
38+
resource.actions = %w(endorse vote amend)
3439
resource.searchable = true
3540
end
3641

decidim-blogs/spec/models/decidim/blogs/post_spec.rb

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,5 +39,49 @@ module Decidim::Blogs
3939
it "has an associated component" do
4040
expect(post.component).to be_a(Decidim::Component)
4141
end
42+
43+
describe "#endorsed_by?" do
44+
let(:user) { create(:user, organization: subject.organization) }
45+
46+
context "with User endorsement" do
47+
it "returns false if the post is not endorsed by the given user" do
48+
expect(subject).not_to be_endorsed_by(user)
49+
end
50+
51+
it "returns true if the post is not endorsed by the given user" do
52+
create(:endorsement, resource: subject, author: user)
53+
expect(subject).to be_endorsed_by(user)
54+
end
55+
end
56+
57+
context "with Organization endorsement" do
58+
let!(:user_group) { create(:user_group, verified_at: Time.current, organization: user.organization) }
59+
let!(:membership) { create(:user_group_membership, user: user, user_group: user_group) }
60+
61+
before { user_group.reload }
62+
63+
it "returns false if the post is not endorsed by the given organization" do
64+
expect(subject).not_to be_endorsed_by(user, user_group)
65+
end
66+
67+
it "returns true if the post is not endorsed by the given organization" do
68+
create(:endorsement, resource: subject, author: user, user_group: user_group)
69+
expect(subject).to be_endorsed_by(user, user_group)
70+
end
71+
end
72+
end
73+
74+
describe "#users_to_notify_on_comment_created" do
75+
let!(:follows) { create_list(:follow, 3, followable: subject) }
76+
let(:followers) { follows.map(&:user) }
77+
let(:participatory_space) { subject.component.participatory_space }
78+
let(:organization) { participatory_space.organization }
79+
80+
context "when creating new comment" do
81+
it "returns the followers" do
82+
expect(subject.users_to_notify_on_comment_created).to match_array(followers)
83+
end
84+
end
85+
end
4286
end
4387
end

decidim-proposals/app/assets/javascripts/decidim/proposals/identity_selector_dialog.js.es6 renamed to decidim-core/app/assets/javascripts/decidim/identity_selector_dialog.js.es6

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,14 @@
66
$(document).ready(function () {
77

88
let button = $("#select-identity-button"),
9-
refreshUrl = null,
9+
identitiesUrl = null,
1010
userIdentitiesDialog = $("#user-identities");
1111

1212
if (userIdentitiesDialog.length) {
13-
refreshUrl = userIdentitiesDialog.data("refresh-url");
13+
identitiesUrl = userIdentitiesDialog.data("reveal-identities-url");
1414

1515
button.click(function () {
16-
$.ajax(refreshUrl).done(function(response) {
16+
$.ajax(identitiesUrl).done(function(response) {
1717
userIdentitiesDialog.html(response).foundation("open");
1818
button.trigger("ajax:success")
1919
});
@@ -32,21 +32,26 @@ $(document).ready(function () {
3232
$("#user-identities ul.reveal__list li").each(function(index, elem) {
3333
let liTag = $(elem)
3434
liTag.on("click", function() {
35-
let method = liTag.data("method")
36-
let url = liTag.data("url")
35+
let method = liTag.data("method"),
36+
urlDataAttr = null;
37+
if (method === "POST") {
38+
urlDataAttr = "create_url";
39+
} else {
40+
urlDataAttr = "destroy_url";
41+
}
3742
$.ajax({
38-
url: url,
43+
url: liTag.data(urlDataAttr),
3944
method: method,
4045
dataType: "script",
4146
success: function() {
4247
if (liTag.hasClass("selected")) {
4348
liTag.removeClass("selected")
4449
liTag.find(".icon--circle-check").addClass("invisible")
45-
liTag.data("method", "post")
50+
liTag.data("method", "POST")
4651
} else {
4752
liTag.addClass("selected")
4853
liTag.find(".icon--circle-check").removeClass("invisible")
49-
liTag.data("method", "delete")
54+
liTag.data("method", "DELETE")
5055
}
5156
}
5257
})

0 commit comments

Comments
 (0)