decidim-accountability 0.1.2 → 0.7.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (66) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +1 -21
  3. data/app/assets/javascripts/decidim/accountability/accountability.js.es6 +3 -3
  4. data/app/assets/javascripts/decidim/accountability/admin/accountability_admin.js +3 -2
  5. data/app/assets/stylesheets/decidim/accountability/accountability/_categories.scss +13 -13
  6. data/app/assets/stylesheets/decidim/accountability/accountability/_lines_breadcrumb.scss +5 -5
  7. data/app/assets/stylesheets/decidim/accountability/accountability/_results.scss +5 -5
  8. data/app/commands/decidim/accountability/admin/create_result.rb +0 -1
  9. data/app/commands/decidim/accountability/admin/update_result.rb +0 -5
  10. data/app/controllers/decidim/accountability/application_controller.rb +1 -1
  11. data/app/controllers/decidim/accountability/results_controller.rb +1 -12
  12. data/app/forms/decidim/accountability/admin/result_form.rb +0 -11
  13. data/app/helpers/decidim/accountability/application_helper.rb +8 -6
  14. data/app/models/decidim/accountability/result.rb +3 -10
  15. data/app/services/decidim/accountability/result_search.rb +6 -3
  16. data/app/services/decidim/accountability/result_stats_calculator.rb +2 -6
  17. data/app/services/decidim/accountability/results_calculator.rb +1 -1
  18. data/app/views/decidim/accountability/admin/results/_form.html.erb +0 -4
  19. data/app/views/decidim/accountability/admin/results/index.html.erb +5 -2
  20. data/app/views/decidim/accountability/admin/shared/_extra.html.erb +1 -0
  21. data/app/views/decidim/accountability/admin/shared/_subnav.html.erb +1 -3
  22. data/app/views/decidim/accountability/results/_home_categories.html.erb +15 -9
  23. data/app/views/decidim/accountability/results/_home_header.html.erb +12 -13
  24. data/app/views/decidim/accountability/results/_linked_results.html.erb +1 -1
  25. data/app/views/decidim/accountability/results/_results_leaf.html.erb +5 -3
  26. data/app/views/decidim/accountability/results/_results_parent.html.erb +5 -3
  27. data/app/views/decidim/accountability/results/_show_leaf.html.erb +14 -14
  28. data/app/views/decidim/accountability/results/_show_parent.html.erb +1 -1
  29. data/config/locales/ca.yml +9 -41
  30. data/config/locales/en.yml +8 -40
  31. data/config/locales/es.yml +9 -41
  32. data/config/locales/eu.yml +99 -21
  33. data/config/locales/fi.yml +101 -21
  34. data/config/locales/fr.yml +157 -0
  35. data/config/locales/it.yml +157 -0
  36. data/config/locales/nl.yml +157 -0
  37. data/config/locales/pl.yml +158 -0
  38. data/config/locales/ru.yml +159 -0
  39. data/config/locales/uk.yml +159 -0
  40. data/db/migrate/20170426104125_create_accountability_results.rb +0 -1
  41. data/db/migrate/20170508104902_add_description_and_progress_to_statuses.rb +2 -0
  42. data/db/migrate/20170623094200_migrate_accountability_results_category.rb +2 -0
  43. data/db/migrate/20170623144902_add_children_counter_cache_to_results.rb +2 -0
  44. data/db/migrate/20170928073905_migrate_old_results.rb +53 -0
  45. data/lib/decidim/accountability.rb +2 -1
  46. data/lib/decidim/accountability/admin_engine.rb +0 -2
  47. data/lib/decidim/accountability/{list_engine.rb → engine.rb} +1 -2
  48. data/lib/decidim/accountability/feature.rb +53 -19
  49. data/lib/decidim/accountability/result_serializer.rb +66 -0
  50. data/lib/decidim/accountability/test/factories.rb +16 -16
  51. data/lib/decidim/accountability/version.rb +10 -0
  52. metadata +111 -53
  53. data/app/commands/decidim/accountability/admin/update_template_texts.rb +0 -47
  54. data/app/controllers/decidim/accountability/admin/imports_controller.rb +0 -30
  55. data/app/controllers/decidim/accountability/admin/template_texts_controller.rb +0 -38
  56. data/app/forms/decidim/accountability/admin/template_texts_form.rb +0 -19
  57. data/app/models/decidim/accountability/template_texts.rb +0 -17
  58. data/app/services/decidim/accountability/csv_exporter.rb +0 -77
  59. data/app/services/decidim/accountability/csv_importer.rb +0 -106
  60. data/app/views/decidim/accountability/admin/imports/new.html.erb +0 -47
  61. data/app/views/decidim/accountability/admin/template_texts/_form.html.erb +0 -30
  62. data/app/views/decidim/accountability/admin/template_texts/edit.html.erb +0 -8
  63. data/app/views/decidim/accountability/results/_tags.html.erb +0 -10
  64. data/config/i18n-tasks.yml +0 -10
  65. data/db/migrate/20170508161109_create_template_texts.rb +0 -14
  66. data/db/migrate/20170606102902_add_index_to_accountability_results_on_external_id.rb +0 -5
@@ -1,47 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Decidim
4
- module Accountability
5
- module Admin
6
- # This command is executed when the user changes TemplateTexts from the admin
7
- # panel.
8
- class UpdateTemplateTexts < Rectify::Command
9
- # Initializes an UpdateResult Command.
10
- #
11
- # form - The form from which to get the data.
12
- # template_texts - The current instance of the template_texts to be updated.
13
- def initialize(form, template_texts)
14
- @form = form
15
- @template_texts = template_texts
16
- end
17
-
18
- # Updates the result if valid.
19
- #
20
- # Broadcasts :ok if successful, :invalid otherwise.
21
- def call
22
- return broadcast(:invalid) if form.invalid?
23
-
24
- transaction do
25
- update_template_texts
26
- end
27
-
28
- broadcast(:ok)
29
- end
30
-
31
- private
32
-
33
- attr_reader :template_texts, :form
34
-
35
- def update_template_texts
36
- template_texts.update_attributes!(
37
- intro: @form.intro,
38
- categories_label: @form.categories_label,
39
- subcategories_label: @form.subcategories_label,
40
- heading_parent_level_results: @form.heading_parent_level_results,
41
- heading_leaf_level_results: @form.heading_leaf_level_results,
42
- )
43
- end
44
- end
45
- end
46
- end
47
- end
@@ -1,30 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Decidim
4
- module Accountability
5
- module Admin
6
- # This controller allows an admin to import results from a csv file for the Accountability feature
7
- class ImportsController < Admin::ApplicationController
8
-
9
- def new
10
- @errors = []
11
- end
12
-
13
- def create
14
- @csv_file = params[:csv_file]
15
- redirect_to new_import_path and return unless @csv_file.present?
16
-
17
- i = CSVImporter.new(current_feature, @csv_file.path)
18
- @errors = i.import!
19
- if @errors.empty?
20
- flash[:notice] = I18n.t("imports.create.success", scope: "decidim.accountability.admin")
21
- redirect_to new_import_path
22
- else
23
- flash.now[:error] = I18n.t("imports.create.invalid", scope: "decidim.accountability.admin")
24
- render :new
25
- end
26
- end
27
- end
28
- end
29
- end
30
- end
@@ -1,38 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Decidim
4
- module Accountability
5
- module Admin
6
- # This controller allows an admin to manage template texts per Accountability feature
7
- class TemplateTextsController < Admin::ApplicationController
8
- helper_method :template_texts
9
-
10
- def edit
11
- @form = form(TemplateTextsForm).from_model(template_texts)
12
- end
13
-
14
- def update
15
- @form = form(TemplateTextsForm).from_params(params)
16
-
17
- UpdateTemplateTexts.call(@form, template_texts) do
18
- on(:ok) do
19
- flash[:notice] = I18n.t("template_texts.update.success", scope: "decidim.accountability.admin")
20
- redirect_to edit_template_texts_path
21
- end
22
-
23
- on(:invalid) do
24
- flash.now[:alert] = I18n.t("template_texts.update.invalid", scope: "decidim.accountability.admin")
25
- render action: "edit"
26
- end
27
- end
28
- end
29
-
30
- private
31
-
32
- def template_texts
33
- @template_texts ||= TemplateTexts.for(current_feature)
34
- end
35
- end
36
- end
37
- end
38
- end
@@ -1,19 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Decidim
4
- module Accountability
5
- module Admin
6
- # This class holds a Form to create/update template texts from Decidim's admin panel.
7
- class TemplateTextsForm < Decidim::Form
8
- include TranslatableAttributes
9
- include TranslationsHelper
10
-
11
- translatable_attribute :intro, String
12
- translatable_attribute :categories_label, String
13
- translatable_attribute :subcategories_label, String
14
- translatable_attribute :heading_parent_level_results, String
15
- translatable_attribute :heading_leaf_level_results, String
16
- end
17
- end
18
- end
19
- end
@@ -1,17 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Decidim
4
- module Accountability
5
- # The data store for a Result in the Decidim::Accountability component. It stores a
6
- # title, description and any other useful information to render a custom result.
7
- class TemplateTexts < Accountability::ApplicationRecord
8
- include Decidim::HasFeature
9
-
10
- feature_manifest_name "accountability"
11
-
12
- def self.for(current_feature)
13
- self.where(feature: current_feature).first || self.create!(feature: current_feature)
14
- end
15
- end
16
- end
17
- end
@@ -1,77 +0,0 @@
1
- # frozen_string_literal: true
2
- require "csv"
3
-
4
- module Decidim
5
- module Accountability
6
- # This class handles exporting results to a CSV file.
7
- # Needs a `current_feature` param with a `Decidim::Feature`
8
- class CSVExporter
9
-
10
- # Public: Initializes the service.
11
- # feature - A Decidim::Feature to import the results into.
12
- def initialize(feature)
13
- @feature = feature
14
- end
15
-
16
- def export
17
- results = Decidim::Accountability::Result.where(feature: @feature).order(:id)
18
-
19
- generated_csv = CSV.generate(headers: true) do |csv|
20
- headers = [
21
- "result_id",
22
- "decidim_category_id",
23
- "decidim_scope_id",
24
- "parent_id",
25
- "external_id",
26
- "start_date",
27
- "end_date",
28
- "decidim_accountability_status_id",
29
- "progress",
30
- "proposal_ids"
31
- ]
32
-
33
- available_locales = @feature.participatory_space.organization.available_locales
34
- available_locales.each do |locale|
35
- headers << "title_#{locale}"
36
- headers << "description_#{locale}"
37
- end
38
-
39
- csv << headers
40
-
41
- results.find_each do |result|
42
- row = Rails.cache.fetch("#{result.cache_key}/csv") do
43
- row_for_result(result, available_locales)
44
- end
45
-
46
- csv << row
47
- end
48
- end
49
-
50
- generated_csv
51
- end
52
-
53
- private
54
-
55
- def row_for_result(result, available_locales)
56
- row = [
57
- result.id,
58
- result.category.try(:id),
59
- result.decidim_scope_id,
60
- result.parent_id,
61
- result.external_id,
62
- result.start_date,
63
- result.end_date,
64
- result.decidim_accountability_status_id,
65
- result.progress,
66
- result.linked_resources(:proposals, "included_proposals").pluck(:id).sort.join(";"),
67
- ]
68
- available_locales.each do |locale|
69
- row << result.title[locale]
70
- row << result.description[locale]
71
- end
72
-
73
- row
74
- end
75
- end
76
- end
77
- end
@@ -1,106 +0,0 @@
1
- # frozen_string_literal: true
2
- require "csv"
3
-
4
- module Decidim
5
- module Accountability
6
- # This class handles importing results from a CSV file.
7
- # Needs a `current_feature` param with a `Decidim::Feature`
8
- # in order to import the results in that feature.
9
- class CSVImporter
10
- include Decidim::FormFactory
11
-
12
- # Public: Initializes the service.
13
- # feature - A Decidim::Feature to import the results into.
14
- # csv_file_path - The path to the csv file.
15
- def initialize(feature, csv_file_path)
16
- @feature = feature
17
- @csv_file_path = csv_file_path
18
- @extra_context = { current_feature: feature, current_organization: feature.organization}
19
- end
20
-
21
- def import!
22
- errors = []
23
-
24
- ActiveRecord::Base.transaction do
25
- i = 1
26
- CSV.foreach(@csv_file_path, headers: true) do |row|
27
- i += 1
28
- next if row.empty?
29
-
30
- params = {}
31
- params["result"] = row.to_hash
32
-
33
- if row["result_id"].present?
34
- existing_result = Decidim::Accountability::Result.find_by(id: row['result_id'].to_i)
35
- unless existing_result.present?
36
- errors << [i, [I18n.t("imports.create.not_found", scope: "decidim.accountability.admin", result_id: row["result_id"])]]
37
- next
38
- end
39
- elsif row["external_id"].present?
40
- existing_result = Decidim::Accountability::Result.find_by(external_id: row["external_id"])
41
- params["result"]["id"] = existing_result.id if existing_result
42
- end
43
-
44
- if row["parent_id"].blank? && row["parent_external_id"].present?
45
- if parent = Decidim::Accountability::Result.find_by(external_id: row["parent_external_id"])
46
- params["result"]["parent_id"] = parent.id
47
- end
48
- end
49
-
50
- if row["decidim_accountability_status_id"].present? && status = Decidim::Accountability::Status.find_by(id: row["decidim_accountability_status_id"])
51
- params["result"]["progress"] = status.progress if status.progress.present?
52
- end
53
-
54
- default_locale = @feature.participatory_space.organization.default_locale
55
- available_locales = @feature.participatory_space.organization.available_locales
56
-
57
- available_locales.each do |locale|
58
- params["result"]["title_#{locale}"] = params["result"]["title_#{default_locale}"] if params["result"]["title_#{locale}"].blank?
59
- params["result"]["description_#{locale}"] = params["result"]["description_#{default_locale}"] if params["result"]["description_#{locale}"].blank?
60
- end
61
-
62
- if params["result"]["proposal_ids"].presence
63
- proposal_ids = params["result"]["proposal_ids"].split(";")
64
- params["result"]["proposal_ids"] = proposal_ids
65
- end
66
-
67
- @form = form(Decidim::Accountability::Admin::ResultForm).from_params(params, @extra_context)
68
-
69
- begin
70
- start_date = Date.parse(row["start_date"]) if row["start_date"].present?
71
- rescue ArgumentError
72
- @form.errors.add(:start_date, :invalid_date)
73
- end
74
-
75
- begin
76
- end_date = Date.parse(row["end_date"]) if row["end_date"].present?
77
- rescue ArgumentError
78
- @form.errors.add(:end_date, :invalid_date)
79
- end
80
-
81
- # add form errors now because when calling valid on the form in UpdateResult/CreateResult will clear the errors
82
- errors << [i, @form.errors.full_messages] if @form.errors.any?
83
-
84
- if existing_result #update existing result
85
- Decidim::Accountability::Admin::UpdateResult.call(@form, existing_result) do
86
- on(:invalid) do
87
- errors << [i, @form.errors.full_messages]
88
- end
89
- end
90
- else #create new result
91
- Decidim::Accountability::Admin::CreateResult.call(@form) do
92
- on(:invalid) do
93
- errors << [i, @form.errors.full_messages]
94
- end
95
- end
96
- end
97
- end
98
-
99
- raise ActiveRecord::Rollback if errors.any?
100
- end
101
-
102
- errors
103
- end
104
- end
105
- end
106
- end
@@ -1,47 +0,0 @@
1
- <%= form_tag({:action => :create}, 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
- <%= render partial: "decidim/accountability/admin/shared/subnav" %>
7
- </h2>
8
- </div>
9
-
10
- <% unless @errors.empty? %>
11
- <div class="card-section">
12
- <div class="row column">
13
- <table>
14
- <thead>
15
- <tr>
16
- <th><%= t(".row_number") %></th>
17
- <th><%= t(".errors") %></th>
18
- </tr>
19
- </thead>
20
- <% @errors.each do |error| %>
21
- <tr>
22
- <td><%= error.first %></td>
23
- <td>
24
- <ul>
25
- <% error.last.each do |error_message| %>
26
- <li><%= error_message %></li>
27
- <% end %>
28
- </ul>
29
- </td>
30
- </tr>
31
- <% end %>
32
- </table>
33
- </div>
34
- </div>
35
- <% end %>
36
-
37
- <div class="card-section">
38
- <div class="row column">
39
- <%= file_field_tag :csv_file %>
40
- </div>
41
- </div>
42
- </div>
43
-
44
- <div class="button--double form-general-submit">
45
- <%= submit_tag t(".import"), class: "button" %>
46
- </div>
47
- <% end %>
@@ -1,30 +0,0 @@
1
- <div class="card">
2
- <div class="card-divider">
3
- <h2 class="card-title">
4
- <%= t(".title") %>
5
- <%= render partial: "decidim/accountability/admin/shared/subnav" %>
6
- </h2>
7
- </div>
8
-
9
- <div class="card-section">
10
- <div class="row column">
11
- <%= form.translated :editor, :intro, autofocus: true %>
12
- </div>
13
-
14
- <div class="row column">
15
- <%= form.translated :text_field, :categories_label %>
16
- </div>
17
-
18
- <div class="row column">
19
- <%= form.translated :text_field, :subcategories_label %>
20
- </div>
21
-
22
- <div class="row column">
23
- <%= form.translated :text_field, :heading_parent_level_results %>
24
- </div>
25
-
26
- <div class="row column">
27
- <%= form.translated :text_field, :heading_leaf_level_results %>
28
- </div>
29
- </div>
30
- </div>
@@ -1,8 +0,0 @@
1
- <%= decidim_form_for(@form, url: template_texts_path, html: { class: "form edit_template_texts" }) do |f| %>
2
- <%= render partial: 'form', object: f, locals: { title: t('.title') } %>
3
-
4
- <div class="button--double form-general-submit">
5
- <%= f.submit t(".update") %>
6
- </div>
7
- <% end %>
8
-
@@ -1,10 +0,0 @@
1
- <% if result.category.present? || result.scope.present? %>
2
- <ul class="tags tags--result" >
3
- <% if result.category.present? %>
4
- <li><%= link_to translated_attribute(result.category.name), results_path(filter: { category_id: result.category.id }) %></li>
5
- <% end %>
6
- <% if !current_participatory_process.scope && result.scope.present? %>
7
- <li><%= link_to result.scope.name, results_path(filter: { scope_id: [result.scope.id] }) %></li>
8
- <% end %>
9
- </ul>
10
- <% end %>