Merge pull request #4292 from consul/sdg_view
Add SDG view with related content
This commit is contained in:
@@ -123,3 +123,23 @@ $pagination-radius: $global-radius;
|
||||
$show-header-for-stacked: true;
|
||||
|
||||
$tooltip-background-color: $brand;
|
||||
|
||||
$sdg-colors: (
|
||||
1: #e5243b,
|
||||
2: #dda63a,
|
||||
3: #4c9f38,
|
||||
4: #c5192d,
|
||||
5: #ff3a21,
|
||||
6: #26bde2,
|
||||
7: #fcc30b,
|
||||
8: #a21942,
|
||||
9: #fd6925,
|
||||
10: #dd1367,
|
||||
11: #fd9d24,
|
||||
12: #bf8b2e,
|
||||
13: #3f7e44,
|
||||
14: #0a97d9,
|
||||
15: #56c02b,
|
||||
16: #00689d,
|
||||
17: #19486a
|
||||
);
|
||||
|
||||
@@ -28,4 +28,6 @@
|
||||
@import "leaflet";
|
||||
@import "sticky_overrides";
|
||||
@import "admin/*";
|
||||
@import "sdg/**/*";
|
||||
@import "sdg_management/*";
|
||||
@import "widgets/**/*";
|
||||
|
||||
@@ -2794,7 +2794,8 @@ table {
|
||||
// ------------
|
||||
|
||||
.home-page,
|
||||
.custom-page {
|
||||
.custom-page,
|
||||
.sdg-goal-show {
|
||||
|
||||
a {
|
||||
|
||||
@@ -2859,6 +2860,13 @@ table {
|
||||
}
|
||||
}
|
||||
|
||||
h2 {
|
||||
&.title {
|
||||
@include header-font-size(h3);
|
||||
}
|
||||
}
|
||||
|
||||
h2,
|
||||
h3 {
|
||||
|
||||
&.title {
|
||||
@@ -2893,10 +2901,6 @@ table {
|
||||
|
||||
.feeds-list {
|
||||
|
||||
.proposal {
|
||||
clear: both;
|
||||
}
|
||||
|
||||
a {
|
||||
|
||||
&.see-all {
|
||||
@@ -2910,40 +2914,6 @@ table {
|
||||
}
|
||||
}
|
||||
|
||||
.feed-image {
|
||||
display: inline-block;
|
||||
height: rem-calc(120);
|
||||
overflow: hidden;
|
||||
width: 100%;
|
||||
|
||||
@include breakpoint(medium) {
|
||||
height: rem-calc(96);
|
||||
}
|
||||
|
||||
img {
|
||||
max-width: none;
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.feed-description {
|
||||
|
||||
p {
|
||||
font-size: $small-font-size;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.feed-content {
|
||||
|
||||
.debate,
|
||||
.proposal {
|
||||
margin-bottom: 0;
|
||||
margin-top: 0;
|
||||
padding: $line-height / 2 0;
|
||||
}
|
||||
}
|
||||
|
||||
.figure-card {
|
||||
display: flex;
|
||||
margin: 0 0 $line-height;
|
||||
|
||||
@@ -209,3 +209,11 @@
|
||||
text-decoration: none;
|
||||
}
|
||||
}
|
||||
|
||||
@mixin header-font-size($heading-tag) {
|
||||
@each $size, $headers in $header-styles {
|
||||
@include breakpoint($size) {
|
||||
font-size: rem-calc(map-get(map-get($headers, $heading-tag), font-size));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
40
app/assets/stylesheets/sdg/goals/show.scss
Normal file
40
app/assets/stylesheets/sdg/goals/show.scss
Normal file
@@ -0,0 +1,40 @@
|
||||
.sdg-goal-show {
|
||||
@include grid-row;
|
||||
|
||||
> :not(.feeds-participation) {
|
||||
@include grid-column-gutter;
|
||||
}
|
||||
|
||||
.sdg-goal {
|
||||
|
||||
> header {
|
||||
color: #fff;
|
||||
margin-top: $line-height / 2;
|
||||
padding-left: rem-calc(24);
|
||||
text-shadow: 0 0 1px $black;
|
||||
}
|
||||
|
||||
@each $code, $color in $sdg-colors {
|
||||
&.sdg-goal-#{$code} {
|
||||
> header {
|
||||
background-color: $color;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.feed-processes {
|
||||
|
||||
.feed-content {
|
||||
@include breakpoint(medium) {
|
||||
@include grid-row-nest;
|
||||
display: flex;
|
||||
|
||||
> * {
|
||||
@include grid-column-gutter;
|
||||
width: 50%;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
24
app/assets/stylesheets/widgets/feeds/feed.scss
Normal file
24
app/assets/stylesheets/widgets/feeds/feed.scss
Normal file
@@ -0,0 +1,24 @@
|
||||
.widget-feed {
|
||||
|
||||
.feed-description {
|
||||
|
||||
p {
|
||||
font-size: $small-font-size;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.feed-content {
|
||||
|
||||
.debate,
|
||||
.proposal {
|
||||
margin-bottom: 0;
|
||||
margin-top: 0;
|
||||
padding: $line-height / 2 0;
|
||||
}
|
||||
}
|
||||
|
||||
.no-items {
|
||||
margin-top: $line-height;
|
||||
}
|
||||
}
|
||||
30
app/assets/stylesheets/widgets/feeds/participation.scss
Normal file
30
app/assets/stylesheets/widgets/feeds/participation.scss
Normal file
@@ -0,0 +1,30 @@
|
||||
.feeds-participation {
|
||||
|
||||
@include breakpoint(medium) {
|
||||
display: flex;
|
||||
|
||||
.feed-proposals:not(:only-child) {
|
||||
width: 2 * 100% / 3;
|
||||
}
|
||||
|
||||
.feed-debates:not(:only-child) {
|
||||
width: 1 * 100% / 3;
|
||||
}
|
||||
|
||||
.feed-proposals,
|
||||
.feed-debates {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
.feed-content {
|
||||
flex: 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.feed-debates,
|
||||
.feed-proposals {
|
||||
@include grid-col;
|
||||
margin-top: $line-height;
|
||||
}
|
||||
}
|
||||
20
app/assets/stylesheets/widgets/feeds/proposal.scss
Normal file
20
app/assets/stylesheets/widgets/feeds/proposal.scss
Normal file
@@ -0,0 +1,20 @@
|
||||
.feed-proposals .proposal {
|
||||
@include grid-row-nest;
|
||||
clear: both;
|
||||
|
||||
.feed-image {
|
||||
display: inline-block;
|
||||
height: rem-calc(120);
|
||||
overflow: hidden;
|
||||
width: 100%;
|
||||
|
||||
@include breakpoint(medium) {
|
||||
height: rem-calc(96);
|
||||
}
|
||||
|
||||
img {
|
||||
max-width: none;
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
1
app/components/sdg/goals/index_component.html.erb
Normal file
1
app/components/sdg/goals/index_component.html.erb
Normal file
@@ -0,0 +1 @@
|
||||
<%= link_list(*goals.map { |goal| [goal.code_and_title, sdg_goal_path(goal.code)] }) %>
|
||||
8
app/components/sdg/goals/index_component.rb
Normal file
8
app/components/sdg/goals/index_component.rb
Normal file
@@ -0,0 +1,8 @@
|
||||
class SDG::Goals::IndexComponent < ApplicationComponent
|
||||
attr_reader :goals
|
||||
delegate :link_list, to: :helpers
|
||||
|
||||
def initialize(goals)
|
||||
@goals = goals
|
||||
end
|
||||
end
|
||||
19
app/components/sdg/goals/show_component.html.erb
Normal file
19
app/components/sdg/goals/show_component.html.erb
Normal file
@@ -0,0 +1,19 @@
|
||||
<% provide(:title) { goal.title } %>
|
||||
|
||||
<div class="sdg-goal-show">
|
||||
<%= back_link_to sdg_goals_path %>
|
||||
|
||||
<article class="sdg-goal sdg-goal-<%= goal.code %>">
|
||||
<header>
|
||||
<h1><%= goal.title %></h1>
|
||||
</header>
|
||||
</article>
|
||||
|
||||
<%= render Widgets::Feeds::ParticipationComponent.new(feeds) %>
|
||||
|
||||
<% if processes_feed %>
|
||||
<div class="feeds-list">
|
||||
<%= render Widgets::Feeds::FeedComponent.new(processes_feed) %>
|
||||
</div>
|
||||
<% end %>
|
||||
</div>
|
||||
18
app/components/sdg/goals/show_component.rb
Normal file
18
app/components/sdg/goals/show_component.rb
Normal file
@@ -0,0 +1,18 @@
|
||||
class SDG::Goals::ShowComponent < ApplicationComponent
|
||||
attr_reader :goal
|
||||
delegate :back_link_to, to: :helpers
|
||||
|
||||
def initialize(goal)
|
||||
@goal = goal
|
||||
end
|
||||
|
||||
def feeds
|
||||
SDG::Widget::Feed.for_goal(goal)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def processes_feed
|
||||
feeds.find { |feed| feed.kind == "processes" }
|
||||
end
|
||||
end
|
||||
3
app/components/widgets/feeds/debate_component.html.erb
Normal file
3
app/components/widgets/feeds/debate_component.html.erb
Normal file
@@ -0,0 +1,3 @@
|
||||
<div class="debate">
|
||||
<strong><%= link_to debate.title, url_for(debate) %></strong>
|
||||
</div>
|
||||
7
app/components/widgets/feeds/debate_component.rb
Normal file
7
app/components/widgets/feeds/debate_component.rb
Normal file
@@ -0,0 +1,7 @@
|
||||
class Widgets::Feeds::DebateComponent < ApplicationComponent
|
||||
attr_reader :debate
|
||||
|
||||
def initialize(debate)
|
||||
@debate = debate
|
||||
end
|
||||
end
|
||||
17
app/components/widgets/feeds/feed_component.html.erb
Normal file
17
app/components/widgets/feeds/feed_component.html.erb
Normal file
@@ -0,0 +1,17 @@
|
||||
<section id="feed_<%= kind %>" class="widget-feed feed-<%= kind %>">
|
||||
<header>
|
||||
<h2 class="title"><%= t("welcome.feed.most_active.#{kind}") %></h2>
|
||||
</header>
|
||||
|
||||
<% if feed.items.any? %>
|
||||
<div class="feed-content">
|
||||
<% feed.items.each do |item| %>
|
||||
<%= render item_component_class.new(item) %>
|
||||
<% end %>
|
||||
</div>
|
||||
|
||||
<%= link_to t("welcome.feed.see_all.#{kind}"), see_all_path, class: "see-all" %>
|
||||
<% else %>
|
||||
<div class="no-items callout primary"><%= t("welcome.feed.no_items.#{kind}") %></div>
|
||||
<% end %>
|
||||
</section>
|
||||
33
app/components/widgets/feeds/feed_component.rb
Normal file
33
app/components/widgets/feeds/feed_component.rb
Normal file
@@ -0,0 +1,33 @@
|
||||
class Widgets::Feeds::FeedComponent < ApplicationComponent
|
||||
attr_reader :feed
|
||||
delegate :kind, to: :feed
|
||||
|
||||
def initialize(feed)
|
||||
@feed = feed
|
||||
end
|
||||
|
||||
def see_all_path
|
||||
polymorphic_path(feed.items.model, filters)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def item_component_class
|
||||
case kind
|
||||
when "proposals"
|
||||
Widgets::Feeds::ProposalComponent
|
||||
when "debates"
|
||||
Widgets::Feeds::DebateComponent
|
||||
when "processes"
|
||||
Widgets::Feeds::ProcessComponent
|
||||
end
|
||||
end
|
||||
|
||||
def filters
|
||||
if feed.respond_to?(:goal) && kind != "processes"
|
||||
{ advanced_search: { goal: feed.goal.code }}
|
||||
else
|
||||
{}
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,7 @@
|
||||
<div class="row margin-bottom feeds-list feeds-participation">
|
||||
<% feeds.each do |feed| %>
|
||||
<% if feed_proposals?(feed) || feed_debates?(feed) %>
|
||||
<%= render Widgets::Feeds::FeedComponent.new(feed) %>
|
||||
<% end %>
|
||||
<% end %>
|
||||
</div>
|
||||
17
app/components/widgets/feeds/participation_component.rb
Normal file
17
app/components/widgets/feeds/participation_component.rb
Normal file
@@ -0,0 +1,17 @@
|
||||
class Widgets::Feeds::ParticipationComponent < ApplicationComponent
|
||||
attr_reader :feeds
|
||||
|
||||
def initialize(feeds)
|
||||
@feeds = feeds
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def feed_debates?(feed)
|
||||
feed.kind == "debates"
|
||||
end
|
||||
|
||||
def feed_proposals?(feed)
|
||||
feed.kind == "proposals"
|
||||
end
|
||||
end
|
||||
13
app/components/widgets/feeds/process_component.html.erb
Normal file
13
app/components/widgets/feeds/process_component.html.erb
Normal file
@@ -0,0 +1,13 @@
|
||||
<div class="legislation-process card">
|
||||
<%= link_to url_for(process) do %>
|
||||
<figure class="figure-card">
|
||||
<%= image_tag("welcome_process.png", alt: "") %>
|
||||
<figcaption>
|
||||
<span><%= t("welcome.feed.process_label") %></span><br>
|
||||
<h3><%= process.title %></h3>
|
||||
</figcaption>
|
||||
</figure>
|
||||
<p class="description small"><%= process.summary %></p>
|
||||
<p class="small"><%= t("welcome.feed.see_process") %></p>
|
||||
<% end %>
|
||||
</div>
|
||||
7
app/components/widgets/feeds/process_component.rb
Normal file
7
app/components/widgets/feeds/process_component.rb
Normal file
@@ -0,0 +1,7 @@
|
||||
class Widgets::Feeds::ProcessComponent < ApplicationComponent
|
||||
attr_reader :process
|
||||
|
||||
def initialize(process)
|
||||
@process = process
|
||||
end
|
||||
end
|
||||
16
app/components/widgets/feeds/proposal_component.html.erb
Normal file
16
app/components/widgets/feeds/proposal_component.html.erb
Normal file
@@ -0,0 +1,16 @@
|
||||
<div class="proposal">
|
||||
<div class="feed-description small-12 column
|
||||
<%= "medium-6 large-9" if proposal.image.present? %>">
|
||||
<strong><%= link_to proposal.title, url_for(proposal) %></strong><br>
|
||||
<p><%= proposal.summary %></p>
|
||||
</div>
|
||||
|
||||
<% if proposal.image.present? %>
|
||||
<div class="small-12 medium-6 large-3 column">
|
||||
<div class="feed-image">
|
||||
<%= image_tag proposal.image_url(:thumb),
|
||||
alt: proposal.image.title.unicode_normalize %>
|
||||
</div>
|
||||
</div>
|
||||
<% end %>
|
||||
</div>
|
||||
7
app/components/widgets/feeds/proposal_component.rb
Normal file
7
app/components/widgets/feeds/proposal_component.rb
Normal file
@@ -0,0 +1,7 @@
|
||||
class Widgets::Feeds::ProposalComponent < ApplicationComponent
|
||||
attr_reader :proposal
|
||||
|
||||
def initialize(proposal)
|
||||
@proposal = proposal
|
||||
end
|
||||
end
|
||||
12
app/controllers/sdg/goals_controller.rb
Normal file
12
app/controllers/sdg/goals_controller.rb
Normal file
@@ -0,0 +1,12 @@
|
||||
class SDG::GoalsController < ApplicationController
|
||||
include FeatureFlags
|
||||
feature_flag :sdg
|
||||
load_and_authorize_resource find_by: :code, id_param: :code
|
||||
|
||||
def index
|
||||
@goals = @goals.order(:code)
|
||||
end
|
||||
|
||||
def show
|
||||
end
|
||||
end
|
||||
@@ -1,29 +1,9 @@
|
||||
module FeedsHelper
|
||||
def feed_debates?(feed)
|
||||
feed.kind == "debates"
|
||||
end
|
||||
|
||||
def feed_proposals?(feed)
|
||||
feed.kind == "proposals"
|
||||
end
|
||||
|
||||
def feed_processes?(feed)
|
||||
feed.kind == "processes"
|
||||
end
|
||||
|
||||
def feed_debates_enabled?
|
||||
Setting["homepage.widgets.feeds.debates"].present?
|
||||
end
|
||||
|
||||
def feed_proposals_enabled?
|
||||
Setting["homepage.widgets.feeds.proposals"].present?
|
||||
end
|
||||
|
||||
def feed_processes_enabled?
|
||||
Setting["homepage.widgets.feeds.processes"].present?
|
||||
end
|
||||
|
||||
def feed_debates_and_proposals_enabled?
|
||||
feed_debates_enabled? && feed_proposals_enabled?
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
module LayoutsHelper
|
||||
def layout_menu_link_to(text, path, is_active, options)
|
||||
title = t("shared.go_to_page") + text
|
||||
|
||||
if is_active
|
||||
tag.span(t("shared.you_are_in"), class: "show-for-sr") + " " +
|
||||
link_to(text, path, options.merge(class: "is-active"))
|
||||
link_to(text, path, options.merge(class: "is-active", title: title))
|
||||
else
|
||||
link_to(text, path, options)
|
||||
link_to(text, path, options.merge(title: title))
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -27,6 +27,8 @@ module Abilities
|
||||
can [:read], Legislation::Question
|
||||
can [:read, :map, :share], Legislation::Proposal
|
||||
can [:search, :comments, :read, :create, :new_comment], Legislation::Annotation
|
||||
|
||||
can :read, ::SDG::Goal
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -4,7 +4,6 @@ class Abilities::SDG::Manager
|
||||
def initialize(user)
|
||||
merge Abilities::Common.new(user)
|
||||
|
||||
can :read, ::SDG::Goal
|
||||
can :read, ::SDG::Target
|
||||
can :manage, ::SDG::LocalTarget
|
||||
end
|
||||
|
||||
@@ -20,7 +20,7 @@ module Filterable
|
||||
def allowed_filter?(filter, value)
|
||||
return if value.blank?
|
||||
|
||||
["official_level", "date_range"].include?(filter)
|
||||
["official_level", "date_range", "goal"].include?(filter)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
17
app/models/sdg/widget/feed.rb
Normal file
17
app/models/sdg/widget/feed.rb
Normal file
@@ -0,0 +1,17 @@
|
||||
class SDG::Widget::Feed
|
||||
attr_reader :feed, :goal
|
||||
delegate :kind, to: :feed
|
||||
|
||||
def initialize(feed, goal)
|
||||
@feed = feed
|
||||
@goal = goal
|
||||
end
|
||||
|
||||
def items
|
||||
feed.items.by_goal(goal.code)
|
||||
end
|
||||
|
||||
def self.for_goal(goal)
|
||||
::Widget::Feed.active.map { |feed| new(feed, goal) }
|
||||
end
|
||||
end
|
||||
1
app/views/sdg/goals/index.html.erb
Normal file
1
app/views/sdg/goals/index.html.erb
Normal file
@@ -0,0 +1 @@
|
||||
<%= render SDG::Goals::IndexComponent.new(@goals) %>
|
||||
1
app/views/sdg/goals/show.html.erb
Normal file
1
app/views/sdg/goals/show.html.erb
Normal file
@@ -0,0 +1 @@
|
||||
<%= render SDG::Goals::ShowComponent.new(@goal) %>
|
||||
@@ -7,8 +7,7 @@
|
||||
<%= layout_menu_link_to t("layouts.header.debates"),
|
||||
debates_path,
|
||||
controller_name == "debates",
|
||||
accesskey: "1",
|
||||
title: t("shared.go_to_page") + t("layouts.header.debates") %>
|
||||
accesskey: "1" %>
|
||||
</li>
|
||||
<% end %>
|
||||
<% if feature?(:proposals) %>
|
||||
@@ -16,8 +15,7 @@
|
||||
<%= layout_menu_link_to t("layouts.header.proposals"),
|
||||
proposals_path,
|
||||
controller.class == ProposalsController,
|
||||
accesskey: "2",
|
||||
title: t("shared.go_to_page") + t("layouts.header.proposals") %>
|
||||
accesskey: "2" %>
|
||||
</li>
|
||||
<% end %>
|
||||
<% if feature?(:polls) %>
|
||||
@@ -25,8 +23,7 @@
|
||||
<%= layout_menu_link_to t("layouts.header.poll_questions"),
|
||||
polls_path,
|
||||
controller_name == "polls" || (controller_name == "questions" && controller.class.parent == Polls),
|
||||
accesskey: "3",
|
||||
title: t("shared.go_to_page") + t("layouts.header.poll_questions") %>
|
||||
accesskey: "3" %>
|
||||
</li>
|
||||
<% end %>
|
||||
<% if feature?(:legislation) %>
|
||||
@@ -42,8 +39,15 @@
|
||||
<%= layout_menu_link_to t("layouts.header.budgets"),
|
||||
budgets_path,
|
||||
controller_name == "budgets" || controller_name == "investments",
|
||||
accesskey: "5",
|
||||
title: t("shared.go_to_page") + t("layouts.header.budgets") %>
|
||||
accesskey: "5" %>
|
||||
</li>
|
||||
<% end %>
|
||||
<% if feature?(:sdg) %>
|
||||
<li>
|
||||
<%= layout_menu_link_to t("layouts.header.sdg"),
|
||||
sdg_goals_path,
|
||||
controller_path.split("/").first == "sdg",
|
||||
accesskey: "6" %>
|
||||
</li>
|
||||
<% end %>
|
||||
<% if feature?(:help_page) %>
|
||||
@@ -51,8 +55,7 @@
|
||||
<%= layout_menu_link_to t("layouts.header.help"),
|
||||
help_path,
|
||||
current_page?(help_path),
|
||||
accesskey: "6",
|
||||
title: t("shared.go_to_page") + t("layouts.header.help") %>
|
||||
accesskey: "7" %>
|
||||
</li>
|
||||
<% end %>
|
||||
|
||||
|
||||
@@ -1,51 +1 @@
|
||||
<div class="row margin-bottom feeds-list" data-equalizer data-equalize-on="medium">
|
||||
<% @feeds.each do |feed| %>
|
||||
|
||||
<% if feed_proposals?(feed) %>
|
||||
<div id="feed_proposals" class="small-12 column margin-top
|
||||
<%= "medium-8" if feed_debates_and_proposals_enabled? %>">
|
||||
<div class="feed-content" data-equalizer-watch>
|
||||
<h3 class="title"><%= t("welcome.feed.most_active.#{feed.kind}") %></h3>
|
||||
|
||||
<% feed.items.each do |item| %>
|
||||
<div class="<%= item.class.to_s.parameterize(separator: "_") %> row">
|
||||
<div class="feed-description small-12 column
|
||||
<%= "medium-6 large-9" if item.image.present? %>">
|
||||
<strong><%= link_to item.title, url_for(item) %></strong><br>
|
||||
<p><%= item.summary %></p>
|
||||
</div>
|
||||
<% if item.image.present? %>
|
||||
<div class="small-12 medium-6 large-3 column">
|
||||
<div class="feed-image">
|
||||
<%= image_tag item.image_url(:thumb),
|
||||
alt: item.image.title.unicode_normalize %>
|
||||
</div>
|
||||
</div>
|
||||
<% end %>
|
||||
</div>
|
||||
<% end %>
|
||||
</div>
|
||||
|
||||
<%= link_to t("welcome.feed.see_all_proposals"), proposals_path, class: "see-all" %>
|
||||
</div>
|
||||
<% end %>
|
||||
|
||||
<% if feed_debates?(feed) %>
|
||||
<div id="feed_debates" class="small-12 column margin-top
|
||||
<%= "medium-4" if feed_debates_and_proposals_enabled? %>">
|
||||
<div class="feed-content" data-equalizer-watch>
|
||||
<h3 class="title"><%= t("welcome.feed.most_active.#{feed.kind}") %></h3>
|
||||
|
||||
<% feed.items.each do |item| %>
|
||||
<div class="<%= item.class.to_s.parameterize(separator: "_") %>">
|
||||
<strong><%= link_to item.title, url_for(item) %></strong>
|
||||
</div>
|
||||
<% end %>
|
||||
</div>
|
||||
|
||||
<%= link_to t("welcome.feed.see_all_debates"), debates_path, class: "see-all" %>
|
||||
</div>
|
||||
<% end %>
|
||||
|
||||
<% end %>
|
||||
</div>
|
||||
<%= render Widgets::Feeds::ParticipationComponent.new(@feeds) %>
|
||||
|
||||
@@ -1,29 +1,7 @@
|
||||
<div class="feeds-list">
|
||||
<% @feeds.each do |feed| %>
|
||||
|
||||
<% if feed_processes?(feed) %>
|
||||
<div class="card small-12 column margin-bottom">
|
||||
<div class="feed-content">
|
||||
<h3 class="title"><%= t("welcome.feed.most_active.#{feed.kind}") %></h3>
|
||||
|
||||
<% feed.items.each do |item| %>
|
||||
<%= link_to url_for(item) do %>
|
||||
<figure class="figure-card <%= item.class.to_s.parameterize(separator: "_") %>">
|
||||
<%= image_tag("welcome_process.png", alt: "") %>
|
||||
<figcaption>
|
||||
<span><%= t("welcome.feed.process_label") %></span><br>
|
||||
<h3><%= item.title %></h3>
|
||||
</figcaption>
|
||||
</figure>
|
||||
<p class="description small"><%= item.summary %></p>
|
||||
<p class="small"><%= t("welcome.feed.see_process") %></p>
|
||||
<% end %>
|
||||
<% end %>
|
||||
|
||||
<%= link_to t("welcome.feed.see_all_processes"), legislation_processes_path, class: "float-right see-all" %>
|
||||
</div>
|
||||
</div>
|
||||
<%= render Widgets::Feeds::FeedComponent.new(feed) %>
|
||||
<% end %>
|
||||
|
||||
<% end %>
|
||||
</div>
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
<div class="row">
|
||||
<% if @cards.any? %>
|
||||
<div class="small-12 column <%= "large-8" if feed_processes_enabled? %>">
|
||||
<h3 class="title"><%= t("welcome.cards.title") %></h3>
|
||||
<h2 class="title"><%= t("welcome.cards.title") %></h2>
|
||||
|
||||
<%= render "shared/cards" %>
|
||||
</div>
|
||||
|
||||
@@ -251,6 +251,7 @@ en:
|
||||
other: You have %{count} new notifications
|
||||
notifications: Notifications
|
||||
no_notifications: "You don't have new notifications"
|
||||
sdg: "SDG"
|
||||
notifications:
|
||||
index:
|
||||
empty_notifications: You don't have new notifications.
|
||||
@@ -874,9 +875,14 @@ en:
|
||||
debates: "Most active debates"
|
||||
proposals: "Most active proposals"
|
||||
processes: "Open processes"
|
||||
see_all_debates: See all debates
|
||||
see_all_proposals: See all proposals
|
||||
see_all_processes: See all processes
|
||||
see_all:
|
||||
debates: See all debates
|
||||
proposals: See all proposals
|
||||
processes: See all processes
|
||||
no_items:
|
||||
debates: There are no debates right now
|
||||
proposals: There are no proposals right now
|
||||
processes: There are no open processes right now
|
||||
process_label: Process
|
||||
see_process: See process
|
||||
cards:
|
||||
|
||||
@@ -251,6 +251,7 @@ es:
|
||||
other: Tienes %{count} notificaciones nuevas
|
||||
notifications: Notificaciones
|
||||
no_notifications: "No tienes notificaciones nuevas"
|
||||
sdg: "ODS"
|
||||
notifications:
|
||||
index:
|
||||
empty_notifications: No tienes notificaciones nuevas.
|
||||
@@ -874,9 +875,14 @@ es:
|
||||
debates: "Debates más activos"
|
||||
proposals: "Propuestas más activas"
|
||||
processes: "Procesos abiertos"
|
||||
see_all_debates: Ver todos los debates
|
||||
see_all_proposals: Ver todas las propuestas
|
||||
see_all_processes: Ver todos los procesos
|
||||
see_all:
|
||||
debates: Ver todos los debates
|
||||
proposals: Ver todas las propuestas
|
||||
processes: Ver todos los procesos
|
||||
no_items:
|
||||
debates: Ahora mismo no hay debates
|
||||
proposals: Ahora mismo no hay propuestas
|
||||
processes: Ahora mismo no hay procesos abiertos
|
||||
process_label: Proceso
|
||||
see_process: Ver proceso
|
||||
cards:
|
||||
|
||||
@@ -21,6 +21,7 @@ Rails.application.routes.draw do
|
||||
draw :poll
|
||||
draw :proposal
|
||||
draw :related_content
|
||||
draw :sdg
|
||||
draw :sdg_management
|
||||
draw :tag
|
||||
draw :user
|
||||
|
||||
3
config/routes/sdg.rb
Normal file
3
config/routes/sdg.rb
Normal file
@@ -0,0 +1,3 @@
|
||||
namespace :sdg do
|
||||
resources :goals, param: :code, only: [:index, :show]
|
||||
end
|
||||
@@ -1,4 +1,4 @@
|
||||
(1..17).each do |code|
|
||||
(1..17).to_a.shuffle.each do |code|
|
||||
SDG::Goal.where(code: code).first_or_create!
|
||||
end
|
||||
|
||||
|
||||
74
spec/components/widgets/feeds/feed_component_spec.rb
Normal file
74
spec/components/widgets/feeds/feed_component_spec.rb
Normal file
@@ -0,0 +1,74 @@
|
||||
require "rails_helper"
|
||||
|
||||
describe Widgets::Feeds::FeedComponent, type: :component do
|
||||
it "renders a message when there are no items" do
|
||||
feed = double(kind: "debates", items: [])
|
||||
component = Widgets::Feeds::FeedComponent.new(feed)
|
||||
|
||||
render_inline component
|
||||
|
||||
expect(page).to have_content "no debates"
|
||||
end
|
||||
|
||||
describe "#see_all_path" do
|
||||
context "debates" do
|
||||
let(:feed) { Widget::Feed.new(kind: "debates") }
|
||||
|
||||
it "points to the debates path for homepage debates feeds" do
|
||||
component = Widgets::Feeds::FeedComponent.new(feed)
|
||||
|
||||
render_inline component
|
||||
|
||||
expect(component.see_all_path).to eq "/debates"
|
||||
end
|
||||
|
||||
it "points to the debates filtered by goal for goal feeds" do
|
||||
component = Widgets::Feeds::FeedComponent.new(SDG::Widget::Feed.new(feed, SDG::Goal[6]))
|
||||
|
||||
render_inline component
|
||||
|
||||
expect(component.see_all_path).to eq "/debates?advanced_search#{CGI.escape("[goal]")}=6"
|
||||
end
|
||||
end
|
||||
|
||||
context "proposals" do
|
||||
let(:feed) { Widget::Feed.new(kind: "proposals") }
|
||||
|
||||
it "points to the proposals path for homepage proposals feeds" do
|
||||
component = Widgets::Feeds::FeedComponent.new(feed)
|
||||
|
||||
render_inline component
|
||||
|
||||
expect(component.see_all_path).to eq "/proposals"
|
||||
end
|
||||
|
||||
it "points to the proposals filtered by goal for goal feeds" do
|
||||
component = Widgets::Feeds::FeedComponent.new(SDG::Widget::Feed.new(feed, SDG::Goal[6]))
|
||||
|
||||
render_inline component
|
||||
|
||||
expect(component.see_all_path).to eq "/proposals?advanced_search#{CGI.escape("[goal]")}=6"
|
||||
end
|
||||
end
|
||||
|
||||
context "processes" do
|
||||
let(:feed) { Widget::Feed.new(kind: "processes") }
|
||||
|
||||
it "points to the legislation processes path for homepage processes feeds" do
|
||||
component = Widgets::Feeds::FeedComponent.new(feed)
|
||||
|
||||
render_inline component
|
||||
|
||||
expect(component.see_all_path).to eq "/legislation/processes"
|
||||
end
|
||||
|
||||
it "points to the legislation processes path for goal processes feeds" do
|
||||
component = Widgets::Feeds::FeedComponent.new(SDG::Widget::Feed.new(feed, SDG::Goal[6]))
|
||||
|
||||
render_inline component
|
||||
|
||||
expect(component.see_all_path).to eq "/legislation/processes"
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
13
spec/controllers/sdg/goals_spec.rb
Normal file
13
spec/controllers/sdg/goals_spec.rb
Normal file
@@ -0,0 +1,13 @@
|
||||
require 'rails_helper'
|
||||
|
||||
describe SDG::GoalsController do
|
||||
context "featured disabled" do
|
||||
before do
|
||||
Setting["feature.sdg"] = false
|
||||
end
|
||||
|
||||
it "raises feature disabled" do
|
||||
expect { get :index }.to raise_exception(FeatureFlags::FeatureDisabled)
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -107,7 +107,6 @@ describe Abilities::Administrator do
|
||||
it { should be_able_to(:create, LocalCensusRecords::Import) }
|
||||
it { should be_able_to(:show, LocalCensusRecords::Import) }
|
||||
|
||||
it { should be_able_to(:read, SDG::Goal) }
|
||||
it { should be_able_to(:read, SDG::Target) }
|
||||
|
||||
it { should be_able_to(:read, SDG::Manager) }
|
||||
|
||||
@@ -305,7 +305,6 @@ describe Abilities::Common do
|
||||
it { should be_able_to(:disable_recommendations, Proposal) }
|
||||
end
|
||||
|
||||
it { should_not be_able_to(:read, SDG::Goal) }
|
||||
it { should_not be_able_to(:read, SDG::Target) }
|
||||
|
||||
it { should_not be_able_to(:read, SDG::Manager) }
|
||||
|
||||
@@ -53,7 +53,7 @@ describe Abilities::Everyone do
|
||||
it { should_not be_able_to(:summary, create(:legislation_process, :open)) }
|
||||
it { should_not be_able_to(:summary, create(:legislation_process, :past, :not_published)) }
|
||||
|
||||
it { should_not be_able_to(:read, SDG::Goal) }
|
||||
it { should be_able_to(:read, SDG::Goal) }
|
||||
it { should_not be_able_to(:read, SDG::Target) }
|
||||
|
||||
it { should_not be_able_to(:read, SDG::Manager) }
|
||||
|
||||
@@ -109,7 +109,6 @@ describe Abilities::Moderator do
|
||||
it { should_not be_able_to(:comment_as_administrator, legislation_question) }
|
||||
end
|
||||
|
||||
it { should_not be_able_to(:read, SDG::Goal) }
|
||||
it { should_not be_able_to(:read, SDG::Target) }
|
||||
|
||||
it { should_not be_able_to(:read, SDG::Manager) }
|
||||
|
||||
@@ -23,7 +23,6 @@ describe "Abilities::Organization" do
|
||||
it { should be_able_to(:create, Comment) }
|
||||
it { should_not be_able_to(:vote, Comment) }
|
||||
|
||||
it { should_not be_able_to(:read, SDG::Goal) }
|
||||
it { should_not be_able_to(:read, SDG::Target) }
|
||||
|
||||
it { should_not be_able_to(:read, SDG::Manager) }
|
||||
|
||||
@@ -7,7 +7,6 @@ describe "Abilities::SDG::Manager" do
|
||||
let(:user) { sdg_manager.user }
|
||||
let(:sdg_manager) { create(:sdg_manager) }
|
||||
|
||||
it { should be_able_to(:read, SDG::Goal) }
|
||||
it { should be_able_to(:read, SDG::Target) }
|
||||
it { should be_able_to(:manage, SDG::LocalTarget) }
|
||||
|
||||
|
||||
@@ -40,7 +40,6 @@ describe Abilities::Valuator do
|
||||
it { should_not be_able_to(:comment_valuation, assigned_investment) }
|
||||
end
|
||||
|
||||
it { should_not be_able_to(:read, SDG::Goal) }
|
||||
it { should_not be_able_to(:read, SDG::Target) }
|
||||
|
||||
it { should_not be_able_to(:read, SDG::Manager) }
|
||||
|
||||
19
spec/routing/sdg_routes_spec.rb
Normal file
19
spec/routing/sdg_routes_spec.rb
Normal file
@@ -0,0 +1,19 @@
|
||||
require "rails_helper"
|
||||
|
||||
describe "SDG routes" do
|
||||
it "maps goals to their code" do
|
||||
expect(get("/sdg/goals/1")).to route_to(
|
||||
controller: "sdg/goals",
|
||||
action: "show",
|
||||
code: "1"
|
||||
)
|
||||
end
|
||||
|
||||
it "requires using the code instead of the ID" do
|
||||
expect(get(sdg_goal_path(SDG::Goal[2].code))).to route_to(
|
||||
controller: "sdg/goals",
|
||||
action: "show",
|
||||
code: "2"
|
||||
)
|
||||
end
|
||||
end
|
||||
@@ -92,9 +92,6 @@ describe "Homepage", :admin do
|
||||
expect(page).to have_content "Most active debates"
|
||||
expect(page).to have_css(".debate", count: 3)
|
||||
end
|
||||
|
||||
expect(page).to have_css("#feed_proposals.medium-8")
|
||||
expect(page).to have_css("#feed_debates.medium-4")
|
||||
end
|
||||
|
||||
scenario "Processes", :js do
|
||||
@@ -109,7 +106,7 @@ describe "Homepage", :admin do
|
||||
visit root_path
|
||||
|
||||
expect(page).to have_content "Open processes"
|
||||
expect(page).to have_css(".legislation_process", count: 3)
|
||||
expect(page).to have_css(".legislation-process", count: 3)
|
||||
end
|
||||
|
||||
xscenario "Deactivate"
|
||||
|
||||
88
spec/system/sdg/goals_spec.rb
Normal file
88
spec/system/sdg/goals_spec.rb
Normal file
@@ -0,0 +1,88 @@
|
||||
require "rails_helper"
|
||||
|
||||
describe "SDG Goals", :js do
|
||||
before do
|
||||
Setting["feature.sdg"] = true
|
||||
end
|
||||
|
||||
describe "SDG navigation link" do
|
||||
scenario "is not present when the feature is disabled" do
|
||||
Setting["feature.sdg"] = false
|
||||
|
||||
visit root_path
|
||||
|
||||
within("#navigation_bar") { expect(page).not_to have_link "SDG" }
|
||||
end
|
||||
|
||||
scenario "routes to the goals index" do
|
||||
visit root_path
|
||||
within("#navigation_bar") { click_link "SDG" }
|
||||
|
||||
expect(page).to have_current_path sdg_goals_path
|
||||
end
|
||||
end
|
||||
|
||||
describe "Index" do
|
||||
scenario "has links to SDGs" do
|
||||
visit sdg_goals_path
|
||||
|
||||
click_link "7. Affordable and Clean Energy"
|
||||
|
||||
expect(page).to have_current_path sdg_goal_path(7)
|
||||
end
|
||||
end
|
||||
|
||||
describe "Show" do
|
||||
before do
|
||||
goal = SDG::Goal[15]
|
||||
|
||||
create(:debate, title: "Solar panels", sdg_goals: [SDG::Goal[7]])
|
||||
create(:debate, title: "Hunting ground", sdg_goals: [goal])
|
||||
create(:proposal, title: "Animal farm", sdg_goals: [goal])
|
||||
create(:proposal, title: "Sea farm", sdg_goals: [SDG::Goal[14]])
|
||||
create(:legislation_process, title: "Bullfighting regulations", sdg_goals: [goal])
|
||||
create(:legislation_process, title: "Tax regulations", sdg_goals: [SDG::Goal[10]])
|
||||
end
|
||||
|
||||
scenario "shows the SDG and its related content" do
|
||||
visit sdg_goal_path(15)
|
||||
|
||||
within(".sdg-goal header") { expect(page).to have_content "Life on Land" }
|
||||
|
||||
within ".feed-proposals" do
|
||||
expect(page).to have_content "Animal farm"
|
||||
expect(page).not_to have_content "Sea farm"
|
||||
end
|
||||
|
||||
within ".feed-debates" do
|
||||
expect(page).to have_content "Hunting ground"
|
||||
expect(page).not_to have_content "Solar panels"
|
||||
end
|
||||
|
||||
within ".feed-processes" do
|
||||
expect(page).to have_content "BULLFIGHTING REGULATIONS"
|
||||
expect(page).not_to have_content "TAX REGULATIONS"
|
||||
end
|
||||
end
|
||||
|
||||
scenario "has links to debates and proposals filtered by goal" do
|
||||
visit sdg_goal_path(15)
|
||||
|
||||
click_link "See all debates"
|
||||
|
||||
within "#debates" do
|
||||
expect(page).to have_content "Hunting ground"
|
||||
expect(page).not_to have_content "Solar panels"
|
||||
end
|
||||
|
||||
go_back
|
||||
|
||||
click_link "See all proposals"
|
||||
|
||||
within "#proposals" do
|
||||
expect(page).to have_content "Animal farm"
|
||||
expect(page).not_to have_content "Sea farm"
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
Reference in New Issue
Block a user