Table copiedCopied "+a+" row"+(1==a?"":"s")+
+" to the clipboard.
",1500)}}),pdf:e.extend({},TableTools.buttonBase,{sAction:"flash_pdf",sNewLine:"\n",sFileName:"*.pdf",sButtonClass:"DTTT_button_pdf",sButtonText:"PDF",sPdfOrientation:"portrait",sPdfSize:"A4",sPdfMessage:"",fnClick:function(a,b,c){this.fnSetText(c,"title:"+this.fnGetTitle(b)+"\nmessage:"+b.sPdfMessage+"\ncolWidth:"+this.fnCalcColRatios(b)+"\norientation:"+b.sPdfOrientation+"\nsize:"+b.sPdfSize+"\n--/TableToolsOpts--\n"+this.fnGetTableData(b))}}),print:e.extend({},TableTools.buttonBase,
+{sInfo:"Print view
Please use your browser's print function to print this table. Press escape when finished.",sMessage:null,bShowAll:!0,sToolTip:"View print view",sButtonClass:"DTTT_button_print",sButtonText:"Print",fnClick:function(a,b){this.fnPrint(!0,b)}}),text:e.extend({},TableTools.buttonBase),select:e.extend({},TableTools.buttonBase,{sButtonText:"Select button",fnSelect:function(a){0!==this.fnGetSelected().length?e(a).removeClass(this.classes.buttons.disabled):e(a).addClass(this.classes.buttons.disabled)},
+fnInit:function(a){e(a).addClass(this.classes.buttons.disabled)}}),select_single:e.extend({},TableTools.buttonBase,{sButtonText:"Select button",fnSelect:function(a){1==this.fnGetSelected().length?e(a).removeClass(this.classes.buttons.disabled):e(a).addClass(this.classes.buttons.disabled)},fnInit:function(a){e(a).addClass(this.classes.buttons.disabled)}}),select_all:e.extend({},TableTools.buttonBase,{sButtonText:"Select all",fnClick:function(){this.fnSelectAll()},fnSelect:function(a){this.fnGetSelected().length==
+this.s.dt.fnRecordsDisplay()?e(a).addClass(this.classes.buttons.disabled):e(a).removeClass(this.classes.buttons.disabled)}}),select_none:e.extend({},TableTools.buttonBase,{sButtonText:"Deselect all",fnClick:function(){this.fnSelectNone()},fnSelect:function(a){0!==this.fnGetSelected().length?e(a).removeClass(this.classes.buttons.disabled):e(a).addClass(this.classes.buttons.disabled)},fnInit:function(a){e(a).addClass(this.classes.buttons.disabled)}}),ajax:e.extend({},TableTools.buttonBase,{sAjaxUrl:"/xhr.php",
+sButtonText:"Ajax button",fnClick:function(a,b){var c=this.fnGetTableData(b);e.ajax({url:b.sAjaxUrl,data:[{name:"tableData",value:c}],success:b.fnAjaxComplete,dataType:"json",type:"POST",cache:!1,error:function(){alert("Error detected when sending table data to server")}})},fnAjaxComplete:function(){alert("Ajax complete")}}),div:e.extend({},TableTools.buttonBase,{sAction:"div",sTag:"div",sButtonClass:"DTTT_nonbutton",sButtonText:"Text button"}),collection:e.extend({},TableTools.buttonBase,{sAction:"collection",
+sButtonClass:"DTTT_button_collection",sButtonText:"Collection",fnClick:function(a,b){this._fnCollectionShow(a,b)}})};TableTools.classes={container:"DTTT_container",buttons:{normal:"DTTT_button",disabled:"DTTT_disabled"},collection:{container:"DTTT_collection",background:"DTTT_collection_background",buttons:{normal:"DTTT_button",disabled:"DTTT_disabled"}},select:{table:"DTTT_selectable",row:"DTTT_selected"},print:{body:"DTTT_Print",info:"DTTT_print_info",message:"DTTT_PrintMessage"}};TableTools.classes_themeroller=
+{container:"DTTT_container ui-buttonset ui-buttonset-multi",buttons:{normal:"DTTT_button ui-button ui-state-default"},collection:{container:"DTTT_collection ui-buttonset ui-buttonset-multi"}};TableTools.DEFAULTS={sSwfPath:"/static/adm/swf/copy_csv_xls_pdf.swf",sRowSelect:"none",sSelectedClass:null,fnPreRowSelect:null,fnRowSelected:null,fnRowDeselected:null,aButtons:["copy","csv","xls","pdf","print"],oTags:{container:"div",button:"a",liner:"span",collection:{container:"div",button:"a",liner:"span"}}};TableTools.prototype.CLASS=
+"TableTools";TableTools.VERSION="2.1.5";TableTools.prototype.VERSION=TableTools.VERSION;"function"==typeof e.fn.dataTable&&"function"==typeof e.fn.dataTableExt.fnVersionCheck&&e.fn.dataTableExt.fnVersionCheck("1.9.0")?e.fn.dataTableExt.aoFeatures.push({fnInit:function(a){a=new TableTools(a.oInstance,"undefined"!=typeof a.oInit.oTableTools?a.oInit.oTableTools:{});TableTools._aInstances.push(a);return a.dom.container},cFeature:"T",sFeature:"TableTools"}):alert("Warning: TableTools 2 requires DataTables 1.9.0 or newer - www.datatables.net/download");
+e.fn.DataTable.TableTools=TableTools})(jQuery,window,document);
diff --git a/server/src/uds/static/adm/js/ZeroClipboard.js b/server/src/uds/static/adm/js/ZeroClipboard.js
new file mode 100755
index 000000000..de0f6b67b
--- /dev/null
+++ b/server/src/uds/static/adm/js/ZeroClipboard.js
@@ -0,0 +1,367 @@
+// Simple Set Clipboard System
+// Author: Joseph Huckaby
+
+var ZeroClipboard_TableTools = {
+
+ version: "1.0.4-TableTools2",
+ clients: {}, // registered upload clients on page, indexed by id
+ moviePath: '', // URL to movie
+ nextId: 1, // ID of next movie
+
+ $: function(thingy) {
+ // simple DOM lookup utility function
+ if (typeof(thingy) == 'string') thingy = document.getElementById(thingy);
+ if (!thingy.addClass) {
+ // extend element with a few useful methods
+ thingy.hide = function() { this.style.display = 'none'; };
+ thingy.show = function() { this.style.display = ''; };
+ thingy.addClass = function(name) { this.removeClass(name); this.className += ' ' + name; };
+ thingy.removeClass = function(name) {
+ this.className = this.className.replace( new RegExp("\\s*" + name + "\\s*"), " ").replace(/^\s+/, '').replace(/\s+$/, '');
+ };
+ thingy.hasClass = function(name) {
+ return !!this.className.match( new RegExp("\\s*" + name + "\\s*") );
+ }
+ }
+ return thingy;
+ },
+
+ setMoviePath: function(path) {
+ // set path to ZeroClipboard.swf
+ this.moviePath = path;
+ },
+
+ dispatch: function(id, eventName, args) {
+ // receive event from flash movie, send to client
+ var client = this.clients[id];
+ if (client) {
+ client.receiveEvent(eventName, args);
+ }
+ },
+
+ register: function(id, client) {
+ // register new client to receive events
+ this.clients[id] = client;
+ },
+
+ getDOMObjectPosition: function(obj) {
+ // get absolute coordinates for dom element
+ var info = {
+ left: 0,
+ top: 0,
+ width: obj.width ? obj.width : obj.offsetWidth,
+ height: obj.height ? obj.height : obj.offsetHeight
+ };
+
+ if ( obj.style.width != "" )
+ info.width = obj.style.width.replace("px","");
+
+ if ( obj.style.height != "" )
+ info.height = obj.style.height.replace("px","");
+
+ while (obj) {
+ info.left += obj.offsetLeft;
+ info.top += obj.offsetTop;
+ obj = obj.offsetParent;
+ }
+
+ return info;
+ },
+
+ Client: function(elem) {
+ // constructor for new simple upload client
+ this.handlers = {};
+
+ // unique ID
+ this.id = ZeroClipboard_TableTools.nextId++;
+ this.movieId = 'ZeroClipboard_TableToolsMovie_' + this.id;
+
+ // register client with singleton to receive flash events
+ ZeroClipboard_TableTools.register(this.id, this);
+
+ // create movie
+ if (elem) this.glue(elem);
+ }
+};
+
+ZeroClipboard_TableTools.Client.prototype = {
+
+ id: 0, // unique ID for us
+ ready: false, // whether movie is ready to receive events or not
+ movie: null, // reference to movie object
+ clipText: '', // text to copy to clipboard
+ fileName: '', // default file save name
+ action: 'copy', // action to perform
+ handCursorEnabled: true, // whether to show hand cursor, or default pointer cursor
+ cssEffects: true, // enable CSS mouse effects on dom container
+ handlers: null, // user event handlers
+ sized: false,
+
+ glue: function(elem, title) {
+ // glue to DOM element
+ // elem can be ID or actual DOM element object
+ this.domElement = ZeroClipboard_TableTools.$(elem);
+
+ // float just above object, or zIndex 99 if dom element isn't set
+ var zIndex = 99;
+ if (this.domElement.style.zIndex) {
+ zIndex = parseInt(this.domElement.style.zIndex) + 1;
+ }
+
+ // find X/Y position of domElement
+ var box = ZeroClipboard_TableTools.getDOMObjectPosition(this.domElement);
+
+ // create floating DIV above element
+ this.div = document.createElement('div');
+ var style = this.div.style;
+ style.position = 'absolute';
+ style.left = '0px';
+ style.top = '0px';
+ style.width = (box.width) + 'px';
+ style.height = box.height + 'px';
+ style.zIndex = zIndex;
+
+ if ( typeof title != "undefined" && title != "" ) {
+ this.div.title = title;
+ }
+ if ( box.width != 0 && box.height != 0 ) {
+ this.sized = true;
+ }
+
+ // style.backgroundColor = '#f00'; // debug
+ if ( this.domElement ) {
+ this.domElement.appendChild(this.div);
+ this.div.innerHTML = this.getHTML( box.width, box.height );
+ }
+ },
+
+ positionElement: function() {
+ var box = ZeroClipboard_TableTools.getDOMObjectPosition(this.domElement);
+ var style = this.div.style;
+
+ style.position = 'absolute';
+ //style.left = (this.domElement.offsetLeft)+'px';
+ //style.top = this.domElement.offsetTop+'px';
+ style.width = box.width + 'px';
+ style.height = box.height + 'px';
+
+ if ( box.width != 0 && box.height != 0 ) {
+ this.sized = true;
+ } else {
+ return;
+ }
+
+ var flash = this.div.childNodes[0];
+ flash.width = box.width;
+ flash.height = box.height;
+ },
+
+ getHTML: function(width, height) {
+ // return HTML for movie
+ var html = '';
+ var flashvars = 'id=' + this.id +
+ '&width=' + width +
+ '&height=' + height;
+
+ if (navigator.userAgent.match(/MSIE/)) {
+ // IE gets an OBJECT tag
+ var protocol = location.href.match(/^https/i) ? 'https://' : 'http://';
+ html += '';
+ }
+ else {
+ // all other browsers get an EMBED tag
+ html += '';
+ }
+ return html;
+ },
+
+ hide: function() {
+ // temporarily hide floater offscreen
+ if (this.div) {
+ this.div.style.left = '-2000px';
+ }
+ },
+
+ show: function() {
+ // show ourselves after a call to hide()
+ this.reposition();
+ },
+
+ destroy: function() {
+ // destroy control and floater
+ if (this.domElement && this.div) {
+ this.hide();
+ this.div.innerHTML = '';
+
+ var body = document.getElementsByTagName('body')[0];
+ try { body.removeChild( this.div ); } catch(e) {;}
+
+ this.domElement = null;
+ this.div = null;
+ }
+ },
+
+ reposition: function(elem) {
+ // reposition our floating div, optionally to new container
+ // warning: container CANNOT change size, only position
+ if (elem) {
+ this.domElement = ZeroClipboard_TableTools.$(elem);
+ if (!this.domElement) this.hide();
+ }
+
+ if (this.domElement && this.div) {
+ var box = ZeroClipboard_TableTools.getDOMObjectPosition(this.domElement);
+ var style = this.div.style;
+ style.left = '' + box.left + 'px';
+ style.top = '' + box.top + 'px';
+ }
+ },
+
+ clearText: function() {
+ // clear the text to be copy / saved
+ this.clipText = '';
+ if (this.ready) this.movie.clearText();
+ },
+
+ appendText: function(newText) {
+ // append text to that which is to be copied / saved
+ this.clipText += newText;
+ if (this.ready) { this.movie.appendText(newText) ;}
+ },
+
+ setText: function(newText) {
+ // set text to be copied to be copied / saved
+ this.clipText = newText;
+ if (this.ready) { this.movie.setText(newText) ;}
+ },
+
+ setCharSet: function(charSet) {
+ // set the character set (UTF16LE or UTF8)
+ this.charSet = charSet;
+ if (this.ready) { this.movie.setCharSet(charSet) ;}
+ },
+
+ setBomInc: function(bomInc) {
+ // set if the BOM should be included or not
+ this.incBom = bomInc;
+ if (this.ready) { this.movie.setBomInc(bomInc) ;}
+ },
+
+ setFileName: function(newText) {
+ // set the file name
+ this.fileName = newText;
+ if (this.ready) this.movie.setFileName(newText);
+ },
+
+ setAction: function(newText) {
+ // set action (save or copy)
+ this.action = newText;
+ if (this.ready) this.movie.setAction(newText);
+ },
+
+ addEventListener: function(eventName, func) {
+ // add user event listener for event
+ // event types: load, queueStart, fileStart, fileComplete, queueComplete, progress, error, cancel
+ eventName = eventName.toString().toLowerCase().replace(/^on/, '');
+ if (!this.handlers[eventName]) this.handlers[eventName] = [];
+ this.handlers[eventName].push(func);
+ },
+
+ setHandCursor: function(enabled) {
+ // enable hand cursor (true), or default arrow cursor (false)
+ this.handCursorEnabled = enabled;
+ if (this.ready) this.movie.setHandCursor(enabled);
+ },
+
+ setCSSEffects: function(enabled) {
+ // enable or disable CSS effects on DOM container
+ this.cssEffects = !!enabled;
+ },
+
+ receiveEvent: function(eventName, args) {
+ // receive event from flash
+ eventName = eventName.toString().toLowerCase().replace(/^on/, '');
+
+ // special behavior for certain events
+ switch (eventName) {
+ case 'load':
+ // movie claims it is ready, but in IE this isn't always the case...
+ // bug fix: Cannot extend EMBED DOM elements in Firefox, must use traditional function
+ this.movie = document.getElementById(this.movieId);
+ if (!this.movie) {
+ var self = this;
+ setTimeout( function() { self.receiveEvent('load', null); }, 1 );
+ return;
+ }
+
+ // firefox on pc needs a "kick" in order to set these in certain cases
+ if (!this.ready && navigator.userAgent.match(/Firefox/) && navigator.userAgent.match(/Windows/)) {
+ var self = this;
+ setTimeout( function() { self.receiveEvent('load', null); }, 100 );
+ this.ready = true;
+ return;
+ }
+
+ this.ready = true;
+ this.movie.clearText();
+ this.movie.appendText( this.clipText );
+ this.movie.setFileName( this.fileName );
+ this.movie.setAction( this.action );
+ this.movie.setCharSet( this.charSet );
+ this.movie.setBomInc( this.incBom );
+ this.movie.setHandCursor( this.handCursorEnabled );
+ break;
+
+ case 'mouseover':
+ if (this.domElement && this.cssEffects) {
+ //this.domElement.addClass('hover');
+ if (this.recoverActive) this.domElement.addClass('active');
+ }
+ break;
+
+ case 'mouseout':
+ if (this.domElement && this.cssEffects) {
+ this.recoverActive = false;
+ if (this.domElement.hasClass('active')) {
+ this.domElement.removeClass('active');
+ this.recoverActive = true;
+ }
+ //this.domElement.removeClass('hover');
+ }
+ break;
+
+ case 'mousedown':
+ if (this.domElement && this.cssEffects) {
+ this.domElement.addClass('active');
+ }
+ break;
+
+ case 'mouseup':
+ if (this.domElement && this.cssEffects) {
+ this.domElement.removeClass('active');
+ this.recoverActive = false;
+ }
+ break;
+ } // switch eventName
+
+ if (this.handlers[eventName]) {
+ for (var idx = 0, len = this.handlers[eventName].length; idx < len; idx++) {
+ var func = this.handlers[eventName][idx];
+
+ if (typeof(func) == 'function') {
+ // actual function reference
+ func(this, args);
+ }
+ else if ((typeof(func) == 'object') && (func.length == 2)) {
+ // PHP style object + method, i.e. [myObject, 'myMethod']
+ func[0][ func[1] ](this, args);
+ }
+ else if (typeof(func) == 'string') {
+ // name of function
+ window[func](this, args);
+ }
+ } // foreach event handler defined
+ } // user defined handler for event
+ }
+
+};
diff --git a/server/src/uds/static/adm/js/dataTables.bootstrap.js b/server/src/uds/static/adm/js/dataTables.bootstrap.js
new file mode 100644
index 000000000..ba563e81e
--- /dev/null
+++ b/server/src/uds/static/adm/js/dataTables.bootstrap.js
@@ -0,0 +1,148 @@
+/* Set the defaults for DataTables initialisation */
+$.extend( true, $.fn.dataTable.defaults, {
+ "sDom": "<'row'<'col-xs-6'l><'col-xs-6'f>r>t<'row'<'col-xs-6'i><'col-xs-6'p>>",
+ "sPaginationType": "bootstrap",
+ "oLanguage": {
+ "sLengthMenu": "_MENU_ records per page"
+ }
+} );
+
+/* Default class modification */
+$.extend( $.fn.dataTableExt.oStdClasses, {
+ "sWrapper": "dataTables_wrapper form-inline",
+ "sFilterInput": "form-control input-sm",
+ "sLengthSelect": "form-control input-sm"
+} );
+
+/* API method to get paging information */
+$.fn.dataTableExt.oApi.fnPagingInfo = function ( oSettings )
+{
+ return {
+ "iStart": oSettings._iDisplayStart,
+ "iEnd": oSettings.fnDisplayEnd(),
+ "iLength": oSettings._iDisplayLength,
+ "iTotal": oSettings.fnRecordsTotal(),
+ "iFilteredTotal": oSettings.fnRecordsDisplay(),
+ "iPage": oSettings._iDisplayLength === -1 ?
+ 0 : Math.ceil( oSettings._iDisplayStart / oSettings._iDisplayLength ),
+ "iTotalPages": oSettings._iDisplayLength === -1 ?
+ 0 : Math.ceil( oSettings.fnRecordsDisplay() / oSettings._iDisplayLength )
+ };
+};
+
+
+/* Bootstrap style pagination control */
+$.extend( $.fn.dataTableExt.oPagination, {
+ "bootstrap": {
+ "fnInit": function( oSettings, nPaging, fnDraw ) {
+ var oLang = oSettings.oLanguage.oPaginate;
+ var fnClickHandler = function ( e ) {
+ e.preventDefault();
+ if ( oSettings.oApi._fnPageChange(oSettings, e.data.action) ) {
+ fnDraw( oSettings );
+ }
+ };
+
+ $(nPaging).append(
+ '
'
+ );
+ var els = $('a', nPaging);
+ $(els[0]).bind( 'click.DT', { action: "previous" }, fnClickHandler );
+ $(els[1]).bind( 'click.DT', { action: "next" }, fnClickHandler );
+ },
+
+ "fnUpdate": function ( oSettings, fnDraw ) {
+ var iListLength = 5;
+ var oPaging = oSettings.oInstance.fnPagingInfo();
+ var an = oSettings.aanFeatures.p;
+ var i, ien, j, sClass, iStart, iEnd, iHalf=Math.floor(iListLength/2);
+
+ if ( oPaging.iTotalPages < iListLength) {
+ iStart = 1;
+ iEnd = oPaging.iTotalPages;
+ }
+ else if ( oPaging.iPage <= iHalf ) {
+ iStart = 1;
+ iEnd = iListLength;
+ } else if ( oPaging.iPage >= (oPaging.iTotalPages-iHalf) ) {
+ iStart = oPaging.iTotalPages - iListLength + 1;
+ iEnd = oPaging.iTotalPages;
+ } else {
+ iStart = oPaging.iPage - iHalf + 1;
+ iEnd = iStart + iListLength - 1;
+ }
+
+ for ( i=0, ien=an.length ; i'+j+'')
+ .insertBefore( $('li:last', an[i])[0] )
+ .bind('click', function (e) {
+ e.preventDefault();
+ oSettings._iDisplayStart = (parseInt($('a', this).text(),10)-1) * oPaging.iLength;
+ fnDraw( oSettings );
+ } );
+ }
+
+ // Add / remove disabled classes from the static elements
+ if ( oPaging.iPage === 0 ) {
+ $('li:first', an[i]).addClass('disabled');
+ } else {
+ $('li:first', an[i]).removeClass('disabled');
+ }
+
+ if ( oPaging.iPage === oPaging.iTotalPages-1 || oPaging.iTotalPages === 0 ) {
+ $('li:last', an[i]).addClass('disabled');
+ } else {
+ $('li:last', an[i]).removeClass('disabled');
+ }
+ }
+ }
+ }
+} );
+
+
+/*
+ * TableTools Bootstrap compatibility
+ * Required TableTools 2.1+
+ */
+if ( $.fn.DataTable.TableTools ) {
+ // Set the classes that TableTools uses to something suitable for Bootstrap
+ $.extend( true, $.fn.DataTable.TableTools.classes, {
+ "container": "DTTT btn-group",
+ "buttons": {
+ "normal": "btn btn-default",
+ "disabled": "disabled"
+ },
+ "collection": {
+ "container": "DTTT_dropdown dropdown-menu",
+ "buttons": {
+ "normal": "",
+ "disabled": "disabled"
+ }
+ },
+ "print": {
+ "info": "DTTT_print_info modal"
+ },
+ "select": {
+ "row": "active"
+ }
+ } );
+
+ // Have the collection use a bootstrap compatible dropdown
+ $.extend( true, $.fn.DataTable.TableTools.DEFAULTS.oTags, {
+ "collection": {
+ "container": "ul",
+ "button": "li",
+ "liner": "a"
+ }
+ } );
+}
+
diff --git a/server/src/uds/static/adm/js/gui.js b/server/src/uds/static/adm/js/gui.js
index ff964d735..82bf888ff 100644
--- a/server/src/uds/static/adm/js/gui.js
+++ b/server/src/uds/static/adm/js/gui.js
@@ -14,13 +14,13 @@
// Several convenience "constants"
gui.dataTablesLanguage = {
- "sLengthMenu": gettext("Display _MENU_ records per page"),
+ "sLengthMenu": gettext("_MENU_ records per page"),
"sZeroRecords": gettext("Nothing found - sorry"),
- "sInfo": gettext("Showing record _START_ to _END_ of _TOTAL_"),
- "sInfoEmpty": gettext("Showing 0 to 0 of 0 records"),
+ "sInfo": gettext("Records _START_ to _END_ of _TOTAL_"),
+ "sInfoEmpty": gettext("No records"),
"sInfoFiltered": gettext("(filtered from _MAX_ total records)"),
"sProcessing": gettext("Please wait, processing"),
- "sSearch": gettext("Search"),
+ "sSearch": gettext("Filter"),
"sInfoThousands": django.formats.THOUSAND_SEPARATOR,
"oPaginate": {
"sFirst": gettext("First"),
@@ -40,7 +40,7 @@
return '';
+ '';
}
gui.breadcrumbs = function(path) {
@@ -89,6 +89,12 @@
$.each(sidebarLinks, function(index, value){
gui.doLog('Adding ' + value.id)
$('.'+value.id).unbind('click').click(value.exec);
+ // Navbar click so navbar is closed...
+ $('.nav a').on('click', function(){
+ if($('.navbar-toggle').css('display') !='none'){
+ $(".navbar-toggle").trigger( "click" );
+ }
+ });
});
}
@@ -129,8 +135,12 @@ GuiElement.prototype = {
$(styles).appendTo('head');
});
},
- table: function(container_id) {
- // Empty container_id first
+ table: function(options) {
+ // Options (all are optionals)
+ // rowSelect: 'single' or 'multi'
+ // container: ID of the element that will hold this table (will be emptied)
+ // rowSelectFnc: function to invoke on row selection. receives 1 array - node : TR elements that were selected
+ // rowDeselectFnc: function to invoke on row deselection. receives 1 array - node : TR elements that were selected
gui.doLog('Composing table for ' + this.name);
var tableId = this.name + '-table';
var $this = this;
@@ -140,7 +150,6 @@ GuiElement.prototype = {
$.each(data.fields,function(index, value) {
for( var v in value ){
var options = value[v];
- gui.doLog(options);
var column = { mData: v };
column.sTitle = options.title;
if( options.type )
@@ -161,26 +170,149 @@ GuiElement.prototype = {
}
});
gui.doLog(columns);
+
+ var processResponse = function(data) {
+ $.each(data, function(index, value){
+ var type = $this.types[value.type];
+ data[index].name = ' ' + value.name
+ });
+ };
+
$this.rest.get({
success: function(data) {
- $.each(data, function(index, value){
- var type = $this.types[value.type];
- data[index].name = ' ' + value.name
- });
-
+ processResponse(data);
var table = gui.table(title, tableId);
- if( container_id == undefined ) {
+ if( options.container == undefined ) {
gui.appendToWorkspace('');
} else {
- $('#'+container_id).empty();
- $('#'+container_id).append(table);
+ $('#'+options.container).empty();
+ $('#'+options.container).append(table);
}
+ var btns = [
+ /*{
+ "sExtends": "csv",
+ "sTitle": title,
+ "sFileName": title + '.csv',
+ },*/
+ /*{
+ "sExtends": "pdf",
+ "sTitle": title,
+ "sPdfMessage": "Summary Info",
+ "sFileName": title + '.pdf',
+ "sPdfOrientation": "portrait"
+ },*/
+ ];
+
+ if( options.buttons ) {
+
+ // methods for buttons click
+ var editFnc = function() {
+ gui.doLog('Edit');
+ gui.doLog(this);
+ };
+ var deleteFnc = function() {
+ gui.doLog('Delete');
+ gui.doLog(this);
+ };
+ var refreshFnc = function(btn) {
+ // Refreshes table content
+ gui.doLog('Refresh');
+ gui.doLog(this);
+ gui.doLog(btn);
+ var tbl = $('#' + tableId).dataTable();
+ var width = $(btn).width();
+ var saved = $(btn).html();
+ $(btn).addClass('disabled').html('').width(width);
+ $this.rest.get({
+ success: function(data) {
+ processResponse(data);
+ tbl.fnClearTable();
+ tbl.fnAddData(data);
+ $(btn).removeClass('disabled').html(saved);
+ }
+ });
+ }
+
+ // methods for buttons on row select
+ var editSelected = function(btn, obj, node) {
+ var sel = this.fnGetSelectedData();
+ if( sel.length == 1) {
+ $(btn).removeClass('disabled').addClass('btn-info');
+ } else {
+ $(btn).removeClass('btn-info').addClass('disabled');
+ }
+ };
+ var deleteSelected = function(btn, obj, node) {
+ var sel = this.fnGetSelectedData();
+ if( sel.length > 0) {
+ $(btn).removeClass('disabled').addClass('btn-warning');
+ } else {
+ $(btn).removeClass('btn-warning').addClass('disabled');
+ }
+ };
+
+ $.each(options.buttons, function(index, value){
+ var btn = undefined;
+ switch(value) {
+ case 'edit':
+ btn = {
+ "sExtends": "text",
+ "sButtonText": gettext('Edit'),
+ "fnSelect": editSelected,
+ "fnClick": editFnc,
+ "sButtonClass": "disabled"
+ }
+ break;
+ case 'delete':
+ btn = {
+ "sExtends": "text",
+ "sButtonText": gettext('Delete'),
+ "fnSelect": deleteSelected,
+ "fnClick": deleteFnc,
+ "sButtonClass": "disabled"
+ }
+ break;
+ case 'refresh':
+ btn = {
+ "sExtends": "text",
+ "sButtonText": gettext('Refresh'),
+ "fnClick": refreshFnc,
+ "sButtonClass": "btn-info"
+ }
+ break;
+ }
+
+ if( btn != undefined )
+ btns.push(btn);
+ });
+ }
+
+ // Initializes oTableTools
+ oTableTools = {
+ "aButtons": btns
+ };
+ if( options.rowSelect ) {
+ oTableTools.sRowSelect = options.rowSelect
+ }
+ if( options.rowSelectFnc ) {
+ oTableTools.fnRowSelected = options.rowSelectFnc
+ }
+ if( options.rowDeselectFnc ) {
+ oTableTools.fnRowDeselected = options.rowDeselectFnc
+ }
+
+
$('#' + tableId).dataTable({
"aaData": data,
"aoColumns": columns,
- "oLanguage": gui.dataTablesLanguage,
+ "oLanguage": gui.dataTablesLanguage,
+ "oTableTools": oTableTools,
+ // First is upper row, second row is lower (pagination) row
+ "sDom": "<'row'<'col-xs-6'T><'col-xs-6'f>r>t<'row'<'col-xs-5'i><'col-xs-7'p>>",
+
});
+ $('#' + tableId + '_filter input').addClass('form-control');
}
});
});
@@ -192,12 +324,20 @@ GuiElement.prototype = {
// Compose gui API
// Service providers
-gui.providers = new GuiElement(api.providers, 'prov'); // Tha 'name' must be the same as uses on REST api
+gui.providers = new GuiElement(api.providers, 'provi');
gui.providers.link = function(event) {
gui.clearWorkspace();
gui.appendToWorkspace(gui.breadcrumbs(gettext('Service Providers')));
- var tableId = gui.providers.table();
+ var tableId = gui.providers.table({
+ rowSelect: 'multi',
+ rowSelectFnc: function(nodes){
+ gui.doLog(nodes);
+ gui.doLog(this);
+ gui.doLog(this.fnGetSelectedData());
+ },
+ buttons: ['edit', 'refresh', 'delete'],
+ });
return false;
};
@@ -207,7 +347,10 @@ gui.authenticators.link = function(event) {
gui.clearWorkspace();
gui.appendToWorkspace(gui.breadcrumbs(gettext('Authenticators')));
- gui.authenticators.table();
+ gui.authenticators.table({
+ rowSelect: 'single',
+ buttons: ['edit', 'refresh', 'delete'],
+ });
return false;
};
@@ -217,7 +360,10 @@ gui.osmanagers.link = function(event) {
gui.clearWorkspace();
gui.appendToWorkspace(gui.breadcrumbs('Os Managers'));
- gui.osmanagers.table();
+ gui.osmanagers.table({
+ rowSelect: 'single',
+ buttons: ['edit', 'refresh', 'delete'],
+ });
return false;
};
@@ -232,6 +378,14 @@ gui.connectivity.link = function(event) {
gui.appendToWorkspace(gui.breadcrumbs(gettext('Connectivity')));
gui.appendToWorkspace('');
- gui.connectivity.transports.table('ttbl');
- gui.connectivity.networks.table('ntbl');
+ gui.connectivity.transports.table({
+ rowSelect: 'multi',
+ container: 'ttbl',
+ buttons: ['edit', 'refresh', 'delete'],
+ });
+ gui.connectivity.networks.table({
+ rowSelect: 'single',
+ container: 'ntbl',
+ buttons: ['edit', 'refresh', 'delete'],
+ });
}
diff --git a/server/src/uds/static/adm/js/templating.js b/server/src/uds/static/adm/js/templating.js
index 622830711..28872d7eb 100644
--- a/server/src/uds/static/adm/js/templating.js
+++ b/server/src/uds/static/adm/js/templating.js
@@ -21,11 +21,11 @@
// Convert the template into pure JavaScript
str
.replace(/[\r\t\n]/g, " ")
- .split("<%").join("\t")
- .replace(/((^|%>)[^\t]*)'/g, "$1\r")
- .replace(/\t=(.*?)%>/g, "',$1,'")
+ .split("<$").join("\t")
+ .replace(/((^|$>)[^\t]*)'/g, "$1\r")
+ .replace(/\t=(.*?)$>/g, "',$1,'")
.split("\t").join("');")
- .split("%>").join("p.push('")
+ .split("$>").join("p.push('")
.split("\r").join("\\'")
+ "');}return p.join('');");
diff --git a/server/src/uds/static/adm/swf/copy_csv_xls.swf b/server/src/uds/static/adm/swf/copy_csv_xls.swf
new file mode 100644
index 000000000..082c7acbf
Binary files /dev/null and b/server/src/uds/static/adm/swf/copy_csv_xls.swf differ
diff --git a/server/src/uds/static/adm/swf/copy_csv_xls_pdf.swf b/server/src/uds/static/adm/swf/copy_csv_xls_pdf.swf
new file mode 100644
index 000000000..063131dfe
Binary files /dev/null and b/server/src/uds/static/adm/swf/copy_csv_xls_pdf.swf differ
diff --git a/server/src/uds/static/css/bootstrap-select.min.css b/server/src/uds/static/css/bootstrap-select.min.css
new file mode 100644
index 000000000..6875365c4
--- /dev/null
+++ b/server/src/uds/static/css/bootstrap-select.min.css
@@ -0,0 +1,7 @@
+/*!
+ * bootstrap-select v1.3.5
+ * http://silviomoreto.github.io/bootstrap-select/
+ *
+ * Copyright 2013 bootstrap-select
+ * Licensed under the MIT license
+ */.bootstrap-select.btn-group,.bootstrap-select.btn-group[class*="span"]{float:none;display:inline-block;margin-bottom:10px;margin-left:0}.form-search .bootstrap-select.btn-group,.form-inline .bootstrap-select.btn-group,.form-horizontal .bootstrap-select.btn-group{margin-bottom:0}.bootstrap-select.form-control{padding:0;border:0}.bootstrap-select.btn-group.pull-right,.bootstrap-select.btn-group[class*="span"].pull-right,.row-fluid .bootstrap-select.btn-group[class*="span"].pull-right{float:right}.input-append .bootstrap-select.btn-group{margin-left:-1px}.input-prepend .bootstrap-select.btn-group{margin-right:-1px}.bootstrap-select:not([class*="span"]):not([class*="col-"]):not([class*="form-control"]){width:220px}.bootstrap-select{width:220px\0}.bootstrap-select.form-control:not([class*="span"]){width:100%}.bootstrap-select>.btn{width:100%}.error .bootstrap-select .btn{border:1px solid #b94a48}.dropdown-menu{z-index:2000}.bootstrap-select.show-menu-arrow.open>.btn{z-index:2051}.bootstrap-select .btn:focus{outline:thin dotted #333 !important;outline:5px auto -webkit-focus-ring-color !important;outline-offset:-2px}.bootstrap-select.btn-group .btn .filter-option{overflow:hidden;position:absolute;left:12px;right:25px;text-align:left}.bootstrap-select.btn-group .btn .caret{position:absolute;top:50%;right:12px;margin-top:-2px;vertical-align:middle}.bootstrap-select.btn-group>.disabled,.bootstrap-select.btn-group .dropdown-menu li.disabled>a{cursor:not-allowed}.bootstrap-select.btn-group>.disabled:focus{outline:none !important}.bootstrap-select.btn-group[class*="span"] .btn{width:100%}.bootstrap-select.btn-group .dropdown-menu{min-width:100%;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box}.bootstrap-select.btn-group .dropdown-menu.inner{position:static;border:0;padding:0;margin:0;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none}.bootstrap-select.btn-group .dropdown-menu dt{display:block;padding:3px 20px;cursor:default}.bootstrap-select.btn-group .div-contain{overflow:hidden}.bootstrap-select.btn-group .dropdown-menu li{position:relative}.bootstrap-select.btn-group .dropdown-menu li>a.opt{position:relative;padding-left:35px}.bootstrap-select.btn-group .dropdown-menu li>a{cursor:pointer}.bootstrap-select.btn-group .dropdown-menu li>dt small{font-weight:normal}.bootstrap-select.btn-group.show-tick .dropdown-menu li.selected a i.check-mark{display:inline-block;position:absolute;right:15px;margin-top:2.5px}.bootstrap-select.btn-group .dropdown-menu li a i.check-mark{display:none}.bootstrap-select.btn-group.show-tick .dropdown-menu li a span.text{margin-right:34px}.bootstrap-select.btn-group .dropdown-menu li small{padding-left:.5em}.bootstrap-select.btn-group .dropdown-menu li:not(.disabled)>a:hover small,.bootstrap-select.btn-group .dropdown-menu li:not(.disabled)>a:focus small{color:#64b1d8;color:rgba(255,255,255,0.4)}.bootstrap-select.btn-group .dropdown-menu li>dt small{font-weight:normal}.bootstrap-select.show-menu-arrow .dropdown-toggle:before{content:'';display:inline-block;border-left:7px solid transparent;border-right:7px solid transparent;border-bottom:7px solid #CCC;border-bottom-color:rgba(0,0,0,0.2);position:absolute;bottom:-4px;left:9px;display:none}.bootstrap-select.show-menu-arrow .dropdown-toggle:after{content:'';display:inline-block;border-left:6px solid transparent;border-right:6px solid transparent;border-bottom:6px solid white;position:absolute;bottom:-4px;left:10px;display:none}.bootstrap-select.show-menu-arrow.dropup .dropdown-toggle:before{bottom:auto;top:-3px;border-top:7px solid #ccc;border-bottom:0;border-top-color:rgba(0,0,0,0.2)}.bootstrap-select.show-menu-arrow.dropup .dropdown-toggle:after{bottom:auto;top:-3px;border-top:6px solid #fff;border-bottom:0}.bootstrap-select.show-menu-arrow.pull-right .dropdown-toggle:before{right:12px;left:auto}.bootstrap-select.show-menu-arrow.pull-right .dropdown-toggle:after{right:13px;left:auto}.bootstrap-select.show-menu-arrow.open>.dropdown-toggle:before,.bootstrap-select.show-menu-arrow.open>.dropdown-toggle:after{display:block}.mobile-device{position:absolute;top:0;left:0;display:block !important;width:100%;height:100% !important;opacity:0}.bootstrap-select.fit-width{width:auto !important}.bootstrap-select.btn-group.fit-width .btn .filter-option{position:static}.bootstrap-select.btn-group.fit-width .btn .caret{position:static;top:auto;margin-top:-1px}.control-group.error .bootstrap-select .dropdown-toggle{border-color:#b94a48}.bootstrap-select-searchbox{padding:4px 8px}
\ No newline at end of file
diff --git a/server/src/uds/static/js/bootstrap-select.min.js b/server/src/uds/static/js/bootstrap-select.min.js
new file mode 100644
index 000000000..0b304fee8
--- /dev/null
+++ b/server/src/uds/static/js/bootstrap-select.min.js
@@ -0,0 +1,8 @@
+/*!
+ * bootstrap-select v1.3.5
+ * http://silviomoreto.github.io/bootstrap-select/
+ *
+ * Copyright 2013 bootstrap-select
+ * Licensed under the MIT license
+ */
+;!function(b){b.expr[":"].icontains=function(e,c,d){return b(e).text().toUpperCase().indexOf(d[3].toUpperCase())>=0};var a=function(d,c,f){if(f){f.stopPropagation();f.preventDefault()}this.$element=b(d);this.$newElement=null;this.$button=null;this.$menu=null;this.options=b.extend({},b.fn.selectpicker.defaults,this.$element.data(),typeof c=="object"&&c);if(this.options.title==null){this.options.title=this.$element.attr("title")}this.val=a.prototype.val;this.render=a.prototype.render;this.refresh=a.prototype.refresh;this.setStyle=a.prototype.setStyle;this.selectAll=a.prototype.selectAll;this.deselectAll=a.prototype.deselectAll;this.init()};a.prototype={constructor:a,init:function(d){this.$element.hide();this.multiple=this.$element.prop("multiple");var f=this.$element.attr("id");this.$newElement=this.createView();this.$element.after(this.$newElement);this.$menu=this.$newElement.find("> .dropdown-menu");this.$button=this.$newElement.find("> button");this.$searchbox=this.$newElement.find("input");if(f!==undefined){var c=this;this.$button.attr("data-id",f);b('label[for="'+f+'"]').click(function(g){g.preventDefault();c.$button.focus()})}this.checkDisabled();this.clickListener();this.liveSearchListener();this.render();this.liHeight();this.setStyle();this.setWidth();if(this.options.container){this.selectPosition()}this.$menu.data("this",this);this.$newElement.data("this",this)},createDropdown:function(){var c=this.multiple?" show-tick":"";var f=this.options.header?''+this.options.header+"
":"";var e=this.options.liveSearch?'':"";var d="";return b(d)},createView:function(){var c=this.createDropdown();var d=this.createLi();c.find("ul").append(d);return c},reloadLi:function(){this.destroyLi();var c=this.createLi();this.$menu.find("ul").append(c)},destroyLi:function(){this.$menu.find("li").remove()},createLi:function(){var d=this,e=[],c="";this.$element.find("option").each(function(h){var j=b(this);var g=j.attr("class")||"";var i=j.attr("style")||"";var n=j.data("content")?j.data("content"):j.html();var l=j.data("subtext")!==undefined?''+j.data("subtext")+"":"";var k=j.data("icon")!==undefined?' ':"";if(k!==""&&(j.is(":disabled")||j.parent().is(":disabled"))){k=""+k+""}if(!j.data("content")){n=k+''+n+l+""}if(d.options.hideDisabled&&(j.is(":disabled")||j.parent().is(":disabled"))){e.push('')}else{if(j.parent().is("optgroup")&&j.data("divider")!=true){if(j.index()==0){var m=j.parent().attr("label");var o=j.parent().data("subtext")!==undefined?''+j.parent().data("subtext")+"":"";var f=j.parent().data("icon")?' ':"";m=f+''+m+o+"";if(j[0].index!=0){e.push(''+m+""+d.createA(n,"opt "+g,i))}else{e.push(""+m+""+d.createA(n,"opt "+g,i))}}else{e.push(d.createA(n,"opt "+g,i))}}else{if(j.data("divider")==true){e.push('')}else{if(b(this).data("hidden")==true){e.push("")}else{e.push(d.createA(n,g,i))}}}}});b.each(e,function(f,g){c+=""+g+""});if(!this.multiple&&this.$element.find("option:selected").length==0&&!this.options.title){this.$element.find("option").eq(0).prop("selected",true).attr("selected","selected")}return b(c)},createA:function(e,c,d){return''+e+''},render:function(){var d=this;this.$element.find("option").each(function(h){d.setDisabled(h,b(this).is(":disabled")||b(this).parent().is(":disabled"));d.setSelected(h,b(this).is(":selected"))});this.tabIndex();var g=this.$element.find("option:selected").map(function(h,k){var l=b(this);var j=l.data("icon")&&d.options.showIcon?' ':"";var i;if(d.options.showSubtext&&l.attr("data-subtext")&&!d.multiple){i=' '+l.data("subtext")+""}else{i=""}if(l.data("content")&&d.options.showContent){return l.data("content")}else{if(l.attr("title")!=undefined){return l.attr("title")}else{return j+l.html()+i}}}).toArray();var f=!this.multiple?g[0]:g.join(", ");if(this.multiple&&this.options.selectedTextFormat.indexOf("count")>-1){var c=this.options.selectedTextFormat.split(">");var e=this.options.hideDisabled?":not([disabled])":"";if((c.length>1&&g.length>c[1])||(c.length==1&&g.length>=2)){f=this.options.countSelectedText.replace("{0}",g.length).replace("{1}",this.$element.find('option:not([data-divider="true"]):not([data-hidden="true"])'+e).length)}}if(!f){f=this.options.title!=undefined?this.options.title:this.options.noneSelectedText}this.$newElement.find(".filter-option").html(f)},setStyle:function(e,d){if(this.$element.attr("class")){this.$newElement.addClass(this.$element.attr("class").replace(/selectpicker|mobile-device/gi,""))}var c=e?e:this.options.style;if(d=="add"){this.$button.addClass(c)}else{if(d=="remove"){this.$button.removeClass(c)}else{this.$button.removeClass(this.options.style);this.$button.addClass(c)}}},liHeight:function(){var f=this.$newElement.clone();f.appendTo("body");var e=f.addClass("open").find("> .dropdown-menu");var d=e.find("li > a").outerHeight();var c=this.options.header?e.find(".popover-title").outerHeight():0;var g=this.options.liveSearch?e.find(".bootstrap-select-searchbox").outerHeight():0;f.remove();this.$newElement.data("liHeight",d).data("headerHeight",c).data("searchHeight",g)},setSize:function(){var h=this,d=this.$menu,i=d.find(".inner"),p=i.find("li > a"),u=this.$newElement.outerHeight(),f=this.$newElement.data("liHeight"),s=this.$newElement.data("headerHeight"),l=this.$newElement.data("searchHeight"),k=d.find("li .divider").outerHeight(true),r=parseInt(d.css("padding-top"))+parseInt(d.css("padding-bottom"))+parseInt(d.css("border-top-width"))+parseInt(d.css("border-bottom-width")),o=this.options.hideDisabled?":not(.disabled)":"",n=b(window),g=r+parseInt(d.css("margin-top"))+parseInt(d.css("margin-bottom"))+2,q,v,t,j=function(){v=h.$newElement.offset().top-n.scrollTop();t=n.height()-v-u};j();if(this.options.header){d.css("padding-top",0)}if(this.options.size=="auto"){var e=function(){var w;j();q=t-g;h.$newElement.toggleClass("dropup",(v>t)&&(q-g)3){w=f*3+g-2}else{w=0}d.css({"max-height":q+"px",overflow:"hidden","min-height":w+"px"});i.css({"max-height":q-s-l-r+"px","overflow-y":"auto","min-height":w-r+"px"})};e();b(window).resize(e);b(window).scroll(e)}else{if(this.options.size&&this.options.size!="auto"&&d.find("li"+o).length>this.options.size){var m=d.find("li"+o+" > *").filter(":not(.div-contain)").slice(0,this.options.size).last().parent().index();var c=d.find("li").slice(0,m+1).find(".div-contain").length;q=f*this.options.size+c*k+r;this.$newElement.toggleClass("dropup",(v>t)&&q .dropdown-menu").css("width");d.remove();this.$newElement.css("width",c)}else{if(this.options.width=="fit"){this.$menu.css("min-width","");this.$newElement.css("width","").addClass("fit-width")}else{if(this.options.width){this.$menu.css("min-width","");this.$newElement.css("width",this.options.width)}else{this.$menu.css("min-width","");this.$newElement.css("width","")}}}if(this.$newElement.hasClass("fit-width")&&this.options.width!=="fit"){this.$newElement.removeClass("fit-width")}},selectPosition:function(){var e=this,d="",f=b(d),h,g,c=function(i){f.addClass(i.attr("class")).toggleClass("dropup",i.hasClass("dropup"));h=i.offset();g=i.hasClass("dropup")?0:i[0].offsetHeight;f.css({top:h.top+g,left:h.left,width:i[0].offsetWidth,position:"absolute"})};this.$newElement.on("click",function(i){c(b(this));f.appendTo(e.options.container);f.toggleClass("open",!b(this).hasClass("open"));f.append(e.$menu)});b(window).resize(function(){c(e.$newElement)});b(window).on("scroll",function(i){c(e.$newElement)});b("html").on("click",function(i){if(b(i.target).closest(e.$newElement).length<1){f.removeClass("open")}})},mobile:function(){this.$element.addClass("mobile-device").appendTo(this.$newElement);if(this.options.container){this.$menu.hide()}},refresh:function(){this.reloadLi();this.render();this.setWidth();this.setStyle();this.checkDisabled();this.liHeight()},update:function(){this.reloadLi();this.setWidth();this.setStyle();this.checkDisabled();this.liHeight()},setSelected:function(c,d){this.$menu.find("li").eq(c).toggleClass("selected",d)},setDisabled:function(c,d){if(d){this.$menu.find("li").eq(c).addClass("disabled").find("a").attr("href","#").attr("tabindex",-1)}else{this.$menu.find("li").eq(c).removeClass("disabled").find("a").removeAttr("href").attr("tabindex",0)}},isDisabled:function(){return this.$element.is(":disabled")},checkDisabled:function(){var c=this;if(this.isDisabled()){this.$button.addClass("disabled").attr("tabindex",-1)}else{if(this.$button.hasClass("disabled")){this.$button.removeClass("disabled")}if(this.$button.attr("tabindex")==-1){if(!this.$element.data("tabindex")){this.$button.removeAttr("tabindex")}}}this.$button.click(function(){return !c.isDisabled()})},tabIndex:function(){if(this.$element.is("[tabindex]")){this.$element.data("tabindex",this.$element.attr("tabindex"));this.$button.attr("tabindex",this.$element.data("tabindex"))}},clickListener:function(){var c=this;b("body").on("touchstart.dropdown",".dropdown-menu",function(d){d.stopPropagation()});this.$newElement.on("click",function(){c.setSize()});this.$menu.on("click","li a",function(k){var f=b(this).parent().index(),j=b(this).parent(),i=c.$element.val();if(c.multiple){k.stopPropagation()}k.preventDefault();if(!c.isDisabled()&&!b(this).parent().hasClass("disabled")){var d=c.$element.find("option");var h=d.eq(f);if(!c.multiple){d.prop("selected",false);h.prop("selected",true)}else{var g=h.prop("selected");h.prop("selected",!g)}c.$button.focus();if(i!=c.$element.val()){c.$element.change()}}});this.$menu.on("click","li.disabled a, li dt, li .div-contain, h3.popover-title",function(d){if(d.target==this){d.preventDefault();d.stopPropagation();c.$button.focus()}});this.$searchbox.on("click",function(d){d.stopPropagation()});this.$element.change(function(){c.render()})},liveSearchListener:function(){var c=this;this.$newElement.on("click.dropdown.data-api",function(d){if(c.options.liveSearch){setTimeout(function(){c.$searchbox.focus()},10)}});this.$searchbox.on("input",function(){if(c.$searchbox.val()){c.$menu.find("li").show().not(":icontains("+c.$searchbox.val()+")").hide()}else{c.$menu.find("li").show()}})},val:function(c){if(c!=undefined){this.$element.val(c);this.$element.change();return this.$element}else{return this.$element.val()}},selectAll:function(){this.$element.find("option").prop("selected",true).attr("selected","selected");this.render()},deselectAll:function(){this.$element.find("option").prop("selected",false).removeAttr("selected");this.render()},keydown:function(o){var p,n,h,m,j,i,q,d,g,l;p=b(this);h=p.parent();l=h.data("this");if(l.options.container){h=l.$menu}n=b("[role=menu] li:not(.divider):visible a",h);if(!n.length){return}if(/(38|40)/.test(o.keyCode)){m=n.index(n.filter(":focus"));i=n.parent(":not(.disabled)").first().index();q=n.parent(":not(.disabled)").last().index();j=n.eq(m).parent().nextAll(":not(.disabled)").eq(0).index();d=n.eq(m).parent().prevAll(":not(.disabled)").eq(0).index();g=n.eq(j).parent().prevAll(":not(.disabled)").eq(0).index();if(o.keyCode==38){if(m!=g&&m>d){m=d}if(mq){m=q}if(m==-1){m=0}}n.eq(m).focus()}else{var f={48:"0",49:"1",50:"2",51:"3",52:"4",53:"5",54:"6",55:"7",56:"8",57:"9",59:";",65:"a",66:"b",67:"c",68:"d",69:"e",70:"f",71:"g",72:"h",73:"i",74:"j",75:"k",76:"l",77:"m",78:"n",79:"o",80:"p",81:"q",82:"r",83:"s",84:"t",85:"u",86:"v",87:"w",88:"x",89:"y",90:"z",96:"0",97:"1",98:"2",99:"3",100:"4",101:"5",102:"6",103:"7",104:"8",105:"9"};var c=[];n.each(function(){if(b(this).parent().is(":not(.disabled)")){if(b.trim(b(this).text().toLowerCase()).substring(0,1)==f[o.keyCode]){c.push(b(this).parent().index())}}});var k=b(document).data("keycount");k++;b(document).data("keycount",k);var r=b.trim(b(":focus").text().toLowerCase()).substring(0,1);if(r!=f[o.keyCode]){k=1;b(document).data("keycount",k)}else{if(k>=c.length){b(document).data("keycount",0)}}n.eq(c[k-1]).focus()}if(/(13|32)/.test(o.keyCode)){o.preventDefault();b(":focus").click();b(document).data("keycount",0)}},hide:function(){this.$newElement.hide()},show:function(){this.$newElement.show()},destroy:function(){this.$newElement.remove();this.$element.remove()}};b.fn.selectpicker=function(e,f){var c=arguments;var g;var d=this.each(function(){if(b(this).is("select")){var m=b(this),l=m.data("selectpicker"),h=typeof e=="object"&&e;if(!l){m.data("selectpicker",(l=new a(this,h,f)))}else{if(h){for(var j in h){l.options[j]=h[j]}}}if(typeof e=="string"){var k=e;if(l[k] instanceof Function){[].shift.apply(c);g=l[k].apply(l,c)}else{g=l.options[k]}}}});if(g!=undefined){return g}else{return d}};b.fn.selectpicker.defaults={style:"btn-default",size:"auto",title:null,selectedTextFormat:"values",noneSelectedText:"Nothing selected",countSelectedText:"{0} of {1} selected",width:false,container:false,hideDisabled:false,showSubtext:false,showIcon:true,showContent:true,dropupAuto:true,header:false,liveSearch:false};b(document).data("keycount",0).on("keydown","[data-toggle=dropdown], [role=menu]",a.prototype.keydown)}(window.jQuery);
diff --git a/server/src/uds/templates/uds/admin/base.html b/server/src/uds/templates/uds/admin/index.html
similarity index 97%
rename from server/src/uds/templates/uds/admin/base.html
rename to server/src/uds/templates/uds/admin/index.html
index d9ef9c25f..587aa3a66 100644
--- a/server/src/uds/templates/uds/admin/base.html
+++ b/server/src/uds/templates/uds/admin/index.html
@@ -22,9 +22,9 @@
-
+
-
+
{% block css %}{% endblock %}
@@ -48,7 +48,7 @@
-
+
diff --git a/server/src/uds/web/forms/LoginForm.py b/server/src/uds/web/forms/LoginForm.py
index bad0f0709..bb2217653 100644
--- a/server/src/uds/web/forms/LoginForm.py
+++ b/server/src/uds/web/forms/LoginForm.py
@@ -32,7 +32,7 @@ from django.utils.safestring import mark_safe
@author: Adolfo Gómez, dkmaster at dkmon dot com
'''
-from django.utils.translation import ugettext_lazy as _
+from django.utils.translation import ugettext_lazy as _, ugettext
from django import forms
from django.forms.forms import NON_FIELD_ERRORS
from django.forms.util import ErrorDict
@@ -47,7 +47,7 @@ class CustomSelect(forms.Select):
visible = 'style="display: none;"'
else:
visible = '';
- res = '