Page MenuHomeGRNET

No OneTemporary

File Metadata

Created
Sun, May 18, 8:55 PM
diff --git a/app/controllers/admin/users_controller.rb b/app/controllers/admin/users_controller.rb
new file mode 100644
index 0000000..7afa118
--- /dev/null
+++ b/app/controllers/admin/users_controller.rb
@@ -0,0 +1,20 @@
+class Admin::UsersController < Admin::BaseController
+ # GET /admin/users
+ def index
+ @baculized_host_names = Hash.new { |h, k| h[k] = [] }
+ @non_baculized_host_names = Hash.new { |h, k| h[k] = [] }
+ @unverified_host_names = Hash.new { |h, k| h[k] = [] }
+
+ @users = User.all.includes(:hosts)
+ @users.each do |user|
+ user.hosts.each do |host|
+ if host.deployed? || host.updated? || host.dispatched? || host.for_removal?
+ @baculized_host_names[user.id] << host.name
+ else
+ @non_baculized_host_names[user.id] << host.name
+ @unverified_host_names[user.id] << host.name if !host.verified?
+ end
+ end
+ end
+ end
+end
diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb
index bb628ea..1bb6ee0 100644
--- a/app/helpers/application_helper.rb
+++ b/app/helpers/application_helper.rb
@@ -1,82 +1,106 @@
module ApplicationHelper
# Custom helper for better display of big numbers
# @example number_by_magnitude(4242)
# "4.2K"
#
# @param number[Numeric]
# @return [String] human friendly respresentation
def number_by_magnitude(number)
number_to_human(number, units: { thousand: :K, million: :M, billion: :G })
end
# Creates a bootstrap form-group div with an additional 'Add' button next to the select field
#
# @param object[ActiveRecord::Object] the form's subject
# @param resource[Symbol] the objects class
# @param attr[Symbol] the select box's attribute
# @param attr_name[String] the attribute's display name
# @param options[Array] the select box options
# @param path[String] the add button's path
def select_with_errors_and_button(object, resource, attr, attr_name, options, path)
has_errors = object.errors[attr].present?
content_tag(:div, class: "form-group #{' has-error' if has_errors }") do
attr_label = label(resource, attr, attr_name, class: 'control-label col-xs-5 required')
select_div = content_tag(:div, class: 'col-xs-5') do
select_part = select_tag([resource, attr].join('_').to_sym,
options,
name: "#{resource}[#{attr}]",
class: 'form-control'
)
if has_errors
select_part.concat(content_tag(:span, class: 'help-block') { object.errors[attr].first })
end
select_part
end
button_part = content_tag(:div, class: 'col-xs-1') do
link_to 'Add', path, class: 'btn btn-primary', role: 'button'
end
attr_label.concat(select_div).concat(button_part)
end
end
# Returns a style class depending on the given parameter
#
# @param status[Char]
def success_class(status)
case status
when 'T' then 'success'
when 'E' then 'danger'
when 'f' then 'fatal'
end
end
# Fetches the html class for a given path
#
# @param path[String] the path to check for
# @param partial[Boolean] forces a left partial match
#
# @return [Hash] { class: 'active' } if the given path is the current page
def active_class(path, partial = false)
if current_page?(path) || (partial && request.path.starts_with?(path))
{ class: 'active' }
else
{}
end
end
# Constructs a breadcrumb out the given options
#
# @param options[Hash] a hash containing the breadcrumb links in name: path sets
# @return an html ol breadcrumb
def breadcrumb_with(options)
content_tag(:ol, class: 'breadcrumb') do
options.map { |name, path|
content_tag(:li, active_class(path)) do
link_to_if !current_page?(path), name, path
end
}.inject { |result, element| result.concat(element) }
end
end
+
+ # Constructs a list with the given array elements
+ #
+ # @example:
+ # inline_list([:foo, :bar])
+ #
+ # <ul class="list-inline'>
+ # <li><span class="label label-default">foo</span></li>
+ # <li><span class="label label-default">bar</span></li>
+ # </ul>
+ #
+ # @param arr[Array]
+ # @return an html ul list
+ def inline_list(arr)
+ content_tag(:ul, class: 'list-inline') do
+ arr.map { |element|
+ content_tag(:li) do
+ content_tag(:span, class: 'label label-default') do
+ element
+ end
+ end
+ }.inject { |result, element| result.concat(element) }
+ end
+ end
end
diff --git a/app/views/admin/users/_user.html.erb b/app/views/admin/users/_user.html.erb
new file mode 100644
index 0000000..849d53c
--- /dev/null
+++ b/app/views/admin/users/_user.html.erb
@@ -0,0 +1,10 @@
+<tr>
+ <td>#<%= user.id %></td>
+ <td><%= user.username %></td>
+ <td><%= user.email %></td>
+ <td><%= user.user_type %></td>
+ <td><%= I18n.l(user.created_at, format: :short) %></td>
+ <td><%= inline_list @baculized_host_names[user.id] %></td>
+ <td><%= inline_list @unverified_host_names[user.id] %></td>
+ <td><%= inline_list @non_baculized_host_names[user.id] %></td>
+</tr>
diff --git a/app/views/admin/users/index.html.erb b/app/views/admin/users/index.html.erb
new file mode 100644
index 0000000..367fbb0
--- /dev/null
+++ b/app/views/admin/users/index.html.erb
@@ -0,0 +1,22 @@
+<h1>Users</h1>
+
+<div class="table-responsive">
+ <table class="table table-striped table-bordered table-condensed">
+ <thead>
+ <tr>
+ <th>id</th>
+ <th>username</th>
+ <th>email</th>
+ <th>user type</th>
+ <th>created at</th>
+ <th>clients</th>
+ <th>unverified hosts</th>
+ <th>pending hosts</th>
+ </tr>
+ </thead>
+
+ <tbody>
+ <%= render partial: 'user', collection: @users %>
+ </tbody>
+ </table>
+</div>
diff --git a/app/views/shared/_nav.html.erb b/app/views/shared/_nav.html.erb
index ecaf656..343a4b1 100644
--- a/app/views/shared/_nav.html.erb
+++ b/app/views/shared/_nav.html.erb
@@ -1,58 +1,61 @@
<!-- Fixed navbar -->
<nav class="navbar navbar-default navbar-fixed-top">
<div class="container-fluid">
<div class="navbar-header">
<button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
</div>
<div id="navbar" class="navbar-collapse collapse">
<ul class="nav navbar-nav">
<li class="logo">
<%= link_to root_path do %>
<p><b>GRNET NOC</b></p>
<p>Archiving</p>
<% end %>
</li>
<% if current_user %>
<%= content_tag(:li, active_class(clients_path, true)) do %>
<%= link_to 'Clients', clients_path %>
<% end %>
<li><a href="/contact">Contact</a></li>
<li class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown">Profile <span class="caret"></span></a>
<ul class="dropdown-menu">
<li><a href="#">Logout</a></li>
<li class="divider"></li>
<li class="dropdown-header">Profile</li>
<li><a href="#">Edit</a></li>
</ul>
</li>
<% if current_user %>
<li><%= link_to current_user.username, '#' %></li>
<% end %>
<li><%= link_to 'logout', logout_path %></li>
<% end %>
</ul>
<% if current_user.try(:admin?) %>
<ul class="nav navbar-nav navbar-right">
<%= content_tag(:li, active_class(admin_path)) do %>
<%= link_to 'Admin', admin_path %>
<% end %>
<%= content_tag(:li, active_class(admin_clients_path, true)) do %>
<%= link_to 'Clients', admin_clients_path %>
<% end %>
<%= content_tag(:li, active_class(unverified_admin_hosts_path, true)) do %>
<%= link_to 'Hosts', unverified_admin_hosts_path %>
<% end %>
+ <%= content_tag(:li, active_class(admin_users_path)) do %>
+ <%= link_to 'Users', admin_users_path %>
+ <% end %>
<%= content_tag(:li, active_class(admin_settings_path)) do %>
<%= link_to 'Settings', admin_settings_path %>
<% end %>
</ul>
<% end %>
</div><!--/.nav-collapse -->
</div>
</nav>
diff --git a/config/routes.rb b/config/routes.rb
index 44af95e..4d1cd47 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -1,69 +1,71 @@
Rails.application.routes.draw do
root 'application#index'
post 'login' => 'application#login'
match 'vima', to: 'application#vima', :via => [:get, :post]
get 'logout' => 'application#logout'
resources :clients, only: [:index, :show] do
member do
get :jobs
get :logs
get :stats
post :stats
get :users
end
collection do
post :index
end
end
resources :hosts, only: [:new, :create, :show, :edit, :update, :destroy] do
member do
post :submit_config
get :restore
post :run_restore
delete :revoke
end
resources :jobs, only: [:new, :create, :show, :edit, :update, :destroy] do
member do
patch :toggle_enable
post :backup_now
end
end
resources :filesets, only: [:show, :new, :create, :destroy]
resources :schedules, only: [:show, :new, :edit, :create, :update, :destroy]
end
namespace :admin do
match '/', to: 'base#index', via: [:get, :post]
resources :settings, only: [:index, :new, :create, :edit, :update] do
member do
delete :reset
end
end
resources :clients, only: [:index, :show] do
member do
get :jobs
get :logs
get :stats
post :stats
get :configuration
end
end
resources :hosts, only: [:show] do
collection do
get :unverified
end
member do
post :verify
end
end
+
+ resources :users, only: [:index]
end
end

Event Timeline