Plugins can have CSS and Javascript loaded within <head>

This commit is contained in:
Oliver Gorwits
2013-06-02 12:48:06 +01:00
parent ed1bfa1ae7
commit 66b3ced179
13 changed files with 99 additions and 21 deletions

View File

@@ -12,7 +12,9 @@
* Job Queue view and delete page * Job Queue view and delete page
* Empty device table prompts initial discover on homepage * Empty device table prompts initial discover on homepage
* Support for App::NetdiscoX::Web::Plugin namespace * Support for App::NetdiscoX::Web::Plugin namespace
* Plugins can add columns to Device Ports display
* Observium Sparklines port column plugin * Observium Sparklines port column plugin
* Plugins can have CSS and Javascript loaded within <head>
[ENHANCEMENTS] [ENHANCEMENTS]

View File

@@ -10,6 +10,7 @@ use HTML::Entities (); # to ensure dependency is met
use URI::QueryParam (); # part of URI, to add helper methods use URI::QueryParam (); # part of URI, to add helper methods
use App::Netdisco::Web::AuthN; use App::Netdisco::Web::AuthN;
use App::Netdisco::Web::Static;
use App::Netdisco::Web::Search; use App::Netdisco::Web::Search;
use App::Netdisco::Web::Device; use App::Netdisco::Web::Device;
use App::Netdisco::Web::Report; use App::Netdisco::Web::Report;

View File

@@ -18,6 +18,8 @@ hook 'before' => sub {
if (session('user') && session->id) { if (session('user') && session->id) {
var(user => schema('netdisco')->resultset('User') var(user => schema('netdisco')->resultset('User')
->find(session('user'))); ->find(session('user')));
var('user')->port_control(0)
if setting('no_port_control');
} }
}; };

View File

@@ -4,6 +4,8 @@ use Dancer ':syntax';
use Dancer::Plugin; use Dancer::Plugin;
set( set(
'_additional_css' => [],
'_additional_javascript' => [],
'_extra_device_port_cols' => [], '_extra_device_port_cols' => [],
'_navbar_items' => [], '_navbar_items' => [],
'_search_tabs' => [], '_search_tabs' => [],
@@ -30,6 +32,32 @@ register 'register_template_path' => sub {
$path; $path;
}; };
sub _register_include {
my ($type, $plugin) = @_;
if (!length $type) {
error "bad type to _register_include";
return;
}
if (!length $plugin) {
error "bad plugin name to register_$type";
return;
}
push @{ setting("_additional_$type") }, $plugin;
}
register 'register_css' => sub {
my ($self, $plugin) = plugin_args(@_);
_register_include('css', $plugin);
};
register 'register_javascript' => sub {
my ($self, $plugin) = plugin_args(@_);
_register_include('javascript', $plugin);
};
register 'register_device_port_column' => sub { register 'register_device_port_column' => sub {
my ($self, $config) = plugin_args(@_); my ($self, $config) = plugin_args(@_);
$config->{default} ||= ''; $config->{default} ||= '';

View File

@@ -77,7 +77,7 @@ ajax '/ajax/content/device/ports' => sub {
template 'ajax/device/ports.tt', { template 'ajax/device/ports.tt', {
results => $results, results => $results,
nodes => $nodes_name, nodes => $nodes_name,
device => $device->ip, device => $device,
}, { layout => undef }; }, { layout => undef };
}; };

View File

@@ -0,0 +1,30 @@
package App::Netdisco::Web::Static;
use Dancer ':syntax';
use Path::Class;
get '/plugin/*/*.js' => sub {
my ($plugin) = splat;
my $content = template
"plugin/$plugin/$plugin.js", {},
{ layout => undef };
send_file \$content,
content_type => 'application/javascript',
filename => "$plugin.js";
};
get '/plugin/*/*.css' => sub {
my ($plugin) = splat;
my $content = template
"plugin/$plugin/$plugin.css", {},
{ layout => undef };
send_file \$content,
content_type => 'text/css',
filename => "$plugin.css";
};
true;

View File

@@ -5,11 +5,17 @@ use Dancer::Plugin::DBIC;
use App::Netdisco::Web::Plugin; use App::Netdisco::Web::Plugin;
use File::ShareDir 'dist_dir';
use Path::Class;
register_device_port_column({ register_device_port_column({
name => 'c_observiumsparklines', name => 'observiumsparklines',
position => 'mid', position => 'mid',
label => 'Traffic', label => 'Traffic',
default => 'on', default => 'on',
}); });
register_css('observiumsparklines');
register_javascript('observiumsparklines');
true; true;

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -32,7 +32,7 @@
[% NEXT UNLESS config.position == 'left' AND params.${config.name} %] [% NEXT UNLESS config.position == 'left' AND params.${config.name} %]
<td> <td>
[% TRY %] [% TRY %]
[% INCLUDE "plugin/device_port_column/${config.name}.tt" %] [% INCLUDE "plugin/${config.name}/device_port_column.tt" %]
[% CATCH %] [% CATCH %]
<!-- dummy content required by Template Toolkit TRY --> <!-- dummy content required by Template Toolkit TRY -->
[% END %] [% END %]
@@ -43,13 +43,13 @@
[% IF vars.user.port_control AND params.c_admin %] [% IF vars.user.port_control AND params.c_admin %]
[% IF row.up_admin == 'up' %] [% IF row.up_admin == 'up' %]
<td nowrap class="nd_editable-cell" data-action="down" <td nowrap class="nd_editable-cell" data-action="down"
data-field="c_port" data-for-device="[% device | html_entity %]" data-for-port="[% row.port | html_entity %]"> data-field="c_port" data-for-device="[% device.ip | html_entity %]" data-for-port="[% row.port | html_entity %]">
<i class="icon-hand-down nd_hand-icon" <i class="icon-hand-down nd_hand-icon"
rel="tooltip" data-placement="top" data-offset="3" rel="tooltip" data-placement="top" data-offset="3"
data-animation="" data-title="Click to Disable"></i> data-animation="" data-title="Click to Disable"></i>
[% ELSE %] [% ELSE %]
<td nowrap class="nd_editable-cell" data-action="up" <td nowrap class="nd_editable-cell" data-action="up"
data-field="c_port" data-for-device="[% device | html_entity %]" data-for-port="[% row.port | html_entity %]"> data-field="c_port" data-for-device="[% device.ip | html_entity %]" data-for-port="[% row.port | html_entity %]">
<i class="icon-hand-up nd_hand-icon" <i class="icon-hand-up nd_hand-icon"
rel="tooltip" data-placement="top" data-offset="3" rel="tooltip" data-placement="top" data-offset="3"
data-animation="" data-title="Click to Enable"></i> data-animation="" data-title="Click to Enable"></i>
@@ -66,13 +66,9 @@
[% FOREACH config IN settings._extra_device_port_cols %] [% FOREACH config IN settings._extra_device_port_cols %]
[% NEXT UNLESS config.position == 'mid' AND params.${config.name} %] [% NEXT UNLESS config.position == 'mid' AND params.${config.name} %]
<td> <td>
[% TRY %] [% INCLUDE "plugin/${config.name}/device_port_column.tt" %]
[% INCLUDE "plugin/device_port_column/${config.name}.tt" %]
[% CATCH %]
<!-- dummy content required by Template Toolkit TRY -->
[% END %]
</td> </td>
[% END %] [% END -%]
[% IF params.c_descr %] [% IF params.c_descr %]
<td nowrap>[% row.descr | html_entity %]</td> <td nowrap>[% row.descr | html_entity %]</td>
@@ -97,7 +93,7 @@
[% IF params.c_name %] [% IF params.c_name %]
[% IF vars.user.port_control AND params.c_admin %] [% IF vars.user.port_control AND params.c_admin %]
<td nowrap class="nd_editable-cell" contenteditable="true" <td nowrap class="nd_editable-cell" contenteditable="true"
data-field="c_name" data-for-device="[% device | html_entity %]" data-for-port="[% row.port | html_entity %]"> data-field="c_name" data-for-device="[% device.ip | html_entity %]" data-for-port="[% row.port | html_entity %]">
<i class="icon-edit nd_edit-icon"></i> <i class="icon-edit nd_edit-icon"></i>
[% ELSE %] [% ELSE %]
<td nowrap> <td nowrap>
@@ -123,7 +119,7 @@
[% IF params.c_vlan %] [% IF params.c_vlan %]
[% IF vars.user.port_control AND params.c_admin %] [% IF vars.user.port_control AND params.c_admin %]
<td class="nd_editable-cell" contenteditable="true" <td class="nd_editable-cell" contenteditable="true"
data-field="c_vlan" data-for-device="[% device | html_entity %]" data-for-port="[% row.port | html_entity %]"> data-field="c_vlan" data-for-device="[% device.ip | html_entity %]" data-for-port="[% row.port | html_entity %]">
<i class="icon-edit nd_edit-icon"></i> <i class="icon-edit nd_edit-icon"></i>
<div class="nd_editable-cell-content"> <div class="nd_editable-cell-content">
[% IF row.vlan %][% row.vlan | html_entity %][% END %] [% IF row.vlan %][% row.vlan | html_entity %][% END %]
@@ -164,7 +160,7 @@
[% IF row.power.admin == 'true' %] [% IF row.power.admin == 'true' %]
[% IF vars.user.port_control AND params.c_admin %] [% IF vars.user.port_control AND params.c_admin %]
<td nowrap data-action="false" <td nowrap data-action="false"
data-field="c_power" data-for-device="[% device | html_entity %]" data-field="c_power" data-for-device="[% device.ip | html_entity %]"
data-for-port="[% row.port | html_entity %]"> data-for-port="[% row.port | html_entity %]">
<i class="icon-off nd_power-icon nd_power-on" <i class="icon-off nd_power-icon nd_power-on"
@@ -184,7 +180,7 @@
[% ELSE %] [% ELSE %]
[% IF vars.user.port_control AND params.c_admin %] [% IF vars.user.port_control AND params.c_admin %]
<td nowrap data-action="true" <td nowrap data-action="true"
data-field="c_power" data-for-device="[% device | html_entity %]" data-field="c_power" data-for-device="[% device.ip | html_entity %]"
data-for-port="[% row.port | html_entity %]"> data-for-port="[% row.port | html_entity %]">
<i class="icon-off nd_power-icon" <i class="icon-off nd_power-icon"
@@ -256,7 +252,7 @@
[% NEXT UNLESS config.position == 'right' AND params.${config.name} %] [% NEXT UNLESS config.position == 'right' AND params.${config.name} %]
<td> <td>
[% TRY %] [% TRY %]
[% INCLUDE "plugin/device_port_column/${config.name}.tt" %] [% INCLUDE "plugin/${config.name}/device_port_column.tt" %]
[% CATCH %] [% CATCH %]
<!-- dummy content required by Template Toolkit TRY --> <!-- dummy content required by Template Toolkit TRY -->
[% END %] [% END %]

View File

@@ -17,26 +17,34 @@
<script type="text/javascript" src="[% uri_base %]/javascripts/jquery-history.js"></script> <script type="text/javascript" src="[% uri_base %]/javascripts/jquery-history.js"></script>
<script type="text/javascript" src="[% uri_base %]/javascripts/jquery-deserialize.js"></script> <script type="text/javascript" src="[% uri_base %]/javascripts/jquery-deserialize.js"></script>
<script type="text/javascript" src="[% uri_base %]/javascripts/bootstrap.min.js"></script> <script type="text/javascript" src="[% uri_base %]/javascripts/bootstrap.min.js"></script>
<script type="text/javascript" src="[% uri_base %]/javascripts/jquery.qtip.min.js"></script>
<script type="text/javascript" src="[% uri_base %]/javascripts/d3.min.js"></script> <script type="text/javascript" src="[% uri_base %]/javascripts/d3.min.js"></script>
<script type="text/javascript" src="[% uri_base %]/javascripts/toastr.js"></script>
<script type="text/javascript"> <script type="text/javascript">
var uri_base = '[% uri_base %]'; var uri_base = '[% uri_base %]';
</script> </script>
<script type="text/javascript" src="[% uri_base %]/javascripts/netdisco.js"></script> <script type="text/javascript" src="[% uri_base %]/javascripts/netdisco.js"></script>
[% IF vars.user.port_control %] [% IF vars.user.port_control %]
<script type="text/javascript" src="[% uri_base %]/javascripts/toastr.js"></script>
<script type="text/javascript" src="[% uri_base %]/javascripts/netdisco_portcontrol.js"></script> <script type="text/javascript" src="[% uri_base %]/javascripts/netdisco_portcontrol.js"></script>
[% END %]
<link rel="stylesheet" href="[% uri_base %]/css/toastr.css"/> [% FOREACH add_js IN settings._additional_javascript %]
<script type="text/javascript" src="[% uri_base %]/plugin/[% add_js %]/[% add_js %].js"></script>
[% END %] [% END %]
<link rel="stylesheet" href="[% uri_base %]/css/bootstrap.min.css"/> <link rel="stylesheet" href="[% uri_base %]/css/bootstrap.min.css"/>
<link rel="stylesheet" href="[% uri_base %]/css/jquery.qtip.min.css"/>
<link rel="stylesheet" href="[% uri_base %]/css/smoothness/jquery-ui.custom.min.css"/> <link rel="stylesheet" href="[% uri_base %]/css/smoothness/jquery-ui.custom.min.css"/>
<link rel="stylesheet" href="[% uri_base %]/css/font-awesome.min.css"/> <link rel="stylesheet" href="[% uri_base %]/css/font-awesome.min.css"/>
<link rel="stylesheet" href="[% uri_base %]/css/toastr.css"/>
<link rel="stylesheet" href="[% uri_base %]/css/netdisco.css"/> <link rel="stylesheet" href="[% uri_base %]/css/netdisco.css"/>
<link rel="stylesheet" href="[% uri_base %]/css/nd_print.css" media="print"/> <link rel="stylesheet" href="[% uri_base %]/css/nd_print.css" media="print"/>
[% FOREACH add_css IN settings._additional_css %]
<link rel="stylesheet" href="[% uri_base %]/plugin/[% add_css %]/[% add_css %].css"/>
[% END %]
</head> </head>
<body> <body>

View File

@@ -1,2 +0,0 @@
<!-- not yet a hyperlink as observium does not support device details page by device-name -->
<img src="http://[% settings.plugin_c_observiumsparklines.webhost | html_entity %]/graph.php?type=port_bits&device=[% device | uri %]&port=[% row.port | uri %]&from=-1d&to=now&width=100&height=20&legend=no"/>

View File

@@ -0,0 +1,4 @@
<button class="btn" rel="popover" data-trigger="hover" data-html="true" data-content='
<img src="http://[% settings.plugin_observiumsparklines.webhost | html_entity %]/graph.php?type=port_bits&device=[% device.dns || device.name | uri %]&port=[% row.port | uri %]&from=-1w&to=now&width=208&height=100&title=yes"/>
'
><i class="icon-bar-chart"></i></button>