decidim-accountability 0.21.0 → 0.22.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (80) hide show
  1. checksums.yaml +4 -4
  2. data/app/assets/javascripts/decidim/accountability/admin/accountability_admin.js.es6 +6 -42
  3. data/app/assets/stylesheets/decidim/accountability/accountability/_categories.scss +8 -1
  4. data/app/assets/stylesheets/decidim/accountability/accountability/_lines_breadcrumb.scss +8 -0
  5. data/app/assets/stylesheets/decidim/accountability/accountability/_results.scss +0 -3
  6. data/app/cells/decidim/accountability/highlighted_results_for_component/show.erb +3 -3
  7. data/app/cells/decidim/accountability/highlighted_results_for_component_cell.rb +1 -1
  8. data/app/commands/decidim/accountability/admin/create_imported_result.rb +106 -0
  9. data/app/commands/decidim/accountability/admin/update_imported_result.rb +110 -0
  10. data/app/controllers/decidim/accountability/admin/import_results_controller.rb +34 -0
  11. data/app/controllers/decidim/accountability/admin/results_controller.rb +2 -20
  12. data/app/controllers/decidim/accountability/versions_controller.rb +7 -8
  13. data/app/jobs/application_job.rb +4 -0
  14. data/app/jobs/decidim/accountability/admin/import_results_csv_job.rb +19 -0
  15. data/app/mailers/decidim/accountability/import_mailer.rb +26 -0
  16. data/app/queries/decidim/accountability/metrics/results_metric_manage.rb +2 -8
  17. data/app/services/decidim/accountability/results_csv_importer.rb +139 -0
  18. data/app/views/decidim/accountability/admin/import_results/new.html.erb +22 -0
  19. data/app/views/decidim/accountability/admin/results/_form.html.erb +1 -5
  20. data/app/views/decidim/accountability/admin/results/index.html.erb +1 -0
  21. data/app/views/decidim/accountability/admin/results/proposals_picker.html.erb +1 -0
  22. data/app/views/decidim/accountability/import_mailer/import.html.erb +25 -0
  23. data/app/views/decidim/accountability/results/_linked_results.html.erb +1 -1
  24. data/app/views/decidim/accountability/results/_results_leaf.html.erb +5 -5
  25. data/app/views/decidim/accountability/results/_results_parent.html.erb +2 -2
  26. data/app/views/decidim/accountability/results/_scope_filters.html.erb +16 -3
  27. data/app/views/decidim/accountability/results/_search.html.erb +3 -3
  28. data/app/views/decidim/accountability/results/_stats_box.html.erb +11 -4
  29. data/app/views/decidim/accountability/results/_timeline.html.erb +2 -2
  30. data/app/views/decidim/accountability/versions/index.html.erb +7 -25
  31. data/app/views/decidim/accountability/versions/show.html.erb +9 -31
  32. data/app/views/decidim/participatory_spaces/_result.html.erb +3 -3
  33. data/config/locales/ar.yml +1 -24
  34. data/config/locales/bg-BG.yml +220 -0
  35. data/config/locales/ca.yml +19 -22
  36. data/config/locales/cs.yml +44 -47
  37. data/config/locales/da-DK.yml +1 -0
  38. data/config/locales/de.yml +19 -22
  39. data/config/locales/el.yml +222 -0
  40. data/config/locales/en.yml +19 -22
  41. data/config/locales/es-MX.yml +19 -22
  42. data/config/locales/es-PY.yml +19 -22
  43. data/config/locales/es.yml +19 -22
  44. data/config/locales/et-EE.yml +1 -0
  45. data/config/locales/eu.yml +1 -24
  46. data/config/locales/fi-plain.yml +19 -22
  47. data/config/locales/fi.yml +32 -35
  48. data/config/locales/fr-CA.yml +222 -0
  49. data/config/locales/fr.yml +18 -22
  50. data/config/locales/ga-IE.yml +1 -0
  51. data/config/locales/gl.yml +1 -24
  52. data/config/locales/hr-HR.yml +1 -0
  53. data/config/locales/hu.yml +18 -22
  54. data/config/locales/id-ID.yml +1 -24
  55. data/config/locales/is-IS.yml +1 -21
  56. data/config/locales/it.yml +37 -40
  57. data/config/locales/ja-JP.yml +221 -0
  58. data/config/locales/lt-LT.yml +1 -0
  59. data/config/locales/lv-LV.yml +218 -0
  60. data/config/locales/mt-MT.yml +1 -0
  61. data/config/locales/nl.yml +18 -22
  62. data/config/locales/no.yml +25 -28
  63. data/config/locales/pl.yml +46 -49
  64. data/config/locales/pt-BR.yml +2 -25
  65. data/config/locales/pt.yml +59 -62
  66. data/config/locales/ro-RO.yml +223 -0
  67. data/config/locales/ru.yml +1 -24
  68. data/config/locales/sk-SK.yml +224 -0
  69. data/config/locales/sk.yml +207 -0
  70. data/config/locales/sl.yml +129 -0
  71. data/config/locales/sr-CS.yml +205 -0
  72. data/config/locales/sv.yml +21 -24
  73. data/config/locales/tr-TR.yml +1 -24
  74. data/config/locales/uk.yml +1 -21
  75. data/db/migrate/20200320105903_index_foreign_keys_in_decidim_accountability_results.rb +7 -0
  76. data/lib/decidim/accountability/admin_engine.rb +4 -3
  77. data/lib/decidim/accountability/version.rb +1 -1
  78. metadata +54 -24
  79. data/app/views/decidim/accountability/admin/results/_proposals.html.erb +0 -12
  80. data/app/views/decidim/accountability/versions/_version.html.erb +0 -20
@@ -0,0 +1,4 @@
1
+ # frozen_string_literal: true
2
+
3
+ class ApplicationJob < ActiveJob::Base
4
+ end
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module Accountability
5
+ module Admin
6
+ class ImportResultsCSVJob < ApplicationJob
7
+ queue_as :default
8
+
9
+ def perform(current_user, current_component, csv_file)
10
+ importer = Decidim::Accountability::ResultsCSVImporter.new(current_component, csv_file, current_user)
11
+
12
+ errors = importer.import!
13
+
14
+ Decidim::Accountability::ImportMailer.import(current_user, errors).deliver_now
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module Accountability
5
+ # This mailer sends a notification email containing the result of importing a
6
+ # CSV of results.
7
+ class ImportMailer < Decidim::ApplicationMailer
8
+ # Public: Sends a notification email with the result of a CSV import
9
+ # of results.
10
+ #
11
+ # user - The user to be notified.
12
+ # errors - The list of errors generated by the import
13
+ #
14
+ # Returns nothing.
15
+ def import(user, errors)
16
+ @user = user
17
+ @organization = user.organization
18
+ @errors = errors
19
+
20
+ with_user(user) do
21
+ mail(to: "#{user.name} <#{user.email}>", subject: I18n.t("decidim.accountability.import_mailer.import.subject"))
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
@@ -9,9 +9,6 @@ module Decidim
9
9
  end
10
10
 
11
11
  def save
12
- return @registry if @registry
13
-
14
- @registry = []
15
12
  cumulative.each do |key, cumulative_value|
16
13
  next if cumulative_value.zero?
17
14
 
@@ -26,10 +23,8 @@ module Decidim
26
23
  related_object_type: "Decidim::Component",
27
24
  related_object_id: related_object_id)
28
25
  record.assign_attributes(cumulative: cumulative_value, quantity: quantity_value)
29
- @registry << record
26
+ record.save!
30
27
  end
31
- @registry.each(&:save!)
32
- @registry
33
28
  end
34
29
 
35
30
  private
@@ -40,9 +35,8 @@ module Decidim
40
35
  spaces = Decidim.participatory_space_manifests.flat_map do |manifest|
41
36
  manifest.participatory_spaces.call(@organization).public_spaces
42
37
  end
43
- components = Decidim::Component.where(participatory_space: spaces).published
44
38
  @query = Decidim::Accountability::Result.select(:decidim_component_id)
45
- .where(component: components)
39
+ .where(component: visible_component_ids_from_spaces(spaces))
46
40
  .joins(:component)
47
41
  .left_outer_joins(:category)
48
42
  @query = @query.where("decidim_accountability_results.created_at <= ?", end_time)
@@ -0,0 +1,139 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "csv"
4
+
5
+ module Decidim
6
+ module Accountability
7
+ # This class handles importing results from a CSV file.
8
+ # Needs a `current_component` param with a `Decidim::component`
9
+ # in order to import the results in that component.
10
+ class ResultsCSVImporter
11
+ include Decidim::FormFactory
12
+
13
+ # Public: Initializes the service.
14
+ # component - A Decidim::component to import the results into.
15
+ # csv_file - The contents of the CSV to read.
16
+ def initialize(component, csv_file, current_user)
17
+ @component = component
18
+ @csv_file = csv_file
19
+
20
+ @extra_context = {
21
+ current_component: component,
22
+ current_organization: component.organization,
23
+ current_user: current_user,
24
+ current_participatory_space: component.participatory_space
25
+ }
26
+ @matches_ids = []
27
+ end
28
+
29
+ def import!
30
+ errors = []
31
+
32
+ ActiveRecord::Base.transaction do
33
+ i = 1
34
+ csv = CSV.new(@csv_file, headers: true, col_sep: ";")
35
+ while (row = csv.shift).present?
36
+ i += 1
37
+ next if row.empty?
38
+
39
+ params = set_params_for_import_result_form(row, @component)
40
+ existing_result = Decidim::Accountability::Result.find_by(id: row["id"], component: @component) if row["id"].present?
41
+ params["result"].merge!(parse_date_params(row, "start_date"))
42
+ params["result"].merge!(parse_date_params(row, "end_date"))
43
+ @form = form(Decidim::Accountability::Admin::ResultForm).from_params(params, @extra_context)
44
+ errors << [i, @form.errors.full_messages] if @form.errors.any?
45
+
46
+ if existing_result.present?
47
+ Decidim::Accountability::Admin::UpdateImportedResult.call(@form, existing_result, params["result"]["parent/id"]) do
48
+ on(:invalid) do
49
+ errors << [i, @form.errors.full_messages]
50
+ end
51
+ end
52
+ else
53
+ Decidim::Accountability::Admin::CreateImportedResult.call(@form, params["result"]["parent/id"]) do
54
+ on(:invalid) do
55
+ errors << [i, @form.errors.full_messages]
56
+ end
57
+ end
58
+ add_match_id(row["id"])
59
+ end
60
+
61
+ end
62
+
63
+ raise ActiveRecord::Rollback if errors.any?
64
+
65
+ update_parents
66
+ remove_invalid_results
67
+
68
+ Rails.logger.info "Processed: #{i}"
69
+ end
70
+
71
+ errors
72
+ end
73
+
74
+ private
75
+
76
+ def set_params_for_import_result_form(row, component)
77
+ params = {}
78
+ params["result"] = row.to_hash
79
+ default_locale = component.participatory_space.organization.default_locale
80
+ available_locales = component.participatory_space.organization.available_locales
81
+ params["result"].merge!(get_locale_attributes(default_locale, available_locales, :title, row))
82
+ params["result"].merge!(get_locale_attributes(default_locale, available_locales, :description, row))
83
+ params["result"]["decidim_category_id"] = row["category/id"] if row["category/id"].present?
84
+ params["result"]["decidim_accountability_status_id"] = row["status/id"] if row["status/id"].present?
85
+ params["result"].merge!(get_proposal_ids(row["proposal_urls"]))
86
+ params
87
+ end
88
+
89
+ def get_locale_attributes(default_locale, available_locales, field, row)
90
+ array_field_localized = available_locales.map do |locale|
91
+ if row["#{field}/#{locale}"].present?
92
+ ["#{field}_#{locale}", row["#{field}/#{locale}"]]
93
+ else
94
+ ["#{field}_#{locale}", row["#{field}/#{default_locale}"]]
95
+ end
96
+ end
97
+
98
+ Hash[*array_field_localized.flatten]
99
+ end
100
+
101
+ def parse_date_params(row, field)
102
+ begin
103
+ return { field => Date.parse(row[field]) } if row[field].present?
104
+ rescue ArgumentError
105
+ @form.errors.add(field.to_sym, :invalid_date)
106
+ end
107
+ {}
108
+ end
109
+
110
+ def get_proposal_ids(proposal_urls)
111
+ if proposal_urls.present?
112
+ proposal_urls = proposal_urls.split(";")
113
+ { "proposal_ids" => proposal_urls.map { |proposal_url| proposal_url.scan(/\d$/).first.to_i } }
114
+ else
115
+ {}
116
+ end
117
+ end
118
+
119
+ def add_match_id(id)
120
+ last_created_result = Decidim::Accountability::Result.last
121
+ @matches_ids << [id, Decidim::Accountability::Result.last.id] if id.present? && last_created_result.present?
122
+ end
123
+
124
+ def update_parents
125
+ @matches_ids.each do |match|
126
+ Decidim::Accountability::Result.where(component: @component, parent_id: match.first).find_each { |result| result.update(parent_id: match.last) }
127
+ end
128
+ end
129
+
130
+ def remove_invalid_results
131
+ Decidim::Accountability::Result.includes(:parent).references(:parent)
132
+ .where(parents_decidim_accountability_results: { id: nil })
133
+ .where.not(parent_id: nil).each do |result|
134
+ DestroyResult.call(result, @extra_context[:current_user])
135
+ end
136
+ end
137
+ end
138
+ end
139
+ end
@@ -0,0 +1,22 @@
1
+ <%= form_tag(import_results_path, multipart: true, class: "form new_import") do %>
2
+ <div class="card">
3
+ <div class="card-divider">
4
+ <h2 class="card-title">
5
+ <%= t(".title") %>
6
+ </h2>
7
+ </div>
8
+
9
+ <div class="card-section">
10
+ <div class="row column">
11
+ <%= file_field_tag :csv_file %>
12
+ </div>
13
+ </div>
14
+ </div>
15
+
16
+ <div class="button--double form-general-submit">
17
+ <%= submit_tag t(".import"), class: "button" %>
18
+ </div>
19
+ <div class="import-process-info">
20
+ <%= t(".info", link_new_status: new_status_path, link_new_result: new_result_path, link_export_csv: link_to(t(".link"), exports_path(@current_component, id: "results", format: "CSV"), method: :post)).try("html_safe") %>
21
+ </div>
22
+ <% end %>
@@ -53,11 +53,7 @@
53
53
  </div>
54
54
 
55
55
  <div class="row column">
56
- <% if @form.proposals %>
57
- <% picker_options = { id: "decidim_accountability_proposals", class: "picker-multiple", name: "result[proposal_ids]", multiple: true }
58
- prompt_params= { url: proposals_results_path(current_component, format: :html), text: t(".add_proposal") } %>
59
- <%= form.data_picker(:proposals, picker_options, prompt_params) {|item| { url:proposals_results_path(current_component, format: :json), text: "##{item.id}- #{present(item).title}" }} %>
60
- <% end %>
56
+ <%= proposals_picker(form, :proposals, proposals_picker_results_path) %>
61
57
  </div>
62
58
 
63
59
  <div class="row column">
@@ -7,6 +7,7 @@
7
7
  <%= link_to t("actions.new", scope: "decidim.accountability", name: t("models.result.name", scope: "decidim.accountability.admin")), new_result_path(parent_id: parent_result), class: "button tiny button--simple" if allowed_to? :create, :result %>
8
8
  <%= render partial: "decidim/accountability/admin/shared/subnav" unless parent_result %>
9
9
  <%= export_dropdown %>
10
+ <%= link_to t("actions.import_csv", scope: "decidim.accountability"), import_results_path, class: "button tiny button--simple" if allowed_to? :create, :result %>
10
11
  </div>
11
12
  </h2>
12
13
  </div>
@@ -0,0 +1 @@
1
+ <%= cell "decidim/proposals/proposals_picker", current_component %>
@@ -0,0 +1,25 @@
1
+ <% if @errors.empty? %>
2
+ <p><%= t(".success") %></p>
3
+ <% else %>
4
+ <p><%= t(".errors_present") %>:</p>
5
+ <table>
6
+ <thead>
7
+ <tr>
8
+ <th><%= t(".row_number") %></th>
9
+ <th><%= t(".errors") %></th>
10
+ </tr>
11
+ </thead>
12
+ <% @errors.each do |error| %>
13
+ <tr>
14
+ <td><%= error.first %></td>
15
+ <td>
16
+ <ul>
17
+ <% error.last.each do |error_message| %>
18
+ <li><%= error_message %></li>
19
+ <% end %>
20
+ </ul>
21
+ </td>
22
+ </tr>
23
+ <% end %>
24
+ </table>
25
+ <% end %>
@@ -1,7 +1,7 @@
1
1
  <div class="card card--action card--list">
2
2
  <% resources.each do |result| %>
3
3
  <div class="card--list__item">
4
- <%= icon "actions", class: "card--list__icon", remove_icon_class: true %>
4
+ <%= icon "actions", class: "card--list__icon", role: "img", "aria-hidden": true, remove_icon_class: true %>
5
5
  <%= link_to resource_locator(result).path, class: "card--list__text card__link card__link--block" do %>
6
6
  <h5 class="card--list__heading">
7
7
  <%= translated_attribute(result.title) %>
@@ -1,7 +1,7 @@
1
1
  <div class="title-action">
2
- <h2 id="results-count" class="title-action__title section-heading">
2
+ <h3 id="results-count" class="title-action__title section-heading">
3
3
  <%= heading_leaf_level_results(total_count) %>
4
- </h2>
4
+ </h3>
5
5
  </div>
6
6
 
7
7
  <div class="row">
@@ -9,12 +9,12 @@
9
9
  <div class="card card--action card--list">
10
10
  <% results.each do |result| %>
11
11
  <div class="card--list__item">
12
- <%= icon "actions", class: "card--list__icon", remove_icon_class: true %>
12
+ <%= icon "actions", class: "card--list__icon", role: "img", "aria-hidden": true, remove_icon_class: true %>
13
13
 
14
14
  <%= link_to result_path(result), class: "card--list__text card__link card__link--block" do %>
15
- <h5 class="card--list__heading">
15
+ <h4 class="card--list__heading">
16
16
  <%= translated_attribute(result.title) %>
17
- </h5>
17
+ </h4>
18
18
 
19
19
  <div class="text-small card--meta">
20
20
  <% if result.start_date %>
@@ -12,9 +12,9 @@
12
12
  <%= icon "proposals", class: "card--list__icon", remove_icon_class: true %>
13
13
 
14
14
  <%= link_to result, class: "card--list__text card__link card__link--block" do %>
15
- <h5 class="card--list__heading">
15
+ <h3 class="card--list__heading">
16
16
  <%= translated_attribute result.title %>
17
- </h5>
17
+ </h3>
18
18
 
19
19
  <span class="text-small"><%= heading_leaf_level_results(result.children.count) %></span>
20
20
  <% end %>
@@ -3,15 +3,28 @@
3
3
  <div><%= t("results.filters.scopes", scope: "decidim.accountability") %></div>
4
4
 
5
5
  <ul class="tags tags--action">
6
- <li <%= active_class_if_current(nil) %>><%= link_to t("results.filters.all", scope: "decidim.accountability"), url_for(filter: { category_id: category.try(:id) }) %></li>
6
+ <li <%= active_class_if_current(nil) %>>
7
+ <%= link_to url_for(filter: { category_id: category.try(:id) }) do %>
8
+ <span class="show-for-sr"><%= Decidim::Scope.model_name.human(count: 2) %></span>
9
+ <%= t("results.filters.all", scope: "decidim.accountability") %>
10
+ <% end %>
11
+ </li>
7
12
 
8
13
  <% if current_participatory_space.scope %>
9
14
  <li <%= active_class_if_current(current_participatory_space.scope.id) %>>
10
- <%= link_to translated_attribute(current_participatory_space.scope.name), url_for(filter: { scope_id: current_participatory_space.scope.id, category_id: category.try(:id) }) %>
15
+ <%= link_to url_for(filter: { scope_id: current_participatory_space.scope.id, category_id: category.try(:id) }) do %>
16
+ <span class="show-for-sr"><%= Decidim::Scope.model_name.human(count: 1) %></span>
17
+ <%= translated_attribute(current_participatory_space.scope.name) %>
18
+ <% end %>
11
19
  </li>
12
20
  <% end %>
13
21
  <% current_participatory_space.subscopes.each do |scope| %>
14
- <li <%= active_class_if_current(scope.id) %>><%= link_to translated_attribute(scope.name), url_for(filter: { scope_id: scope.id, category_id: category.try(:id) }) %></li>
22
+ <li <%= active_class_if_current(scope.id) %>>
23
+ <%= link_to url_for(filter: { scope_id: scope.id, category_id: category.try(:id) }) do %>
24
+ <span class="show-for-sr"><%= Decidim::Scope.model_name.human(count: 1) %></span>
25
+ <%= translated_attribute(scope.name) %>
26
+ <% end %>
27
+ </li>
15
28
  <% end %>
16
29
  </ul>
17
30
  <% end %>
@@ -1,10 +1,10 @@
1
1
  <%= form_tag results_path, method: :get do %>
2
2
  <div class="filters__search">
3
3
  <div class="input-group">
4
- <%= search_field_tag "filter[search_text]", nil, label: false, class: "input-group-field", placeholder: t(".search"), value: "" %>
4
+ <%= search_field_tag "filter[search_text]", nil, class: "input-group-field", placeholder: t(".search"), value: "", title: t(".search") %>
5
5
  <div class="input-group-button">
6
- <button type="submit" class="button button--muted">
7
- <%= icon "magnifying-glass", aria_label: t(".search") %>
6
+ <button type="submit" class="button">
7
+ <%= icon "magnifying-glass", aria_label: t(".search"), role: "img" %>
8
8
  </button>
9
9
  </div>
10
10
  </div>
@@ -20,10 +20,17 @@
20
20
  <div class="definition-data">
21
21
  <% if result.versions.any? %>
22
22
  <div class="definition-data__item versions_count">
23
- <span class="definition-data__title"><%= t("results.show.stats.version_number", scope: "decidim.accountability") %></span>
24
- <%= result.versions.count %>
25
- <div class="pr-s pl-s">
26
- <%= link_to t("results.show.stats.show_all_versions", scope: "decidim.accountability"), result_versions_path(result), class: "button button--sc hollow secondary small expanded" %>
23
+ <div>
24
+ <%= resource_version_number(result.versions_count, "text-large") %>
25
+ <small class="text-medium">
26
+ <%= resource_version_of(result.versions_count) %>
27
+ </small>
28
+ </div>
29
+
30
+ <div>
31
+ <span class="text-medium">
32
+ <%= link_to_other_resource_versions(result_versions_path(result)) %>
33
+ </span>
27
34
  </div>
28
35
  </div>
29
36
  <% if result.last_editor.present? %>
@@ -12,9 +12,9 @@
12
12
  <span class="timeline__date text-small">
13
13
  <%= timeline_entry.entry_date %>
14
14
  </span>
15
- <h6 class="timeline__title">
15
+ <h4 class="timeline__title">
16
16
  <%= translated_attribute timeline_entry.description %>
17
- </h6>
17
+ </h4>
18
18
  </div>
19
19
  </div>
20
20
  </li>
@@ -1,30 +1,12 @@
1
1
  <div class="row accountability">
2
2
  <div class="small-12 columns">
3
- <%= render partial: "decidim/accountability/results/nav_breadcrumb", locals: { category: result.parent.try(:category) || result.try(:category) } %>
3
+ <%= render partial: "decidim/accountability/results/nav_breadcrumb", locals: { category: versioned_resource.parent.try(:category) || versioned_resource.try(:category) } %>
4
4
  </div>
5
- <div class="small-12 columns">
6
- <h2 class="heading2"><%= t(".changes_at_title", title: translated_attribute(result.title)) %></h2>
7
- <h3 class="section-heading"><%= t(".title") %></h3>
8
- <div class="row">
9
- <div class="mediumlarge-8 columns">
10
- <div class="section">
11
- <div class="card card--list">
12
- <% result.versions.each_with_index do |version, index| %>
13
- <%= render partial: "version", locals: { version: version, index: index } %>
14
- <% end %>
15
- </div>
16
- </div>
17
- </div>
18
5
 
19
- <div class="columns section mediumlarge-4 large-3">
20
- <div class="card extra definition-data">
21
- <div class="definition-data__item versions_count">
22
- <span class="definition-data__title"><%= t("results.show.stats.number_of_versions", scope: "decidim.accountability") %></span>
23
- <%= result.versions.count %>
24
- <%= link_to t("results.show.stats.back_to_result", scope: "decidim.accountability"), result_path(result), class: "button button--sc hollow secondary small expanded" %>
25
- </div>
26
- </div>
27
- </div>
28
- </div>
29
- </div>
6
+ <%= cell(
7
+ "decidim/versions_list",
8
+ versioned_resource,
9
+ version_path: proc { |version_index| url_for(action: :show, id: version_index) },
10
+ i18n_scope: "decidim.accountability.results.show.stats"
11
+ ) %>
30
12
  </div>