diff --git a/app/assets/stylesheets/participation.scss b/app/assets/stylesheets/participation.scss
index 9c014addc..d47dda44e 100644
--- a/app/assets/stylesheets/participation.scss
+++ b/app/assets/stylesheets/participation.scss
@@ -606,12 +606,6 @@
img {
max-width: 12rem;
}
-
- .budget-investment-content {
- ul {
- margin-bottom: 0;
- }
- }
}
}
diff --git a/app/assets/stylesheets/sdg/goals/filter_links.scss b/app/assets/stylesheets/sdg/goals/tag_cloud.scss
similarity index 69%
rename from app/assets/stylesheets/sdg/goals/filter_links.scss
rename to app/assets/stylesheets/sdg/goals/tag_cloud.scss
index 914c4e7b0..8008cfb64 100644
--- a/app/assets/stylesheets/sdg/goals/filter_links.scss
+++ b/app/assets/stylesheets/sdg/goals/tag_cloud.scss
@@ -1,4 +1,4 @@
-.sdg-goal-filter-links {
+.sdg-goal-tag-cloud {
.sdg-goal-tag-list {
@extend %sdg-goal-list;
diff --git a/app/components/concerns/sdg/tag_list.rb b/app/components/concerns/sdg/tag_list.rb
index a27225370..59ba6d4e3 100644
--- a/app/components/concerns/sdg/tag_list.rb
+++ b/app/components/concerns/sdg/tag_list.rb
@@ -1,50 +1,31 @@
module SDG::TagList
extend ActiveSupport::Concern
- attr_reader :record_or_name, :limit
- delegate :link_list, to: :helpers
+ attr_reader :record, :limit
- def initialize(record_or_name, limit: nil)
- @record_or_name = record_or_name
+ def initialize(record, limit: nil)
+ @record = record
@limit = limit
end
def render?
- process.enabled?
+ SDG::ProcessEnabled.new(record).enabled?
end
- def see_more_link(collection)
- count = count_out_of_limit(collection)
+ def tag_records
+ tags = record.send(association_name)
- if count > 0
- [
- "#{count}+",
- polymorphic_path(record),
- class: "more-#{i18n_namespace}", title: t("sdg.#{i18n_namespace}.filter.more", count: count)
- ]
+ if tags.respond_to?(:limit)
+ tags.order(:code).limit(limit)
+ else
+ tags.sort[0..(limit.to_i - 1)]
end
end
- def filter_text(goal_or_target)
- t("sdg.#{i18n_namespace}.filter.link",
- resources: model.model_name.human(count: :other),
- code: goal_or_target.code)
+ def see_more_link
+ render Shared::SeeMoreLinkComponent.new(record, association_name, limit: limit)
end
- def index_by(advanced_search)
- polymorphic_path(model, advanced_search: advanced_search)
- end
-
- def count_out_of_limit(collection)
- return 0 unless limit
-
- collection.size - limit
- end
-
- def process
- @process ||= SDG::ProcessEnabled.new(record_or_name)
- end
-
- def model
- process.name.constantize
+ def association_name
+ raise NotImplementedError, "method must be implemented in the included class"
end
end
diff --git a/app/components/sdg/filter_links_component.html.erb b/app/components/sdg/filter_links_component.html.erb
new file mode 100644
index 000000000..874755b8a
--- /dev/null
+++ b/app/components/sdg/filter_links_component.html.erb
@@ -0,0 +1 @@
+<%= link_list(*links, class: "sdg-#{parameter_name}-tag-list") %>
diff --git a/app/components/sdg/filter_links_component.rb b/app/components/sdg/filter_links_component.rb
new file mode 100644
index 000000000..80cc6b548
--- /dev/null
+++ b/app/components/sdg/filter_links_component.rb
@@ -0,0 +1,49 @@
+class SDG::FilterLinksComponent < ApplicationComponent
+ attr_reader :records, :related_model, :see_more_link
+ delegate :link_list, to: :helpers
+
+ def initialize(records, related_model, see_more_link: nil)
+ @records = records
+ @related_model = related_model
+ @see_more_link = see_more_link
+ end
+
+ def links
+ [*sdg_links, see_more_link]
+ end
+
+ private
+
+ def sdg_links
+ records.map do |goal_or_target|
+ [
+ render(SDG::TagComponent.new(goal_or_target)),
+ index_by(parameter_name => goal_or_target.code),
+ title: filter_text(goal_or_target),
+ data: { code: goal_or_target.code }
+ ]
+ end
+ end
+
+ def filter_text(goal_or_target)
+ t("sdg.#{i18n_namespace}.filter.link",
+ resources: related_model.model_name.human(count: :other),
+ code: goal_or_target.code)
+ end
+
+ def index_by(advanced_search)
+ polymorphic_path(related_model, advanced_search: advanced_search)
+ end
+
+ def i18n_namespace
+ parameter_name.pluralize
+ end
+
+ def parameter_name
+ if records.first.is_a?(SDG::Goal)
+ "goal"
+ else
+ "target"
+ end
+ end
+end
diff --git a/app/components/sdg/goals/filter_links_component.html.erb b/app/components/sdg/goals/filter_links_component.html.erb
deleted file mode 100644
index dc4b3c122..000000000
--- a/app/components/sdg/goals/filter_links_component.html.erb
+++ /dev/null
@@ -1,5 +0,0 @@
-
-
-
- <%= render SDG::Goals::TagListComponent.new(class_name) %>
-
diff --git a/app/components/sdg/goals/plain_tag_list_component.rb b/app/components/sdg/goals/plain_tag_list_component.rb
index 8b60b692b..5e8b4ff53 100644
--- a/app/components/sdg/goals/plain_tag_list_component.rb
+++ b/app/components/sdg/goals/plain_tag_list_component.rb
@@ -3,31 +3,17 @@ class SDG::Goals::PlainTagListComponent < ApplicationComponent
private
- def record
- record_or_name
- end
-
def tags
- [*goal_tags, see_more_link].compact
- end
-
- def see_more_link
- options = super(goals)
-
- link_to(*options) if options.present?
+ [*goal_tags, see_more_link].select(&:present?)
end
def goal_tags
- goals.order(:code).limit(limit).map do |goal|
- render SDG::Goals::IconComponent.new(goal)
+ tag_records.map do |goal|
+ render SDG::TagComponent.new(goal)
end
end
- def goals
- record.sdg_goals
- end
-
- def i18n_namespace
- "goals"
+ def association_name
+ :sdg_goals
end
end
diff --git a/app/components/sdg/goals/tag_cloud_component.html.erb b/app/components/sdg/goals/tag_cloud_component.html.erb
new file mode 100644
index 000000000..d44f9768f
--- /dev/null
+++ b/app/components/sdg/goals/tag_cloud_component.html.erb
@@ -0,0 +1,5 @@
+
+
+
+ <%= render SDG::FilterLinksComponent.new(goals, class_name.constantize) %>
+
diff --git a/app/components/sdg/goals/filter_links_component.rb b/app/components/sdg/goals/tag_cloud_component.rb
similarity index 68%
rename from app/components/sdg/goals/filter_links_component.rb
rename to app/components/sdg/goals/tag_cloud_component.rb
index 3d4affc78..0ffac19b9 100644
--- a/app/components/sdg/goals/filter_links_component.rb
+++ b/app/components/sdg/goals/tag_cloud_component.rb
@@ -1,4 +1,4 @@
-class SDG::Goals::FilterLinksComponent < ApplicationComponent
+class SDG::Goals::TagCloudComponent < ApplicationComponent
attr_reader :class_name
def initialize(class_name)
@@ -14,4 +14,8 @@ class SDG::Goals::FilterLinksComponent < ApplicationComponent
def heading
t("sdg.goals.filter.heading")
end
+
+ def goals
+ SDG::Goal.order(:code)
+ end
end
diff --git a/app/components/sdg/goals/tag_list_component.html.erb b/app/components/sdg/goals/tag_list_component.html.erb
index 344d54181..1ddd0dd2d 100644
--- a/app/components/sdg/goals/tag_list_component.html.erb
+++ b/app/components/sdg/goals/tag_list_component.html.erb
@@ -1 +1 @@
-<%= link_list(*links, class: "sdg-goal-tag-list") %>
+<%= render SDG::FilterLinksComponent.new(tag_records, related_model, see_more_link: see_more_link) %>
diff --git a/app/components/sdg/goals/tag_list_component.rb b/app/components/sdg/goals/tag_list_component.rb
index 391e07f55..fb9c181e9 100644
--- a/app/components/sdg/goals/tag_list_component.rb
+++ b/app/components/sdg/goals/tag_list_component.rb
@@ -3,33 +3,11 @@ class SDG::Goals::TagListComponent < ApplicationComponent
private
- def record
- record_or_name if record_or_name.respond_to?(:sdg_goals)
+ def association_name
+ :sdg_goals
end
- def links
- [*goal_links, see_more_link(goals)]
- end
-
- def goal_links
- goals.order(:code).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 || SDG::Goal.all
- end
-
- def index_by_goal(goal)
- index_by(goal: goal.code)
- end
-
- def i18n_namespace
- "goals"
+ def related_model
+ record.class
end
end
diff --git a/app/components/sdg/tag_component.html.erb b/app/components/sdg/tag_component.html.erb
new file mode 100644
index 000000000..bfbda2748
--- /dev/null
+++ b/app/components/sdg/tag_component.html.erb
@@ -0,0 +1 @@
+<%= text -%>
diff --git a/app/components/sdg/tag_component.rb b/app/components/sdg/tag_component.rb
new file mode 100644
index 000000000..366e5005a
--- /dev/null
+++ b/app/components/sdg/tag_component.rb
@@ -0,0 +1,15 @@
+class SDG::TagComponent < ApplicationComponent
+ attr_reader :goal_or_target
+
+ def initialize(goal_or_target)
+ @goal_or_target = goal_or_target
+ end
+
+ def text
+ if goal_or_target.is_a?(SDG::Goal)
+ render SDG::Goals::IconComponent.new(goal_or_target)
+ else
+ "#{SDG::Target.model_name.human} #{goal_or_target.code}"
+ end
+ end
+end
diff --git a/app/components/sdg/targets/plain_tag_list_component.rb b/app/components/sdg/targets/plain_tag_list_component.rb
index b24792cb2..78ccc4b42 100644
--- a/app/components/sdg/targets/plain_tag_list_component.rb
+++ b/app/components/sdg/targets/plain_tag_list_component.rb
@@ -3,35 +3,17 @@ class SDG::Targets::PlainTagListComponent < ApplicationComponent
private
- def record
- record_or_name
- end
-
def tags
- [*target_tags, see_more_link].compact
- end
-
- def see_more_link
- options = super(targets)
-
- link_to(*options) if options.present?
+ [*target_tags, see_more_link].select(&:present?)
end
def target_tags
- targets.sort[0..(limit.to_i - 1)].map do |target|
- tag.span(text(target), data: { code: target.code })
+ tag_records.map do |target|
+ tag.span(render(SDG::TagComponent.new(target)), data: { code: target.code })
end
end
- def targets
- record.sdg_targets
- end
-
- def text(target)
- "#{SDG::Target.model_name.human} #{target.code}"
- end
-
- def i18n_namespace
- "targets"
+ def association_name
+ :sdg_targets
end
end
diff --git a/app/components/sdg/targets/tag_list_component.html.erb b/app/components/sdg/targets/tag_list_component.html.erb
index 1c97ade36..1ddd0dd2d 100644
--- a/app/components/sdg/targets/tag_list_component.html.erb
+++ b/app/components/sdg/targets/tag_list_component.html.erb
@@ -1 +1 @@
-<%= link_list(*links, class: "sdg-target-tag-list") %>
+<%= render SDG::FilterLinksComponent.new(tag_records, related_model, see_more_link: see_more_link) %>
diff --git a/app/components/sdg/targets/tag_list_component.rb b/app/components/sdg/targets/tag_list_component.rb
index cb79f80b6..2d8e1a92b 100644
--- a/app/components/sdg/targets/tag_list_component.rb
+++ b/app/components/sdg/targets/tag_list_component.rb
@@ -3,34 +3,11 @@ class SDG::Targets::TagListComponent < ApplicationComponent
private
- def record
- record_or_name
+ def association_name
+ :sdg_targets
end
- def links
- [*target_links, see_more_link(targets)]
- end
-
- def target_links
- targets.sort[0..(limit.to_i - 1)].map do |target|
- [
- "#{SDG::Target.model_name.human} #{target.code}",
- index_by_target(target),
- title: filter_text(target),
- data: { code: target.code }
- ]
- end
- end
-
- def targets
- record.sdg_targets
- end
-
- def index_by_target(target)
- index_by(target: target.code)
- end
-
- def i18n_namespace
- "targets"
+ def related_model
+ record.class
end
end
diff --git a/app/components/shared/see_more_link_component.html.erb b/app/components/shared/see_more_link_component.html.erb
new file mode 100644
index 000000000..dd78b17a5
--- /dev/null
+++ b/app/components/shared/see_more_link_component.html.erb
@@ -0,0 +1,3 @@
+<% if count_out_of_limit > 0 %>
+ <%= link_to text, url, class: html_class, title: title %>
+<% end %>
diff --git a/app/components/shared/see_more_link_component.rb b/app/components/shared/see_more_link_component.rb
new file mode 100644
index 000000000..339f66384
--- /dev/null
+++ b/app/components/shared/see_more_link_component.rb
@@ -0,0 +1,37 @@
+class Shared::SeeMoreLinkComponent < ApplicationComponent
+ attr_reader :record, :association_name, :limit
+
+ def initialize(record, association_name, limit: nil)
+ @record = record
+ @association_name = association_name
+ @limit = limit
+ end
+
+ private
+
+ def text
+ "#{count_out_of_limit}+"
+ end
+
+ def url
+ polymorphic_path(record)
+ end
+
+ def title
+ t("#{i18n_namespace}.filter.more", count: count_out_of_limit)
+ end
+
+ def count_out_of_limit
+ return 0 unless limit
+
+ record.send(association_name).size - limit
+ end
+
+ def i18n_namespace
+ association_name.to_s.tr("_", ".")
+ end
+
+ def html_class
+ "more-#{i18n_namespace.split(".").last}"
+ end
+end
diff --git a/app/components/shared/tag_list_component.html.erb b/app/components/shared/tag_list_component.html.erb
new file mode 100644
index 000000000..217f9855c
--- /dev/null
+++ b/app/components/shared/tag_list_component.html.erb
@@ -0,0 +1 @@
+<%= link_list(*links, class: "tags", id: "tags_#{dom_id(taggable)}") %>
diff --git a/app/components/shared/tag_list_component.rb b/app/components/shared/tag_list_component.rb
new file mode 100644
index 000000000..79510718e
--- /dev/null
+++ b/app/components/shared/tag_list_component.rb
@@ -0,0 +1,37 @@
+class Shared::TagListComponent < ApplicationComponent
+ attr_reader :taggable, :limit
+ delegate :link_list, to: :helpers
+
+ def initialize(taggable, limit:)
+ @taggable = taggable
+ @limit = limit
+ end
+
+ private
+
+ def links
+ [*tag_links, see_more_link]
+ end
+
+ def tag_links
+ taggable.tag_list_with_limit(limit).map do |tag|
+ [
+ sanitize(tag.name),
+ taggables_path(taggable, tag.name)
+ ]
+ end
+ end
+
+ def see_more_link
+ render Shared::SeeMoreLinkComponent.new(taggable, :tags, limit: limit)
+ end
+
+ def taggables_path(taggable, tag_name)
+ case taggable.class.name
+ when "Legislation::Proposal"
+ legislation_process_proposals_path(taggable.process, search: tag_name)
+ else
+ polymorphic_path(taggable.class, search: tag_name)
+ end
+ end
+end
diff --git a/app/helpers/link_list_helper.rb b/app/helpers/link_list_helper.rb
index f3e00d1bb..5af374fae 100644
--- a/app/helpers/link_list_helper.rb
+++ b/app/helpers/link_list_helper.rb
@@ -1,11 +1,15 @@
module LinkListHelper
def link_list(*links, **options)
- return "" if links.compact.empty?
+ return "" if links.select(&:present?).empty?
tag.ul(options) do
- safe_join(links.compact.map do |text, url, current = false, **link_options|
+ safe_join(links.select(&:present?).map do |text, url, current = false, **link_options|
tag.li(({ "aria-current": true } if current)) do
- link_to text, url, link_options
+ if url
+ link_to text, url, link_options
+ else
+ text
+ end
end
end, "\n")
end
diff --git a/app/helpers/tags_helper.rb b/app/helpers/tags_helper.rb
deleted file mode 100644
index 464a155d0..000000000
--- a/app/helpers/tags_helper.rb
+++ /dev/null
@@ -1,10 +0,0 @@
-module TagsHelper
- def taggables_path(taggable, tag_name)
- case taggable.class.name
- when "Legislation::Proposal"
- legislation_process_proposals_path(taggable.process, search: tag_name)
- else
- polymorphic_path(taggable.class, search: tag_name)
- end
- end
-end
diff --git a/app/models/concerns/taggable.rb b/app/models/concerns/taggable.rb
index c840dd97e..73889ae81 100644
--- a/app/models/concerns/taggable.rb
+++ b/app/models/concerns/taggable.rb
@@ -12,13 +12,6 @@ module Taggable
tags.sort { |a, b| b.taggings_count <=> a.taggings_count }[0, limit]
end
- def tags_count_out_of_limit(limit = nil)
- return 0 unless limit
-
- count = tags.size - limit
- count < 0 ? 0 : count
- end
-
def max_number_of_tags
errors.add(:tag_list, :less_than_or_equal_to, count: 6) if tag_list.count > 6
end
diff --git a/app/views/shared/_tag_cloud.html.erb b/app/views/shared/_tag_cloud.html.erb
index 05507c5e2..1983f262a 100644
--- a/app/views/shared/_tag_cloud.html.erb
+++ b/app/views/shared/_tag_cloud.html.erb
@@ -13,4 +13,4 @@
-<%= render SDG::Goals::FilterLinksComponent.new(taggable) %>
+<%= render SDG::Goals::TagCloudComponent.new(taggable) %>
diff --git a/app/views/shared/_tags.html.erb b/app/views/shared/_tags.html.erb
index f4ac1773e..bb868393e 100644
--- a/app/views/shared/_tags.html.erb
+++ b/app/views/shared/_tags.html.erb
@@ -1,20 +1,4 @@
<%- limit ||= nil %>
<%= render SDG::TagListComponent.new(taggable, limit: limit) %>
-
-<% if taggable.tags.any? %>
-
-<% end %>
+<%= render Shared::TagListComponent.new(taggable, limit: limit) %>
diff --git a/config/i18n-tasks.yml b/config/i18n-tasks.yml
index 37a8abda1..dd76cacec 100644
--- a/config/i18n-tasks.yml
+++ b/config/i18n-tasks.yml
@@ -221,6 +221,7 @@ ignore_unused:
- "sdg.goals.goal_*"
- "sdg.*.filter.more.*"
- "sdg_management.relations.index.filter*"
+ - "tags.filter.more.*"
####
## Exclude these keys from the `i18n-tasks eq-base" report:
# ignore_eq_base:
diff --git a/config/locales/en/general.yml b/config/locales/en/general.yml
index a150efd5a..3985effb9 100644
--- a/config/locales/en/general.yml
+++ b/config/locales/en/general.yml
@@ -973,3 +973,8 @@ en:
create:
enqueue_remote_translation: Translations have been correctly requested.
button: Translate page
+ tags:
+ filter:
+ more:
+ one: "One more tag"
+ other: "%{count} more tags"
diff --git a/config/locales/es/general.yml b/config/locales/es/general.yml
index c9e011657..9b0e15134 100644
--- a/config/locales/es/general.yml
+++ b/config/locales/es/general.yml
@@ -973,3 +973,8 @@ es:
create:
enqueue_remote_translation: Se han solicitado correctamente las traducciones.
button: Traducir página
+ tags:
+ filter:
+ more:
+ one: "Una etiqueta más"
+ other: "%{count} etiquetas más"
diff --git a/spec/components/sdg/goals/filter_links_component_spec.rb b/spec/components/sdg/goals/filter_links_component_spec.rb
deleted file mode 100644
index 408e8ee1b..000000000
--- a/spec/components/sdg/goals/filter_links_component_spec.rb
+++ /dev/null
@@ -1,25 +0,0 @@
-require "rails_helper"
-
-describe SDG::Goals::FilterLinksComponent, type: :component do
- before do
- Setting["feature.sdg"] = true
- Setting["sdg.process.debates"] = true
- Setting["sdg.process.proposals"] = true
- end
-
- it "renders a title" do
- component = SDG::Goals::FilterLinksComponent.new("Debate")
-
- render_inline component
-
- expect(page).to have_content "Filters by SDG"
- end
-
- it "renders all goals" do
- component = SDG::Goals::FilterLinksComponent.new("Proposal")
-
- render_inline component
-
- expect(page).to have_css ".sdg-goal-icon", count: 17
- end
-end
diff --git a/spec/components/sdg/goals/tag_cloud_component_spec.rb b/spec/components/sdg/goals/tag_cloud_component_spec.rb
new file mode 100644
index 000000000..6738ba0da
--- /dev/null
+++ b/spec/components/sdg/goals/tag_cloud_component_spec.rb
@@ -0,0 +1,27 @@
+require "rails_helper"
+
+describe SDG::Goals::TagCloudComponent, type: :component do
+ before do
+ Setting["feature.sdg"] = true
+ Setting["sdg.process.debates"] = true
+ Setting["sdg.process.proposals"] = true
+ end
+
+ it "renders a title" do
+ component = SDG::Goals::TagCloudComponent.new("Debate")
+
+ render_inline component
+
+ expect(page).to have_content "Filters by SDG"
+ end
+
+ it "renders all goals ordered by code" do
+ component = SDG::Goals::TagCloudComponent.new("Proposal")
+
+ render_inline component
+
+ expect(page).to have_selector ".sdg-goal-icon", count: 17
+ expect(page.first("a")[:title]).to end_with "goal 1"
+ expect(page.all("a").last[:title]).to end_with "goal 17"
+ end
+end
diff --git a/spec/components/sdg/goals/tag_list_component_spec.rb b/spec/components/sdg/goals/tag_list_component_spec.rb
index 6f1d3f12b..493dc9dbc 100644
--- a/spec/components/sdg/goals/tag_list_component_spec.rb
+++ b/spec/components/sdg/goals/tag_list_component_spec.rb
@@ -60,16 +60,4 @@ describe SDG::Goals::TagListComponent, type: :component do
title: "One more goal",
href: "/debates/#{debate.to_param}"
end
-
- context "given a class name" do
- let(:component) { SDG::Goals::TagListComponent.new("Debate") }
-
- it "renders all goals ordered by code" do
- render_inline component
-
- expect(page).to have_selector "li", count: 17
- expect(page.first("a")[:title]).to end_with "goal 1"
- expect(page.all("a").last[:title]).to end_with "goal 17"
- end
- end
end
diff --git a/spec/helpers/link_list_helper_spec.rb b/spec/helpers/link_list_helper_spec.rb
index 31ff73768..7626d0198 100644
--- a/spec/helpers/link_list_helper_spec.rb
+++ b/spec/helpers/link_list_helper_spec.rb
@@ -19,6 +19,15 @@ describe LinkListHelper do
expect(list).to be_html_safe
end
+ it "accepts anchor tags" do
+ list = helper.link_list(link_to("Home", "/"), ["Info", "/info"], class: "menu")
+
+ expect(list).to eq ''
+ expect(list).to be_html_safe
+ end
+
it "accepts options for links" do
render helper.link_list(["Home", "/", class: "root"], ["Info", "/info", id: "info"])
@@ -30,7 +39,15 @@ describe LinkListHelper do
it "ignores nil entries" do
render helper.link_list(["Home", "/", class: "root"], nil, ["Info", "/info", id: "info"])
- expect(page).to have_css "a", count: 2
+ expect(page).to have_css "li", count: 2
+ expect(page).to have_css "a.root", count: 1, exact_text: "Home"
+ expect(page).to have_css "a#info", count: 1, exact_text: "Info"
+ end
+
+ it "ignores empty entries" do
+ render helper.link_list(["Home", "/", class: "root"], "", ["Info", "/info", id: "info"])
+
+ expect(page).to have_css "li", count: 2
expect(page).to have_css "a.root", count: 1, exact_text: "Home"
expect(page).to have_css "a#info", count: 1, exact_text: "Info"
end