Skip to content
This repository has been archived by the owner on Dec 16, 2024. It is now read-only.

Commit

Permalink
fix: use image name env var
Browse files Browse the repository at this point in the history
Add paper_trail
  • Loading branch information
LindseySaari authored Feb 15, 2022
2 parents 4c0abf4 + cb35192 commit 1362b98
Show file tree
Hide file tree
Showing 17 changed files with 256 additions and 12 deletions.
1 change: 1 addition & 0 deletions Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ gem 'flipper-redis', '~> 0.23' # Redis adapter for Flipper
gem 'flipper-ui', '~> 0.23' # UI for the Flipper gem
gem 'jbuilder', '~> 2.11' # Build JSON APIs with ease [https://github.com/rails/jbuilder]
gem 'pagy', '~> 5.10' # Agnostic pagination in plain ruby
gem 'paper_trail', '~> 12.2' # Track changes to your models, for auditing or versioning
gem 'pg', '~> 1.3' # Use postgresql as the database for Active Record
gem 'puma', '~> 5.6' # Use the Puma web server [https://github.com/puma/puma]
gem 'redis', '~> 4.6' # Use Redis adapter to run Action Cable in production
Expand Down
6 changes: 6 additions & 0 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,9 @@ GEM
racc (~> 1.4)
pagy (5.10.1)
activesupport
paper_trail (12.2.0)
activerecord (>= 5.2)
request_store (~> 1.1)
parallel (1.21.0)
parser (3.1.0.0)
ast (~> 2.4.1)
Expand Down Expand Up @@ -208,6 +211,8 @@ GEM
rake (13.0.6)
redis (4.6.0)
regexp_parser (2.2.0)
request_store (1.5.1)
rack (>= 1.4)
rexml (3.2.5)
rolify (6.0.0)
rubocop (1.25.1)
Expand Down Expand Up @@ -300,6 +305,7 @@ DEPENDENCIES
jbuilder (~> 2.11)
minitest-ci
pagy (~> 5.10)
paper_trail (~> 12.2)
pg (~> 1.3)
pry-awesome_print
pry-rails
Expand Down
1 change: 1 addition & 0 deletions app/controllers/application_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,5 @@
class ApplicationController < ActionController::Base
include Authenticatable
include Pagy::Backend
before_action :set_paper_trail_whodunnit
end
29 changes: 29 additions & 0 deletions app/controllers/audits_controller.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# frozen_string_literal: true

# Displays an audits table to track changes to models, for auditing and versioning
class AuditsController < ApplicationController
before_action :authorize_session!

# GET /audits or /audits.json
def index
@audits = PaperTrail::Version.all
@pagy, @audits = pagy(
@audits.reorder(sort_column => sort_direction),
items: params.fetch(:count, 25),
link_extra: 'data-turbo-action="advance"'
)
end

# GET /audits/1 or /audits/1.json
def show; end

private

def sort_column
%w[created_at].include?(params[:sort]) ? params[:sort] : 'created_at'
end

def sort_direction
%w[asc desc].include?(params[:direction]) ? params[:direction] : 'desc'
end
end
18 changes: 18 additions & 0 deletions app/javascript/controllers/toggle_controller.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { Controller } from "@hotwired/stimulus"

export default class extends Controller {

static get targets() {
return ['item']
}

connect() {
this.class = this.hasHiddenClass ? this.hiddenClass : 'hidden'
}

toggleTargets() {
this.itemTargets.forEach(item => {
item.classList.toggle(this.class)
});
}
}
1 change: 1 addition & 0 deletions app/models/app.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,6 @@

class App < ApplicationRecord
belongs_to :team
has_paper_trail
validates :name, presence: true
end
2 changes: 1 addition & 1 deletion app/models/role.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

class Role < ApplicationRecord
has_many :users, through: :user_roles

has_paper_trail
belongs_to :resource,
polymorphic: true,
optional: true
Expand Down
3 changes: 2 additions & 1 deletion app/models/team.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

class Team < ApplicationRecord
belongs_to :owner, polymorphic: true
validates :name, presence: true
has_many :apps, dependent: :nullify
has_paper_trail
validates :name, presence: true
end
4 changes: 2 additions & 2 deletions app/models/user.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@

# The User Model
class User < ApplicationRecord
rolify
has_paper_trail
has_secure_password

before_validation :downcase_email
rolify
validates :email, uniqueness: true
validates :name, :email, presence: true
validates :password, length: { minimum: 8 }, if: :password
Expand Down
95 changes: 95 additions & 0 deletions app/views/audits/index.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
<div class="flex justify-between">
<h1 class="text-2xl font-bold leading-7 text-gray-900 sm:text-3xl sm:truncate mt-4">
Audits
</h1>
</div>

<br>

<% if @audits.present? %>
<%= form_with url: '', method: :get, class: 'mb-2 px-2 py-2', data: { turbo_frame: 'audits', turbo_action: 'advance' } do |form| %>
Show <%= form.select :count, options_for_select([10, 25, 50, 100], selected: @pagy.items), {},
{ class: 'rounded-md text-sm focus:border-blue-900 focus:ring-0', onchange: 'this.form.requestSubmit()' } %>
<% end %>
<%= turbo_frame_tag 'audits' do %>
<div class="flex flex-col">
<div class="-my-2 overflow-x-auto sm:-mx-6 lg:-mx-8">
<div class="py-2 align-middle inline-block min-w-full sm:px-6 lg:px-8">
<div class="shadow overflow-hidden border-b border-gray-200 sm:rounded-lg">
<table class="table-fixed min-w-full divide-y divide-gray-200" id="audits">
<thead class="bg-gray-50">
<tr>
<th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase w-full">
Item Type
</th>
<th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase w-full">
Item Id
</th>
<th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase w-full">
Event
</th>
<th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase w-full">
Created At
</th>
<th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase w-full">
Whodunnit?
</th>
<th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase w-full">
Details
</th>
</tr>
</thead>
<tbody>
<% @audits.each do |audit| %>
<tr class="<%= cycle 'bg-white', 'bg-gray-50' %>">
<td class="px-6 py-2 whitespace-nowrap text-sm font-medium text-gray-900">
<%= audit.item_type %>
</td>
<td class="px-6 py-4 whitespace-nowrap text-sm font-medium text-gray-900">
<%= audit.item_id %>
</td>
<td class="px-6 py-4 whitespace-nowrap text-sm font-medium text-gray-900">
<%= audit.event %>
</td>
<td class="px-6 py-4 whitespace-nowrap text-sm font-medium text-gray-900">
<%= audit.whodunnit %>
</td>
<td class="px-6 py-4 whitespace-nowrap text-sm font-medium text-gray-900">
<%= audit.created_at %>
</td>
<td class="max-w-7xl text-sm font-medium text-gray-900">
<% if audit.object.present? %>
<div data-controller="toggle" data-toggle-hidden-class="hidden">
<%= button_tag "Show/Hide", data: {controller: "toggle", action: "click->toggle#toggleTargets", class: "hidden" } do %>
<div data-toggle-target="item" class="hidden text-left">
<span style="float:left;" class="inline-flex items-center px-4 py-2 border border-transparent text-sm font-medium rounded-md shadow-sm text-white bg-blue-900 hover:bg-blue-800 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500">Hide Details</span>
<br/><br/>
<span><%= audit.object %></span>
</div>
<div data-toggle-target="item" class="inline-flex items-center px-4 py-2 border border-transparent text-sm font-medium rounded-md shadow-sm text-white bg-blue-900 hover:bg-blue-800 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500">Details</div>
<% end %>
</div>
<% end %>
</td>
</tr>
<% end %>
</tbody>
</table>
</div>
</div>
</div>
</div>

<% if @pagy %>
<div class="flex-wrap lg:flex mt-6 lg:mt-0 justify-between space-x-4 text-center">
<%== pagy_info @pagy %>
<%== pagy_nav @pagy, size: [1,1,1,1] %>
</div>
<% end %>
<% end %>
<% else %>
<div class="text-center border-dashed border-gray-300 hover:border-gray-400 border-2 rounded-lg p-6 max-w-lg m-auto">
<svg width="96" height="96" fill="none" class="mx-auto mb-6 text-gray-900"><path d="M36 28.024A18.05 18.05 0 0025.022 39M59.999 28.024A18.05 18.05 0 0170.975 39" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"></path><ellipse cx="37.5" cy="43.5" rx="4.5" ry="7.5" fill="currentColor"></ellipse><ellipse cx="58.5" cy="43.5" rx="4.5" ry="7.5" fill="currentColor"></ellipse><path d="M24.673 75.42a9.003 9.003 0 008.879 5.563m-8.88-5.562A8.973 8.973 0 0124 72c0-7.97 9-18 9-18s9 10.03 9 18a9 9 0 01-8.448 8.983m-8.88-5.562C16.919 68.817 12 58.983 12 48c0-19.882 16.118-36 36-36s36 16.118 36 36-16.118 36-36 36a35.877 35.877 0 01-14.448-3.017" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"></path><path d="M41.997 71.75A14.94 14.94 0 0148 70.5c2.399 0 4.658.56 6.661 1.556a3 3 0 003.999-4.066 12 12 0 00-10.662-6.49 11.955 11.955 0 00-7.974 3.032c1.11 2.37 1.917 4.876 1.972 7.217z" fill="currentColor"></path></svg>
<h3 class="mt-2 text-sm font-medium text-gray-900">No Audits</h3>
</div>
<% end %>
3 changes: 3 additions & 0 deletions app/views/audits/index.json.jbuilder
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# frozen_string_literal: true

json.array! @audits, partial: 'audits/audit', as: :audit
1 change: 1 addition & 0 deletions config/routes.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
require 'authenticatable_constraint'

Rails.application.routes.draw do
resources :audits, only: [:index]
resources :teams do
resources :apps
end
Expand Down
17 changes: 17 additions & 0 deletions db/migrate/20220215144301_create_versions.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# frozen_string_literal: true

# This migration creates the `versions` table, the only schema PT requires.
# All other migrations PT provides are optional.
class CreateVersions < ActiveRecord::Migration[7.0]
def change
create_table :versions do |t|
t.string :item_type, null: false
t.bigint :item_id, null: false
t.string :event, null: false
t.string :whodunnit
t.text :object
t.datetime :created_at
end
add_index :versions, %i[item_type item_id]
end
end
25 changes: 17 additions & 8 deletions db/schema.rb

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 6 additions & 0 deletions test/models/app_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,12 @@ class AppTest < ActiveSupport::TestCase
assert app.valid?
end

test 'valid app with papertrail versions' do
app = @team.apps.new(name: 'New App 1', team_id: @team.id)
assert app.valid?
assert_not_nil app.versions
end

test 'invalid app' do
app = @team.apps.build(name: nil, team_id: @team.id)
assert_not app.valid?
Expand Down
25 changes: 25 additions & 0 deletions test/models/team_test.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# frozen_string_literal: true

require 'test_helper'

class TeamTest < ActiveSupport::TestCase
setup do
@team = teams(:one)
end

test 'valid team' do
@team.update(name: 'Console Services')
assert @team.valid?
end

test 'valid team with papertrail versions' do
@team.update(name: 'Console Services')
assert @team.valid?
assert_not_nil @team.versions
end

test 'invalid team' do
team = Team.new
assert_not team.valid?
end
end
31 changes: 31 additions & 0 deletions test/system/audits_test.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# frozen_string_literal: true

require 'application_system_test_case'

class AuditsTest < ApplicationSystemTestCase
setup do
login_as :john

(1..3).each do |t|
new_app = apps(:one).dup
new_app.name = "App #{t}"
new_app.save

new_team = teams(:one).dup
new_team.name = "Team #{t}"
new_team.save
end
end

test 'visiting the index' do
visit audits_url
assert_selector 'h1', text: 'Audits'
assert_selector 'th', text: 'ITEM TYPE'
assert_selector 'td', text: 'App'
assert_selector 'td', text: 'Team'
assert_selector 'div', text: 'DETAILS'

click_on 'Details', match: :first
assert_selector 'span', text: 'Hide Details'
end
end

0 comments on commit 1362b98

Please sign in to comment.