diff --git a/Netdisco/share/public/css/netdisco.css b/Netdisco/share/public/css/netdisco.css index 816dbf30..e603a95f 100644 --- a/Netdisco/share/public/css/netdisco.css +++ b/Netdisco/share/public/css/netdisco.css @@ -80,6 +80,11 @@ div.content > div.tab-content table.nd_floatinghead thead { min-width: 0px; } +/* for when hidden modals interfere with mouse actions on higher elements */ +.nd_deep-horizon { + z-index: -1000; +} + /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ /* styles to adjust the hero box used for homepage + login */ @@ -147,6 +152,11 @@ div.content > div.tab-content table.nd_floatinghead thead { text-align: center; } +/* undo nd_center-cell when in a modial dialog (which lives in table cell) */ +.table .nd_center-cell .modal-body { + text-align: left; +} + /* fix layout of form fields inside the (topology) table */ td div.input-append { margin-bottom: 0px; diff --git a/Netdisco/share/public/javascripts/netdisco_portcontrol.js b/Netdisco/share/public/javascripts/netdisco_portcontrol.js index 81c1be86..0bea4ffa 100644 --- a/Netdisco/share/public/javascripts/netdisco_portcontrol.js +++ b/Netdisco/share/public/javascripts/netdisco_portcontrol.js @@ -1,51 +1,64 @@ +// to tell whether bootstrap's modal had Submit button pressed :( +var nd_save_ok = false; + // user clicked or asked for port changes to be submitted via ajax function port_control (e) { - var td = $(e).closest('td'); + var td = $(e).closest('td'), + logmessage = $('#nd_portlog_log').val(); + $('#nd_portlog_log').val(''); + + if (nd_save_ok == false) { + td.find('.nd_editable-cell-content').text(td.data('default')); + td.blur(); + return; + } + nd_save_ok = false; $.ajax({ type: 'POST' ,url: uri_base + '/ajax/portcontrol' ,data: { - device: td.attr('data-for-device') - ,port: td.attr('data-for-port') - ,field: td.attr('data-field') - ,action: td.attr('data-action') + device: td.data('for-device') + ,port: td.data('for-port') + ,field: td.data('field') + ,action: td.data('action') ,value: td.text().trim() + ,log: logmessage, } ,success: function() { toastr.info('Submitted change request'); // update all the screen furniture for port up/down control - if ($.trim(td.attr('data-action')) == 'down') { + if ($.trim(td.data('action')) == 'down') { td.prev('td').html('S'); $(e).toggleClass('icon-hand-down'); $(e).toggleClass('icon-hand-up'); $(e).data('tooltip').options.title = 'Click to Enable'; - td.attr('data-action', 'up'); + td.data('action', 'up'); } - else if ($.trim(td.attr('data-action')) == 'up') { + else if ($.trim(td.data('action')) == 'up') { td.prev('td').html(''); $(e).toggleClass('icon-hand-up'); $(e).toggleClass('icon-hand-down'); $(e).data('tooltip').options.title = 'Click to Disable'; - td.attr('data-action', 'down'); + td.data('action', 'down'); } - else if ($.trim(td.attr('data-action')) == 'false') { + else if ($.trim(td.data('action')) == 'false') { $(e).next('span').text(''); $(e).toggleClass('nd_power-on'); $(e).data('tooltip').options.title = 'Click to Enable'; - td.attr('data-action', 'true'); + td.data('action', 'true'); } - else if ($.trim(td.attr('data-action')) == 'true') { + else if ($.trim(td.data('action')) == 'true') { $(e).toggleClass('nd_power-on'); $(e).data('tooltip').options.title = 'Click to Disable'; - td.attr('data-action', 'false'); + td.data('action', 'false'); } } ,error: function() { toastr.error('Failed to submit change request'); - document.execCommand('undo'); - $(e).blur(); + td.find('.nd_editable-cell-content').text(td.data('default')); + td.blur(); } }); } @@ -95,34 +108,49 @@ $(document).ready(function() { $(this).siblings('td').find('.nd_device-details-edit').hide(); // details }); - // activity for port up/down control - $('#ports_pane').on('click', '.icon-hand-up', function() { - port_control(this); // save - }); - $('#ports_pane').on('click', '.icon-hand-down', function() { - port_control(this); // save + // to tell whether bootstrap's modal had Submit button pressed :( + $('#ports_pane').on('click', '#nd_portlog_submit', function() { + nd_save_ok = true; }); - // activity for power enable/disable control - $('#ports_pane').on('click', '.nd_power-icon', function() { - port_control(this); // save + // activity for port up/down control, power enable/disable control + $('#ports_pane').on('click', '.icon-hand-up,.icon-hand-down,.nd_power-icon', function() { + var clicked = this; // create a closure + $('#nd_portlog').one('hidden', function() { + port_control(clicked); // save + }); + $('#nd_portlog').modal('show'); }); + // has cell content changed? var dirty = false; // activity for contenteditable control $('.tab-content').on('keydown', '[contenteditable=true]', function(event) { - var esc = event.which == 27, + var cell = this, + td = $(cell).closest('td'), + esc = event.which == 27, nl = event.which == 13; if (esc) { - $(this).blur(); + $(cell).blur(); } else if (nl) { event.preventDefault(); - port_control(this); // save + + if (td.data('field') == 'c_vlan') { + $('#nd_portlog').one('hidden', function() { + port_control(cell); // save + }); + $('#nd_portlog').modal('show'); + } + else { + // no confirm for port descr change + port_control(cell); // save + } + dirty = false; - $(this).blur(); + $(cell).blur(); } else { dirty = true; diff --git a/Netdisco/share/views/ajax/admintask/pseudodevice.tt b/Netdisco/share/views/ajax/admintask/pseudodevice.tt index 8678e256..0fe8f67e 100644 --- a/Netdisco/share/views/ajax/admintask/pseudodevice.tt +++ b/Netdisco/share/views/ajax/admintask/pseudodevice.tt @@ -16,7 +16,9 @@ + [% SET count = 0 %] [% WHILE (row = results.next) %] + [% SET count = count + 1 %] [% row.dns | html_entity %] @@ -28,10 +30,30 @@ - - - - + + + + [% END %] diff --git a/Netdisco/share/views/ajax/admintask/topology.tt b/Netdisco/share/views/ajax/admintask/topology.tt index cef965d4..bd836438 100644 --- a/Netdisco/share/views/ajax/admintask/topology.tt +++ b/Netdisco/share/views/ajax/admintask/topology.tt @@ -38,7 +38,9 @@ + [% SET count = 0 %] [% WHILE (row = results.next) %] + [% SET count = count + 1 %] [% (row.device1.dns || row.device1.name || row.device1.ip) | html_entity %] @@ -48,11 +50,36 @@ [% (row.device2.dns || row.device2.name || row.device2.ip) | html_entity %] [% row.port2 | html_entity %] - - - - - + + + [% END %] diff --git a/Netdisco/share/views/ajax/admintask/users.tt b/Netdisco/share/views/ajax/admintask/users.tt index 5c6c649d..e1a2644e 100644 --- a/Netdisco/share/views/ajax/admintask/users.tt +++ b/Netdisco/share/views/ajax/admintask/users.tt @@ -23,7 +23,9 @@ + [% SET count = 0 %] [% WHILE (row = results.next) %] + [% SET count = count + 1 %] @@ -46,8 +48,27 @@ - - + + + + [% END %] diff --git a/Netdisco/share/views/ajax/device/details.tt b/Netdisco/share/views/ajax/device/details.tt index acaf8edb..b1f1b686 100644 --- a/Netdisco/share/views/ajax/device/details.tt +++ b/Netdisco/share/views/ajax/device/details.tt @@ -98,12 +98,38 @@ Admin Tasks - - - - - - + + + + + + + + + + [% END %] diff --git a/Netdisco/share/views/ajax/device/ports.tt b/Netdisco/share/views/ajax/device/ports.tt index c86584cc..5476cfe3 100644 --- a/Netdisco/share/views/ajax/device/ports.tt +++ b/Netdisco/share/views/ajax/device/ports.tt @@ -125,7 +125,7 @@ [% IF params.c_vlan %] [% IF user_can_port_control AND params.c_admin %] -
@@ -273,3 +273,17 @@ [% END %] + +[% IF user_can_port_control %] + +[% END %] diff --git a/Netdisco/share/views/js/admintask.js b/Netdisco/share/views/js/admintask.js index aaeea43b..2c4da17a 100644 --- a/Netdisco/share/views/js/admintask.js +++ b/Netdisco/share/views/js/admintask.js @@ -59,6 +59,9 @@ ,delay: 150 ,minLength: 0 }); + + // activate modals + $('.nd_modal').modal({show: false}); } // on load, establish global delegations for now and future diff --git a/Netdisco/share/views/js/device.js b/Netdisco/share/views/js/device.js index 3899738e..72d7af7e 100644 --- a/Netdisco/share/views/js/device.js +++ b/Netdisco/share/views/js/device.js @@ -27,7 +27,8 @@ $('#nd_netmap-help').hide(); } - // activate tooltips and popovers + // activate modals, tooltips and popovers + $('.nd_modal').modal({show: false}); $("[rel=tooltip]").tooltip({live: true}); $("[rel=popover]").popover({live: true}); } @@ -37,7 +38,7 @@ var tab = '[% tab.tag %]' var target = '#' + tab + '_pane'; - // sidebar form fields should change colour and have bin/copy icon + // sidebar form fields should change colour and have trash/copy icon form_inputs.each(function() {device_form_state($(this))}); form_inputs.change(function() {device_form_state($(this))}); @@ -52,7 +53,7 @@ .toggleClass('icon-chevron-up icon-chevron-down'); }); - // handler for bin icon in port filter box + // handler for trashcan icon in port filter box var portfilter = $('#ports_form').find("input[name=f]"); $('.nd_field-clear-icon').click(function() { portfilter.val(''); @@ -101,15 +102,24 @@ ,async: true ,dataType: 'html' ,url: uri_base + '/ajax/control/admin/' + mode - ,data: tr.find('input[data-form="' + mode + '"]').serializeArray() + ,data: tr.find('input[data-form="' + mode + '"],textarea[data-form="' + mode + '"]').serializeArray() ,success: function() { - toastr.info('Queued '+ mode +' for device '+ tr.attr('data-for-device')); + toastr.info('Queued '+ mode +' for device '+ tr.data('for-device')); } // skip any error reporting for now // TODO: fix sanity_ok in Netdisco Web ,error: function() { - toastr.error('Failed to queue '+ mode +' for device '+ tr.attr('data-for-device')); + toastr.error('Failed to queue '+ mode +' for device '+ tr.data('for-device')); } }); }); + + // bootstrap modal mucks about with mouse actions on higher elements + // so need to bury and raise it when needed + $('#ports_pane').on('show', '.nd_modal', function () { + $(this).toggleClass('nd_deep-horizon'); + }); + $('#ports_pane').on('hidden', '.nd_modal', function () { + $(this).toggleClass('nd_deep-horizon'); + }); });