From 805b2255525b74562910186f6a4b8fe43498259f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adolfo=20G=C3=B3mez?= Date: Tue, 19 Nov 2013 11:26:27 +0000 Subject: [PATCH] I had 3d buttons not working (clicks events not fired). After a while of looking for why, i realized that in fact the button was moving, and the event was not fired sometimes for this reason. So i have created a little "fix" on tools.js, where we use mousedown && mouse up events (on button & parent) to "simulate" a click over an static button. Also, i have included a way of blocking UI (using jquery.blockUI plugin), so user know when something is going on.. hard work resolving the 3d buttons "bug" :-) --- server/src/uds/static/adm/css/buttons.css | 12 +- server/src/uds/static/adm/css/uds-admin.css | 6 + server/src/uds/static/adm/img/loading.gif | Bin 0 -> 6820 bytes server/src/uds/static/adm/js/api.js | 34 +- .../uds/static/adm/js/dataTables.bootstrap.js | 2 +- server/src/uds/static/adm/js/gui-elements.js | 33 + server/src/uds/static/adm/js/gui.js | 51 +- .../src/uds/static/adm/js/jquery.blockUI.js | 618 ++++++++++++++++++ server/src/uds/static/adm/js/tools.js | 49 ++ server/src/uds/templates/uds/admin/index.html | 6 +- .../templates/uds/admin/tmpl/dashboard.html | 13 + 11 files changed, 796 insertions(+), 28 deletions(-) create mode 100644 server/src/uds/static/adm/img/loading.gif create mode 100644 server/src/uds/static/adm/js/jquery.blockUI.js diff --git a/server/src/uds/static/adm/css/buttons.css b/server/src/uds/static/adm/css/buttons.css index a874d5407..3ad634f38 100644 --- a/server/src/uds/static/adm/css/buttons.css +++ b/server/src/uds/static/adm/css/buttons.css @@ -14,27 +14,27 @@ .btn3d:active { top:9px; } -.btn-default { +.btn3d-default { box-shadow:0 0 0 1px #ebebeb inset, 0 0 0 2px rgba(255,255,255,0.15) inset, 0 8px 0 0 #adadad, 0 8px 0 1px rgba(0,0,0,0.4), 0 8px 8px 1px rgba(0,0,0,0.5); background-color:#fff; } -.btn-primary { +.btn3d-primary { box-shadow:0 0 0 1px #428bca inset, 0 0 0 2px rgba(255,255,255,0.15) inset, 0 8px 0 0 #357ebd, 0 8px 0 1px rgba(0,0,0,0.4), 0 8px 8px 1px rgba(0,0,0,0.5); background-color:#428bca; } - .btn-success { + .btn3d-success { box-shadow:0 0 0 1px #5cb85c inset, 0 0 0 2px rgba(255,255,255,0.15) inset, 0 8px 0 0 #4cae4c, 0 8px 0 1px rgba(0,0,0,0.4), 0 8px 8px 1px rgba(0,0,0,0.5); background-color:#5cb85c; } - .btn-info { + .btn3d-info { box-shadow:0 0 0 1px #5bc0de inset, 0 0 0 2px rgba(255,255,255,0.15) inset, 0 8px 0 0 #46b8da, 0 8px 0 1px rgba(0,0,0,0.4), 0 8px 8px 1px rgba(0,0,0,0.5); background-color:#5bc0de; } -.btn-warning { +.btn3d-warning { box-shadow:0 0 0 1px #f0ad4e inset, 0 0 0 2px rgba(255,255,255,0.15) inset, 0 8px 0 0 #eea236, 0 8px 0 1px rgba(0,0,0,0.4), 0 8px 8px 1px rgba(0,0,0,0.5); background-color:#f0ad4e; } -.btn-danger { +.btn3d-danger { box-shadow:0 0 0 1px #c63702 inset, 0 0 0 2px rgba(255,255,255,0.15) inset, 0 8px 0 0 #C24032, 0 8px 0 1px rgba(0,0,0,0.4), 0 8px 8px 1px rgba(0,0,0,0.5); background-color:#c63702; } diff --git a/server/src/uds/static/adm/css/uds-admin.css b/server/src/uds/static/adm/css/uds-admin.css index d586bb005..83232c2a9 100644 --- a/server/src/uds/static/adm/css/uds-admin.css +++ b/server/src/uds/static/adm/css/uds-admin.css @@ -84,6 +84,12 @@ table.tablesorter thead tr th:hover { .btn3d-tables { margin-top:0px; + margin-botton: 8px; + margin-right: 8px; +} + +.btn-group-3d { + margin-bottom:12px; } diff --git a/server/src/uds/static/adm/img/loading.gif b/server/src/uds/static/adm/img/loading.gif new file mode 100644 index 0000000000000000000000000000000000000000..35218b31b5e09d98e59af8f8c17ab0c548b302b6 GIT binary patch literal 6820 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 literal 0 HcmV?d00001 diff --git a/server/src/uds/static/adm/js/api.js b/server/src/uds/static/adm/js/api.js index ee9c30d8b..9c0413c50 100644 --- a/server/src/uds/static/adm/js/api.js +++ b/server/src/uds/static/adm/js/api.js @@ -11,7 +11,12 @@ } }; - + + // Returns a cache object (for easy caching requests, templates, etc...) + api.cache = function(cacheName) { + return new Cache(cacheName); + }; + api.getJson = function(path, success_fnc) { url = api.url_for(path); api.doLog('Ajax GET Json for "' + url + '"'); @@ -37,6 +42,33 @@ api.debug = false; }(window.api = window.api || {}, jQuery)); + +// Cache related +function Cache(cacheName) { + api.cacheTable = api.cacheTable || {}; + + api.cacheTable[cacheName] = api.cacheTable[cacheName] || {}; + + this.name = cacheName; + this.cache = api.cacheTable[cacheName]; +} + +Cache.prototype = { + get: function(key, not_found_fnc){ + not_found_fnc = not_found_fnc || function() { return undefined; }; + + if( this.cache[key] === undefined ) { + this.cache[key] = not_found_fnc(); + } + return this.cache[key]; + }, + + put: function(key, value) { + this.cache[key] = value; + }, +}; + + // Great part of UDS REST api provides same methods. // We will take advantage of this and save a lot of nonsense, prone to failure // code :-) diff --git a/server/src/uds/static/adm/js/dataTables.bootstrap.js b/server/src/uds/static/adm/js/dataTables.bootstrap.js index 2db25c528..382554f4a 100644 --- a/server/src/uds/static/adm/js/dataTables.bootstrap.js +++ b/server/src/uds/static/adm/js/dataTables.bootstrap.js @@ -114,7 +114,7 @@ if ($.fn.DataTable.TableTools) { $.extend(true, $.fn.DataTable.TableTools.classes, { "container" : "DTTT btn-group-3d", "buttons" : { - "normal" : "btn btn-default", + "normal" : "btn btn3d-default", "disabled" : "disabled" }, "collection" : { diff --git a/server/src/uds/static/adm/js/gui-elements.js b/server/src/uds/static/adm/js/gui-elements.js index 37026e4a6..afd12f2d7 100644 --- a/server/src/uds/static/adm/js/gui-elements.js +++ b/server/src/uds/static/adm/js/gui-elements.js @@ -1,8 +1,34 @@ +/* jshint strict: true */ // Compose gui elements +gui.dashboard = new BasicGuiElement('Dashboard'); +gui.dashboard.link = function(event) { + "use strict"; + gui.clearWorkspace(); + api.templates.get('dashboard', function(tmpl) { + gui.doLog('enter dashboard'); + gui.appendToWorkspace(api.templates.evaluate(tmpl, { + })); + gui.setLinksEvents(); + + $.each($('.btn3d'), function() { + console.log(this); + var counter = 0; + $(this).click(function(){ + counter += 1; + $(this).text($(this).text().split(' ')[0] + ' ' + counter); + /*$('Click ' + counter + ' on ' + $(this).text() + '--').appendTo('#out');*/ + }); + }); + + api.tools.fix3dButtons('#test'); + }); +}; + // Service providers gui.providers = new GuiElement(api.providers, 'provi'); gui.providers.link = function(event) { + "use strict"; gui.clearWorkspace(); gui.appendToWorkspace(gui.breadcrumbs(gettext('Service Providers'))); @@ -25,6 +51,7 @@ gui.providers.link = function(event) { gui.authenticators = new GuiElement(api.authenticators, 'auth'); gui.authenticators.link = function(event) { + "use strict"; gui.doLog('enter auths'); api.templates.get('authenticators', function(tmpl) { gui.clearWorkspace(); @@ -39,6 +66,7 @@ gui.authenticators.link = function(event) { rowSelect : 'single', buttons : [ 'edit', 'refresh', 'delete', 'xls' ], onRowSelect : function(nodes) { + api.tools.blockUI(); var id = this.fnGetSelectedData()[0].id; var user = new GuiElement(api.authenticators.detail(id, 'users'), 'users'); user.table({ @@ -46,6 +74,9 @@ gui.authenticators.link = function(event) { rowSelect : 'multi', buttons : [ 'edit', 'refresh', 'delete', 'xls' ], scroll : true, + onLoad: function(k) { + api.tools.unblockUI(); + }, }); return false; }, @@ -60,6 +91,7 @@ gui.authenticators.link = function(event) { gui.osmanagers = new GuiElement(api.osmanagers, 'osm'); gui.osmanagers.link = function(event) { + "use strict"; gui.clearWorkspace(); gui.appendToWorkspace(gui.breadcrumbs('Os Managers')); @@ -77,6 +109,7 @@ gui.connectivity = { }; gui.connectivity.link = function(event) { + "use strict"; api.templates.get('connectivity', function(tmpl) { gui.clearWorkspace(); gui.appendToWorkspace(api.templates.evaluate(tmpl, { diff --git a/server/src/uds/static/adm/js/gui.js b/server/src/uds/static/adm/js/gui.js index bba91888d..96d2d7c1e 100644 --- a/server/src/uds/static/adm/js/gui.js +++ b/server/src/uds/static/adm/js/gui.js @@ -69,11 +69,6 @@ }; // Links methods - gui.dashboard = function() { - gui.clearWorkspace(); - gui.appendToWorkspace(gui.breadcrumbs('Dasboard')); - gui.doLog(this); - }; gui.deployed_services = function() { gui.clearWorkspace(); @@ -83,7 +78,7 @@ gui.setLinksEvents = function() { var sidebarLinks = [ { id : 'lnk-dashboard', - exec : gui.dashboard + exec : gui.dashboard.link, }, { id : 'lnk-service_providers', exec : gui.providers.link @@ -114,12 +109,18 @@ gui.init = function() { gui.setLinksEvents(); + gui.dashboard.link(); }; // Public attributes gui.debug = true; }(window.gui = window.gui || {}, jQuery)); +function BasicGuiElement(name) { + "use strict"; + this.name = name; +} + function GuiElement(restItem, name) { "use strict"; this.rest = restItem; @@ -308,16 +309,23 @@ GuiElement.prototype = { var refreshFnc = function(btn) { // Refreshes table content var tbl = $('#' + tableId).dataTable(); - var width = $(btn).width(); + /*var width = $(btn).width(); var saved = $(btn).html(); - /*$(btn).addClass('disabled').html('') + $(btn).addClass('disabled').html('') .width(width);*/ - onRefresh(); + if( data.length > 1000 ) + api.tools.blockUI(); + + onRefresh($this); + $this.rest.get({ success : function(data) { - tbl.fnClearTable(); - tbl.fnAddData(data); /*$(btn).removeClass('disabled').width('').html(saved);*/ + setTimeout( function() { + tbl.fnClearTable(); + tbl.fnAddData(data); + api.tools.unblockUI(); + }, 0); } }); }; @@ -326,17 +334,17 @@ GuiElement.prototype = { var editSelected = function(btn, obj, node) { var sel = this.fnGetSelectedData(); if (sel.length == 1) { - $(btn).removeClass('disabled').addClass('btn-info'); + $(btn).removeClass('disabled').addClass('btn3d-success'); } else { - $(btn).removeClass('btn-info').addClass('disabled'); + $(btn).removeClass('btn3d-success').addClass('disabled'); } }; var deleteSelected = function(btn, obj, node) { var sel = this.fnGetSelectedData(); if (sel.length > 0) { - $(btn).removeClass('disabled').addClass('btn-warning'); + $(btn).removeClass('disabled').addClass('btn3d-warning'); } else { - $(btn).removeClass('btn-warning').addClass('disabled'); + $(btn).removeClass('btn3d-warning').addClass('disabled'); } }; @@ -366,7 +374,7 @@ GuiElement.prototype = { "sExtends" : "text", "sButtonText" : gettext('Refresh'), "fnClick" : refreshFnc, - "sButtonClass" : "btn-info btn3d btn3d-tables" + "sButtonClass" : "btn3d-primary btn3d btn3d-tables" }; break; case 'xls': @@ -413,7 +421,7 @@ GuiElement.prototype = { }, 20); }); }, - "sButtonClass" : "btn-info btn3d btn3d-tables" + "sButtonClass" : "btn3d-info btn3d btn3d-tables" }; /*case 'csv': btn = { @@ -470,11 +478,18 @@ GuiElement.prototype = { "sDom" : "<'row'<'col-xs-8'T><'col-xs-4'f>r>t<'row'<'col-xs-5'i><'col-xs-7'p>>", }); - $('#' + tableId + '_filter input').addClass('form-control'); + // Fix 3dbuttons + api.tools.fix3dButtons('#' + tableId + '_wrapper .btn-group-3d'); + // Fix form + //$('#' + tableId + '_filter input').addClass('form-control'); if (options.scroll !== undefined ) { var tableTop = $('#' + tableId).offset().top; $('html, body').scrollTop(tableTop); } + // if table rendered event + if( options.onLoad ) { + options.onLoad($this); + } } }); }); diff --git a/server/src/uds/static/adm/js/jquery.blockUI.js b/server/src/uds/static/adm/js/jquery.blockUI.js new file mode 100644 index 000000000..42a7db68b --- /dev/null +++ b/server/src/uds/static/adm/js/jquery.blockUI.js @@ -0,0 +1,618 @@ +/*! + * jQuery blockUI plugin + * Version 2.66.0-2013.10.09 + * Requires jQuery v1.7 or later + * + * Examples at: http://malsup.com/jquery/block/ + * Copyright (c) 2007-2013 M. Alsup + * Dual licensed under the MIT and GPL licenses: + * http://www.opensource.org/licenses/mit-license.php + * http://www.gnu.org/licenses/gpl.html + * + * Thanks to Amir-Hossein Sobhi for some excellent contributions! + */ + +;(function() { +"use strict"; + + function setup($) { + $.fn._fadeIn = $.fn.fadeIn; + + var noOp = $.noop || function() {}; + + // this bit is to ensure we don't call setExpression when we shouldn't (with extra muscle to handle + // confusing userAgent strings on Vista) + var msie = /MSIE/.test(navigator.userAgent); + var ie6 = /MSIE 6.0/.test(navigator.userAgent) && ! /MSIE 8.0/.test(navigator.userAgent); + var mode = document.documentMode || 0; + var setExpr = $.isFunction( document.createElement('div').style.setExpression ); + + // global $ methods for blocking/unblocking the entire page + $.blockUI = function(opts) { install(window, opts); }; + $.unblockUI = function(opts) { remove(window, opts); }; + + // convenience method for quick growl-like notifications (http://www.google.com/search?q=growl) + $.growlUI = function(title, message, timeout, onClose) { + var $m = $('
'); + if (title) $m.append('

'+title+'

'); + if (message) $m.append('

'+message+'

'); + if (timeout === undefined) timeout = 3000; + + // Added by konapun: Set timeout to 30 seconds if this growl is moused over, like normal toast notifications + var callBlock = function(opts) { + opts = opts || {}; + + $.blockUI({ + message: $m, + fadeIn : typeof opts.fadeIn !== 'undefined' ? opts.fadeIn : 700, + fadeOut: typeof opts.fadeOut !== 'undefined' ? opts.fadeOut : 1000, + timeout: typeof opts.timeout !== 'undefined' ? opts.timeout : timeout, + centerY: false, + showOverlay: false, + onUnblock: onClose, + css: $.blockUI.defaults.growlCSS + }); + }; + + callBlock(); + var nonmousedOpacity = $m.css('opacity'); + $m.mouseover(function() { + callBlock({ + fadeIn: 0, + timeout: 30000 + }); + + var displayBlock = $('.blockMsg'); + displayBlock.stop(); // cancel fadeout if it has started + displayBlock.fadeTo(300, 1); // make it easier to read the message by removing transparency + }).mouseout(function() { + $('.blockMsg').fadeOut(1000); + }); + // End konapun additions + }; + + // plugin method for blocking element content + $.fn.block = function(opts) { + if ( this[0] === window ) { + $.blockUI( opts ); + return this; + } + var fullOpts = $.extend({}, $.blockUI.defaults, opts || {}); + this.each(function() { + var $el = $(this); + if (fullOpts.ignoreIfBlocked && $el.data('blockUI.isBlocked')) + return; + $el.unblock({ fadeOut: 0 }); + }); + + return this.each(function() { + if ($.css(this,'position') == 'static') { + this.style.position = 'relative'; + $(this).data('blockUI.static', true); + } + this.style.zoom = 1; // force 'hasLayout' in ie + install(this, opts); + }); + }; + + // plugin method for unblocking element content + $.fn.unblock = function(opts) { + if ( this[0] === window ) { + $.unblockUI( opts ); + return this; + } + return this.each(function() { + remove(this, opts); + }); + }; + + $.blockUI.version = 2.66; // 2nd generation blocking at no extra cost! + + // override these in your code to change the default behavior and style + $.blockUI.defaults = { + // message displayed when blocking (use null for no message) + message: '

Please wait...

', + + title: null, // title string; only used when theme == true + draggable: true, // only used when theme == true (requires jquery-ui.js to be loaded) + + theme: false, // set to true to use with jQuery UI themes + + // styles for the message when blocking; if you wish to disable + // these and use an external stylesheet then do this in your code: + // $.blockUI.defaults.css = {}; + css: { + padding: 0, + margin: 0, + width: '30%', + top: '40%', + left: '35%', + textAlign: 'center', + color: '#000', + border: '3px solid #aaa', + backgroundColor:'#fff', + cursor: 'wait' + }, + + // minimal style set used when themes are used + themedCSS: { + width: '30%', + top: '40%', + left: '35%' + }, + + // styles for the overlay + overlayCSS: { + backgroundColor: '#000', + opacity: 0.6, + cursor: 'wait' + }, + + // style to replace wait cursor before unblocking to correct issue + // of lingering wait cursor + cursorReset: 'default', + + // styles applied when using $.growlUI + growlCSS: { + width: '350px', + top: '10px', + left: '', + right: '10px', + border: 'none', + padding: '5px', + opacity: 0.6, + cursor: 'default', + color: '#fff', + backgroundColor: '#000', + '-webkit-border-radius':'10px', + '-moz-border-radius': '10px', + 'border-radius': '10px' + }, + + // IE issues: 'about:blank' fails on HTTPS and javascript:false is s-l-o-w + // (hat tip to Jorge H. N. de Vasconcelos) + /*jshint scripturl:true */ + iframeSrc: /^https/i.test(window.location.href || '') ? 'javascript:false' : 'about:blank', + + // force usage of iframe in non-IE browsers (handy for blocking applets) + forceIframe: false, + + // z-index for the blocking overlay + baseZ: 1000, + + // set these to true to have the message automatically centered + centerX: true, // <-- only effects element blocking (page block controlled via css above) + centerY: true, + + // allow body element to be stetched in ie6; this makes blocking look better + // on "short" pages. disable if you wish to prevent changes to the body height + allowBodyStretch: true, + + // enable if you want key and mouse events to be disabled for content that is blocked + bindEvents: true, + + // be default blockUI will supress tab navigation from leaving blocking content + // (if bindEvents is true) + constrainTabKey: true, + + // fadeIn time in millis; set to 0 to disable fadeIn on block + fadeIn: 200, + + // fadeOut time in millis; set to 0 to disable fadeOut on unblock + fadeOut: 400, + + // time in millis to wait before auto-unblocking; set to 0 to disable auto-unblock + timeout: 0, + + // disable if you don't want to show the overlay + showOverlay: true, + + // if true, focus will be placed in the first available input field when + // page blocking + focusInput: true, + + // elements that can receive focus + focusableElements: ':input:enabled:visible', + + // suppresses the use of overlay styles on FF/Linux (due to performance issues with opacity) + // no longer needed in 2012 + // applyPlatformOpacityRules: true, + + // callback method invoked when fadeIn has completed and blocking message is visible + onBlock: null, + + // callback method invoked when unblocking has completed; the callback is + // passed the element that has been unblocked (which is the window object for page + // blocks) and the options that were passed to the unblock call: + // onUnblock(element, options) + onUnblock: null, + + // callback method invoked when the overlay area is clicked. + // setting this will turn the cursor to a pointer, otherwise cursor defined in overlayCss will be used. + onOverlayClick: null, + + // don't ask; if you really must know: http://groups.google.com/group/jquery-en/browse_thread/thread/36640a8730503595/2f6a79a77a78e493#2f6a79a77a78e493 + quirksmodeOffsetHack: 4, + + // class name of the message block + blockMsgClass: 'blockMsg', + + // if it is already blocked, then ignore it (don't unblock and reblock) + ignoreIfBlocked: false + }; + + // private data and functions follow... + + var pageBlock = null; + var pageBlockEls = []; + + function install(el, opts) { + var css, themedCSS; + var full = (el == window); + var msg = (opts && opts.message !== undefined ? opts.message : undefined); + opts = $.extend({}, $.blockUI.defaults, opts || {}); + + if (opts.ignoreIfBlocked && $(el).data('blockUI.isBlocked')) + return; + + opts.overlayCSS = $.extend({}, $.blockUI.defaults.overlayCSS, opts.overlayCSS || {}); + css = $.extend({}, $.blockUI.defaults.css, opts.css || {}); + if (opts.onOverlayClick) + opts.overlayCSS.cursor = 'pointer'; + + themedCSS = $.extend({}, $.blockUI.defaults.themedCSS, opts.themedCSS || {}); + msg = msg === undefined ? opts.message : msg; + + // remove the current block (if there is one) + if (full && pageBlock) + remove(window, {fadeOut:0}); + + // if an existing element is being used as the blocking content then we capture + // its current place in the DOM (and current display style) so we can restore + // it when we unblock + if (msg && typeof msg != 'string' && (msg.parentNode || msg.jquery)) { + var node = msg.jquery ? msg[0] : msg; + var data = {}; + $(el).data('blockUI.history', data); + data.el = node; + data.parent = node.parentNode; + data.display = node.style.display; + data.position = node.style.position; + if (data.parent) + data.parent.removeChild(node); + } + + $(el).data('blockUI.onUnblock', opts.onUnblock); + var z = opts.baseZ; + + // blockUI uses 3 layers for blocking, for simplicity they are all used on every platform; + // layer1 is the iframe layer which is used to supress bleed through of underlying content + // layer2 is the overlay layer which has opacity and a wait cursor (by default) + // layer3 is the message content that is displayed while blocking + var lyr1, lyr2, lyr3, s; + if (msie || opts.forceIframe) + lyr1 = $(''); + else + lyr1 = $(''); + + if (opts.theme) + lyr2 = $(''); + else + lyr2 = $(''); + + if (opts.theme && full) { + s = ''; + } + else if (opts.theme) { + s = ''; + } + else if (full) { + s = ''; + } + else { + s = ''; + } + lyr3 = $(s); + + // if we have a message, style it + if (msg) { + if (opts.theme) { + lyr3.css(themedCSS); + lyr3.addClass('ui-widget-content'); + } + else + lyr3.css(css); + } + + // style the overlay + if (!opts.theme /*&& (!opts.applyPlatformOpacityRules)*/) + lyr2.css(opts.overlayCSS); + lyr2.css('position', full ? 'fixed' : 'absolute'); + + // make iframe layer transparent in IE + if (msie || opts.forceIframe) + lyr1.css('opacity',0.0); + + //$([lyr1[0],lyr2[0],lyr3[0]]).appendTo(full ? 'body' : el); + var layers = [lyr1,lyr2,lyr3], $par = full ? $('body') : $(el); + $.each(layers, function() { + this.appendTo($par); + }); + + if (opts.theme && opts.draggable && $.fn.draggable) { + lyr3.draggable({ + handle: '.ui-dialog-titlebar', + cancel: 'li' + }); + } + + // ie7 must use absolute positioning in quirks mode and to account for activex issues (when scrolling) + var expr = setExpr && (!$.support.boxModel || $('object,embed', full ? null : el).length > 0); + if (ie6 || expr) { + // give body 100% height + if (full && opts.allowBodyStretch && $.support.boxModel) + $('html,body').css('height','100%'); + + // fix ie6 issue when blocked element has a border width + if ((ie6 || !$.support.boxModel) && !full) { + var t = sz(el,'borderTopWidth'), l = sz(el,'borderLeftWidth'); + var fixT = t ? '(0 - '+t+')' : 0; + var fixL = l ? '(0 - '+l+')' : 0; + } + + // simulate fixed position + $.each(layers, function(i,o) { + var s = o[0].style; + s.position = 'absolute'; + if (i < 2) { + if (full) + s.setExpression('height','Math.max(document.body.scrollHeight, document.body.offsetHeight) - (jQuery.support.boxModel?0:'+opts.quirksmodeOffsetHack+') + "px"'); + else + s.setExpression('height','this.parentNode.offsetHeight + "px"'); + if (full) + s.setExpression('width','jQuery.support.boxModel && document.documentElement.clientWidth || document.body.clientWidth + "px"'); + else + s.setExpression('width','this.parentNode.offsetWidth + "px"'); + if (fixL) s.setExpression('left', fixL); + if (fixT) s.setExpression('top', fixT); + } + else if (opts.centerY) { + if (full) s.setExpression('top','(document.documentElement.clientHeight || document.body.clientHeight) / 2 - (this.offsetHeight / 2) + (blah = document.documentElement.scrollTop ? document.documentElement.scrollTop : document.body.scrollTop) + "px"'); + s.marginTop = 0; + } + else if (!opts.centerY && full) { + var top = (opts.css && opts.css.top) ? parseInt(opts.css.top, 10) : 0; + var expression = '((document.documentElement.scrollTop ? document.documentElement.scrollTop : document.body.scrollTop) + '+top+') + "px"'; + s.setExpression('top',expression); + } + }); + } + + // show the message + if (msg) { + if (opts.theme) + lyr3.find('.ui-widget-content').append(msg); + else + lyr3.append(msg); + if (msg.jquery || msg.nodeType) + $(msg).show(); + } + + if ((msie || opts.forceIframe) && opts.showOverlay) + lyr1.show(); // opacity is zero + if (opts.fadeIn) { + var cb = opts.onBlock ? opts.onBlock : noOp; + var cb1 = (opts.showOverlay && !msg) ? cb : noOp; + var cb2 = msg ? cb : noOp; + if (opts.showOverlay) + lyr2._fadeIn(opts.fadeIn, cb1); + if (msg) + lyr3._fadeIn(opts.fadeIn, cb2); + } + else { + if (opts.showOverlay) + lyr2.show(); + if (msg) + lyr3.show(); + if (opts.onBlock) + opts.onBlock(); + } + + // bind key and mouse events + bind(1, el, opts); + + if (full) { + pageBlock = lyr3[0]; + pageBlockEls = $(opts.focusableElements,pageBlock); + if (opts.focusInput) + setTimeout(focus, 20); + } + else + center(lyr3[0], opts.centerX, opts.centerY); + + if (opts.timeout) { + // auto-unblock + var to = setTimeout(function() { + if (full) + $.unblockUI(opts); + else + $(el).unblock(opts); + }, opts.timeout); + $(el).data('blockUI.timeout', to); + } + } + + // remove the block + function remove(el, opts) { + var count; + var full = (el == window); + var $el = $(el); + var data = $el.data('blockUI.history'); + var to = $el.data('blockUI.timeout'); + if (to) { + clearTimeout(to); + $el.removeData('blockUI.timeout'); + } + opts = $.extend({}, $.blockUI.defaults, opts || {}); + bind(0, el, opts); // unbind events + + if (opts.onUnblock === null) { + opts.onUnblock = $el.data('blockUI.onUnblock'); + $el.removeData('blockUI.onUnblock'); + } + + var els; + if (full) // crazy selector to handle odd field errors in ie6/7 + els = $('body').children().filter('.blockUI').add('body > .blockUI'); + else + els = $el.find('>.blockUI'); + + // fix cursor issue + if ( opts.cursorReset ) { + if ( els.length > 1 ) + els[1].style.cursor = opts.cursorReset; + if ( els.length > 2 ) + els[2].style.cursor = opts.cursorReset; + } + + if (full) + pageBlock = pageBlockEls = null; + + if (opts.fadeOut) { + count = els.length; + els.stop().fadeOut(opts.fadeOut, function() { + if ( --count === 0) + reset(els,data,opts,el); + }); + } + else + reset(els, data, opts, el); + } + + // move blocking element back into the DOM where it started + function reset(els,data,opts,el) { + var $el = $(el); + if ( $el.data('blockUI.isBlocked') ) + return; + + els.each(function(i,o) { + // remove via DOM calls so we don't lose event handlers + if (this.parentNode) + this.parentNode.removeChild(this); + }); + + if (data && data.el) { + data.el.style.display = data.display; + data.el.style.position = data.position; + if (data.parent) + data.parent.appendChild(data.el); + $el.removeData('blockUI.history'); + } + + if ($el.data('blockUI.static')) { + $el.css('position', 'static'); // #22 + } + + if (typeof opts.onUnblock == 'function') + opts.onUnblock(el,opts); + + // fix issue in Safari 6 where block artifacts remain until reflow + var body = $(document.body), w = body.width(), cssW = body[0].style.width; + body.width(w-1).width(w); + body[0].style.width = cssW; + } + + // bind/unbind the handler + function bind(b, el, opts) { + var full = el == window, $el = $(el); + + // don't bother unbinding if there is nothing to unbind + if (!b && (full && !pageBlock || !full && !$el.data('blockUI.isBlocked'))) + return; + + $el.data('blockUI.isBlocked', b); + + // don't bind events when overlay is not in use or if bindEvents is false + if (!full || !opts.bindEvents || (b && !opts.showOverlay)) + return; + + // bind anchors and inputs for mouse and key events + var events = 'mousedown mouseup keydown keypress keyup touchstart touchend touchmove'; + if (b) + $(document).bind(events, opts, handler); + else + $(document).unbind(events, handler); + + // former impl... + // var $e = $('a,:input'); + // b ? $e.bind(events, opts, handler) : $e.unbind(events, handler); + } + + // event handler to suppress keyboard/mouse events when blocking + function handler(e) { + // allow tab navigation (conditionally) + if (e.type === 'keydown' && e.keyCode && e.keyCode == 9) { + if (pageBlock && e.data.constrainTabKey) { + var els = pageBlockEls; + var fwd = !e.shiftKey && e.target === els[els.length-1]; + var back = e.shiftKey && e.target === els[0]; + if (fwd || back) { + setTimeout(function(){focus(back);},10); + return false; + } + } + } + var opts = e.data; + var target = $(e.target); + if (target.hasClass('blockOverlay') && opts.onOverlayClick) + opts.onOverlayClick(e); + + // allow events within the message content + if (target.parents('div.' + opts.blockMsgClass).length > 0) + return true; + + // allow events for content that is not being blocked + return target.parents().children().filter('div.blockUI').length === 0; + } + + function focus(back) { + if (!pageBlockEls) + return; + var e = pageBlockEls[back===true ? pageBlockEls.length-1 : 0]; + if (e) + e.focus(); + } + + function center(el, x, y) { + var p = el.parentNode, s = el.style; + var l = ((p.offsetWidth - el.offsetWidth)/2) - sz(p,'borderLeftWidth'); + var t = ((p.offsetHeight - el.offsetHeight)/2) - sz(p,'borderTopWidth'); + if (x) s.left = l > 0 ? (l+'px') : '0'; + if (y) s.top = t > 0 ? (t+'px') : '0'; + } + + function sz(el, p) { + return parseInt($.css(el,p),10)||0; + } + + } + + + /*global define:true */ + if (typeof define === 'function' && define.amd && define.amd.jQuery) { + define(['jquery'], setup); + } else { + setup(jQuery); + } + +})(); diff --git a/server/src/uds/static/adm/js/tools.js b/server/src/uds/static/adm/js/tools.js index 054d7503b..6418ae4fa 100644 --- a/server/src/uds/static/adm/js/tools.js +++ b/server/src/uds/static/adm/js/tools.js @@ -1,5 +1,54 @@ +/* jshint strict: true */ (function(tools, $, undefined) { + "use strict"; tools.base64 = function(s) { return window.btoa(unescape(encodeURIComponent(s))); }; + + tools.fix3dButtons = function(selector) { + selector = selector || ''; + selector += ' .btn3d'; + console.log(selector); + $.each($(selector), function(index, value) { + var $this = $(this); + + var clkEvents = []; + + // Store old click events, so we can reconstruct click chain later + $.each($._data(value, 'events').click, function(index, fnc) { + clkEvents.push(fnc); + }); + $this.unbind('click'); + + /* If Mousedown registers a temporal mouseUp event on parent, to lauch button click */ + $this.mousedown(function(event){ + $this.parent().mouseup(function(e){ + // Remove temporal mouseup handler + $(this).unbind('mouseup'); + + // If movement of mouse is not too far... (16 px maybe well for 3d buttons?) + var x = event.pageX - e.pageX, y = event.pageY - e.pageY; + var dist_square = x*x + y*y; + if( dist_square < 16*16 ) { + // Register again old event handlers + $.each(clkEvents, function(index, fnc){ + $this.click(fnc.handler); + }); + $this.click(); + $this.unbind('click'); + } + }); + }); + }); + }; + + tools.blockUI = function(message) { + message = message || '

' + gettext('Just a moment...') + '

' + $.blockUI({ message: message }); + }; + + tools.unblockUI = function() { + $.unblockUI(); + }; + }(api.tools = api.tools || {}, jQuery)); diff --git a/server/src/uds/templates/uds/admin/index.html b/server/src/uds/templates/uds/admin/index.html index 5cc82b094..31ecaeab2 100644 --- a/server/src/uds/templates/uds/admin/index.html +++ b/server/src/uds/templates/uds/admin/index.html @@ -46,6 +46,7 @@ + @@ -68,6 +69,7 @@ api.token = "{% auth_token %}"; api.auth_header = "{% auth_token_header %}"; api.base_url = "{% url 'REST' '' %}"; + api.img_url = "{% get_static_prefix %}adm/img/"; api.url_for = function(path) { return api.base_url + path; @@ -75,8 +77,8 @@ }(window.api = window.api || {}, jQuery)); - - + + diff --git a/server/src/uds/templates/uds/admin/tmpl/dashboard.html b/server/src/uds/templates/uds/admin/tmpl/dashboard.html index 2d762f9da..314b0ed03 100644 --- a/server/src/uds/templates/uds/admin/tmpl/dashboard.html +++ b/server/src/uds/templates/uds/admin/tmpl/dashboard.html @@ -7,3 +7,16 @@ + +
+
+ + + + +
+
+
+
+
+
\ No newline at end of file