decidim-participatory_processes 0.13.1 → 0.14.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/app/cells/decidim/participatory_processes/content_blocks/highlighted_processes/_all_processes.erb +6 -0
- data/app/cells/decidim/participatory_processes/content_blocks/highlighted_processes/show.erb +32 -0
- data/app/cells/decidim/participatory_processes/content_blocks/highlighted_processes/single_process.erb +39 -0
- data/app/cells/decidim/participatory_processes/content_blocks/highlighted_processes_cell.rb +40 -0
- data/app/cells/decidim/participatory_processes/process_cell.rb +1 -1
- data/app/cells/decidim/participatory_processes/process_filters/filter_tabs.erb +16 -0
- data/app/cells/decidim/participatory_processes/process_filters/show.erb +13 -0
- data/app/cells/decidim/participatory_processes/process_filters_cell.rb +57 -0
- data/app/cells/decidim/participatory_processes/process_group_cell.rb +1 -1
- data/app/cells/decidim/participatory_processes/process_group_m_cell.rb +1 -1
- data/app/cells/decidim/participatory_processes/process_m/tags.erb +8 -6
- data/app/controllers/decidim/participatory_processes/admin/participatory_space_private_users_controller.rb +0 -4
- data/app/controllers/decidim/participatory_processes/participatory_processes_controller.rb +23 -3
- data/app/forms/decidim/participatory_processes/admin/participatory_process_step_form.rb +2 -12
- data/app/models/decidim/participatory_process.rb +4 -4
- data/app/queries/decidim/participatory_processes/filtered_participatory_process_groups.rb +2 -2
- data/app/views/decidim/participatory_processes/admin/participatory_process_copies/new.html.erb +1 -1
- data/app/views/decidim/participatory_processes/participatory_process_groups/show.html.erb +1 -2
- data/app/views/decidim/participatory_processes/participatory_processes/_order_by_processes.html.erb +1 -0
- data/app/views/decidim/participatory_processes/participatory_processes/index.html.erb +9 -1
- data/app/views/decidim/participatory_processes/participatory_processes/index.js.erb +1 -1
- data/app/views/decidim/participatory_processes/participatory_processes/show.html.erb +9 -0
- data/app/views/layouts/decidim/participatory_process.html.erb +0 -2
- data/config/locales/ca.yml +36 -14
- data/config/locales/en.yml +36 -14
- data/config/locales/es-PY.yml +36 -14
- data/config/locales/es.yml +36 -14
- data/config/locales/eu.yml +36 -14
- data/config/locales/fi.yml +80 -58
- data/config/locales/fr.yml +32 -10
- data/config/locales/gl.yml +36 -14
- data/config/locales/hu.yml +371 -0
- data/config/locales/it.yml +36 -14
- data/config/locales/nl.yml +36 -14
- data/config/locales/pl.yml +46 -16
- data/config/locales/pt-BR.yml +42 -20
- data/config/locales/pt.yml +36 -14
- data/config/locales/ru.yml +49 -19
- data/config/locales/sv.yml +105 -83
- data/config/locales/uk.yml +51 -21
- data/lib/decidim/participatory_processes/admin_engine.rb +1 -0
- data/lib/decidim/participatory_processes/engine.rb +5 -16
- data/lib/decidim/participatory_processes/participatory_space.rb +12 -4
- data/lib/decidim/participatory_processes/test/factories.rb +12 -12
- data/lib/decidim/participatory_processes/version.rb +1 -1
- metadata +18 -11
- data/app/views/decidim/participatory_processes/_order_by_processes.html.erb +0 -12
- data/app/views/decidim/participatory_processes/pages/home/_highlighted_processes.html.erb +0 -35
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6a8ad562172fbb6e2f42b1772f225fd64a96aedc0ebf86fd3c1f603eae18dab5
|
4
|
+
data.tar.gz: 808814fd81f14405f847f71fff76d0195146ba0be87604075a68d3102fe00ec1
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b78ec048fe1dcd7ee0d60cb67a253b6a38b639c360eb962acfe1e88ddcb4874952564b78275a42ffc3aa9ebc1598c0b804f6f317f8b5c598ba19bd3140971d79
|
7
|
+
data.tar.gz: eeca8f2c950844b9fbd1297ee14d3ef420d658761dd613eab383e53f63fe40adbd7af589ad5658d5a6c48a66716c9feb3a8fcd9cef939cc30ba4fa7c889849a3
|
@@ -0,0 +1,6 @@
|
|
1
|
+
<div class="row" id="see-all-processes">
|
2
|
+
<div class="columns small-centered small-12
|
3
|
+
smallmedium-8 medium-6 large-4">
|
4
|
+
<%= link_to t("see_all_processes", scope: i18n_scope), decidim_participatory_processes.participatory_processes_path, class: "button expanded hollow button--sc home-section__cta" %>
|
5
|
+
</div>
|
6
|
+
</div>
|
@@ -0,0 +1,32 @@
|
|
1
|
+
<section class="wrapper-home home-section">
|
2
|
+
<div class="row" id="highlighted-processes">
|
3
|
+
<h3 class="section-heading"><%= t("active_processes", scope: i18n_scope) %></h3>
|
4
|
+
<div class="row collapse">
|
5
|
+
<div class="row small-up-1 smallmedium-up-2 mediumlarge-up-3
|
6
|
+
large-up-4 card-grid">
|
7
|
+
<% highlighted_processes.each do |process| %>
|
8
|
+
<div class="column">
|
9
|
+
<article class="card card--process card--mini">
|
10
|
+
<%= link_to decidim_participatory_processes.participatory_process_path(process), class: "card__link" do %>
|
11
|
+
<div class="card__image-top"
|
12
|
+
style="background-image:url(<%= process.hero_image.url %>)"></div>
|
13
|
+
<% end %>
|
14
|
+
<div class="card__content">
|
15
|
+
<%= link_to decidim_participatory_processes.participatory_process_path(process), class: "card__link" do %>
|
16
|
+
<h4 class="card__title"><%= translated_attribute process.title %></h4>
|
17
|
+
<% end %>
|
18
|
+
<% if process.active_step %>
|
19
|
+
<span class="card--process__small">
|
20
|
+
<%= t("active_step", scope: i18n_scope) %>
|
21
|
+
<strong><%= translated_attribute process.active_step.title %></strong>
|
22
|
+
</span>
|
23
|
+
<% end %>
|
24
|
+
</div>
|
25
|
+
</article>
|
26
|
+
</div>
|
27
|
+
<% end %>
|
28
|
+
</div>
|
29
|
+
</div>
|
30
|
+
</div>
|
31
|
+
<%= render "_all_processes" %>
|
32
|
+
</section>
|
@@ -0,0 +1,39 @@
|
|
1
|
+
<% process = highlighted_processes.first %>
|
2
|
+
<section class="wrapper-home home-section">
|
3
|
+
<div class="row" id="highlighted-processes">
|
4
|
+
<h3 class="section-heading"><%= t("active_processes", scope: i18n_scope) %></h3>
|
5
|
+
<div class="row collapse">
|
6
|
+
<article class="card card--full card--process">
|
7
|
+
<div class="row collapse card--process__row">
|
8
|
+
<div class="column large-6 card--process__column">
|
9
|
+
<div class="card__content">
|
10
|
+
<%= link_to decidim_participatory_processes.participatory_process_path(process), class: "card__link" do %>
|
11
|
+
<h2 class="card__title"><%= translated_attribute process.title %></h2>
|
12
|
+
<% end %>
|
13
|
+
<%= decidim_sanitize translated_attribute(process.description) %>
|
14
|
+
<%= link_to t("more_information", scope: i18n_scope), decidim_participatory_processes.participatory_process_path(process), class: "button secondary small hollow" %>
|
15
|
+
</div>
|
16
|
+
</div>
|
17
|
+
<div class="column large-6 card--process__column">
|
18
|
+
<div class="card--full__image" style="background-image:url(<%= process.hero_image.url %>)">
|
19
|
+
<div class="card__content row collapse">
|
20
|
+
<div class="large-6 large-offset-6 columns">
|
21
|
+
<%= link_to decidim_participatory_processes.participatory_process_path(process), class: "button expanded button--sc" do %>
|
22
|
+
<%= t("participate", scope: i18n_scope) %>
|
23
|
+
<% if process.active_step %>
|
24
|
+
<span class="button__info">
|
25
|
+
<%= t("active_step", scope: i18n_scope) %>
|
26
|
+
<strong><%= translated_attribute process.active_step.title %></strong>
|
27
|
+
</span>
|
28
|
+
<% end %>
|
29
|
+
<% end %>
|
30
|
+
</div>
|
31
|
+
</div>
|
32
|
+
</div>
|
33
|
+
</div>
|
34
|
+
</div>
|
35
|
+
</article>
|
36
|
+
</div>
|
37
|
+
</div>
|
38
|
+
<%= render "_all_processes" %>
|
39
|
+
</section>
|
@@ -0,0 +1,40 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Decidim
|
4
|
+
module ParticipatoryProcesses
|
5
|
+
module ContentBlocks
|
6
|
+
class HighlightedProcessesCell < Decidim::ViewModel
|
7
|
+
include Decidim::SanitizeHelper
|
8
|
+
|
9
|
+
delegate :current_organization, to: :controller
|
10
|
+
delegate :current_user, to: :controller
|
11
|
+
|
12
|
+
def show
|
13
|
+
if single_process?
|
14
|
+
render "single_process"
|
15
|
+
elsif highlighted_processes.any?
|
16
|
+
render
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def single_process?
|
21
|
+
highlighted_processes.to_a.length == 1
|
22
|
+
end
|
23
|
+
|
24
|
+
def highlighted_processes
|
25
|
+
OrganizationPublishedParticipatoryProcesses.new(current_organization, current_user) |
|
26
|
+
HighlightedParticipatoryProcesses.new |
|
27
|
+
FilteredParticipatoryProcesses.new("active")
|
28
|
+
end
|
29
|
+
|
30
|
+
def i18n_scope
|
31
|
+
"decidim.participatory_processes.pages.home.highlighted_processes"
|
32
|
+
end
|
33
|
+
|
34
|
+
def decidim_participatory_processes
|
35
|
+
Decidim::ParticipatoryProcesses::Engine.routes.url_helpers
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
<span class="order-by__tabs ml-s">
|
2
|
+
<%# <span class="muted mr-s ml-s">No hay procesos activos</span> %>
|
3
|
+
<% if should_show_tabs? %>
|
4
|
+
<%= explanation %>
|
5
|
+
<span class="muted mr-xs"><%= t("decidim.participatory_processes.participatory_processes.filters.see") %></span>
|
6
|
+
<% other_filters_with_value.each do |filter| %>
|
7
|
+
<%= link_to filter_link(filter), remote: true, class: "order-by__tab" do %>
|
8
|
+
<strong>
|
9
|
+
<%= filter_name(filter) %>
|
10
|
+
</strong> <span>(<%= model[filter] %>)</span>
|
11
|
+
<% end %>
|
12
|
+
<% end %>
|
13
|
+
<% else %>
|
14
|
+
<%= explanation %>
|
15
|
+
<% end %>
|
16
|
+
</span>
|
@@ -0,0 +1,13 @@
|
|
1
|
+
<div class="row collapse order-by">
|
2
|
+
<h2 class="order-by__text section-heading">
|
3
|
+
<%= title %>
|
4
|
+
<%= render :filter_tabs %>
|
5
|
+
</h2>
|
6
|
+
</div>
|
7
|
+
<% if model["active"] == 0 && model["upcoming"] == 0 %>
|
8
|
+
<div class="row column">
|
9
|
+
<div class="callout warning mb-sm">
|
10
|
+
<p><%= t("decidim.participatory_processes.participatory_processes.filters.explanations.no_active_nor_upcoming_callout") %></p>
|
11
|
+
</div>
|
12
|
+
</div>
|
13
|
+
<% end %>
|
@@ -0,0 +1,57 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Decidim
|
4
|
+
module ParticipatoryProcesses
|
5
|
+
class ProcessFiltersCell < Decidim::ViewModel
|
6
|
+
ALL_FILTERS = %w(active past upcoming all).freeze
|
7
|
+
|
8
|
+
def filter_link(filter)
|
9
|
+
Decidim::ParticipatoryProcesses::Engine
|
10
|
+
.routes
|
11
|
+
.url_helpers
|
12
|
+
.participatory_processes_path(filter: filter)
|
13
|
+
end
|
14
|
+
|
15
|
+
def current_filter
|
16
|
+
options[:current_filter]
|
17
|
+
end
|
18
|
+
|
19
|
+
def other_filters
|
20
|
+
@other_filters ||= ALL_FILTERS - [current_filter]
|
21
|
+
end
|
22
|
+
|
23
|
+
def other_filters_with_value
|
24
|
+
@other_filters_with_value ||= other_filters.select do |filter|
|
25
|
+
model[filter].positive?
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def should_show_tabs?
|
30
|
+
other_filters_with_value.any?
|
31
|
+
other_filters_with_value != ["all"]
|
32
|
+
end
|
33
|
+
|
34
|
+
def title
|
35
|
+
I18n.t(current_filter, scope: "decidim.participatory_processes.participatory_processes.filters.counters", count: model[current_filter])
|
36
|
+
end
|
37
|
+
|
38
|
+
def filter_name(filter)
|
39
|
+
I18n.t(filter, scope: "decidim.participatory_processes.participatory_processes.filters.names")
|
40
|
+
end
|
41
|
+
|
42
|
+
def explanation
|
43
|
+
return if model["active"].positive?
|
44
|
+
content_tag(
|
45
|
+
:span,
|
46
|
+
I18n.t(explanation_text, scope: "decidim.participatory_processes.participatory_processes.filters.explanations"),
|
47
|
+
class: "muted mr-s ml-s"
|
48
|
+
)
|
49
|
+
end
|
50
|
+
|
51
|
+
def explanation_text
|
52
|
+
return "no_active" if model["upcoming"].positive?
|
53
|
+
"no_active_nor_upcoming"
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
@@ -39,7 +39,7 @@ module Decidim
|
|
39
39
|
content_tag(
|
40
40
|
:strong,
|
41
41
|
t("layouts.decidim.participatory_process_groups.participatory_process_group.processes_count")
|
42
|
-
) + " " + model.participatory_processes.count.to_s
|
42
|
+
) + " " + model.participatory_processes.published.count.to_s
|
43
43
|
end
|
44
44
|
end
|
45
45
|
end
|
@@ -1,6 +1,8 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
1
|
+
<% if model.hashtag.present? %>
|
2
|
+
<%= link_to(
|
3
|
+
"##{model.hashtag}",
|
4
|
+
"https://twitter.com/hashtag/#{model.hashtag}",
|
5
|
+
class: "card__text--category",
|
6
|
+
target: "_blank"
|
7
|
+
) %>
|
8
|
+
<% end %>
|
@@ -17,6 +17,7 @@ module Decidim
|
|
17
17
|
helper ParticipatoryProcessHelper
|
18
18
|
|
19
19
|
helper_method :collection, :promoted_participatory_processes, :participatory_processes, :stats, :filter
|
20
|
+
helper_method :process_count_by_filter
|
20
21
|
|
21
22
|
def index
|
22
23
|
redirect_to "/404" if published_processes.none?
|
@@ -51,8 +52,8 @@ module Decidim
|
|
51
52
|
@collection ||= (participatory_processes.to_a + participatory_process_groups).flatten
|
52
53
|
end
|
53
54
|
|
54
|
-
def filtered_participatory_processes(
|
55
|
-
OrganizationPrioritizedParticipatoryProcesses.new(current_organization,
|
55
|
+
def filtered_participatory_processes(filter_name = filter)
|
56
|
+
OrganizationPrioritizedParticipatoryProcesses.new(current_organization, filter_name, current_user)
|
56
57
|
end
|
57
58
|
|
58
59
|
def participatory_processes
|
@@ -63,8 +64,12 @@ module Decidim
|
|
63
64
|
@promoted_participatory_processes ||= filtered_participatory_processes | PromotedParticipatoryProcesses.new
|
64
65
|
end
|
65
66
|
|
67
|
+
def filtered_participatory_process_groups(filter_name = filter)
|
68
|
+
OrganizationPrioritizedParticipatoryProcessGroups.new(current_organization, filter_name)
|
69
|
+
end
|
70
|
+
|
66
71
|
def participatory_process_groups
|
67
|
-
@participatory_process_groups ||=
|
72
|
+
@participatory_process_groups ||= filtered_participatory_process_groups(filter)
|
68
73
|
end
|
69
74
|
|
70
75
|
def stats
|
@@ -76,8 +81,23 @@ module Decidim
|
|
76
81
|
end
|
77
82
|
|
78
83
|
def default_filter
|
84
|
+
return "active" if process_count_by_filter["active"].positive?
|
85
|
+
return "upcoming" if process_count_by_filter["upcoming"].positive?
|
86
|
+
return "past" if process_count_by_filter["past"].positive?
|
79
87
|
"active"
|
80
88
|
end
|
89
|
+
|
90
|
+
def process_count_by_filter
|
91
|
+
return @process_count_by_filter if @process_count_by_filter
|
92
|
+
|
93
|
+
@process_count_by_filter = %w(active upcoming past).inject({}) do |collection_by_filter, filter_name|
|
94
|
+
processes = filtered_participatory_processes(filter_name)
|
95
|
+
groups = filtered_participatory_process_groups(filter_name)
|
96
|
+
collection_by_filter.merge(filter_name.to_s => processes.count + groups.count)
|
97
|
+
end
|
98
|
+
@process_count_by_filter["all"] = @process_count_by_filter.values.sum
|
99
|
+
@process_count_by_filter
|
100
|
+
end
|
81
101
|
end
|
82
102
|
end
|
83
103
|
end
|
@@ -14,23 +14,13 @@ module Decidim
|
|
14
14
|
|
15
15
|
mimic :participatory_process_step
|
16
16
|
|
17
|
-
attribute :start_date,
|
18
|
-
attribute :end_date,
|
17
|
+
attribute :start_date, Date
|
18
|
+
attribute :end_date, Date
|
19
19
|
|
20
20
|
validates :title, translatable_presence: true
|
21
21
|
|
22
22
|
validates :start_date, date: { before: :end_date, allow_blank: true, if: proc { |obj| obj.end_date.present? } }
|
23
23
|
validates :end_date, date: { after: :start_date, allow_blank: true, if: proc { |obj| obj.start_date.present? } }
|
24
|
-
|
25
|
-
def start_date
|
26
|
-
return nil unless super.respond_to?(:at_midnight)
|
27
|
-
super.at_midnight
|
28
|
-
end
|
29
|
-
|
30
|
-
def end_date
|
31
|
-
return nil unless super.respond_to?(:at_midnight)
|
32
|
-
super.at_midnight
|
33
|
-
end
|
34
24
|
end
|
35
25
|
end
|
36
26
|
end
|
@@ -55,9 +55,9 @@ module Decidim
|
|
55
55
|
mount_uploader :hero_image, Decidim::HeroImageUploader
|
56
56
|
mount_uploader :banner_image, Decidim::BannerImageUploader
|
57
57
|
|
58
|
-
scope :past, -> { where(arel_table[:end_date].lteq(
|
59
|
-
scope :upcoming, -> { where(arel_table[:start_date].gt(
|
60
|
-
scope :active, -> { where(arel_table[:start_date].lteq(
|
58
|
+
scope :past, -> { where(arel_table[:end_date].lteq(Date.current)) }
|
59
|
+
scope :upcoming, -> { where(arel_table[:start_date].gt(Date.current)) }
|
60
|
+
scope :active, -> { where(arel_table[:start_date].lteq(Date.current).and(arel_table[:end_date].gt(Date.current).or(arel_table[:end_date].eq(nil)))) }
|
61
61
|
|
62
62
|
# Scope to return only the promoted processes.
|
63
63
|
#
|
@@ -72,7 +72,7 @@ module Decidim
|
|
72
72
|
|
73
73
|
def past?
|
74
74
|
return false if end_date.blank?
|
75
|
-
end_date <
|
75
|
+
end_date < Date.current
|
76
76
|
end
|
77
77
|
|
78
78
|
def hashtag
|
@@ -15,9 +15,9 @@ module Decidim
|
|
15
15
|
|
16
16
|
processes = case @filter
|
17
17
|
when "past"
|
18
|
-
processes.where("decidim_participatory_processes.end_date <= ?",
|
18
|
+
processes.where("decidim_participatory_processes.end_date <= ?", Date.current)
|
19
19
|
when "upcoming"
|
20
|
-
processes.where("decidim_participatory_processes.start_date > ?",
|
20
|
+
processes.where("decidim_participatory_processes.start_date > ?", Date.current)
|
21
21
|
else
|
22
22
|
processes
|
23
23
|
end
|
data/app/views/decidim/participatory_processes/admin/participatory_process_copies/new.html.erb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
<%= decidim_form_for(@form, url: participatory_process_copies_path(current_participatory_process), method: :post, html: { class: "form copy_participatory_process" }) do |f| %>
|
2
|
-
<%= render partial: "form", object: f, locals: { title: t("participatory_process_copies.new.title", scope: "decidim.admin"), select: t("participatory_process_copies.new.select", scope: "decidim.admin")} %>
|
2
|
+
<%= render partial: "form", object: f, locals: { title: t("participatory_process_copies.new.title", scope: "decidim.admin"), select: t("participatory_process_copies.new.select", scope: "decidim.admin") } %>
|
3
3
|
|
4
4
|
<div class="button--double form-general-submit">
|
5
5
|
<%= f.submit t("participatory_process_copies.new.copy", scope: "decidim.admin") %>
|
@@ -2,8 +2,7 @@
|
|
2
2
|
|
3
3
|
<main class="wrapper">
|
4
4
|
<section id="processes-grid" class="section row collapse">
|
5
|
-
<h1 class="section-heading"><%= t("participatory_process_groups.show.group_participatory_processes", scope: "decidim", group: translated_attribute(group.name)) %></h1>
|
6
|
-
<%= render partial: "decidim/participatory_processes/order_by_processes", locals: { include_filter: false } %>
|
5
|
+
<h1 class="section-heading"><%= t("participatory_process_groups.show.group_participatory_processes", scope: "decidim", count: participatory_processes.count, group: translated_attribute(group.name)) %></h1>
|
7
6
|
<div class="row small-up-1 medium-up-2 large-up-3 card-grid">
|
8
7
|
<%= render participatory_processes %>
|
9
8
|
</div>
|
data/app/views/decidim/participatory_processes/participatory_processes/_order_by_processes.html.erb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
<%= cell "decidim/participatory_processes/process_filters", process_count_by_filter, current_filter: filter %>
|
@@ -1,5 +1,13 @@
|
|
1
1
|
<% add_decidim_meta_tags(title: t("participatory_processes.index.title", scope: "decidim")) %>
|
2
2
|
|
3
|
+
<%
|
4
|
+
edit_link(
|
5
|
+
decidim_admin_participatory_processes.participatory_processes_path,
|
6
|
+
:read,
|
7
|
+
:process_list
|
8
|
+
)
|
9
|
+
%>
|
10
|
+
|
3
11
|
<main class="wrapper">
|
4
12
|
<% if promoted_participatory_processes.any? %>
|
5
13
|
<section id="highlighted-processes" class="row section">
|
@@ -10,7 +18,7 @@
|
|
10
18
|
|
11
19
|
<section id="processes-grid" class="section row collapse">
|
12
20
|
<div class="processes-grid-order-by">
|
13
|
-
<%= render partial: "
|
21
|
+
<%= render partial: "order_by_processes" %>
|
14
22
|
</div>
|
15
23
|
<p class="loading"><%= t(".loading") %></p>
|
16
24
|
<div class="row small-up-1 medium-up-2 large-up-3 card-grid">
|