Skip to content
This repository has been archived by the owner on Mar 1, 2018. It is now read-only.

Commit

Permalink
Merge pull request #110 from rickychilcott/master
Browse files Browse the repository at this point in the history
Various display fixes and now AJAxified computer index. #86
  • Loading branch information
jnraine committed Dec 7, 2011
2 parents 3c7bc53 + 2493533 commit 67ff428
Show file tree
Hide file tree
Showing 18 changed files with 110 additions and 62 deletions.
2 changes: 1 addition & 1 deletion Gemfile
Expand Up @@ -4,7 +4,7 @@ source 'http://gemcutter.org'

gem "rails", "3.0.10"
gem "sqlite3-ruby", :require => "sqlite3"
gem "will_paginate", "~>3.0.beta" # version added for rails 3 compatibility
gem 'will_paginate', '~> 3.0' # version added for rails 3 compatibility
gem "nokogiri"
gem "paperclip"
gem "client_side_validations"
Expand Down
2 changes: 1 addition & 1 deletion Gemfile.lock
Expand Up @@ -124,4 +124,4 @@ DEPENDENCIES
sqlite3-ruby
textmate_backtracer
whenever
will_paginate (~> 3.0.beta)
will_paginate (~> 3.0)
26 changes: 24 additions & 2 deletions app/controllers/computers_controller.rb
@@ -1,10 +1,20 @@
require 'cgi'

class ComputersController < ApplicationController
helper_method :sort_column, :sort_direction

def index
# Set environment at view layer
@computers = ComputerService.collect(params,current_unit,current_environment)
# Scope computers to unit/environment and then order by relevent column and direction
@computers = Computer.unit_and_environment(current_unit, current_environment)
@computers = @computers.order(sort_column + ' ' + sort_direction)

#Search for value on name attribute
@computers = @computers.search(:name, params[:name])

# Add pagination using will_paginate gem
per_page = params[:per_page]
per_page ||= Computer.per_page
@computers = @computers.paginate(:page => params[:page], :per_page => per_page)

respond_to do |format|
format.html # index.html
Expand Down Expand Up @@ -226,4 +236,16 @@ def load_singular_resource
raise Exception("Unable to load singular resource for #{action} action in #{params[:controller]} controller.")
end
end

private

#Helper method to minimize errors and SQL injection attacks
def sort_column
%w[name hostname mac_address last_report_at].include?(params[:sort]) ? params[:sort] : "name"
end

#Helper method to minimize errors and SQL injection attacks
def sort_direction
%w[asc desc].include?(params[:direction]) ? params[:direction] : "asc"
end
end
7 changes: 7 additions & 0 deletions app/helpers/computers_helper.rb
Expand Up @@ -43,4 +43,11 @@ def render_computer_group_header(id)
def computer_group_options
options_for_select(ComputerGroup.unit(current_unit).collect {|cg| [cg.name, cg.id] })
end

def sortable(column, title = nil)
title ||= column.titleize
css_class = column == sort_column ? "current #{sort_direction}" : nil
direction = (column == sort_column && sort_direction == "asc") ? "desc" : "asc"
link_to title, params.merge({:sort => column, :direction => direction, :page => nil}), {:class => css_class}
end
end
2 changes: 1 addition & 1 deletion app/models/managed_install_report.rb
@@ -1,5 +1,5 @@
class ManagedInstallReport < ActiveRecord::Base
belongs_to :computer
belongs_to :computer, :touch => :last_report_at

scope :error_free, where(:munki_errors => [].to_yaml)

Expand Down
8 changes: 5 additions & 3 deletions app/models/manifest/computer.rb
Expand Up @@ -22,6 +22,8 @@ class Computer < ActiveRecord::Base
validates_format_of :mac_address, :with => /^([0-9a-f]{2}(:|$)){6}$/ # mac_address attribute must look something like ff:12:ff:34:ff:56
validates_uniqueness_of :mac_address,:name, :hostname

scope :search, lambda{|column, term|where(["#{column.to_s} LIKE ?", "%#{term}%"]) unless term.blank? or column.blank?}

# before_save :require_computer_group

# Maybe I shouldn't be doing this
Expand Down Expand Up @@ -131,9 +133,9 @@ def last_report
end

# Returns, in words, the time since last run
def time_since_last_report
if last_report.present?
time_ago_in_words(last_report.created_at) + " ago"
def last_report_at_time
if last_report_at.present?
time_ago_in_words(last_report_at) + " ago"
else
"never"
end
Expand Down
17 changes: 17 additions & 0 deletions app/models/os_range_helper.rb
@@ -0,0 +1,17 @@
def os_range(major, minor, point_range = 0..0)
point_range.collect{|point|
[os_version_for_value(major,minor,point), os_version_for_display(major,minor,point)]
}.reverse
end

def os_version_for_display(major, minor, point)
"#{major}.#{minor}.#{point}"
end

def os_version_for_value(major,minor,point)
if point != 0
"#{major}.#{minor}.#{point}"
else
"#{major}.#{minor}"
end
end
4 changes: 3 additions & 1 deletion app/models/package.rb
@@ -1,4 +1,5 @@
require 'digest'
require 'os_range_helper'

class Package < ActiveRecord::Base
magic_mixin :unit_member
Expand Down Expand Up @@ -46,7 +47,7 @@ class Package < ActiveRecord::Base
validates :force_install_after_date_string, :date_time => true, :allow_blank => true

FORM_OPTIONS = {:restart_actions => [['None','None'],['Logout','RequiredLogout'],['Restart','RequiredRestart'],['Shutdown','Shutdown']],
:os_versions => [['Any',''],['10.4','10.4.0'],['10.5','10.5.0'],['10.6','10.6.0'],['10.7','10.7.0']],
:os_versions => [[['Any','']], os_range(10,7,0..2), os_range(10,6,0..8), os_range(10,5,0..11)].flatten(1),
:installer_types => [['Package',''],
['Copy From DMG', 'copy_from_dmg'],
['App DMG','appdmg'],
Expand Down Expand Up @@ -948,4 +949,5 @@ def self.initialize_upload(package_file)
def self.uniquify_name(name)
Time.now.to_s(:ordered_numeric) + rand(10001).to_s + "_" + name
end

end
37 changes: 0 additions & 37 deletions app/models/service/computer_service.rb
Expand Up @@ -64,41 +64,4 @@ def self.import(params, unit)

computers
end

# Returns a collection based on the params passed as well as a unit.
# Intended to encapsulate the typical query done for the index action.
def self.collect(params, unit, env)
# Grab the computers belonging to a specific unit
# Set environment
computers = Computer.unit_and_environment(unit,env)

#Do some error checking on params[:col] to
# ensure against injection attacks or errors
params[:col] = nil unless ["name", "hostname", "mac_address", "last_report"].include? params[:col]
params[:order] = nil unless ["asc", "desc"].include? params[:order]

params[:col] ||= "name"
params[:order] ||= "asc"

case params[:col]
#ToDo: actually impliment this in a non-CPU intensive way
when "last_report"
computers
else
computers = computers.order("#{params[:col]} #{params[:order]}")
end

# Search for a specific computer name
unless params[:name].blank?
computers = computers.where(["name LIKE ?","%#{params[:name]}%"])
end

# Add pagination using will_paginate gem
per_page = params[:per_page]
per_page ||= Computer.per_page
computers = computers.paginate(:page => params[:page], :per_page => per_page)

# Return our results
computers
end
end
4 changes: 3 additions & 1 deletion app/views/computers/_computer_listing.html.erb
Expand Up @@ -14,8 +14,10 @@
<div class="span-16 last" style="text-align:right;">
<%= form_tag computers_url(current_unit), :id => "filter_form", :method => 'get', :remote => true do %>
<%= hidden_field_tag "eid", params['eid'] %>
<%= hidden_field_tag :sort, params[:sort] %>
<%= hidden_field_tag :direction, params[:direction] %>
<%= text_field_tag "name", params['name'] %>
<%= submit_tag "Filter" %>
<%= submit_tag "Filter", :name => nil %>
<% end %>
</div>
<%= form_tag edit_multiple_computers_path(current_unit), :id => "bulk_edit_form", :method => 'GET', :remote => true do %>
Expand Down
16 changes: 5 additions & 11 deletions app/views/computers/_computer_table.html.erb
Expand Up @@ -20,16 +20,10 @@
<th><%= check_box_tag("select_all", nil, nil, :class => "select_all") %></th>
<% end %>
<th><!-- icon header --></th>
<th>
<%= link_to 'Name', {:action => "index", :col => "name", :order => "asc",:gid => params[:gid], :page => params[:page] } %>
</th>
<th>
<%= link_to 'Hostname', {:action => "index", :col => "hostname", :order => "asc",:gid => params[:gid], :page => params[:page] } %>
</th>
<th>
<%= link_to 'MAC Address', {:action => "index", :col => "mac_address", :order => "asc",:gid => params[:gid], :page => params[:page] } %>
</th>
<th>Last Report</th>
<th><%= sortable 'name' %></th>
<th><%= sortable 'hostname' %></th>
<th><%= sortable 'mac_address', 'MAC Address' %></th>
<th><%= sortable 'last_report_at', 'Last Report' %></th>
<th>Actions</th>
</tr>
</thead>
Expand All @@ -44,7 +38,7 @@
<td><%= link_to c.name, computer_url(c.unit, c) %></td>
<td><%= link_to c.hostname, computer_url(c.unit, c) %></td>
<td><%= c.mac_address %></td>
<td><%= c.time_since_last_report %></td>
<td><%= c.last_report_at_time %></td>
<td>
<% if can? :update, c %>
<%= link_to 'Edit', edit_computer_path(c.unit, c) %> |
Expand Down
4 changes: 2 additions & 2 deletions app/views/users/index.html.erb
Expand Up @@ -11,8 +11,8 @@
<td><%= link_to user.username, edit_user_path(user) %></td>
<td><%= user.email %></td>
<td>
<%= link_to "Edit", edit_user_path(user) %>
<%= link_to "Remove", user, :confirm => "Are you sure you want to delete #{user.username}?", :method => :delete %>
<%= link_to "Edit", edit_user_path(user) if can?(:update, user) %>
<%= link_to "Remove", User, :confirm => "Are you sure you want to delete #{user.username}?", :method => :delete if can? :destroy, User %>
</td>
</tr>
<% end %>
Expand Down
9 changes: 9 additions & 0 deletions db/migrate/20111130134407_add_last_report_at_to_computer.rb
@@ -0,0 +1,9 @@
class AddLastReportAtToComputer < ActiveRecord::Migration
def self.up
add_column :computers, :last_report_at, :datetime
end

def self.down
remove_column :computers, :last_report_at
end
end
3 changes: 2 additions & 1 deletion db/schema.rb
Expand Up @@ -11,7 +11,7 @@
#
# It's strongly recommended to check this file into your version control system.

ActiveRecord::Schema.define(:version => 20110904192733) do
ActiveRecord::Schema.define(:version => 20111130134407) do

create_table "bundle_items", :force => true do |t|
t.integer "manifest_id"
Expand Down Expand Up @@ -79,6 +79,7 @@
t.string "hostname", :default => ""
t.integer "configuration_id"
t.string "shortname"
t.datetime "last_report_at"
end

create_table "configurations", :force => true do |t|
Expand Down
Binary file added public/images/down_arrow.gif
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/images/up_arrow.gif
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
16 changes: 16 additions & 0 deletions public/javascripts/application.js
Expand Up @@ -599,6 +599,22 @@ function initializeDatePicker(){
// return false;
// });

// AJAX name search/filter, sorting, and pagination
$(function() {
$("#computer_listing th a, #computer_listing .pagination a").live("click", function() {
$.getScript(this.href);
return false;
});
$("#filter_form input").submit(function() {
// Show the loading graphic while request is made
$("#loading_graphic").show();
// Grab the script and execute it
$.get($("#filter_form").attr("action"), $("#filter_form").serialize(), null, "script");
// // Return false so the form isn't submitted
return false;
});
});

// Text field default message
$.fn.extend({
subtle_value: function(original_value) {
Expand Down
15 changes: 14 additions & 1 deletion public/stylesheets/style.css
Expand Up @@ -746,7 +746,20 @@ dd.permission-check-box {
display:inline;
}

.zebra th {
font-size: 13px;
}
.zebra th .current {
padding-right: 12px;
background-repeat: no-repeat;
background-position: right center;
}
.zebra th .asc {
background-image: url(/images/up_arrow.gif);
}


.zebra th .desc {
background-image: url(/images/down_arrow.gif);
}


0 comments on commit 67ff428

Please sign in to comment.