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.
- checksums.yaml +4 -4
- data/README.md +1 -21
- data/app/assets/javascripts/decidim/accountability/accountability.js.es6 +3 -3
- data/app/assets/javascripts/decidim/accountability/admin/accountability_admin.js +3 -2
- data/app/assets/stylesheets/decidim/accountability/accountability/_categories.scss +13 -13
- data/app/assets/stylesheets/decidim/accountability/accountability/_lines_breadcrumb.scss +5 -5
- data/app/assets/stylesheets/decidim/accountability/accountability/_results.scss +5 -5
- data/app/commands/decidim/accountability/admin/create_result.rb +0 -1
- data/app/commands/decidim/accountability/admin/update_result.rb +0 -5
- data/app/controllers/decidim/accountability/application_controller.rb +1 -1
- data/app/controllers/decidim/accountability/results_controller.rb +1 -12
- data/app/forms/decidim/accountability/admin/result_form.rb +0 -11
- data/app/helpers/decidim/accountability/application_helper.rb +8 -6
- data/app/models/decidim/accountability/result.rb +3 -10
- data/app/services/decidim/accountability/result_search.rb +6 -3
- data/app/services/decidim/accountability/result_stats_calculator.rb +2 -6
- data/app/services/decidim/accountability/results_calculator.rb +1 -1
- data/app/views/decidim/accountability/admin/results/_form.html.erb +0 -4
- data/app/views/decidim/accountability/admin/results/index.html.erb +5 -2
- data/app/views/decidim/accountability/admin/shared/_extra.html.erb +1 -0
- data/app/views/decidim/accountability/admin/shared/_subnav.html.erb +1 -3
- data/app/views/decidim/accountability/results/_home_categories.html.erb +15 -9
- data/app/views/decidim/accountability/results/_home_header.html.erb +12 -13
- data/app/views/decidim/accountability/results/_linked_results.html.erb +1 -1
- data/app/views/decidim/accountability/results/_results_leaf.html.erb +5 -3
- data/app/views/decidim/accountability/results/_results_parent.html.erb +5 -3
- data/app/views/decidim/accountability/results/_show_leaf.html.erb +14 -14
- data/app/views/decidim/accountability/results/_show_parent.html.erb +1 -1
- data/config/locales/ca.yml +9 -41
- data/config/locales/en.yml +8 -40
- data/config/locales/es.yml +9 -41
- data/config/locales/eu.yml +99 -21
- data/config/locales/fi.yml +101 -21
- data/config/locales/fr.yml +157 -0
- data/config/locales/it.yml +157 -0
- data/config/locales/nl.yml +157 -0
- data/config/locales/pl.yml +158 -0
- data/config/locales/ru.yml +159 -0
- data/config/locales/uk.yml +159 -0
- data/db/migrate/20170426104125_create_accountability_results.rb +0 -1
- data/db/migrate/20170508104902_add_description_and_progress_to_statuses.rb +2 -0
- data/db/migrate/20170623094200_migrate_accountability_results_category.rb +2 -0
- data/db/migrate/20170623144902_add_children_counter_cache_to_results.rb +2 -0
- data/db/migrate/20170928073905_migrate_old_results.rb +53 -0
- data/lib/decidim/accountability.rb +2 -1
- data/lib/decidim/accountability/admin_engine.rb +0 -2
- data/lib/decidim/accountability/{list_engine.rb → engine.rb} +1 -2
- data/lib/decidim/accountability/feature.rb +53 -19
- data/lib/decidim/accountability/result_serializer.rb +66 -0
- data/lib/decidim/accountability/test/factories.rb +16 -16
- data/lib/decidim/accountability/version.rb +10 -0
- metadata +111 -53
- data/app/commands/decidim/accountability/admin/update_template_texts.rb +0 -47
- data/app/controllers/decidim/accountability/admin/imports_controller.rb +0 -30
- data/app/controllers/decidim/accountability/admin/template_texts_controller.rb +0 -38
- data/app/forms/decidim/accountability/admin/template_texts_form.rb +0 -19
- data/app/models/decidim/accountability/template_texts.rb +0 -17
- data/app/services/decidim/accountability/csv_exporter.rb +0 -77
- data/app/services/decidim/accountability/csv_importer.rb +0 -106
- data/app/views/decidim/accountability/admin/imports/new.html.erb +0 -47
- data/app/views/decidim/accountability/admin/template_texts/_form.html.erb +0 -30
- data/app/views/decidim/accountability/admin/template_texts/edit.html.erb +0 -8
- data/app/views/decidim/accountability/results/_tags.html.erb +0 -10
- data/config/i18n-tasks.yml +0 -10
- data/db/migrate/20170508161109_create_template_texts.rb +0 -14
- 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 %>
|