Add change log in investment participatory budget

This commit is contained in:
German Galia
2019-06-02 17:44:38 +02:00
committed by lalo
parent 259e05c3e0
commit 16ffa2a259
16 changed files with 243 additions and 3 deletions

View File

@@ -595,6 +595,17 @@ code {
}
}
.log-value {
max-height: rem-calc(65);
overflow: hidden;
max-width: rem-calc(200);
&:hover {
max-height: rem-calc(1000);
transition: max-height 0.9s;
}
}
// 04. Stats
// ---------

View File

@@ -2,17 +2,19 @@ class Admin::BudgetInvestmentsController < Admin::BaseController
include FeatureFlags
include CommentableActions
include DownloadSettingsHelper
include ChangeLogHelper
feature_flag :budgets
has_orders %w[oldest], only: [:show, :edit]
has_filters %w[all], only: [:index, :toggle_selection]
before_action :load_budget
before_action :load_budget, except: :show_investment_log
before_action :load_investment, only: [:show, :edit, :update, :toggle_selection]
before_action :load_ballot, only: [:show, :index]
before_action :parse_valuation_filters
before_action :load_investments, only: [:index, :toggle_selection]
before_action :load_change_log, only: [:show]
def index
respond_to do |format|
@@ -129,4 +131,8 @@ class Admin::BudgetInvestmentsController < Admin::BaseController
end
end
end
def load_change_log
@logs = Budget::Investment::ChangeLog.by_investment(@investment.id)
end
end

View File

@@ -13,6 +13,7 @@ class ApplicationController < ActionController::Base
before_action :set_locale
before_action :track_email_campaign
before_action :set_return_url
before_action :set_current_user
before_action :set_fallbacks_to_all_available_locales
check_authorization unless: :devise_controller?
@@ -120,6 +121,10 @@ class ApplicationController < ActionController::Base
Budget.current
end
def set_current_user
User.current_user = current_user
end
def set_fallbacks_to_all_available_locales
Globalize.set_fallbacks_to_all_available_locales
end

View File

@@ -0,0 +1,8 @@
module ChangeLogHelper
def show_investment_log
@log = Budget::Investment::ChangeLog.find_by(id: params[:id])
render "admin/change_logs/show"
end
end

View File

@@ -3,6 +3,7 @@ class Budget
class Investment < ApplicationRecord
SORTING_OPTIONS = {id: "id", title: "title", supports: "cached_votes_up"}.freeze
include ActiveModel::Dirty
include Rails.application.routes.url_helpers
include Measurable
include Sanitizable
@@ -100,6 +101,7 @@ class Budget
after_save :recalculate_heading_winners
before_validation :set_responsible_name
before_validation :set_denormalized_ids
after_update :change_log
def comments_count
comments.count
@@ -391,5 +393,18 @@ class Budget
self.budget_id ||= heading.try(:group).try(:budget_id)
end
def change_log
self.changed.each do |field|
unless field == "updated_at"
log = Budget::Investment::ChangeLog.new
log.field = field
log.author_id = User.current_user.id unless User.current_user.nil?
log.investment_id = self.id
log.new_value = self.send field
log.old_value = self.send "#{field}_was"
!log.save
end
end
end
end
end

View File

@@ -0,0 +1,10 @@
class Budget::Investment::ChangeLog < ActiveRecord::Base
belongs_to :author, -> { with_hidden }, class_name: "User", foreign_key: "author_id", required: false
validates :old_value, presence: true
validates :new_value, presence: true
validates :field, presence: true
scope :by_investment, ->(investment_id) { where(investment_id: investment_id) }
end

View File

@@ -350,6 +350,15 @@ class User < ApplicationRecord
followables.compact.map { |followable| followable.tags.map(&:name) }.flatten.compact.uniq
end
def self.current_user
Thread.current[:user]
end
def self.current_user=(user)
Thread.current[:user] = user
end
def send_devise_notification(notification, *args)
devise_mailer.send(notification, self, *args).deliver_later
end

View File

@@ -67,3 +67,5 @@
<%= render "valuation/budget_investments/valuation_comments" %>
<%= render "admin/milestones/milestones", milestoneable: @investment %>
<%= render "admin/change_logs/change_log", logs: @logs %>

View File

@@ -0,0 +1,44 @@
<h2 class="inline-block"><%= t("admin.change_log.title") %></h2>
<% if logs.empty? %>
<label><%= t("admin.change_log.empty") %></label>
<% else %>
<table>
<thead>
<tr>
<th><%= t("admin.change_log.id") %></th>
<th><%= t("admin.change_log.field") %></th>
<th><%= t("admin.change_log.old_value") %></th>
<th><%= t("admin.change_log.new_value") %></th>
<th><%= t("admin.change_log.edited_at") %></th>
<th><%= t("admin.change_log.edited_by") %></th>
<th><%= t("admin.change_log.actions") %></th>
</tr>
</thead>
<tbody>
<% logs.each do |log| %>
<tr id="log_<%= log.id %>">
<td class="text-center"><%= log.id %></td>
<td class="small"><%= log.field.capitalize %></td>
<td class="small">
<div class="log-value"><%= log.old_value %></div>
</td>
<td class="small">
<div class="log-value"><%= log.new_value %></div>
</td>
<td class="small">
<%= log.created_at.to_date %>
</td>
<td class="small">
<%= log.author.name unless log.author.nil? %>
</td>
<td>
<%= link_to admin_change_log_path(id: log) do %>
<button class="button hollow primary"><%= t("shared.show") %></button>
<% end %>
</td>
</tr>
<% end %>
</tbody>
</table>
<% end %>

View File

@@ -0,0 +1,12 @@
<h2 class="inline-block"><%= t("admin.change_log.title") %></h2>
<label><strong><%= t("admin.change_log.id") %></strong></label>
<p><%= @log.id %></p>
<label><strong><%= t("admin.change_log.old_value") %></strong></label>
<p><%= @log.old_value %></p>
<label><strong><%= t("admin.change_log.new_value") %></strong></label>
<p><%= @log.new_value %></p>
<label><strong><%= t("admin.change_log.edited_at") %></strong></label>
<p><%= @log.created_at.to_date %></p>
<label><strong><%= t("admin.change_log.edited_by") %></strong></label>
<p><%= @log.author.name unless @log.author.nil? %></p>

View File

@@ -1638,3 +1638,13 @@ en:
translations:
remove_language: Remove language
add_language: Add language
change_log:
title: "Change Log"
id: "ID"
field: "Field"
new_value: "New Value"
old_value: "Old Value"
edited_at: "Edited at"
edited_by: "Edited by"
actions: "Actions"
empty: "There are not changes logged"

View File

@@ -1636,3 +1636,13 @@ es:
translations:
remove_language: Eliminar idioma
add_language: Añadir idioma
change_log:
title: "Historial"
id: "ID"
field: "Campo"
new_value: "Valor nuevo"
old_value: "Valor anterior"
edited_at: "Editado el"
edited_by: "Editado por"
actions: "Acciones"
empty: "No hay cambios registrados"

View File

@@ -245,6 +245,10 @@ namespace :admin do
resources :actions, only: [:index, :new, :create, :edit, :update, :destroy]
resources :administrator_tasks, only: [:index, :edit, :update]
end
get 'download_settings/:resource', to: 'download_settings#edit', as: 'edit_download_settings'
put 'download_settings/:resource', to: 'download_settings#update', as: 'update_download_settings'
get "/change_log/:id", to: "budget_investments#show_investment_log", as: "change_log"
end

View File

@@ -0,0 +1,13 @@
class CreateBudgetInvestmentChangeLogs < ActiveRecord::Migration
def change
create_table :budget_investment_change_logs do |t|
t.integer :investment_id
t.integer :author_id
t.string :field
t.string :new_value
t.string :old_value
t.timestamps null: false
end
end
end

View File

@@ -134,9 +134,9 @@ ActiveRecord::Schema.define(version: 20190607160900) do
t.integer "budget_id"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.integer "ballot_lines_count", default: 0
t.boolean "physical", default: false
t.integer "poll_ballot_id"
t.integer "ballot_lines_count", default: 0
end
create_table "budget_content_blocks", force: :cascade do |t|
@@ -188,6 +188,16 @@ ActiveRecord::Schema.define(version: 20190607160900) do
t.index ["group_id"], name: "index_budget_headings_on_group_id", using: :btree
end
create_table "budget_investment_change_logs", force: :cascade do |t|
t.integer "investment_id"
t.integer "author_id"
t.string "field"
t.string "new_value"
t.string "old_value"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
create_table "budget_investment_milestone_translations", force: :cascade do |t|
t.integer "budget_investment_milestone_id", null: false
t.string "locale", null: false
@@ -1177,12 +1187,12 @@ ActiveRecord::Schema.define(version: 20190607160900) do
t.integer "comments_count", default: 0
t.integer "author_id"
t.datetime "hidden_at"
t.string "slug"
t.boolean "results_enabled", default: false
t.boolean "stats_enabled", default: false
t.datetime "created_at"
t.datetime "updated_at"
t.integer "budget_id"
t.string "slug"
t.string "related_type"
t.integer "related_id"
t.index ["budget_id"], name: "index_polls_on_budget_id", unique: true, using: :btree

View File

@@ -0,0 +1,71 @@
require "rails_helper"
feature "Admin change log" do
let(:budget) {create(:budget)}
let(:administrator) do
create(:administrator, user: create(:user, username: "Ana", email: "ana@admins.org"))
end
context "Investments Participatory Budgets" do
background do
@admin = create(:administrator)
login_as(@admin.user)
end
scenario "No changes" do
budget_investment = create(:budget_investment,
price: 1234,
price_first_year: 1000,
feasibility: "unfeasible",
unfeasibility_explanation: "It is impossible",
administrator: administrator)
visit admin_budget_budget_investments_path(budget_investment.budget)
click_link budget_investment.title
expect(page).to have_content(budget_investment.title)
expect(page).to have_content(budget_investment.description)
expect(page).to have_content(budget_investment.author.name)
expect(page).to have_content(budget_investment.heading.name)
expect(page).to have_content("There are not changes logged")
end
scenario "Changes" do
budget_investment = create(:budget_investment,
price: 1234,
price_first_year: 1000,
feasibility: "unfeasible",
unfeasibility_explanation: "It is impossible",
administrator: administrator)
visit admin_budget_budget_investments_path(budget_investment.budget)
click_link budget_investment.title
expect(page).to have_content(budget_investment.title)
expect(page).to have_content(budget_investment.description)
expect(page).to have_content(budget_investment.author.name)
expect(page).to have_content(budget_investment.heading.name)
expect(page).to have_content("There are not changes logged")
budget_investment.update(title: "test")
visit admin_budget_budget_investments_path(budget_investment.budget)
click_link budget_investment.title
expect(page).not_to have_content("There are not changes logged")
expect(page).to have_content("Change Log")
expect(page).to have_content("Title")
expect(page).to have_content("test")
expect(page).to have_content("Field")
expect(page).to have_content("Old Value")
expect(page).to have_content("New Value")
expect(page).to have_content("Edited at")
expect(page).to have_content("Edited by")
end
end
end