CSV download support via provides_csv plugin attr
Squashed commit of the following: commite44f203f47Author: Oliver Gorwits <oliver@cpan.org> Date: Fri Sep 20 20:00:46 2013 +0100 also set filename on csv download link commit26b47d1296Author: Oliver Gorwits <oliver@cpan.org> Date: Fri Sep 20 19:56:38 2013 +0100 conditionally show csv icon for device and search tabs commit119d2c672dAuthor: Oliver Gorwits <oliver@cpan.org> Date: Fri Sep 20 19:48:24 2013 +0100 tweak look of csv icon commit89816892beAuthor: Oliver Gorwits <oliver@cpan.org> Date: Fri Sep 20 19:38:31 2013 +0100 enable csv icon link rewrite for all pages commitac29769402Author: Oliver Gorwits <oliver@cpan.org> Date: Fri Sep 20 19:28:49 2013 +0100 use single route handler for ajax and csv response commit4b6f89635dAuthor: Oliver Gorwits <oliver@cpan.org> Date: Fri Sep 20 18:59:08 2013 +0100 no need for separate csv link template commit1021329e1cAuthor: Oliver Gorwits <oliver@cpan.org> Date: Fri Sep 20 18:57:20 2013 +0100 display download as csv icon conditionally commitce57cdba69Author: Oliver Gorwits <oliver@cpan.org> Date: Fri Sep 20 09:23:57 2013 +0100 Based on jeneric's CSV download templates; - try to reduce code duplication by using same route handler for ajax and csv, using request->is_ajax to switch the template, and set content-type - use new HTML5 "download" attribute on links so content-disposition header is no longer necessary - download CSV icon is placed on all tables (per report/device/serach section) - update download CSV link using javascript just before table content is fetched - this is necessary to make sure updated sidebar query params are included The idea here is to allow us to support CSV download in the pages which display tables by only doing the following: - (existing routes:) replace "ajax" with "get" route handler - add logic to switch template in handler, based on request->is_ajax - write _csv.tt version of the template, to spit out CSV file content This makes it much easier for new devs to write reports supporting CSV, I think? commitd3553d2623Author: Eric A. Miller <emiller@cpan.org> Date: Thu Sep 19 22:30:27 2013 -0400 add csv download to duplex mismatch, half duplex, and port utilization reports commit5d4df72a24Author: Eric A. Miller <emiller@cpan.org> Date: Wed Sep 18 23:50:27 2013 -0400 add csv download to ap channel distribution report commit0824d7936aAuthor: Eric A. Miller <emiller@cpan.org> Date: Wed Sep 18 23:42:53 2013 -0400 need Template::Plugin::CSV for csv output commitbb1f842d92Author: Eric A. Miller <emiller@cpan.org> Date: Wed Sep 18 23:35:28 2013 -0400 add csv download option to device addresses commit99ada1132cAuthor: Eric A. Miller <emiller@cpan.org> Date: Wed Sep 18 23:32:57 2013 -0400 add csv download option to device, port, and vlan search pages
This commit is contained in:
@@ -36,6 +36,7 @@ requires 'Starman' => 0.3008;
|
||||
requires 'SNMP::Info' => 3.05;
|
||||
requires 'SQL::Translator' => 0.11016;
|
||||
requires 'Template' => 2.24;
|
||||
requires 'Template::Plugin::CSV' => 0.04;
|
||||
requires 'URL::Encode' => 0.01;
|
||||
requires 'YAML' => 0.84;
|
||||
requires 'YAML::XS' => 0.41;
|
||||
|
||||
@@ -1,28 +1,33 @@
|
||||
package App::Netdisco::Web::Plugin::Device::Addresses;
|
||||
|
||||
use Dancer ':syntax';
|
||||
use Dancer::Plugin::Ajax;
|
||||
use Dancer::Plugin::DBIC;
|
||||
use Dancer::Plugin::Auth::Extensible;
|
||||
|
||||
use App::Netdisco::Web::Plugin;
|
||||
|
||||
register_device_tab({ tag => 'addresses', label => 'Addresses' });
|
||||
register_device_tab( { tag => 'addresses', label => 'Addresses', provides_csv => 1 } );
|
||||
|
||||
# device interface addresses
|
||||
ajax '/ajax/content/device/addresses' => require_login sub {
|
||||
get '/ajax/content/device/addresses' => require_login sub {
|
||||
my $q = param('q');
|
||||
|
||||
my $device = schema('netdisco')->resultset('Device')
|
||||
->search_for_device($q) or send_error('Bad device', 400);
|
||||
my $device
|
||||
= schema('netdisco')->resultset('Device')->search_for_device($q)
|
||||
or send_error( 'Bad device', 400 );
|
||||
|
||||
my $set = $device->device_ips->search({}, {order_by => 'alias'});
|
||||
my $set = $device->device_ips->search( {}, { order_by => 'alias' } );
|
||||
return unless $set->count;
|
||||
|
||||
content_type('text/html');
|
||||
template 'ajax/device/addresses.tt', {
|
||||
results => $set,
|
||||
}, { layout => undef };
|
||||
if (request->is_ajax) {
|
||||
template 'ajax/device/addresses.tt', { results => $set, },
|
||||
{ layout => undef };
|
||||
}
|
||||
else {
|
||||
header( 'Content-Type' => 'text/comma-separated-values' );
|
||||
template 'ajax/device/addresses_csv.tt', { results => $set, },
|
||||
{ layout => undef };
|
||||
}
|
||||
};
|
||||
|
||||
true;
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package App::Netdisco::Web::Plugin::Report::ApChannelDist;
|
||||
|
||||
use Dancer ':syntax';
|
||||
use Dancer::Plugin::Ajax;
|
||||
use Dancer::Plugin::DBIC;
|
||||
use Dancer::Plugin::Auth::Extensible;
|
||||
|
||||
@@ -11,10 +10,11 @@ register_report(
|
||||
{ category => 'Wireless',
|
||||
tag => 'apchanneldist',
|
||||
label => 'Access Point Channel Distribution',
|
||||
provides_csv => 1,
|
||||
}
|
||||
);
|
||||
|
||||
ajax '/ajax/content/report/apchanneldist' => require_login sub {
|
||||
get '/ajax/content/report/apchanneldist' => require_login sub {
|
||||
my $set = schema('netdisco')->resultset('DevicePortWireless')->search(
|
||||
{ channel => { '!=', '0' } },
|
||||
{ select => [ 'channel', { count => 'channel' } ],
|
||||
@@ -23,12 +23,17 @@ ajax '/ajax/content/report/apchanneldist' => require_login sub {
|
||||
order_by => { -desc => [qw/count/] },
|
||||
},
|
||||
);
|
||||
|
||||
return unless $set->count;
|
||||
|
||||
content_type('text/html');
|
||||
if (request->is_ajax) {
|
||||
template 'ajax/report/apchanneldist.tt', { results => $set, },
|
||||
{ layout => undef };
|
||||
}
|
||||
else {
|
||||
header( 'Content-Type' => 'text/comma-separated-values' );
|
||||
template 'ajax/report/apchanneldist_csv.tt', { results => $set, },
|
||||
{ layout => undef };
|
||||
}
|
||||
};
|
||||
|
||||
true;
|
||||
|
||||
@@ -1,26 +1,32 @@
|
||||
package App::Netdisco::Web::Plugin::Report::DuplexMismatch;
|
||||
|
||||
use Dancer ':syntax';
|
||||
use Dancer::Plugin::Ajax;
|
||||
use Dancer::Plugin::DBIC;
|
||||
use Dancer::Plugin::Auth::Extensible;
|
||||
|
||||
use App::Netdisco::Web::Plugin;
|
||||
|
||||
register_report({
|
||||
category => 'Port',
|
||||
register_report(
|
||||
{ category => 'Port',
|
||||
tag => 'duplexmismatch',
|
||||
label => 'Duplex Mismatches Between Devices',
|
||||
});
|
||||
provides_csv => 1,
|
||||
}
|
||||
);
|
||||
|
||||
ajax '/ajax/content/report/duplexmismatch' => require_login sub {
|
||||
get '/ajax/content/report/duplexmismatch' => require_login sub {
|
||||
my $set = schema('netdisco')->resultset('Virtual::DuplexMismatch');
|
||||
return unless $set->count;
|
||||
|
||||
content_type('text/html');
|
||||
template 'ajax/report/duplexmismatch.tt', {
|
||||
results => $set,
|
||||
}, { layout => undef };
|
||||
if (request->is_ajax) {
|
||||
template 'ajax/report/duplexmismatch.tt', { results => $set, },
|
||||
{ layout => undef };
|
||||
}
|
||||
else {
|
||||
header( 'Content-Type' => 'text/comma-separated-values' );
|
||||
template 'ajax/report/duplexmismatch_csv.tt', { results => $set, },
|
||||
{ layout => undef };
|
||||
}
|
||||
};
|
||||
|
||||
true;
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package App::Netdisco::Web::Plugin::Report::HalfDuplex;
|
||||
|
||||
use Dancer ':syntax';
|
||||
use Dancer::Plugin::Ajax;
|
||||
use Dancer::Plugin::DBIC;
|
||||
use Dancer::Plugin::Auth::Extensible;
|
||||
|
||||
@@ -11,19 +10,26 @@ register_report({
|
||||
category => 'Port',
|
||||
tag => 'halfduplex',
|
||||
label => 'Ports in Half Duplex Mode',
|
||||
provides_csv => 1,
|
||||
});
|
||||
|
||||
ajax '/ajax/content/report/halfduplex' => require_login sub {
|
||||
get '/ajax/content/report/halfduplex' => require_login sub {
|
||||
my $format = param('format');
|
||||
my $set = schema('netdisco')->resultset('DevicePort')->search(
|
||||
{ up => 'up', duplex => { '-ilike' => 'half' } },
|
||||
{ order_by => [qw/device.dns port/], prefetch => 'device' },
|
||||
);
|
||||
return unless $set->count;
|
||||
|
||||
content_type('text/html');
|
||||
template 'ajax/report/halfduplex.tt', {
|
||||
results => $set,
|
||||
}, { layout => undef };
|
||||
if (request->is_ajax) {
|
||||
template 'ajax/report/halfduplex.tt', { results => $set, },
|
||||
{ layout => undef };
|
||||
}
|
||||
else {
|
||||
header( 'Content-Type' => 'text/comma-separated-values' );
|
||||
template 'ajax/report/halfduplex_csv.tt', { results => $set, },
|
||||
{ layout => undef };
|
||||
}
|
||||
};
|
||||
|
||||
true;
|
||||
|
||||
@@ -1,26 +1,32 @@
|
||||
package App::Netdisco::Web::Plugin::Report::PortUtilization;
|
||||
|
||||
use Dancer ':syntax';
|
||||
use Dancer::Plugin::Ajax;
|
||||
use Dancer::Plugin::DBIC;
|
||||
use Dancer::Plugin::Auth::Extensible;
|
||||
|
||||
use App::Netdisco::Web::Plugin;
|
||||
|
||||
register_report({
|
||||
category => 'Device',
|
||||
register_report(
|
||||
{ category => 'Device',
|
||||
tag => 'portutilization',
|
||||
label => 'Port Utilization',
|
||||
});
|
||||
provides_csv => 1,
|
||||
}
|
||||
);
|
||||
|
||||
ajax '/ajax/content/report/portutilization' => require_login sub {
|
||||
get '/ajax/content/report/portutilization' => require_login sub {
|
||||
return unless schema('netdisco')->resultset('Device')->count;
|
||||
my $set = schema('netdisco')->resultset('Virtual::PortUtilization');
|
||||
|
||||
content_type('text/html');
|
||||
template 'ajax/report/portutilization.tt', {
|
||||
results => $set,
|
||||
}, { layout => undef };
|
||||
if (request->is_ajax) {
|
||||
template 'ajax/report/portutilization.tt', { results => $set, },
|
||||
{ layout => undef };
|
||||
}
|
||||
else {
|
||||
header( 'Content-Type' => 'text/comma-separated-values' );
|
||||
template 'ajax/report/portutilization_csv.tt', { results => $set, },
|
||||
{ layout => undef };
|
||||
}
|
||||
};
|
||||
|
||||
true;
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package App::Netdisco::Web::Plugin::Search::Device;
|
||||
|
||||
use Dancer ':syntax';
|
||||
use Dancer::Plugin::Ajax;
|
||||
use Dancer::Plugin::DBIC;
|
||||
use Dancer::Plugin::Auth::Extensible;
|
||||
|
||||
@@ -9,10 +8,12 @@ use List::MoreUtils ();
|
||||
|
||||
use App::Netdisco::Web::Plugin;
|
||||
|
||||
register_search_tab({ tag => 'device', label => 'Device' });
|
||||
register_search_tab({ tag => 'device', label => 'Device', provides_csv => 1 });
|
||||
|
||||
my $headers = ['Device','Contact','Location','System Name','Model','OS Version','Management IP','Serial'];
|
||||
|
||||
# device with various properties or a default match-all
|
||||
ajax '/ajax/content/search/device' => require_login sub {
|
||||
get '/ajax/content/search/device' => require_login sub {
|
||||
my $has_opt = List::MoreUtils::any {param($_)}
|
||||
qw/name location dns ip description model os_ver vendor/;
|
||||
my $set;
|
||||
@@ -28,10 +29,17 @@ ajax '/ajax/content/search/device' => require_login sub {
|
||||
}
|
||||
return unless $set->count;
|
||||
|
||||
content_type('text/html');
|
||||
template 'ajax/search/device.tt', {
|
||||
if (request->is_ajax) {
|
||||
template 'ajax/search/device.tt', {results => $set},
|
||||
{ layout => undef };
|
||||
}
|
||||
else {
|
||||
header( 'Content-Type' => 'text/comma-separated-values' );
|
||||
template 'ajax/search/device_csv.tt', {
|
||||
results => $set,
|
||||
headers => $headers,
|
||||
}, { layout => undef };
|
||||
}
|
||||
};
|
||||
|
||||
true;
|
||||
|
||||
@@ -1,16 +1,15 @@
|
||||
package App::Netdisco::Web::Plugin::Search::Port;
|
||||
|
||||
use Dancer ':syntax';
|
||||
use Dancer::Plugin::Ajax;
|
||||
use Dancer::Plugin::DBIC;
|
||||
use Dancer::Plugin::Auth::Extensible;
|
||||
|
||||
use App::Netdisco::Web::Plugin;
|
||||
|
||||
register_search_tab({ tag => 'port', label => 'Port' });
|
||||
register_search_tab({ tag => 'port', label => 'Port', provides_csv => 1 });
|
||||
|
||||
# device ports with a description (er, name) matching
|
||||
ajax '/ajax/content/search/port' => require_login sub {
|
||||
get '/ajax/content/search/port' => require_login sub {
|
||||
my $q = param('q');
|
||||
send_error('Missing query', 400) unless $q;
|
||||
my $set;
|
||||
@@ -30,10 +29,15 @@ ajax '/ajax/content/search/port' => require_login sub {
|
||||
}
|
||||
return unless $set->count;
|
||||
|
||||
content_type('text/html');
|
||||
template 'ajax/search/port.tt', {
|
||||
results => $set,
|
||||
}, { layout => undef };
|
||||
if (request->is_ajax) {
|
||||
template 'ajax/search/port.tt', {results => $set},
|
||||
{ layout => undef };
|
||||
}
|
||||
else {
|
||||
header( 'Content-Type' => 'text/comma-separated-values' );
|
||||
template 'ajax/search/port_csv.tt', {results => $set},
|
||||
{ layout => undef };
|
||||
}
|
||||
};
|
||||
|
||||
true;
|
||||
|
||||
@@ -1,32 +1,38 @@
|
||||
package App::Netdisco::Web::Plugin::Search::VLAN;
|
||||
|
||||
use Dancer ':syntax';
|
||||
use Dancer::Plugin::Ajax;
|
||||
use Dancer::Plugin::DBIC;
|
||||
use Dancer::Plugin::Auth::Extensible;
|
||||
|
||||
use App::Netdisco::Web::Plugin;
|
||||
|
||||
register_search_tab({ tag => 'vlan', label => 'VLAN' });
|
||||
register_search_tab( { tag => 'vlan', label => 'VLAN', provides_csv => 1 } );
|
||||
|
||||
# devices carrying vlan xxx
|
||||
ajax '/ajax/content/search/vlan' => require_login sub {
|
||||
get '/ajax/content/search/vlan' => require_login sub {
|
||||
my $q = param('q');
|
||||
send_error('Missing query', 400) unless $q;
|
||||
send_error( 'Missing query', 400 ) unless $q;
|
||||
my $set;
|
||||
|
||||
if ($q =~ m/^\d+$/) {
|
||||
$set = schema('netdisco')->resultset('Device')->carrying_vlan({vlan => $q});
|
||||
if ( $q =~ m/^\d+$/ ) {
|
||||
$set = schema('netdisco')->resultset('Device')
|
||||
->carrying_vlan( { vlan => $q } );
|
||||
}
|
||||
else {
|
||||
$set = schema('netdisco')->resultset('Device')->carrying_vlan_name({name => $q});
|
||||
$set = schema('netdisco')->resultset('Device')
|
||||
->carrying_vlan_name( { name => $q } );
|
||||
}
|
||||
return unless $set->count;
|
||||
|
||||
content_type('text/html');
|
||||
template 'ajax/search/vlan.tt', {
|
||||
results => $set,
|
||||
}, { layout => undef };
|
||||
if (request->is_ajax) {
|
||||
template 'ajax/search/vlan.tt', { results => $set },
|
||||
{ layout => undef };
|
||||
}
|
||||
else {
|
||||
header( 'Content-Type' => 'text/comma-separated-values' );
|
||||
template 'ajax/search/vlan_csv.tt', { results => $set },
|
||||
{ layout => undef };
|
||||
}
|
||||
};
|
||||
|
||||
true;
|
||||
|
||||
@@ -200,6 +200,15 @@ td > form.nd_inline-form {
|
||||
color: #6D5720;
|
||||
}
|
||||
|
||||
/* reset to normal weight for the download as CSV icon */
|
||||
#nd_csv-download {
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
#nd_csv-download:hover {
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
/* for the job control admin page play/pause links */
|
||||
#nd_countdown-refresh:hover, #nd_countdown-control:hover {
|
||||
text-decoration: none;
|
||||
|
||||
@@ -36,6 +36,12 @@
|
||||
<i id="nd_countdown-control-icon" class="text-success icon-play"></i></a>
|
||||
<span id="nd_countdown"></span>
|
||||
</span>
|
||||
[% ELSIF task.provides_csv %]
|
||||
<span id="nd_device-name">
|
||||
<a id="nd_csv-download" href="#" download="netdisco.csv">
|
||||
<i id="nd_csv-download-icon" class="text-info icon-file-text-alt icon-large"
|
||||
rel="tooltip" data-placement="left" data-offset="5" data-title="Download as CSV"></i></a>
|
||||
</span>
|
||||
[% END %]
|
||||
</ul>
|
||||
<div class="tab-content">
|
||||
|
||||
11
Netdisco/share/views/ajax/device/addresses_csv.tt
Normal file
11
Netdisco/share/views/ajax/device/addresses_csv.tt
Normal file
@@ -0,0 +1,11 @@
|
||||
[% USE CSV -%]
|
||||
[% CSV.dump([ 'Address' 'DNS' 'Interface' 'Description' 'Prefix' ]) %]
|
||||
|
||||
[% WHILE (row = results.next) %]
|
||||
[% mylist = [] %]
|
||||
[% FOREACH col IN [ row.alias row.dns row.port row.device_port.name row.subnet ] %]
|
||||
[% mylist.push(col) %]
|
||||
[% END %]
|
||||
[% CSV.dump(mylist) %]
|
||||
|
||||
[% END %]
|
||||
10
Netdisco/share/views/ajax/report/apchanneldist_csv.tt
Normal file
10
Netdisco/share/views/ajax/report/apchanneldist_csv.tt
Normal file
@@ -0,0 +1,10 @@
|
||||
[% USE CSV -%]
|
||||
[% CSV.dump([ 'Channel' 'Count' ]) %]
|
||||
|
||||
[% WHILE (row = results.next) %]
|
||||
[% mylist = [] %]
|
||||
[% mylist.push(row.channel) %]
|
||||
[% mylist.push(row.get_column('ch_count')) %]
|
||||
[% CSV.dump(mylist) %]
|
||||
|
||||
[% END %]
|
||||
13
Netdisco/share/views/ajax/report/duplexmismatch_csv.tt
Normal file
13
Netdisco/share/views/ajax/report/duplexmismatch_csv.tt
Normal file
@@ -0,0 +1,13 @@
|
||||
[% USE CSV -%]
|
||||
[% CSV.dump([ 'Left Device' 'Port' 'Duplex' 'Right Device' 'Port' 'Duplex' ]) %]
|
||||
|
||||
[% WHILE (row = results.next) %]
|
||||
[% mylist = [] %]
|
||||
[% device_left = row.left_dns || row.left_ip %]
|
||||
[% device_right = row.right_dns || row.right_ip %]
|
||||
[% FOREACH col IN [ device_left row.left_port row.left_duplex.ucfirst device_right row.right_port row.right_duplex.ucfirst ] %]
|
||||
[% mylist.push(col) %]
|
||||
[% END %]
|
||||
[% CSV.dump(mylist) %]
|
||||
|
||||
[% END %]
|
||||
12
Netdisco/share/views/ajax/report/halfduplex_csv.tt
Normal file
12
Netdisco/share/views/ajax/report/halfduplex_csv.tt
Normal file
@@ -0,0 +1,12 @@
|
||||
[% USE CSV -%]
|
||||
[% CSV.dump([ 'Device' 'Port' 'Description' 'Duplex' ]) %]
|
||||
|
||||
[% WHILE (row = results.next) %]
|
||||
[% mylist = [] %]
|
||||
[% device = row.device.dns || row.device.ip %]
|
||||
[% FOREACH col IN [ device row.port row.name row.duplex.ucfirst ] %]
|
||||
[% mylist.push(col) %]
|
||||
[% END %]
|
||||
[% CSV.dump(mylist) %]
|
||||
|
||||
[% END %]
|
||||
12
Netdisco/share/views/ajax/report/portutilization_csv.tt
Normal file
12
Netdisco/share/views/ajax/report/portutilization_csv.tt
Normal file
@@ -0,0 +1,12 @@
|
||||
[% USE CSV -%]
|
||||
[% CSV.dump([ 'Device' 'Total Ports' 'In Use' 'Shutdown' 'Free' ]) %]
|
||||
|
||||
[% WHILE (row = results.next) %]
|
||||
[% mylist = [] %]
|
||||
[% device = row.dns || row.ip %]
|
||||
[% FOREACH col IN [ device row.port_count row.ports_in_use row.ports_shutdown row.ports_free ] %]
|
||||
[% mylist.push(col) %]
|
||||
[% END %]
|
||||
[% CSV.dump(mylist) %]
|
||||
|
||||
[% END %]
|
||||
12
Netdisco/share/views/ajax/search/device_csv.tt
Normal file
12
Netdisco/share/views/ajax/search/device_csv.tt
Normal file
@@ -0,0 +1,12 @@
|
||||
[% USE CSV -%]
|
||||
[% CSV.dump(headers) %]
|
||||
|
||||
[% WHILE (row = results.next) %]
|
||||
[% mylist = [] %]
|
||||
[% device = row.dns || row.ip %]
|
||||
[% FOREACH col IN [ device row.contact row.location row.name row.model row.os_ver row.ip row.serial] %]
|
||||
[% mylist.push(col) %]
|
||||
[% END %]
|
||||
[% CSV.dump(mylist) %]
|
||||
|
||||
[% END %]
|
||||
12
Netdisco/share/views/ajax/search/port_csv.tt
Normal file
12
Netdisco/share/views/ajax/search/port_csv.tt
Normal file
@@ -0,0 +1,12 @@
|
||||
[% USE CSV -%]
|
||||
[% CSV.dump([ 'Description' 'Port' 'Name' 'Vlan' ]) %]
|
||||
|
||||
[% WHILE (row = results.next) %]
|
||||
[% mylist = [] %]
|
||||
[% myport = "$row.ip [ $row.port ] (" _ row.device.dns _ ")" IF row.device.dns %]
|
||||
[% FOREACH col IN [ row.name myport row.descr row.vlan ] %]
|
||||
[% mylist.push(col) %]
|
||||
[% END %]
|
||||
[% CSV.dump(mylist) %]
|
||||
|
||||
[% END %]
|
||||
12
Netdisco/share/views/ajax/search/vlan_csv.tt
Normal file
12
Netdisco/share/views/ajax/search/vlan_csv.tt
Normal file
@@ -0,0 +1,12 @@
|
||||
[% USE CSV -%]
|
||||
[% CSV.dump([ 'Vlan' 'Device' 'Description' 'Model' 'OS' 'Vendor' ]) %]
|
||||
|
||||
[% WHILE (row = results.next) %]
|
||||
[% mylist = [] %]
|
||||
[% device = row.dns || row.ip %]
|
||||
[% FOREACH col IN [ row.vlan.vlan device row.vlan.description row.model row.os row.vendor ] %]
|
||||
[% mylist.push(col) %]
|
||||
[% END %]
|
||||
[% CSV.dump(mylist) %]
|
||||
|
||||
[% END %]
|
||||
@@ -45,7 +45,12 @@
|
||||
[% FOREACH tab IN settings._device_tabs %]
|
||||
<li[% ' class="active"' IF params.tab == tab.tag %]><a id="[% tab.tag %]_link" href="#[% tab.tag %]_pane">[% tab.label %]</a></li>
|
||||
[% END %]
|
||||
<span id="nd_device-name">[% d.dns || d.name | html_entity %]</span>
|
||||
<span id="nd_device-name">
|
||||
[% d.dns || d.name | html_entity %]
|
||||
<a id="nd_csv-download" href="#" download="netdisco.csv">
|
||||
<i id="nd_csv-download-icon" class="text-info icon-file-text-alt icon-large"
|
||||
rel="tooltip" data-placement="left" data-offset="5" data-title="Download as CSV"></i></a>
|
||||
</span>
|
||||
</ul>
|
||||
<div class="tab-content">
|
||||
[% FOREACH tab IN settings._device_tabs %]
|
||||
|
||||
@@ -1,3 +1,23 @@
|
||||
// csv download icon on any table page
|
||||
// needs to be dynamically updated to use current search options
|
||||
function update_csv_download_link (type, tab, show) {
|
||||
var form = '#' + tab + '_form';
|
||||
var query = $(form).serialize();
|
||||
|
||||
if (show == '1') {
|
||||
$('#nd_csv-download')
|
||||
.attr('href', '/ajax/content/' + type + '/' + tab + '?' + query)
|
||||
.attr('download', 'netdisco-' + type + '-' + tab + '.csv')
|
||||
.show();
|
||||
}
|
||||
else {
|
||||
$('#nd_csv-download').hide();
|
||||
}
|
||||
}
|
||||
|
||||
// page title includes tab name and possibly device name
|
||||
// this is nice for when you have multiple netdisco pages open in the
|
||||
// browser
|
||||
function update_page_title (tab) {
|
||||
var pgtitle = 'Netdisco';
|
||||
if ($('#nd_device-name').text().length) {
|
||||
@@ -43,6 +63,7 @@
|
||||
[% FOREACH tab IN settings._search_tabs %]
|
||||
$('[% "#${tab.tag}_form" %]').submit(function (event) {
|
||||
var pgtitle = update_page_title('[% tab.tag %]');
|
||||
update_csv_download_link('search', '[% tab.tag %]', '[% tab.provides_csv %]');
|
||||
update_browser_history('[% tab.tag %]', pgtitle);
|
||||
copy_navbar_to_sidebar('[% tab.tag %]');
|
||||
do_search(event, '[% tab.tag %]');
|
||||
@@ -55,8 +76,10 @@
|
||||
[% FOREACH tab IN settings._device_tabs %]
|
||||
$('[% "#${tab.tag}_form" %]').submit(function (event) {
|
||||
var pgtitle = update_page_title('[% tab.tag %]');
|
||||
update_csv_download_link('device', '[% tab.tag %]', '[% tab.provides_csv %]');
|
||||
update_browser_history('[% tab.tag %]', pgtitle);
|
||||
copy_navbar_to_sidebar('[% tab.tag %]');
|
||||
|
||||
[% IF tab.tag == 'ports' %]
|
||||
var cookie = $('#ports_form').find('input,select')
|
||||
.not('#nd_port-query,input[name="q"],input[name="tab"]')
|
||||
@@ -66,6 +89,7 @@
|
||||
});
|
||||
$.cookie('nd_ports-form', $.param(cookie) ,{ expires: 365 });
|
||||
[% END %]
|
||||
|
||||
do_search(event, '[% tab.tag %]');
|
||||
});
|
||||
[% END %]
|
||||
@@ -74,7 +98,8 @@
|
||||
[% IF report %]
|
||||
// for the report pages
|
||||
$('[% "#${report.tag}_form" %]').submit(function (event) {
|
||||
update_page_title('[% tab.tag %]');
|
||||
update_page_title('[% report.tag %]');
|
||||
update_csv_download_link('report', '[% report.tag %]', '1');
|
||||
do_search(event, '[% report.tag %]');
|
||||
});
|
||||
[% END -%]
|
||||
@@ -82,7 +107,8 @@
|
||||
[% IF task %]
|
||||
// for the admin pages
|
||||
$('[% "#${task.tag}_form" %]').submit(function (event) {
|
||||
update_page_title('[% tab.tag %]');
|
||||
update_page_title('[% task.tag %]');
|
||||
update_csv_download_link('task', '[% task.tag %]', '1');
|
||||
do_search(event, '[% task.tag %]');
|
||||
});
|
||||
[% END %]
|
||||
|
||||
@@ -28,6 +28,13 @@
|
||||
<ul id="nd_search-results" class="nav nav-tabs">
|
||||
<li class="active"><a id="[% report.tag %]_link" class="nd_single-tab"
|
||||
href="#[% report.tag %]_pane">[% report.label %]</a></li>
|
||||
[% IF report.provides_csv %]
|
||||
<span id="nd_device-name">
|
||||
<a id="nd_csv-download" href="#" download="netdisco.csv">
|
||||
<i id="nd_csv-download-icon" class="text-info icon-file-text-alt icon-large"
|
||||
rel="tooltip" data-placement="left" data-offset="5" data-title="Download as CSV"></i></a>
|
||||
</span>
|
||||
[% END %]
|
||||
</ul>
|
||||
<div class="tab-content">
|
||||
<div class="tab-pane active" id="[% report.tag %]_pane"></div>
|
||||
|
||||
@@ -32,6 +32,11 @@
|
||||
[% FOREACH tab IN settings._search_tabs %]
|
||||
<li[% ' class="active"' IF params.tab == tab.tag %]><a id="[% tab.tag %]_link" href="#[% tab.tag %]_pane">[% tab.label %]</a></li>
|
||||
[% END %]
|
||||
<span id="nd_device-name">
|
||||
<a id="nd_csv-download" href="#" download="netdisco.csv">
|
||||
<i id="nd_csv-download-icon" class="text-info icon-file-text-alt icon-large"
|
||||
rel="tooltip" data-placement="left" data-offset="5" data-title="Download as CSV"></i></a>
|
||||
</span>
|
||||
</ul>
|
||||
<div class="tab-content">
|
||||
[% FOREACH tab IN settings._search_tabs %]
|
||||
|
||||
Reference in New Issue
Block a user