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:
Javi Martín
2021-01-01 15:40:18 +01:00
parent 53af5749b9
commit ceed3c18d3
13 changed files with 206 additions and 0 deletions

View File

@@ -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;

View File

@@ -0,0 +1,4 @@
.sdg-goal-icon {
min-width: 40px;
width: 4vw;
}

View 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;
}
}
}

View File

@@ -0,0 +1 @@
<%= image_tag image_path, alt: image_text, class: "sdg-goal-icon" %>

View 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

View File

@@ -0,0 +1 @@
<%= link_list(*links, class: "sdg-goal-tag-list") %>

View 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

View File

@@ -16,3 +16,5 @@
<% end %>
</ul>
<% end %>
<%= render SDG::Goals::TagListComponent.new(taggable, limit: limit) %>

View File

@@ -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:

View File

@@ -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"

View File

@@ -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"

View 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

View 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