implement Inventory page feature

This commit is contained in:
Oliver Gorwits
2012-03-09 22:09:04 +00:00
parent c334df9667
commit 0067ed9b47
12 changed files with 167 additions and 21 deletions

View File

@@ -10,6 +10,7 @@ use HTML::Entities (); # to ensure dependency is met
use Netdisco::Web::AuthN;
use Netdisco::Web::Search;
use Netdisco::Web::Device;
use Netdisco::Web::Inventory;
hook 'before_template' => sub {
my $tokens = shift;

View File

@@ -33,7 +33,7 @@ post '/login' => sub {
}
}
}
redirect '/?failed=1';
redirect uri_for('/', {failed => 1});
};
get '/logout' => sub {

View File

@@ -0,0 +1,23 @@
package Netdisco::Web::Inventory;
use Dancer ':syntax';
use Dancer::Plugin::DBIC;
get '/inventory' => sub {
template 'inventory', {
models => scalar schema('netdisco')->resultset('Device')->search({},{
select => [ 'vendor', 'model', { count => 'ip' } ],
as => [qw/vendor model count/],
group_by => [qw/vendor model/],
order_by => [{-asc => 'vendor'}, {-desc => 'count'}, {-asc => 'model'}],
}),
releases => scalar schema('netdisco')->resultset('Device')->search({},{
select => [ 'os', 'os_ver', { count => 'ip' } ],
as => [qw/os os_ver count/],
group_by => [qw/os os_ver/],
order_by => [{-asc => 'os'}, {-desc => 'count'}, {-asc => 'os_ver'}],
}),
};
};
true;

View File

@@ -185,10 +185,12 @@ get '/search' => sub {
schema('netdisco')->resultset('Device')->get_distinct('vendor')
]);
params->{'q'} ||= '_'; # FIXME a cheat Inventory, for now
my $q = param('q');
if ($q and not param('tab')) {
if (not param('tab')) {
if (not $q) {
redirect uri_for('/');
}
# pick most likely tab for initial results
if ($q =~ m/^\d+$/) {
params->{'tab'} = 'vlan';

View File

@@ -17,11 +17,16 @@ body {
padding-top: 11px;
}
/* on both main content and sidebar, hidden overflow is weird and wrong?! */
/* on both main content and sidebar, default is hidden */
.tab-content {
overflow: visible;
}
/* ajax results should fill all available */
.tab-content table {
width: 100%;
}
/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
/* various styles to adjust the hero box used for homepage + login */
@@ -38,6 +43,35 @@ body {
margin-bottom: 0px;
}
/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
/* styles for Reports */
/* from Bootstrap doc style sheet */
.nd_show-grid [class*="span"] {
background-color: cornsilk;
text-align: center;
-webkit-border-radius: 3px;
-moz-border-radius: 3px;
border-radius: 3px;
min-height: 30px;
line-height: 30px;
}
/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
/* styles for Inventory */
#nd_dev_age_form {
margin-top: 10px;
margin-bottom: 12px;
}
.nd_inv_tbl_head {
text-align: center;
color: lightSlateGray;
margin-top: 6px;
margin-bottom: 3px;
}
/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
/* results table links */

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

View File

@@ -31,11 +31,6 @@
<a class="close" data-dismiss="alert">×</a>
Log in to the Demo with username &quot;demo&quot; and password &quot;demo&quot;.
</div>
[% ELSE %]
<div class="alert alert-success fade in">
<a class="close" data-dismiss="alert">×</a>
Hit <strong>Enter</strong> in the Search box to view the current Inventory (<em>temporary feature</em>).
</div>
[% END %]
<div class="hero-unit">
<h2>Welcome to Netdisco</h2>

View File

@@ -0,0 +1,62 @@
<div class="container">
[% IF models.count %]
<div class="row">
<div class="span6">
<h3 class="nd_inv_tbl_head">By Platform</h3>
<table class="table table-condensed">
<thead>
<tr>
<th>Vendor</th>
<th>Model</th>
<th>Count</th>
</tr>
</thead>
<tbody>
[% FOREACH platform IN models.all %]
<tr>
<th>
<a class="nd_stealthlink"
href="[% uri_for('/search') %]?tab=device&matchall=on&vendor=[% platform.vendor %]">
[% platform.vendor %]</a>
</th>
<th>
<a class="nd_linkcell"
href="[% uri_for('/search') %]?tab=device&matchall=on&model=[% platform.model %]">
[% platform.model %]</a>
</th>
<th>[% platform.get_column('count') %]</th>
</tr>
[% END %]
</tbody>
</table>
</div>
<div class="span6">
<h3 class="nd_inv_tbl_head">By Software Release</h3>
<table class="table table-condensed">
<thead>
<tr>
<th>OS</th>
<th>Version</th>
<th>Count</th>
</tr>
</thead>
<tbody>
[% FOREACH release IN releases.all %]
<tr>
<th>[% release.os %]</th>
<th>
<a class="nd_linkcell"
href="[% uri_for('/search') %]?tab=device&matchall=on&os_ver=[% release.os_ver %]">
[% release.os_ver %]</a>
</th>
<th>[% release.get_column('count') %]</th>
</tr>
[% END %]
</tbody>
</table>
</div>
</div>
[% ELSE %]
<div class="span4 alert alert-info">No devices found. Do you need to run a Discover?</div>
[% END %]
</div>

View File

@@ -43,12 +43,13 @@
<a class="brand" href="[% uri_for('/') %]">Netdisco</a>
[% IF session.user %]
<ul class="nav">
<li class="active"><a href="[% uri_for('/') %]">Home</a></li>
<li[% ' class="active"' IF vars('nav') == 'inventory' %]>
<a href="[% uri_for('/inventory') %]">Inventory</a>
</li>
[% IF more_dd.size %]
<li class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown">
More <b class="caret"></b>
</a>
More <b class="caret"></b></a>
<ul class="dropdown-menu">
[% FOREACH title IN more_dd.keys.sort %]
<li><a href="[% uri_for(more_dd.$title) %]">[% title %]</a></li>
@@ -59,14 +60,13 @@
</ul>
<form class="navbar-search pull-left" method="get" action="[% uri_for('/search') %]">
<input placeholder="Find Anything" class="search-query span3" id="nq" name="q" type="text"/>
<img id="navsearchgo" class="navbar_icon" src="[% uri_base %]/images/crystalclear_mag.png"/>
<i id="navsearchgo" class="icon-search icon-white navbar_icon"></i>
</form>
<ul class="nav pull-right">
<li class="nd_navbartext">Logged in as &nbsp;</li>
<li class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown">
[% session.user %] <b class="caret"></b>
</a>
[% session.user %] <b class="caret"></b></a>
<ul class="dropdown-menu">
[% FOREACH item IN user_dd %]
<li><a href="[% uri_for(item.link) %]">[% item.title %]</a></li>

31
Netdisco/views/report.tt Normal file
View File

@@ -0,0 +1,31 @@
<div class="container">
<div class="row nd_show-grid">
<div class="span10 offset1">
<form id="nd_dev_age_form" class="form-inline">
Find Devices
<select name="age_type" class="span2">
<option value="first">First Discovered</option>
<option value="last" selected="selected">Last Updated</option>
</select>
<select name="age_bool" class="span2">
<option value="in">less than</option>
<option value="not_in" selected="selected">more than</option>
</select>
<select name="age_num" class="span1">
[% FOREACH count IN [1..32] %]
<option[% ' selected="selected"' IF count == 3 %]>[% count %]</option>
[% END %]
</select>
<select name="age_unit" class="span2">
<option>days</option>
<option>weeks</option>
<option selected="selected">months</option>
<option>years</option>
</select>
ago.
<button type="submit" class="btn btn-primary">
<i class="icon-search icon-white"></i></button>
</form>
</div>
</div>
</div>

View File

@@ -65,14 +65,12 @@
<li>
<span rel="tooltip" data-placement="left"
data-offset="5" title="Free if Down for this period of time">
<select id="nd_days_select" name="age_num"/>
[% SET count = 1 %]
[% WHILE count < 32 %]
<select id="nd_days_select" name="age_num">
[% FOREACH count IN [1..32] %]
<option[% ' selected="selected"' IF params.age_num == count %]>[% count %]</option>
[% SET count = count + 1 %]
[% END %]
</select>
<select id="nd_age_select" name="age_unit"/>
<select id="nd_age_select" name="age_unit">
[% FOREACH unit IN [ 'days', 'weeks', 'months', 'years' ] %]
<option[% ' selected="selected"' IF params.age_unit == unit %]>[% unit %]</option>
[% END %]