Display SDG icons alongside tags
We're using the translation fallbacks for the icons, just like we do for texts. Note we use the `render?` method provided by view_component to make sure the component will not be rendered when certain features are disabled. Also note the `find_asset` method works differently in development and production, and so we use different approaches here.
This commit is contained in:
@@ -945,6 +945,7 @@ footer {
|
||||
.tag-cloud a,
|
||||
.categories a,
|
||||
.geozone a,
|
||||
.sdg-goal-tag-list .more-goals,
|
||||
.sidebar-links a,
|
||||
.tags span {
|
||||
background: #ececec;
|
||||
|
||||
4
app/assets/stylesheets/sdg/goals/icon.scss
Normal file
4
app/assets/stylesheets/sdg/goals/icon.scss
Normal file
@@ -0,0 +1,4 @@
|
||||
.sdg-goal-icon {
|
||||
min-width: 40px;
|
||||
width: 4vw;
|
||||
}
|
||||
14
app/assets/stylesheets/sdg/goals/tag_list.scss
Normal file
14
app/assets/stylesheets/sdg/goals/tag_list.scss
Normal file
@@ -0,0 +1,14 @@
|
||||
.sdg-goal-tag-list {
|
||||
list-style: none;
|
||||
margin-bottom: 0;
|
||||
margin-left: 0;
|
||||
|
||||
li {
|
||||
display: inline-block;
|
||||
margin-bottom: 1ch;
|
||||
|
||||
&:not(:last-child) {
|
||||
padding-right: 1ch;
|
||||
}
|
||||
}
|
||||
}
|
||||
1
app/components/sdg/goals/icon_component.html.erb
Normal file
1
app/components/sdg/goals/icon_component.html.erb
Normal file
@@ -0,0 +1 @@
|
||||
<%= image_tag image_path, alt: image_text, class: "sdg-goal-icon" %>
|
||||
32
app/components/sdg/goals/icon_component.rb
Normal file
32
app/components/sdg/goals/icon_component.rb
Normal file
@@ -0,0 +1,32 @@
|
||||
class SDG::Goals::IconComponent < ApplicationComponent
|
||||
attr_reader :goal
|
||||
delegate :code, to: :goal
|
||||
|
||||
def initialize(goal)
|
||||
@goal = goal
|
||||
end
|
||||
|
||||
def image_path
|
||||
"sdg/#{folder}/goal_#{code}.png"
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def image_text
|
||||
goal.code_and_title
|
||||
end
|
||||
|
||||
def folder
|
||||
[*I18n.fallbacks[I18n.locale], "default"].find do |locale|
|
||||
find_asset("sdg/#{locale}/goal_#{code}.png")
|
||||
end
|
||||
end
|
||||
|
||||
def find_asset(path)
|
||||
if Rails.application.assets
|
||||
Rails.application.assets.find_asset(path)
|
||||
else
|
||||
Rails.application.assets_manifest.assets[path]
|
||||
end
|
||||
end
|
||||
end
|
||||
1
app/components/sdg/goals/tag_list_component.html.erb
Normal file
1
app/components/sdg/goals/tag_list_component.html.erb
Normal file
@@ -0,0 +1 @@
|
||||
<%= link_list(*links, class: "sdg-goal-tag-list") %>
|
||||
57
app/components/sdg/goals/tag_list_component.rb
Normal file
57
app/components/sdg/goals/tag_list_component.rb
Normal file
@@ -0,0 +1,57 @@
|
||||
class SDG::Goals::TagListComponent < ApplicationComponent
|
||||
attr_reader :record, :limit
|
||||
delegate :link_list, to: :helpers
|
||||
|
||||
def initialize(record, limit: nil)
|
||||
@record = record
|
||||
@limit = limit
|
||||
end
|
||||
|
||||
def render?
|
||||
SDG::ProcessEnabled.new(record.class.name).enabled?
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def links
|
||||
[*goal_links, see_more_link]
|
||||
end
|
||||
|
||||
def goal_links
|
||||
goals.limit(limit).map do |goal|
|
||||
[
|
||||
render(SDG::Goals::IconComponent.new(goal)),
|
||||
index_by_goal(goal),
|
||||
title: filter_text(goal)
|
||||
]
|
||||
end
|
||||
end
|
||||
|
||||
def goals
|
||||
record.sdg_goals.order(:code)
|
||||
end
|
||||
|
||||
def see_more_link
|
||||
return unless limit && count_out_of_limit > 0
|
||||
|
||||
[
|
||||
"#{count_out_of_limit}+",
|
||||
polymorphic_path(record),
|
||||
class: "more-goals", title: t("sdg.goals.filter.more", count: count_out_of_limit)
|
||||
]
|
||||
end
|
||||
|
||||
def index_by_goal(goal)
|
||||
polymorphic_path(record.class, advanced_search: { goal: goal.code })
|
||||
end
|
||||
|
||||
def filter_text(goal)
|
||||
t("sdg.goals.filter.link",
|
||||
resources: record.model_name.human(count: :other),
|
||||
code: goal.code)
|
||||
end
|
||||
|
||||
def count_out_of_limit
|
||||
goals.size - limit
|
||||
end
|
||||
end
|
||||
@@ -16,3 +16,5 @@
|
||||
<% end %>
|
||||
</ul>
|
||||
<% end %>
|
||||
|
||||
<%= render SDG::Goals::TagListComponent.new(taggable, limit: limit) %>
|
||||
|
||||
@@ -45,6 +45,7 @@ data:
|
||||
- config/locales/%{locale}/user_groups.yml
|
||||
- config/locales/%{locale}/i18n.yml
|
||||
- config/locales/%{locale}/milestones.yml
|
||||
- config/locales/%{locale}/sdg.yml
|
||||
- config/locales/%{locale}/sdg_management.yml
|
||||
- config/locales/%{locale}/stats.yml
|
||||
|
||||
@@ -217,6 +218,7 @@ ignore_unused:
|
||||
- landings.cambia_tu_ciudad.*
|
||||
- "seeds.settings.*"
|
||||
- "dashboard.polls.*.submit"
|
||||
- "sdg.goals.goal_*"
|
||||
####
|
||||
## Exclude these keys from the `i18n-tasks eq-base" report:
|
||||
# ignore_eq_base:
|
||||
|
||||
@@ -424,3 +424,8 @@ en:
|
||||
title: "By 2020, enhance capacity-building support to developing countries, including for least developed countries and small island developing States, to increase significantly the availability of high-quality, timely and reliable data disaggregated by income, gender, age, race, ethnicity, migratory status, disability, geographic location and other characteristics relevant in national contexts."
|
||||
target_17_19:
|
||||
title: "By 2030, build on existing initiatives to develop measurements of progress on sustainable development that complement gross domestic product, and support statistical capacity-building in developing countries."
|
||||
filter:
|
||||
link: "See all %{resources} related to goal %{code}"
|
||||
more:
|
||||
one: "One more goal"
|
||||
other: "%{count} more goals"
|
||||
|
||||
@@ -424,3 +424,8 @@ es:
|
||||
title: "De aquí a 2020, mejorar el apoyo a la creación de capacidad prestado a los países en desarrollo, incluidos los países menos adelantados y los pequeños Estados insulares en desarrollo, para aumentar significativamente la disponibilidad de datos oportunos, fiables y de gran calidad desglosados por ingresos, sexo, edad, raza, origen étnico, estatus migratorio, discapacidad, ubicación geográfica y otras características pertinentes en los contextos nacionales."
|
||||
target_17_19:
|
||||
title: "De aquí a 2030, aprovechar las iniciativas existentes para elaborar indicadores que permitan medir los progresos en materia de desarrollo sostenible y complementen el producto interno bruto, y apoyar la creación de capacidad estadística en los países en desarrollo."
|
||||
filter:
|
||||
link: "Ver %{resources} del objetivo %{code}"
|
||||
more:
|
||||
one: "Un objetivo más"
|
||||
other: "%{count} objetivos más"
|
||||
|
||||
19
spec/components/sdg/goals/icon_component_spec.rb
Normal file
19
spec/components/sdg/goals/icon_component_spec.rb
Normal file
@@ -0,0 +1,19 @@
|
||||
require "rails_helper"
|
||||
|
||||
describe SDG::Goals::IconComponent do
|
||||
describe "#image_path" do
|
||||
let(:component) { SDG::Goals::IconComponent.new(SDG::Goal[8]) }
|
||||
|
||||
it "returns icons for the first fallback language with icons" do
|
||||
allow(I18n).to receive(:fallbacks).and_return({ en: [:es, :de] })
|
||||
|
||||
expect(component.image_path).to eq "sdg/es/goal_8.png"
|
||||
end
|
||||
|
||||
it "returns the default icons when no fallback language has icons" do
|
||||
allow(I18n).to receive(:fallbacks).and_return({})
|
||||
|
||||
expect(component.image_path).to eq "sdg/default/goal_8.png"
|
||||
end
|
||||
end
|
||||
end
|
||||
63
spec/components/sdg/goals/tag_list_component_spec.rb
Normal file
63
spec/components/sdg/goals/tag_list_component_spec.rb
Normal file
@@ -0,0 +1,63 @@
|
||||
require "rails_helper"
|
||||
|
||||
describe SDG::Goals::TagListComponent, type: :component do
|
||||
let(:debate) { create(:debate, sdg_goals: [SDG::Goal[1], SDG::Goal[3]]) }
|
||||
let(:component) { SDG::Goals::TagListComponent.new(debate) }
|
||||
|
||||
before do
|
||||
Setting["feature.sdg"] = true
|
||||
Setting["sdg.process.debates"] = true
|
||||
end
|
||||
|
||||
it "does not render when the feature is disabled" do
|
||||
Setting["feature.sdg"] = false
|
||||
|
||||
render_inline component
|
||||
|
||||
expect(page).not_to have_css "li"
|
||||
end
|
||||
|
||||
it "does not render when the SDG process feature is disabled" do
|
||||
Setting["sdg.process.debates"] = false
|
||||
|
||||
render_inline component
|
||||
|
||||
expect(page).not_to have_css "li"
|
||||
end
|
||||
|
||||
it "renders a list of goals" do
|
||||
render_inline component
|
||||
|
||||
expect(page).to have_css "li", count: 2
|
||||
end
|
||||
|
||||
it "renders links for each goal" do
|
||||
render_inline component
|
||||
|
||||
expect(page).to have_selector "a", count: 2
|
||||
expect(page).to have_link "1. No Poverty",
|
||||
title: "See all Debates related to goal 1",
|
||||
href: "/debates?advanced_search#{CGI.escape("[goal]")}=1"
|
||||
expect(page).to have_link "3. Good Health and Well-Being",
|
||||
title: "See all Debates related to goal 3",
|
||||
href: "/debates?advanced_search#{CGI.escape("[goal]")}=3"
|
||||
end
|
||||
|
||||
it "orders goals by code" do
|
||||
render_inline component
|
||||
|
||||
expect(page.first("a")[:title]).to end_with "goal 1"
|
||||
end
|
||||
|
||||
it "renders a link for more goals when out of limit" do
|
||||
component = SDG::Goals::TagListComponent.new(debate, limit: 1)
|
||||
|
||||
render_inline component
|
||||
|
||||
expect(page).to have_selector "a", count: 2
|
||||
expect(page).to have_link "1. No Poverty"
|
||||
expect(page).to have_link "1+",
|
||||
title: "One more goal",
|
||||
href: "/debates/#{debate.to_param}"
|
||||
end
|
||||
end
|
||||
Reference in New Issue
Block a user