X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=plugins%2Fquerytable%2Fstatic%2Fjs%2Fquerytable.js;h=3731f7a9a761cca13cd08b587ee03e11d72b8bdf;hb=6eb1d8c9d03d2b10b514c317b6fff11172097346;hp=8637e7289514bfb336a72856e3f0a6b9b0bcb813;hpb=0bbc8c2d0a8071630df62bf6b953377e9318e09e;p=unfold.git diff --git a/plugins/querytable/static/js/querytable.js b/plugins/querytable/static/js/querytable.js index 8637e728..3731f7a9 100644 --- a/plugins/querytable/static/js/querytable.js +++ b/plugins/querytable/static/js/querytable.js @@ -4,6 +4,10 @@ * License: GPLv3 */ +BGCOLOR_RESET = 0; +BGCOLOR_ADDED = 1; +BGCOLOR_REMOVED = 2; + (function($){ var debug=false; @@ -60,7 +64,7 @@ /* Setup query and record handlers */ this.listen_query(options.query_uuid); - this.listen_query(options.query_all_uuid, 'all'); + //this.listen_query(options.query_all_uuid, 'all'); /* GUI setup and event binding */ this.initialize_table(); @@ -91,7 +95,8 @@ var actual_options = { // Customize the position of Datatables elements (length,filter,button,...) // we use a fluid row on top and another on the bottom, making sure we take 12 grid elt's each time - sDom: "<'row'<'col-xs-5'l><'col-xs-1'r><'col-xs-6'f>>t<'row'<'col-xs-5'i><'col-xs-7'p>>", + //sDom: "<'row'<'col-xs-5'l><'col-xs-1'r><'col-xs-6'f>>t<'row'<'col-xs-5'i><'col-xs-7'p>>", + sDom: "<'row'<'col-xs-5'f><'col-xs-1'r><'col-xs-6 columns_selector'>>t<'row'<'col-xs-5'l><'col-xs-7'p>>", // XXX as of sept. 2013, I cannot locate a bootstrap3-friendly mode for now // hopefully this would come with dataTables v1.10 ? // in any case, search for 'sPaginationType' all over the code for more comments @@ -102,7 +107,24 @@ // WARNING: this one causes tables in a 'tabs' that are not exposed at the time this is run to show up empty // sScrollX: '100%', /* Horizontal scrolling */ bProcessing: true, /* Loading */ - fnDrawCallback: function() { self._querytable_draw_callback.call(self); } + fnDrawCallback: function() { self._querytable_draw_callback.call(self); }, + fnRowCallback: function( nRow, aData, iDisplayIndex, iDisplayIndexFull ) { + // This function is called on fnAddData to set the TR id. What about fnUpdate ? + + // Get the key from the raw data array aData + var key = self.canonical_key; + + // Get the index of the key in the columns + var cols = self.table.fnSettings().aoColumns; + var index = self.getColIndex(key, cols); + if (index != -1) { + // The key is found in the table, set the TR id after the data + $(nRow).attr('id', self.id_from_key(key, aData[index])); + } + + // That's the usual return value + return nRow; + } // XXX use $.proxy here ! }; // the intention here is that options.datatables_options as coming from the python object take precedence @@ -145,6 +167,8 @@ //manifold.raise_event(self.options.query_all_uuid, FIELD_REMOVED, field); self.hide_column(field); }); + $(".dataTables_filter").append("
"); + $(".dataTables_filter input").css("width","100%"); }, // initialize_table /** @@ -194,10 +218,15 @@ var colnames = cols.map(function(x) {return x.sTitle}) var nb_col = cols.length; /* if we've requested checkboxes, then forget about the checkbox column for now */ - if (this.options.checkboxes) nb_col -= 1; - + //if (this.options.checkboxes) nb_col -= 1; + // catch up with the last column if checkboxes were requested + if (this.options.checkboxes) { + // Use a key instead of hostname (hard coded...) + line.push(this.checkbox_html(record)); + } + /* fill in stuff depending on the column name */ - for (var j = 0; j < nb_col; j++) { + for (var j = 1; j < nb_col - 1; j++) { // nb_col includes status if (typeof colnames[j] == 'undefined') { line.push('...'); } else if (colnames[j] == 'hostname') { @@ -217,10 +246,11 @@ } /* XXX TODO: Remove this and have something consistant */ if(obj=='resource'){ - line.push(' '+record[this.init_key]); + //line.push(' '+record[this.init_key]); }else{ - line.push(' '+record[this.init_key]); + //line.push(' '+record[this.init_key]); } + line.push(record[this.init_key]); } else { if (record[colnames[j]]) line.push(record[colnames[j]]); @@ -228,16 +258,11 @@ line.push(''); } } - - // catch up with the last column if checkboxes were requested - if (this.options.checkboxes) { - // Use a key instead of hostname (hard coded...) - line.push(this.checkbox_html(record)); - } + line.push(''); // STATUS // adding an array in one call is *much* more efficient // this.table.fnAddData(line); - this.buffered_lines.push(line); + return line; }, clear_table: function() @@ -271,11 +296,16 @@ // this is used at init-time, at which point only init_key can make sense // (because the argument record, if it comes from query, might not have canonical_key set set_checkbox_from_record: function (record, checked) { - if (checked === undefined) checked = true; + if (checked === undefined) checked = true; var init_id = record[this.init_key]; - if (debug) messages.debug("querytable.set_checkbox_from_record, init_id="+init_id); + this.set_checkbox_from_record_key(init_id, checked); + }, + + set_checkbox_from_record_key: function (record_key, checked) { + if (checked === undefined) checked = true; + if (debug) messages.debug("querytable.set_checkbox_from_record, record_key="+record_key); // using table.$ to search inside elements that are not visible - var element = this.table.$('[init_id="'+init_id+'"]'); + var element = this.table.$('[init_id="'+record_key+'"]'); element.attr('checked',checked); }, @@ -288,27 +318,131 @@ element.attr('checked',checked); }, + /** + * Arguments + * + * key_value: the key from which we deduce the id + * request: STATUS_OKAY, etc. + * content: some HTML content + */ + change_status: function(key_value, warnings) + { + var msg; + + if ($.isEmptyObject(warnings)) { + var state = manifold.query_store.get_record_state(this.options.query_uuid, key_value, STATE_SET); + switch(state) { + case STATE_SET_IN: + case STATE_SET_IN_SUCCESS: + case STATE_SET_OUT_FAILURE: + case STATE_SET_IN_PENDING: + // Checkmark sign if no warning for an object in the set + msg = '✓'; + break; + default: + // Nothing is the object is not in the set + msg = ''; + break; + } + } else { + msg = ''; + } + + $(document.getElementById(this.id_from_key('status', key_value))).html(msg); + $('[data-toggle="tooltip"]').tooltip({'placement': 'bottom'}); + + }, + + set_bgcolor: function(key_value, class_name) + { + var elt = $(document.getElementById(this.id_from_key(this.canonical_key, key_value))) + if (class_name == BGCOLOR_RESET) + elt.removeClass('added removed'); + else + elt.addClass((class_name == BGCOLOR_ADDED ? 'added' : 'removed')); + }, + + do_filter: function() + { + // Let's clear the table and only add lines that are visible + var self = this; + this.clear_table(); + + // XXX Here we have lost checkboxes + // set checkbox from record. + // only the current plugin known that we have an element in a set + + lines = Array(); + var record_keys = []; + manifold.query_store.iter_visible_records(this.options.query_uuid, function (record_key, record) { + lines.push(self.new_record(record)); + record_keys.push(record_key); + }); + this.table.fnAddData(lines); + $.each(record_keys, function(i, record_key) { + var state = manifold.query_store.get_record_state(self.options.query_uuid, record_key, STATE_SET); + var warnings = manifold.query_store.get_record_state(self.options.query_uuid, record_key, STATE_WARNINGS); + switch(state) { + // XXX The row and checkbox still does not exists !!!! + case STATE_SET_IN: + case STATE_SET_IN_SUCCESS: + case STATE_SET_OUT_FAILURE: + self.set_checkbox_from_record_key(record_key, true); + break; + case STATE_SET_OUT: + case STATE_SET_OUT_SUCCESS: + case STATE_SET_IN_FAILURE: + //self.set_checkbox_from_record_key(record_key, false); + break; + case STATE_SET_IN_PENDING: + self.set_checkbox_from_record_key(record_key, true); + self.set_bgcolor(record_key, BGCOLOR_ADDED); + break; + case STATE_SET_OUT_PENDING: + //self.set_checkbox_from_record_key(record_key, false); + self.set_bgcolor(record_key, BGCOLOR_REMOVED); + break; + } + self.change_status(record_key, warnings); // XXX will retrieve status again + }); + }, + /*************************** QUERY HANDLER ****************************/ on_filter_added: function(filter) { + this.do_filter(); + + /* this.filters.push(filter); this.redraw_table(); + */ }, on_filter_removed: function(filter) { + this.do_filter(); + /* // Remove corresponding filters this.filters = $.grep(this.filters, function(x) { return x == filter; }); this.redraw_table(); + */ }, on_filter_clear: function() { - // XXX - this.redraw_table(); + this.do_filter(); }, on_field_added: function(field) @@ -331,20 +465,17 @@ on_all_filter_added: function(filter) { - // XXX - this.redraw_table(); + this.do_filter(); }, on_all_filter_removed: function(filter) { - // XXX - this.redraw_table(); + this.do_filter(); }, on_all_filter_clear: function() { - // XXX - this.redraw_table(); + this.do_filter(); }, on_all_field_added: function(field) @@ -387,83 +518,49 @@ on_query_done: function() { + this.do_filter(); +/* this.received_query = true; // unspin once we have received both if (this.received_all_query && this.received_query) this.unspin(); +*/ }, on_field_state_changed: function(data) { - switch(data.request) { - case FIELD_REQUEST_ADD: - case FIELD_REQUEST_ADD_RESET: - this.set_checkbox_from_data(data.value, true); - break; - case FIELD_REQUEST_REMOVE: - case FIELD_REQUEST_REMOVE_RESET: - this.set_checkbox_from_data(data.value, false); - break; - default: + var state = manifold.query_store.get_record_state(this.options.query_uuid, data.value, data.status); + switch(data.status) { + case STATE_SET: + switch(state) { + case STATE_SET_IN: + case STATE_SET_IN_SUCCESS: + case STATE_SET_OUT_FAILURE: + this.set_checkbox_from_data(data.value, true); + this.set_bgcolor(data.value, BGCOLOR_RESET); + break; + case STATE_SET_OUT: + case STATE_SET_OUT_SUCCESS: + case STATE_SET_IN_FAILURE: + this.set_checkbox_from_data(data.value, false); + this.set_bgcolor(data.value, BGCOLOR_RESET); + break; + case STATE_SET_IN_PENDING: + this.set_checkbox_from_data(data.value, true); + this.set_bgcolor(data.value, BGCOLOR_ADDED); + break; + case STATE_SET_OUT_PENDING: + this.set_checkbox_from_data(data.value, false); + this.set_bgcolor(data.value, BGCOLOR_REMOVED); + break; + } break; - } - }, - /* XXX TODO: make this generic a plugin has to subscribe to a set of Queries to avoid duplicated code ! */ - // all - on_all_field_state_changed: function(data) - { - switch(data.request) { - case FIELD_REQUEST_ADD: - case FIELD_REQUEST_ADD_RESET: - this.set_checkbox_from_data(data.value, true); - break; - case FIELD_REQUEST_REMOVE: - case FIELD_REQUEST_REMOVE_RESET: - this.set_checkbox_from_data(data.value, false); - break; - default: + case STATE_WARNINGS: + this.change_status(data.value, state); break; } }, - on_all_new_record: function(record) - { - this.new_record(record); - }, - - on_all_clear_records: function() - { - this.clear_table(); - - }, - - on_all_query_in_progress: function() - { - // XXX parent - this.spin(); - }, // on_all_query_in_progress - - on_all_query_done: function() - { - if (debug) messages.debug("1-shot initializing dataTables content with " + this.buffered_lines.length + " lines"); - this.table.fnAddData (this.buffered_lines); - this.buffered_lines=[]; - - var self = this; - // if we've already received the slice query, we have not been able to set - // checkboxes on the fly at that time (dom not yet created) - $.each(this.buffered_records_to_check, function(i, record) { - if (debug) messages.debug ("querytable delayed turning on checkbox " + i + " record= " + record); - self.set_checkbox_from_record(record, true); - }); - this.buffered_records_to_check = []; - - this.received_all_query = true; - // unspin once we have received both - if (this.received_all_query && this.received_query) this.unspin(); - - }, // on_all_query_done - /************************** PRIVATE METHODS ***************************/ /** @@ -598,10 +695,10 @@ was in fact given as a third argument, and not second as the various online resources had it - go figure */ $.fn.dataTableExt.afnSortData['dom-checkbox'] = function ( oSettings, _, iColumn ) { - return $.map( oSettings.oApi._fnGetTrNodes(oSettings), function (tr, i) { - return result=$('td:eq('+iColumn+') input', tr).prop('checked') ? '1' : '0'; - } ); - } + return $.map( oSettings.oApi._fnGetTrNodes(oSettings), function (tr, i) { + return result=$('td:eq('+iColumn+') input', tr).prop('checked') ? '1' : '0'; + }); + }; })(jQuery);