diff --git a/Netdisco/Makefile.PL b/Netdisco/Makefile.PL
index 3e2d8440..9ab197cf 100644
--- a/Netdisco/Makefile.PL
+++ b/Netdisco/Makefile.PL
@@ -32,7 +32,7 @@ requires 'Plack' => 1.0023;
requires 'Plack::Middleware::Expires' => 0.03;
requires 'Role::Tiny' => 1.002005;
requires 'Socket6' => 0.23;
-requires 'Starman' => 0.3008;
+requires 'Starman' => 0.4008;
requires 'SNMP::Info' => 3.05;
requires 'SQL::Translator' => 0.11016;
requires 'Template' => 2.24;
diff --git a/Netdisco/lib/App/Netdisco/Web/Plugin/Device/Ports.pm b/Netdisco/lib/App/Netdisco/Web/Plugin/Device/Ports.pm
index 6940b8f4..0f0f04f1 100644
--- a/Netdisco/lib/App/Netdisco/Web/Plugin/Device/Ports.pm
+++ b/Netdisco/lib/App/Netdisco/Web/Plugin/Device/Ports.pm
@@ -36,10 +36,15 @@ ajax '/ajax/content/device/ports' => require_login sub {
$f =~ s/\*/%/g;
$f =~ s/\?/_/g;
# set wilcards at param boundaries
- $f =~ s/^\%*/%/;
- $f =~ s/\%*$/%/;
+ if ($f !~ m/[%_]/) {
+ $f =~ s/^\%*/%/;
+ $f =~ s/\%*$/%/;
+ }
# enable ILIKE op
- $f = { '-ilike' => $f };
+ $f = { (param('invert') ? '-not_ilike' : '-ilike') => $f };
+ }
+ elsif (param('invert')) {
+ $f = { '!=' => $f };
}
if ($set->search({'me.port' => $f})->count) {
diff --git a/Netdisco/share/public/css/netdisco.css b/Netdisco/share/public/css/netdisco.css
index d5f77577..922fb7c2 100644
--- a/Netdisco/share/public/css/netdisco.css
+++ b/Netdisco/share/public/css/netdisco.css
@@ -9,6 +9,7 @@ body {
/* magnifying glass icon for search box */
.nd_navbar-icon {
vertical-align: sub;
+ margin-top: 4px;
cursor: pointer;
}
@@ -205,7 +206,7 @@ td > form.nd_inline-form {
font-weight: normal;
}
-#nd_csv-download:hover {
+#nd_csv-download:hover, #nd_sidebar-reset-link:hover {
text-decoration: none;
}
@@ -398,15 +399,15 @@ td > form.nd_inline-form {
/* fixup for prepended checkbox in sidebar */
.nd_searchcheckbox {
- width: 123px;
+ width: 121px;
padding-left: 8px;
cursor: pointer;
}
/* fixup for prepended partial port name checkbox in sidebar */
.nd_port-partial-checkbox {
- width: 136px;
- padding: 0px 0px 0px 11px !important;
+ width: 84px;
+ padding: 0px 0px 0px 5px !important;
cursor: pointer;
}
@@ -420,6 +421,27 @@ td > form.nd_inline-form {
margin-bottom: 5px !important;
}
+/* fixup for prepended invert port name checkbox in sidebar */
+.nd_port-invert-checkbox {
+ width: 30px;
+ padding: 0px 0px 0px 5px !important;
+ cursor: pointer;
+}
+
+.nd_port-invert-label {
+ padding: 0px !important;
+ /* for some reason only .add-on:first-child gets these */
+ -webkit-border-radius: 4px 0 0 4px !important;
+ -moz-border-radius: 4px 0 0 4px !important;
+ border-radius: 4px 0 0 4px !important;
+}
+
+.nd_port-invert {
+ margin-left: 5px !important;
+ margin-top: -5px;
+ margin-bottom: 5px !important;
+}
+
/* fixup for prepended checkbox in sidebar */
.nd_sidebar .input-prepend {
margin-left: -2px;
@@ -434,7 +456,7 @@ td > form.nd_inline-form {
/* placement of form field in sidebar */
.nd_side-input {
margin-left: -3px;
- width: 152px;
+ width: 151px;
}
/* placement of form field in sidebar */
diff --git a/Netdisco/share/public/javascripts/netdisco.js b/Netdisco/share/public/javascripts/netdisco.js
index 42be2719..7ac3f787 100644
--- a/Netdisco/share/public/javascripts/netdisco.js
+++ b/Netdisco/share/public/javascripts/netdisco.js
@@ -39,7 +39,7 @@ function do_search (event, tab) {
);
return;
}
- if (response === "") {
+ if (response == "") {
$(target).html(
'
No matching records.
'
);
@@ -111,32 +111,41 @@ if (window.History && window.History.enabled) {
// if any field in Search Options has content, highlight in green
function device_form_state(e) {
- if (e.prop('value') != "") {
- e.parent(".clearfix").addClass('success');
+ var with_val = $.grep(form_inputs,
+ function(n,i) {return($(n).prop('value') != "")}).length;
+ var with_text = $.grep(form_inputs.not('select'),
+ function(n,i) {return($(n).val() != "")}).length;
- if (e.parents('#device_form').length) {
- $('#nq').css('text-decoration', 'line-through');
-
- if (e.attr('type') == 'text') {
- $('.nd_field-copy-icon').hide();
- }
- }
-
- var id = '#' + e.attr('name') + '_clear_btn';
- $(id).show();
- }
- else {
+ if (e.prop('value') == "") {
e.parent(".clearfix").removeClass('success');
var id = '#' + e.attr('name') + '_clear_btn';
$(id).hide();
- var num_empty = $.grep(form_inputs,
- function(n,i) {return($(n).val() != "")}).length;
- if (num_empty === 3) {
+ // if form has no field val, clear strikethough
+ if (with_val == 0) {
$('#nq').css('text-decoration', 'none');
+ }
+
+ // for text inputs only, extra formatting
+ if (with_text == 0) {
$('.nd_field-copy-icon').show();
}
}
+ else {
+ e.parent(".clearfix").addClass('success');
+ var id = '#' + e.attr('name') + '_clear_btn';
+ $(id).show();
+
+ // if form still has any field val, set strikethough
+ if (e.parents('form[action="/search"]').length > 0 && with_val != 0) {
+ $('#nq').css('text-decoration', 'line-through');
+ }
+
+ // if we're text, hide copy icon when we get a val
+ if (e.attr('type') == 'text') {
+ $('.nd_field-copy-icon').hide();
+ }
+ }
}
$(document).ready(function() {
diff --git a/Netdisco/share/views/admintask.tt b/Netdisco/share/views/admintask.tt
index d246e2b9..fbaf3d01 100644
--- a/Netdisco/share/views/admintask.tt
+++ b/Netdisco/share/views/admintask.tt
@@ -31,7 +31,7 @@
[% IF task.tag == 'jobqueue' %]
-
+
diff --git a/Netdisco/share/views/ajax/device/addresses.tt b/Netdisco/share/views/ajax/device/addresses.tt
index 36231a3c..4eb5c3ea 100644
--- a/Netdisco/share/views/ajax/device/addresses.tt
+++ b/Netdisco/share/views/ajax/device/addresses.tt
@@ -17,7 +17,7 @@
href="[% device_ports %]&q=[% params.q | uri %]&f=[% row.port | uri %]">[% row.port | html_entity %]
[% row.device_port.name | html_entity %] |
[% row.subnet | html_entity %] |
+ href="[% search_device %]&q=[% row.subnet | uri %]&ip=[% row.subnet | uri %]">[% row.subnet | html_entity %]
[% END %]
diff --git a/Netdisco/share/views/ajax/device/details.tt b/Netdisco/share/views/ajax/device/details.tt
index 0d52e979..21c3cfde 100644
--- a/Netdisco/share/views/ajax/device/details.tt
+++ b/Netdisco/share/views/ajax/device/details.tt
@@ -19,7 +19,7 @@
[% ELSE %]
[% d.location | html_entity %]
+ href="[% search_device %]&q=[% d.location | uri %]&location=[% d.location | uri %]">[% d.location | html_entity %]
|
[% END %]
@@ -42,10 +42,10 @@
Vendor / Model |
[% d.vendor | html_entity %]
+ href="[% search_device %]&q=[% d.vendor | uri %]&vendor=[% d.vendor | uri %]">[% d.vendor | html_entity %]
/
[% d.model | html_entity %]
+ href="[% search_device %]&q=[% d.model | uri %]&model=[% d.model | uri %]">[% d.model | html_entity %]
|
@@ -53,7 +53,7 @@
| [% d.os | html_entity %] /
[% d.os_ver | html_entity %]
+ href="[% search_device %]&q=[% d.os_ver | uri %]&os_ver=[% d.os_ver | uri %]">[% d.os_ver | html_entity %]
|
diff --git a/Netdisco/share/views/ajax/device/ports.tt b/Netdisco/share/views/ajax/device/ports.tt
index 27117abe..5210ac13 100644
--- a/Netdisco/share/views/ajax/device/ports.tt
+++ b/Netdisco/share/views/ajax/device/ports.tt
@@ -24,7 +24,7 @@
[% ELSIF row.has_column_loaded('is_free') AND row.is_free %]
- [% ELSIF row.up_admin == 'up' AND row.up != 'up' %]
+ [% ELSIF row.up_admin == 'up' AND (row.up != 'up' AND row.up != 'dormant') %]
[% ELSE %]
@@ -210,6 +210,7 @@
[% IF params.c_neighbors AND (row.remote_ip OR row.is_uplink) %]
[% IF row.neighbor %]
+
[% row.neighbor.dns.remove(settings.domain_suffix) || row.neighbor.ip | html_entity %]
diff --git a/Netdisco/share/views/inventory.tt b/Netdisco/share/views/inventory.tt
index df7fa2c1..47cc0484 100644
--- a/Netdisco/share/views/inventory.tt
+++ b/Netdisco/share/views/inventory.tt
@@ -17,12 +17,12 @@
|
+ href="[% search_device %]&q=[% platform.vendor | uri %]&vendor=[% platform.vendor | uri %]">
[% platform.vendor | html_entity %]
|
+ href="[% search_device %]&q=[% platform.model | uri %]&model=[% platform.model | uri %]">
[% platform.model | html_entity %]
|
[% platform.get_column('count') | html_entity %] |
@@ -48,7 +48,7 @@
[% release.os | html_entity %] |
+ href="[% search_device %]&q=[% release.os_ver | uri %]&os_ver=[% release.os_ver | uri %]">
[% release.os_ver | html_entity %]
|
[% release.get_column('count') | html_entity %] |
diff --git a/Netdisco/share/views/js/common.js b/Netdisco/share/views/js/common.js
index 61d246f0..6385df6d 100644
--- a/Netdisco/share/views/js/common.js
+++ b/Netdisco/share/views/js/common.js
@@ -20,8 +20,8 @@
// browser
function update_page_title (tab) {
var pgtitle = 'Netdisco';
- if ($('#nd_device-name').text().length) {
- var pgtitle = $('#nd_device-name').text() +' - '+ $('#'+ tab + '_link').text();
+ if ($.trim($('#nd_device-name').text()).length) {
+ pgtitle = $.trim($('#nd_device-name').text()) +' - '+ $('#'+ tab + '_link').text();
}
return pgtitle;
}
@@ -44,14 +44,14 @@
}
// each sidebar search form has a hidden copy of the main navbar search
- // query. when the tab query takes place, copy the navbar locally, then
- // replicate to all other tabs.
function copy_navbar_to_sidebar (tab) {
var form = '#' + tab + '_form';
+ // copy navbar value to currently active sidebar form
if ($('#nq').val()) {
$(form).find("input[name=q]").val( $('#nq').val() );
}
+ // then copy to all other inactive tab sidebars
$('form').find("input[name=q]").each( function() {
$(this).val( $(form).find("input[name=q]").val() );
});
@@ -63,9 +63,9 @@
[% 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 %]');
+ update_browser_history('[% tab.tag %]', pgtitle);
+ update_csv_download_link('search', '[% tab.tag %]', '[% tab.provides_csv %]');
do_search(event, '[% tab.tag %]');
});
[% END %]
@@ -76,9 +76,9 @@
[% 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 %]');
+ update_browser_history('[% tab.tag %]', pgtitle);
+ update_csv_download_link('device', '[% tab.tag %]', '[% tab.provides_csv %]');
[% IF tab.tag == 'ports' %]
// to be fair I can't remember why we do this in JS and not from the app
@@ -93,7 +93,9 @@
// form reset icon on ports tab
$('#nd_sidebar-reset-link').attr('href', '/device?tab=ports&reset=on&' +
- $('#ports_form').find('input[name="q"],input[name="f"],input[name="partial"]').serialize())
+ $('#ports_form')
+ .find('input[name="q"],input[name="f"],input[name="partial"],input[name="invert"]')
+ .serialize())
[% END %]
do_search(event, '[% tab.tag %]');
diff --git a/Netdisco/share/views/layouts/main.tt b/Netdisco/share/views/layouts/main.tt
index 51b77422..208ef22d 100644
--- a/Netdisco/share/views/layouts/main.tt
+++ b/Netdisco/share/views/layouts/main.tt
@@ -88,7 +88,8 @@
-
+
[% IF user_has_role('admin') %]
diff --git a/Netdisco/share/views/sidebar/device/ports.tt b/Netdisco/share/views/sidebar/device/ports.tt
index 46022683..8c9e366b 100644
--- a/Netdisco/share/views/sidebar/device/ports.tt
+++ b/Netdisco/share/views/sidebar/device/ports.tt
@@ -15,6 +15,13 @@
+
+
@@ -29,12 +36,13 @@
Port Free
Admin Disabled
Blocking
+ Neighbor Device
Neighbor Inacessible
IP Phone
Wireless Client
Archived Data
[% IF user_has_role('port_control') %]
- Click "Update View"
+ Click "Update View"
[% END %]
@@ -124,4 +132,5 @@
-
+
diff --git a/Netdisco/share/views/sidebar/search/device.tt b/Netdisco/share/views/sidebar/search/device.tt
index ae5aed96..12974662 100644
--- a/Netdisco/share/views/sidebar/search/device.tt
+++ b/Netdisco/share/views/sidebar/search/device.tt
@@ -77,4 +77,5 @@
Match All Options
-
+
diff --git a/Netdisco/share/views/sidebar/search/node.tt b/Netdisco/share/views/sidebar/search/node.tt
index cce60746..0d53105d 100644
--- a/Netdisco/share/views/sidebar/search/node.tt
+++ b/Netdisco/share/views/sidebar/search/node.tt
@@ -46,4 +46,5 @@
[% END %]
-
+
diff --git a/Netdisco/share/views/sidebar/search/port.tt b/Netdisco/share/views/sidebar/search/port.tt
index 9ea2cabb..92ef81b4 100644
--- a/Netdisco/share/views/sidebar/search/port.tt
+++ b/Netdisco/share/views/sidebar/search/port.tt
@@ -10,4 +10,5 @@
Partial Name
-
+
|