--- /dev/null
+from unfold.plugin import Plugin
+
+from django.template.loader import render_to_string
+
+# XXX We need naming helpers in the python Plugin class also, used in template
+
+class ColumnsEditor(Plugin):
+ def __init__ (self, query, query_all = None, **settings):
+ Plugin.__init__ (self, **settings)
+ self.query=query
+ self.query_uuid = query.query_uuid
+ self.query_all = query_all
+ self.query_all_uuid = query_all.query_uuid if query_all else None
+
+ def template_file(self):
+ return "columns_editor.html"
+
+ def requirements (self):
+ reqs = {
+ 'js_files' : [
+ # XXX datatables
+ 'js/columns_editor.js',
+ ] ,
+ 'css_files': [
+ 'css/query_editor.css',
+ 'css/jquery-ui.css',
+ ]
+ }
+ return reqs
+
+ def export_json_settings (self):
+ return True
+
+ def template_env(self, request):
+ fields = []
+ #hidden_columns = self.hidden_columns
+ metadata = self.page.get_metadata()
+ md_fields = metadata.details_by_object('resource')
+
+ # XXX use django templating system here
+ for md_field in md_fields['column']:
+ if md_field['type'] == 'string':
+ if 'allowed_values' in md_field:
+ allowed_values = md_field['allowed_values'].split(',')
+
+ options = []
+ for v in allowed_values:
+ v_desc = v.split('-')
+ options.append(v_desc[0])
+
+ env = {
+ 'domid': self.domid,
+ 'options': options
+ }
+ filter_input = render_to_string('filter_input_string_values.html', env)
+ else:
+ env = {
+ 'domid': self.domid,
+ 'field': md_field['name']
+ }
+ filter_input = render_to_string('filter_input_string.html', env)
+
+ elif md_field['type'] == 'int':
+ allowed_values = md_field.get('allowed_values', '0,0').split(',')
+ env = {
+ 'domid': self.domid,
+ 'field': md_field['name'],
+ 'min' : allowed_values[0],
+ 'max' : allowed_values[1]
+ }
+ filter_input = render_to_string('filter_input_integer.html', env)
+ else:
+ env = {
+ 'domid': self.domid,
+ 'field': md_field['name']
+ }
+ filter_input = render_to_string('filter_input_others.html', env)
+
+ fields.append({
+ 'name': md_field['name'],
+ 'type': md_field['type'],
+ 'resource_type': 'N/A',
+ 'filter_input': filter_input,
+ 'header': None,
+ 'checked': md_field['name'] in self.query.get_select()
+ })
+ #return { 'fields': fields, 'hidden_columns': hidden_columns }
+ #return { 'fields': fields , 'query_uuid': self.query_uuid, 'query_all_uuid': self.query_all_uuid }
+ return { 'fields': fields }
+
+ def json_settings_list (self): return ['plugin_uuid', 'domid', 'query_uuid', 'query_all_uuid', ]
--- /dev/null
+div.query-editor-spacer {
+ padding: 15px 5px;
+}
+
+table.query-editor {
+ width: 95%;
+ padding-bottom: 10px;
+}
+
+/* Add a scrollbar to autocomplete fields */
+.ui-autocomplete {
+ max-height: 100px;
+ overflow-y: auto;
+ /* prevent horizontal scrollbar */
+ overflow-x: hidden;
+ /* add padding to account for vertical scrollbar */
+ padding-right: 20px;
+
+ /* NEED TO BE IMPROVED LATER... */
+ /* How to use properties from content class in /templates/myslice/css/myslice.css ? */
+ /* How to factorize this ? Maybe applied differently in other plugins ? */
+ font-size: 11px;
+}
+.queryeditor-auto-filter{
+ width:200px;
+}
+/* IE 6 doesn't support max-height
+ * we use height instead, but this forces the menu to always be this tall
+ */
+* html .ui-autocomplete {
+ height: 100px;
+}
+
+table.query-editor {
+ margin: 0 auto;
+ clear: both;
+ /* width: 80%;*/
+ width: 300px;
+}
+
+table.query-editor input {
+ font: normal 12px "Trebuchet MS", Verdana, Arial, Helvetica, sans-serif;
+}
+
+table.query-editor thead th {
+ padding: 3px 18px 3px 3px;
+ border-bottom: 1px solid black;
+ font-weight: bold;
+ cursor: pointer;
+ * cursor: hand;
+}
+
+table.query-editor tfoot th {
+ padding: 3px 18px 3px 10px;
+ border-top: 1px solid black;
+ font-weight: bold;
+}
+
+table.query-editor td {
+ padding: 2px 5px;
+ font: normal 12px "Trebuchet MS", Verdana, Arial, Helvetica, sans-serif;
+}
+
+table.query-editor td.center, table.query-editor th.center {
+ text-align: center;
+}
+
+
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * DataTables row classes
+ */
+table.query-editor tr.odd.gradeA {
+ background-color: #ddffdd;
+}
+
+table.query-editor tr.even.gradeA {
+ background-color: #eeffee;
+}
+
+table.query-editor tr.odd.gradeC {
+ background-color: #ddddff;
+}
+
+table.query-editor tr.even.gradeC {
+ background-color: #eeeeff;
+}
+
+table.query-editor tr.odd.gradeX {
+ background-color: #ffdddd;
+}
+
+table.query-editor tr.even.gradeX {
+ background-color: #ffeeee;
+}
+
+table.query-editor tr.odd.gradeU {
+ background-color: #ddd;
+}
+
+table.query-editor tr.even.gradeU {
+ background-color: #eee;
+}
+
+/* change color: T / even -> odd +1 +5 -3*/
+table.query-editor tr.odd.row_sliver td {
+ background-color: #9FAFD1;
+}
+
+table.query-editor tr.even.row_added td {
+ background-color: #b1d19f;
+}
+table.query-editor tr.odd.row_added td {
+ background-color: #a3c98f;
+}
+
+table.query-editor tr.even.row_removed td {
+ background-color: #d9b0b0;
+}
+
+table.query-editor tr.odd.row_removed td {
+ background-color: #d1a09f;
+}
+
+table.query-editor tr.gradeA {
+ background-color: #eeffee;
+}
+
+table.query-editor tr.gradeC {
+ background-color: #ddddff;
+}
+
+table.query-editor tr.gradeX {
+ background-color: #ffdddd;
+}
+
+table.query-editor tr.gradeU {
+ background-color: #ddd;
+}
+
+
+
+
+div.selected{background-color:gray; color:black}
+
+/* icons */
+.myslice-icon-timestamp {
+ background-image: url('images/myslice-icon-timestamp.png') !important;
+}
+.myslice-icon-filter {
+ background-image: url('images/myslice-icon-filter.png') !important;
+}
+.myslice-icon-fields {
+ background-image: url('images/myslice-icon-fields.png') !important;
+}
+.myslice-icon-groups {
+ background-image: url('images/myslice-icon-groups.png') !important;
+}
+.myslice-icon-summary {
+ background-image: url('images/myslice-icon-summary.png') !important;
+}
+.myslice-icon-resources {
+ background-image: url('images/myslice-icon-resources.png') !important;
+}
+.myslice-icon-users {
+ background-image: url('images/myslice-icon-users.png') !important;
+}
+
+a.source-url{
+ font-weight: bold;
+}
+
+span.bold {
+ font-weight: bold;
+}
+
+div#selectdescr {
+ padding-top:2em;
+ color: #555555;
+}
+
+span.short {
+ height:10px;
+}
+
+span.column-title {
+ font-size: 15px;
+ font-weight: bold;
+}
+
+span.column-detail {
+ font-size: 11px;
+ font-style: italic;
+}
+
+span.group_info {
+ font-size: 11px;
+ color: green;
+ font-weight: bold;
+}
+
+span.filter_info {
+ color: red;
+ font-weight: bold;
+}
+
+
+/* column configuation style */
+
+OPTION.out{
+ background-color:white;
+ color:black;
+}
+OPTION.in{
+ background-color:#CAE8EA;
+ color:#4f6b72;
+}
+
+/* jordan disabled
+ div.out{background-color:white; color:black}
+ div.in{background-color:#CAE8EA; color:#4f6b72}
+ div.selected{background-color:gray; color:black}
+ div.invisible{display:none}
+ */
+
+div.note-div {
+ padding: 4px;
+ background-color: #cae8ea;
+ width: 800px;
+ margin-left:auto;
+ margin-right:auto;
+}
+
+div#scrolldiv_old {
+ border : solid 2px grey;
+ padding:4px;
+ width:300px;
+ height:180px;
+ overflow:auto;
+}
+
+th,td.top {
+ vertical-align: top;
+ text-align: left;
+ padding:10px;
+}
+
+tr.hidden {
+ display:none;
+}
+
+td.smallright {
+ text-align: right;
+ width:20px;
+}
+
+table.center {
+ margin-left:auto;
+ margin-right:auto;
+}
+
+table.columnlist {
+ width:270px;
+}
+
+table.query-editor td.header {
+ background-color: #CAE8EA;
+ text-align: center;
+ width:30px;
+}
+
+span.header {
+ font-weight: bold;
+ color: #3399CC;
+}
+
+a.source-url{
+ font-weight: bold;
+}
+
+span.menubig {
+ font-size: 16px;
+ font-weight: bold;
+}
+
+span.menusmall {
+ font-size: 14px;
+ font-weight: bold;
+}
+
+span.menuright {
+ font-weight: bold;
+ float: right;
+}
+
+span.simpleright {
+ float: right;
+}
+
+span.gray{
+ color: #555555;
+}
+
+span.short {
+ height:10px;
+}
+
+span.column-title {
+ font-size: 13px;
+ font-weight: bold;
+}
+
+span.column-detail {
+ font-size: 11px;
+ font-style: italic;
+}
+
+span.myslice_small {
+ font-size: 11px;
+}
+
+span#username {
+ font-weight: bold;
+ font-size: 1.3em;
+}
+
+.filter_popup{
+ position:relative; /*this is the key*/
+ float: right;
+ z-index:24;
+ background: url('images/myslice-icon-filter.png') no-repeat;
+ /*background-color:#ccc;*/
+ width: 200px;
+ height: 300px;
+ color:#000;
+ text-decoration:none;
+ clear: both;
+}
+
+.filter_popup:hover{
+ z-index:25;
+/*background-color:#ff0*/
+}
+
+.filter_popup span{
+ display: none;
+}
+
+.filter_popup:hover span{ /*the span will display just on :hover state*/
+ display:block;
+ position:absolute;
+ /*top:1em;*/
+ left:-19em;
+ width: 20em;
+ font-size: 8pt;
+ border:1px solid #ccdddd;
+ background-color:#ddeeee;
+ color:#000;
+ text-align: left;
+ padding: 0em 0em 0em 1em;
+}
--- /dev/null
+/**
+ * Description: ColumnsEditor plugin
+ * Copyright (c) 2012-2013 UPMC Sorbonne Universite
+ * License: GPLv3
+ */
+
+// XXX TODO This plugin will be interested in changes in metadata
+// What if we remove a filter, is it removed in the right min/max field ???
+// -> no on_filter_removed is not yet implemented
+// XXX if a plugin has not declared a handler, it might become inconsistent,
+// and the interface should either reset or disable it
+(function($){
+
+ var ColumnsEditor = Plugin.extend({
+
+ event_filter_added: function(op, suffix) {
+ suffix = (typeof suffix === 'undefined') ? '' : manifold.separator + suffix;
+ var self = this;
+ return function(e, ui) {
+ var array = self.array_from_id(e.target.id);
+ var key = self.field_from_id(array); // No need to remove suffix...
+
+ // using autocomplete ui
+ if(typeof(ui) != "undefined"){
+ var value = ui.item.value;
+ }else{
+ var value = e.target.value;
+ }
+
+ if (value) {
+ // XXX This should be handled by manifold
+ //manifold.raise_event(object.options.query_uuid, FILTER_UPDATED, [key, op, value]);
+ manifold.raise_event(self.options.query_uuid, FILTER_ADDED, [key, op, value]);
+ } else {
+ // XXX This should be handled by manifold
+ manifold.raise_event(self.options.query_uuid, FILTER_REMOVED, [key, op]);
+ }
+ };
+ },
+
+ init: function(options, element) {
+ this._super(options, element);
+ this.listen_query(options.query_uuid);
+ // this one is the complete list of resources
+ // and will be bound to callbacks like on_all_new_record
+ this.listen_query(options.query_all_uuid, 'all');
+
+
+ this.elts('queryeditor-auto-filter').change(this.event_filter_added('='));
+ this.elts('queryeditor-filter').change(this.event_filter_added('='));
+ this.elts('queryeditor-filter-min').change(this.event_filter_added('>'));
+ this.elts('queryeditor-filter-max').change(this.event_filter_added('<'));
+
+ var self = this;
+ this.elts('queryeditor-check').click(function() {
+ manifold.raise_event(self.options.query_uuid, this.checked?FIELD_ADDED:FIELD_REMOVED, this.value);
+ });
+
+ /* The following code adds an expandable column for the table
+ // XXX Why isn't it done statically ?
+ var nCloneTh = document.createElement( 'th' );
+ var nCloneTd = document.createElement( 'td' );
+ nCloneTd.innerHTML = "<span class='glyphicon glyphicon-chevron-right' style='cursor:pointer'></span>";
+ //nCloneTd.innerHTML = '<img src="/components/com_tophat/images/details_open.png">';
+ nCloneTh.innerHTML = '<b>Info</b>';
+ nCloneTd.className = "center";
+ nCloneTh.className = "center";
+ this.elmt('table thead tr').each(function() {
+ this.insertBefore(nCloneTh, this.childNodes[0]);
+ });
+ this.elmt('table tbody tr').each(function() {
+ this.insertBefore(nCloneTd.cloneNode( true ), this.childNodes[0]);
+ });
+ */
+
+ // We are currently using a DataTable display, but another browsing component could be better
+ //jQuery('#'+this.options.plugin_uuid+'-table').dataTable...
+ /*
+ var metaTable = this.elmt('table').dataTable({
+// Thierry : I'm turning off all the dataTables options for now, so that
+// the table displays more properly again, might need more tuning though
+// bFilter : false,
+// bPaginate : false,
+// bInfo : false,
+// sScrollX : '100%', // Horizontal scrolling
+// sScrollY : '200px',
+// //bJQueryUI : true, // Use jQuery UI
+// bProcessing : true, // Loading
+// aaSorting : [[ 1, "asc" ]], // sort by column fields on load
+// aoColumnDefs: [
+// { 'bSortable': false, 'aTargets': [ 0 ]},
+// { 'sWidth': '8px', 'aTargets': [ 0 ] },
+// { 'sWidth': '8px', 'aTargets': [ 4 ] } // XXX NB OF COLS
+// ]
+ });
+ this.table = metaTable;
+ */
+ this.table = this.elmt('table');
+
+ // Actions on the newly added fields
+ this.elmt('table tbody td span').on('click', function() {
+ var nTr = this.parentNode.parentNode;
+ // use jQuery UI instead of images to keep a common UI
+ // class="glyphicon glyphicon-chevron-down treeclick tree-minus"
+ // East oriented Triangle class="glyphicon-chevron-right"
+ // South oriented Triangle class="glyphicon-chevron-down"
+
+ if (this.hasClass("glyphicon-chevron-right")) {
+ this.removeClass("glyphicon-chevron-right").addClass("glyphicon-chevron-down");
+ // XXX ??????
+ metaTable.fnOpen(nTr, this.fnFormatDetails(metaTable, nTr, self.options.plugin_uuid+'_div'), 'details' );
+ } else {
+ this.removeClass("glyphicon-chevron-down").addClass("glyphicon-chevron-right");
+ metaTable.fnClose(nTr);
+ }
+ });
+
+ this.elmt('table_wrapper').css({
+ 'padding-top' : '0em',
+ 'padding-bottom': '0em'
+ });
+
+ // autocomplete list of tags
+ this.availableTags = {};
+
+ }, // init
+
+ /* UI management */
+
+ check_field: function(field)
+ {
+ this.elmt('check', field).attr('checked', true);
+ },
+
+ uncheck_field: function(field)
+ {
+ this.elmt('check', field).attr('checked', false);
+ },
+
+ update_filter_value: function(filter, removed)
+ {
+ removed = !(typeof removed === 'undefined'); // default = False
+
+ var key = filter[0];
+ var op = filter[1];
+ var value = filter[2];
+
+ var id = this.id_from_field(key);
+
+ if (op == '=') {
+ var element = this.elmt(id);
+ } else {
+ var suffix;
+ if (op == '<') {
+ this.elmt(id, 'max').val(value);
+ } else if (op == '>') {
+ this.elmt(id, 'min').val(value);
+ } else {
+ return;
+ }
+ var element = this.elmt(id, suffix);
+ }
+
+ element.val(removed?null:value);
+
+ },
+
+ /* Events */
+
+ on_filter_added: function(filter)
+ {
+ this.update_filter_value(filter);
+ },
+
+ on_filter_removed: function(filter)
+ {
+ this.update_filter_value(filter, true);
+ },
+
+ on_field_added: function(field)
+ {
+ this.check_field(field);
+ },
+
+ on_field_removed: function(field)
+ {
+ this.uncheck_field(field);
+ },
+
+ /* RECORD HANDLERS */
+ on_query_done: function()
+ {
+ //console.log("Query_Editor: query_done!");
+ //console.log(this.availableTags);
+ },
+ /* Autocomplete based on query_all to get all the fields, where query get only the fields selected */
+ on_all_new_record: function(record)
+ {
+ /*
+ availableTags = this.availableTags;
+ jQuery.each(record,function(key,value){
+ value = unfold.get_value(value);
+ if(!availableTags.hasOwnProperty(key)){availableTags[key]=new Array();}
+ //availableTags[key].push(value);
+ var currentArray = availableTags[key];
+ if(value!=null){
+ if(jQuery.inArray(value,currentArray)==-1){availableTags[key].push(value);}
+ }
+ });
+ this.availableTags = availableTags;
+ this.update_autocomplete(availableTags);
+ */
+ },
+
+ /* Former code not used at the moment */
+
+ print_field_description: function(field_header, div_id)
+ {
+ //var selected = all_headers[field_header];
+ var selected = getMetadata_field('resource',field_header);
+
+ field_header = div_id+"_"+field_header;
+
+ var output = "<div id='desc"+field_header+"'>";
+
+ output += "<div id='divinfo"+field_header+"'>";
+ output += '<p><span class="column-title">'+selected['title']+'</span></p></span>';
+ output += '<p><span class="column-detail">'+selected['description']+'</span></p></span>';
+
+ var period_select = "<select id='selectperiod"+field_header+"'><option value='Now'> Now </option><option value='latest'> Latest </option><option value=w> Week </option><option value=m> Month </option><option value=y> Year </option></select>";
+
+ if (selected['value_type'] == 'string') {
+
+ var values_select = "<p><select id='selectvalues"+field_header+"' MULTIPLE size=3>";
+
+ output += '<p>Values: ';
+
+ var values_list = selected['allowed_values'].split(",");
+
+ for (var value_index = 0; value_index < values_list.length ; value_index++) {
+ var value_desc = values_list[value_index].split("-");
+ if (value_index > 0)
+ output += ', ';
+ output += '<span class="bold">'+value_desc[0]+'</span>';
+ values_select += "<option value ='"+value_desc[0]+"'> "+value_desc[0];
+ if (value_desc[1]!='')
+ output += ' ('+value_desc[1]+')';
+
+ values_select += " </option>";
+ }
+ values_select += "</select>";
+ }
+ else
+ output+='<p>Unit: '+selected['unit'];
+
+ output+= '</p>';
+
+ output += '<p>Source: <a class="source-url" target="source_window" href="'+selected['platform_url']+'">'+selected['platform']+'</a>';
+
+ //if (selected['via'] != '')
+ //output += ' via <a class="source-url" target="source_window" href="http://'+selected['via_url']+'">'+selected['via']+'</a>';
+
+ output += '</p>';
+ output += "</div>";
+
+ /*
+ output += "<div id='divgroup"+field_header+"'>";
+ output += "<p>Group resources with the same value <input type=checkbox></input>";
+ output += "<p>Select aggregator : <select><option>Count</option><option selected=true>Average</option><option>Maximum</option><option>Minimum</option></select>";
+ output += "</div>";
+ output += "<div id='divtime"+field_header+"'>";
+ output += "<p>Select timestamp : ";
+ output += period_select;
+ output += "</div>";
+ */
+ output += "</div>";
+
+ return output;
+ },
+
+ update_autocomplete: function(availableTags)
+ {
+ var self = this;
+ var domid = this.options.plugin_uuid;
+
+ jQuery.each(availableTags, function(key, value){
+ value.sort();
+ // using dataTables's $ to search also in nodes that are not currently displayed
+ var element = self.table.$("#"+domid+"__field__"+key);
+
+ element.autocomplete({
+ source: value,
+ selectFirst: true,
+ minLength: 0, // allows to browse items with no value typed in
+ select: self.event_filter_added('=')
+ });
+ });
+ }, // update_autocomplete
+
+/*
+ update_autocomplete: function(e, rows, current_query)
+ {
+ var d = data;
+ d.current_query = current_query;
+ var availableTags={};
+ jQuery.each (rows, function(index, obj) {
+ jQuery.each(obj,function(key,value){
+ value = unfold.get_value(value);
+ if(!availableTags.hasOwnProperty(key)){availableTags[key]=new Array();}
+ //availableTags[key].push(value);
+ var currentArray=availableTags[key];
+ if(value!=null){
+ if(jQuery.inArray(value,currentArray)==-1){availableTags[key].push(value);}
+ }
+ });
+ });
+ jQuery.each(availableTags, function(key, value){
+ value.sort();
+ jQuery("#"+options.plugin_uuid+"-filter-"+key).autocomplete({
+ source: value,
+ selectFirst: true,
+ minLength: 0, // allows to browse items with no value typed in
+ select: function(event, ui) {
+ var key=getKeySplitId(this.id,"-");
+ var op='=';
+ var val=ui.item.value;
+
+ query=d.current_query;
+ query.update_filter(key,op,val);
+ // Publish the query changed, the other plugins with subscribe will get the changes
+ jQuery.publish('/query/' + query.uuid + '/changed', query);
+ //add_ActiveFilter(this.id,'=',ui.item.value,d);
+ }
+ });
+ });
+ }, // update_autocomplete
+*/
+ fnFormatDetails: function( metaTable, nTr, div_id )
+ {
+ var aData = metaTable.fnGetData( nTr );
+ var sOut = '<blockquote>';
+ //sOut += prepare_tab_description(aData[1].substr(21, aData[1].length-21-7), div_id);
+ sOut += this.print_field_description(aData[1].substring(3, aData[1].length-4), div_id);
+ sOut += '</blockquote>';
+
+ return sOut;
+ }
+ });
+
+ $.plugin('ColumnsEditor', ColumnsEditor);
+
+})(jQuery);
--- /dev/null
+<!--
+ $infopopup = <<<EOF
+<span class='info'><span> This tab allows you to customize the visible columns in the resource list, below. Note that information on the nodes comes from a variety of monitoring sources. If you, as either a user or a provider of monitoring data, would like to see additional columns made available, please send us your request in mail to <a href='mailto:support@myslice.info'>support@myslice.info</a>. You can find more information about the MySlice project at <a href='http://trac.myslice.info'>http://trac.myslice.info</a>. </span></span>
+EOF;
+
+ $filter_input = "<input id='filter_value' type=text size=5></input>";
+
+EOF; -->
+<div class='query-editor-spacer'>
+ <table id='{{domid}}__table' class='query-editor'>
+ <thead>
+ <tr>
+ <th class='center'>Info</th>
+ <th class='center'>Field</th>
+ <!--
+ <th class='center'>Resource</th>
+ <th class='center'>Type</th>
+ <th class='center'>Filter</th>
+ -->
+ <th class='center'>+/-</th>
+ </tr>
+ </thead>
+ <tbody>
+
+ {# Loop through metadata and display related information #}
+ {% for field in fields %}
+
+ <tr>
+ <td class='center'><span class='glyphicon glyphicon-chevron-right' style='cursor:pointer'></span></td>
+ <td class='center'>{{ field.name }}</td>
+ <!--
+ <td class='center'>{{ field.resource_type }}</td>
+ <td class='center'>{{ field.type }}</td>
+ <td class='center'>{{ field.filter_input }}</td>
+ -->
+ <td class='center'>
+ <input class='queryeditor-check' id='{{domid}}__check__{{ field.name }}' name='{{ field.header }}' type='checkbox' autocomplete='off' value='{{ field.name }}' {% if field.checked %} checked {% endif %}></input>
+ </td>
+ </tr>
+
+ {% endfor %}
+
+ </tbody>
+ </table>
+</div>
--- /dev/null
+<div class="ui-widget content" style="margin-top:0px;">
+<label for='{{field}}'></label>
+<input class='queryeditor-filter-min' id='{{domid}}__field__{{field}}__min' type=text size=3 value='{{ min }}'></input> -
+<input class='queryeditor-filter-max' id='{{domid}}__field__{{field}}__max' type=text size=3 value='{{ max }}'></input>
+</div>
--- /dev/null
+<div class='ui-widget content' style='margin-top:0px;'>
+ <label for='{{field}}'></label>
+ <input class='queryeditor-auto-filter' id='{{domid}}__field__{{field}}' type='text' style='width:206px;'></input>
+</div>
--- /dev/null
+<div class='ui-widget content' style='margin-top:0px;'>
+ <label for='{{domid}}__field__{{field}}'></label>
+ <input class='queryeditor-auto-filter' id='{{domid}}__field__{{field}}' type='text' style='width:206px;'></input>
+</div>
--- /dev/null
+<select class='queryeditor-filter' id='$filter_id'>
+ <option value=''>Show all</option>
+ {% for option in options %}
+ <option>{{option}}</option>
+ {% endfor %}
+</select>
from plugins.queryupdater import QueryUpdater
from plugins.testbeds import TestbedsPlugin
from plugins.scheduler2 import Scheduler2
+from plugins.columns_editor import ColumnsEditor
from myslice.theme import ThemeView
query_all_lease = Query.get('lease').select(lease_fields)
page.enqueue_query(query_all_lease)
- print "!!!!!!!!!! query leases = ",query_all_lease
-
# --------------------------------------------------------------------------
- # RESOURCES LIST
+ # ALL RESOURCES LIST
# resources as a list using datatable plugin
list_resources = QueryTable(
},
)
+
+ # --------------------------------------------------------------------------
+ # RESERVED RESOURCES LIST
+ # resources as a list using datatable plugin
+
+ list_reserved_resources = QueryTable(
+ page = page,
+ domid = 'resources-reserved-list',
+ title = 'List view',
+ query = sq_resource,
+ query_all = sq_resource,
+ init_key = "urn",
+ checkboxes = True,
+ datatables_options = {
+ 'iDisplayLength': 25,
+ 'bLengthChange' : True,
+ 'bAutoWidth' : True,
+ },
+ )
+
+ # --------------------------------------------------------------------------
+ # COLUMNS EDITOR
+ # list of fields to be applied on the query
+ # this will add/remove columns in QueryTable plugin
+
+ filter_column_editor = ColumnsEditor(
+ page = page,
+ query = sq_resource,
+ query_all = query_resource_all,
+ title = "Select Columns",
+ domid = 'select-columns',
+ )
+
# --------------------------------------------------------------------------
# RESOURCES MAP
# the resources part is made of a Tabs (Geographic, List),
template_env = {}
template_env['list_resources'] = list_resources.render(self.request)
+ template_env['list_reserved_resources'] = list_reserved_resources.render(self.request)
+
+ template_env['columns_editor'] = filter_column_editor.render(self.request)
+
template_env['filter_testbeds'] = filter_testbeds.render(self.request)
template_env['map_resources'] = map_resources.render(self.request)
template_env['scheduler'] = resources_as_scheduler2.render(self.request)
<div class="list-group-item list-resources">
<span class="list-group-item-heading">Resources</span>
<a class="list-group-item" data-panel="resources" href="#">All</a>
- <a class="list-group-item" data-panel="resources" href="#">Reserved</a>
+ <a class="list-group-item" data-panel="reserved" href="#">Reserved</a>
<a class="list-group-item" data-panel="pending" href="#">Pending <span class="badge" id="badge-pending" data-number="0"></span></a>
</div>
<li id="Scheduler"><a data-panel="scheduler-tab" href="#">Scheduler</a></li>
</ul>
</div>
+ <div class="row" style="height:100%;display:none;">
+ {{columns_editor}}
+ </div>
<div class="row" style="height:100%;">
<div id="resources" class="panel">
{{list_resources}}
<!-- <table cellpadding="0" cellspacing="0" border="0" class="table" id="objectList"></table> -->
</div>
+ <div id="reserved" class="panel" style="height:370px;display:none;">
+ {{list_reserved_resources}}
+ </div>
<div id="map" class="panel" style="height:370px;display:none;">
{{map_resources}}
</div>