plugins: updated resource selected to receive proper updates from the query
authorJordan Augé <jordan.auge@lip6.fr>
Wed, 14 Aug 2013 12:27:02 +0000 (14:27 +0200)
committerJordan Augé <jordan.auge@lip6.fr>
Wed, 14 Aug 2013 12:27:02 +0000 (14:27 +0200)
manifold/js/manifold.js
manifold/js/plugin.js
plugins/resources_selected/__init__.py
plugins/resources_selected/static/js/resources_selected.js
plugins/resources_selected/static/resources_selected.html
trash/pluginview.py
trash/sliceview.py

index abbd6e6..a59fa10 100644 (file)
@@ -28,6 +28,7 @@ var FIELD_REMOVED  = 5;
 var CLEAR_FIELDS   = 6;
 var NEW_RECORD     = 7;
 var CLEAR_RECORDS  = 8;
+var FIELD_STATE_CHANGED = 9;
 
 var IN_PROGRESS    = 101;
 var DONE           = 102;
@@ -37,6 +38,15 @@ var SET_ADD        = 201;
 var SET_REMOVED    = 202;
 var RUN_UPDATE     = 203;
 
+// request
+var FIELD_REQUEST_CHANGE  = 301;
+var FIELD_REQUEST_ADD     = 302;
+var FIELD_REQUEST_REMOVE  = 303;
+// status
+var FIELD_REQUEST_PENDING = 301;
+var FIELD_REQUEST_SUCCESS = 302;
+var FIELD_REQUEST_FAILURE = 303;
+
 /* Query status */
 var STATUS_NONE               = 500; // Query has not been started yet
 var STATUS_GET_IN_PROGRESS    = 501; // Query has been sent, no result has been received
@@ -48,6 +58,7 @@ var STATUS_UPDATE_RECEIVED    = 506;
 var STATUS_UPDATE_ERROR       = 507;
 // outdated ?
 
+
 // A structure for storing queries
 
 
@@ -539,13 +550,39 @@ var manifold = {
         query = query_ext.query;
 
         switch(event_type) {
+            case FIELD_STATE_CHANGED:
+                // value is an object (request, key, value, status)
+                // update is only possible is the query is not pending, etc
+                // SET_ADD is on a subquery, FIELD_STATE_CHANGED on the query itself
+                // we should map SET_ADD on this...
+
+                // 1. Update internal query store about the change in status
+
+                // 2. Update the update query
+                update_query = query_ext.main_query_ext.update_query_ext.query;
+                update_query.params[value.key].push(value.value);
+
+                // 3. Inform others about the change
+                // a) the main query...
+                manifold.raise_record_event(query_uuid, event_type, value);
+
+                // b) subqueries eventually (dot in the key)
+                // XXX make this DOT a global variable... could be '/'
+                break;
+
             case SET_ADD:
+            case SET_REMOVED:
+    
                 // update is only possible is the query is not pending, etc
                 // CHECK status !
 
                 // XXX we can only update subqueries of the main query. Check !
                 // assert query_ext.parent_query == query_ext.main_query
-                update_query = query_ext.main_query_ext.update_query_ext.query;
+                // old // update_query = query_ext.main_query_ext.update_query_ext.query;
+
+                // This SET_ADD is called on a subquery, so we have to
+                // recontruct the path of the key in the main_query
+                // We then call FIELD_STATE_CHANGED which is the equivalent for the main query
 
                 var path = "";
                 var sq = query_ext;
@@ -556,8 +593,17 @@ var manifold = {
                     sq = sq.parent_query_ext;
                 }
 
-                update_query.params[path].push(value);
-                console.log('Updated query params', update_query);
+                main_query = query_ext.main_query_ext.query;
+                data = {
+                    request: (event_type == SET_ADD) ? FIELD_REQUEST_ADD : FIELD_REQUEST_REMOVE,
+                    key   : path,
+                    value : value,
+                    status: FIELD_REQUEST_PENDING,
+                };
+                this.raise_event(main_query.query_uuid, FIELD_STATE_CHANGED, data);
+
+                // old //update_query.params[path].push(value);
+                // old // console.log('Updated query params', update_query);
                 // NOTE: update might modify the fields in Get
                 // NOTE : we have to modify all child queries
                 // NOTE : parts of a query might not be started (eg slice.measurements, how to handle ?)
@@ -566,11 +612,9 @@ var manifold = {
                 // object = the same as get
                 // filter = key : update a single object for now
                 // fields = the same as get
+                manifold.raise_query_event(query_uuid, event_type, value);
 
                 break;
-            case SET_REMOVED:
-                // Query uuid has been updated with the key of a removed element
-                break;
 
             case RUN_UPDATE:
                 update_query = query_ext.main_query_ext.update_query_ext.query;
@@ -579,8 +623,10 @@ var manifold = {
                 break;
 
             case FILTER_ADDED:
+                manifold.raise_query_event(query_uuid, event_type, value);
                 break;
             case FILTER_REMOVED:
+                manifold.raise_query_event(query_uuid, event_type, value);
                 break;
             case FIELD_ADDED:
                 main_query = query_ext.main_query_ext.query;
@@ -595,6 +641,7 @@ var manifold = {
                 // XXX When is an update query associated ?
                 // XXX main_update_query.select(value);
 
+                manifold.raise_query_event(query_uuid, event_type, value);
                 break;
 
             case FIELD_REMOVED:
index b72cc30..85b2478 100644 (file)
@@ -94,6 +94,9 @@ var Plugin = Class.extend({
             case DONE:
                 fn = 'query_done';
                 break;
+            case FIELD_STATE_CHANGED:
+                fn = 'field_state_changed';
+                break;
             default:
                 return;
         } // switch
index 606a6d8..a5bbac7 100644 (file)
@@ -13,7 +13,7 @@ class ResourcesSelected(Plugin):
         return reqs
 
     def json_settings_list (self):
-        return ['plugin_uuid', 'domid', 'resource_query_uuid', 'lease_query_uuid']
+        return ['plugin_uuid', 'domid', 'query_uuid']
 
     def export_json_settings (self):
         return True
index 77d023c..18b61fd 100644 (file)
  * License: GPLv3
  */
 
-/*
- * It's a best practice to pass jQuery to an IIFE (Immediately Invoked Function
- * Expression) that maps it to the dollar sign so it can't be overwritten by
- * another library in the scope of its execution.
- */
 (function( $ ){
 
-    var PLUGIN_NAME = 'ResourcesSelected';
-
-    // Routing calls
-    jQuery.fn.ResourcesSelected = function( method ) {
-        if ( methods[method] ) {
-            return methods[ method ].apply( this, Array.prototype.slice.call( arguments, 1 ));
-        } else if ( typeof method === 'object' || ! method ) {
-            return methods.init.apply( this, arguments );
-        } else {
-            jQuery.error( 'Method ' +  method + ' does not exist on jQuery.' + PLUGIN_NAME );
-        }    
-
-    };
-
-    /***************************************************************************
-     * Public methods
-     ***************************************************************************/
-
-    var methods = {
-
-        /**
-         * @brief Plugin initialization
-         * @param options : an associative array of setting values
-         * @return : a jQuery collection of objects on which the plugin is
-         *     applied, which allows to maintain chainability of calls
-         */
-        init : function( options ) {
-
-            return this.each(function(){
-
-                var $this = $(this);
-
-                /* An object that will hold private variables and methods */
-                var plugin = new ResourcesSelected(options);
-                $(this).data('Manifold', plugin);
-
-                //$this.set_query_handler(options.query_uuid, hazelnut.query_handler);
-                //$this.set_record_handler(options.query_uuid, hazelnut.record_handler); 
-
-                //var RESULTS_RESOURCES = '/results/' + options.resource_query_uuid + '/changed';
-                //var UPDATE_RESOURCES  = '/update-set/' + options.resource_query_uuid;
-                //$.subscribe(RESULTS_RESOURCES, function(e, resources) { s.set_resources(resources);    });
-                //$.subscribe(UPDATE_RESOURCES,  function(e, resources, change) { s.update_resources(resources, change); });
-                
-            }); // this.each
-        }, // init
-
-        /**
-         * @brief Plugin destruction
-         * @return : a jQuery collection of objects on which the plugin is
-         *     applied, which allows to maintain chainability of calls
-         */
-        destroy : function( ) {
-
-            return this.each(function() {
-                var $this = $(this);
-                var plugin = $this.data('Manifold');
-
-                // Remove associated data
-                plugin.remove();
-                $this.removeData('Manifold');
-            });
-        }, // destroy
-
-    }; // var methods
-
-    /***************************************************************************
-     * Plugin object
-     ***************************************************************************/
-
-    function ResourcesSelected(options)
-    {
-        /* member variables */
-        this.options = options;
-        var object = this;
-
-        /* The resources that are in the slice */
-        this.current_resources = null;
-
-        /* The resources that are in the slice before any edit */
-        this.initial_resources = null;
-
-        var rs = this;
-
-        /* constructor */
-           // ioi: resources table id
-        var TABLE_NAME = '#table-' + options.plugin_uuid;
-        this.table = $(TABLE_NAME).dataTable({
-            //sPaginationType: 'full_numbers',  // Use pagination
-            sPaginationType: 'bootstrap',
-            //bJQueryUI: true,
-            //bRetrieve: true,
-            sScrollX: '100%',                 // Horizontal scrolling 
-            bSortClasses: false,              // Disable style for the sorted column
-            aaSorting: [[ 1, "asc" ]],        // Default sorting on URN
-            fnDrawCallback: function() {      // Reassociate close click every time the table is redrawn
-                /* Prevent to loop on click while redrawing table  */
-                jQuery('.ResourceSelectedClose').unbind('click');
-                /* Handle clicks on close span */
-                /* Reassociate close click every time the table is redrawn */
-                $('.ResourceSelectedClose').bind('click',{instance: rs}, object.close_click);
-            }
-         });
+    // XXX record selected (multiple selection ?)
+    // XXX record disabled ?
+    // XXX out of sync plugin ?
+    // XXX out of date record ?
+    // record tags ???
+    //
+    // criticality of the absence of a handler in a plugin
+    // non-critical only can have switch case
+    // 
+    // Record state through the query cycle
+
 
-        /* methods */
+    var ResourcesSelected = Plugin.extend({
 
-        this.set_resources = function(resources)
+        init: function(options, element)
         {
-            console.log("set_resources");
-            /* Some sanity checks on the API results */
-            if(resources.length==0){
-                this.table.html(errorDisplay("No Result"));   
-                return;
-            }
+            this._super(options, element);
+
+            var self = this;
+            this.table = this.el('table').dataTable({
+                //sPaginationType: 'full_numbers',  // Use pagination
+                sPaginationType: 'bootstrap',
+                //bJQueryUI      : true,
+                //bRetrieve      : true,
+                sScrollX       : '100%',                 // Horizontal scrolling 
+                bSortClasses   : false,              // Disable style for the sorted column
+                aaSorting      : [[ 0, 'asc' ]],        // Default sorting on URN
+                fnDrawCallback: function() {      // Reassociate close click every time the table is redrawn
+                    /* Prevent to loop on click while redrawing table  */
+                    $('.ResourceSelectedClose').unbind('click');
+                    /* Handle clicks on close span */
+                    /* Reassociate close click every time the table is redrawn */
+                    $('.ResourceSelectedClose').bind('click', self, self._close_click);
+                }
+             });
+            
+            this.listen_query(options.query_uuid);
+        },
 
-            if (typeof(resources[0].error) != 'undefined') {
-                this.table.html(errorDisplay(resources[0].error));
-                return;
+        /*************************** PLUGIN EVENTS ****************************/
+
+        /***************************** GUI EVENTS *****************************/
+        
+        // Move through the query cycle
+        // XXX 'update', 'refresh', 'reset' and 'remove annotation' button
+        // This is a query scheduler
+
+        /************************** GUI MANIPULATION **************************/
+
+        clear: function()
+        {
+
+        },
+
+        set_state: function(data)
+        {
+            var action;
+            var color;
+            var msg;
+            var button = '';
+
+            switch(data.request) {
+                case FIELD_REQUEST_CHANGE:
+                    action = 'UPDATE';
+                    break;
+                case FIELD_REQUEST_ADD:
+                    action = 'ADD';
+                    break;
+                case FIELD_REQUEST_REMOVE:
+                    action = 'REMOVE';
+                    break;
             }
 
-            /* Update the table with resources in the slice */
-            //var slivers = $.grep(resources, function(i) {return typeof(i['sliver']) != 'undefined';})
-            var slivers = resources;
-            var sliver_urns = Array();
-            // ioi : refubrished
-               $.each(resources, function(i, x) { sliver_urns.push({urn:x.urn, timeslot:"0"}); }); // ioi
-
-            this.initial_resources = sliver_urns; // We make a copy of the object // ioi
-               // ioi
-           
-            if (this.current_resources == null) {
-                this.current_resources = sliver_urns;
-
-                /* We simply add to the ResourceSelected table */
-                var newlines=Array();
-                $.each(sliver_urns, function(index, elt) {
-                    newlines.push(Array('attached', elt.urn, elt.timeslot, "<span class='ui-icon ui-icon-close ResourceSelectedClose' id='"+elt.urn+"'/>")); // ioi: added last element
-                });
-                this.table.dataTable().fnAddData(newlines);
-            } else {
-                alert('Slice updated. Refresh not yet implemented!');
+            switch(data.status) {
+                case FIELD_REQUEST_PENDING:
+                    msg   = 'PENDING';
+                    color = 'white';
+                    button = "<span class='ui-icon ui-icon-close ResourceSelectedClose' id='" + data.key + "'/>";
+                    break;
+                case FIELD_REQUEST_SUCCESS:
+                    msg   = 'SUCCESS';
+                    color = 'green';
+                    break;
+                case FIELD_REQUEST_FAILURE:
+                    msg   = 'FAILURE';
+                    color = 'red';
+                    break;
             }
-        }
 
-        this.update_resources = function(resources, change) {
+            var status = msg + color;
+
+            this.table.fnAddData([
+                action,
+                data.key,
+                data.value,
+                msg,
+                button
+            ]);
+            // XXX change cell color according to status
+        },
+
+        /*************************** QUERY HANDLER ****************************/
+
+        // NONE
+
+        /*************************** RECORD HANDLER ***************************/
+
+        on_new_record: function(record)
+        {
+            // if (not and update) {
+
+                // initial['resource'], initial['lease'] ?
+                this.initial.push(record.urn);
+
+                // We simply add to the table
+            // } else {
+                //                 \ this.initial_resources
+                //                  \
+                // this.             \
+                // current_resources  \    YES    |   NO
+                // --------------------+----------+---------
+                //       YES           | attached | added
+                //       NO            | removed  |   /
+                // 
+
+            // }
+        },
+
+        // QUERY STATUS
+        //                                      +-----------------+--------------+
+        //                                      v        R        |              |
+        // +-------+  ?G    +-------+        +-------+        +---+---+          |
+        // |       | -----> |       |  !G    |       |        |       |    DA    |
+        // |  ND   |        |  PG   | -----> |   D   | -----> |  PC   | <------+ |
+        // |       | <----- |       |  ~G    |       |   C    |       |        | | 
+        // +-------+   GE   +-------+        +-------+        +-------+      +------+
+        //                                       ^              ^  |         |      |
+        //                                       | DA        UE |  | ?U      | PCA  |
+        //                                       |              |  v         |      |
+        //                                   +-------+        +-------+      +------+
+        //                                   |       |   !U   |       |         ^
+        //                                   |  AD   | <----- |  PU   | --------+
+        //                                   |       |        |       |   ~U     
+        //                                   +-------+        +-------+          
+        //                                                                       
+        //
+        // LEGEND:
+        // 
+        // Plugins (i) receive state information, (ii) perform actions
+        //
+        // States:                                  Actions:
+        // ND : No data                             ?G : Get query
+        // PG : Pending Get                         !G : Get reply  
+        //  D : Data present                        ~G : Get partial reply
+        // PC : Pending changes                     GE : Get error                            
+        // PU : Pending update                       C : Change request
+        // PCA: Pending change with annotation       R : Reset request
+        // AD : Annotated data                      ?U : Update query
+        //                                          !U : Update reply
+        //                                          ~U : Update partial reply
+        //                                          UE : Update error            
+        //                                          DA : Delete annotation request
+        // NOTE:
+        // - D -> PU directly if the user chooses 'dynamic update'
+        // - Be careful for updates if partial Get success
+
+        // ND: No data == initialization state
+        
+        // PG : Pending get
+        // - on_query_in_progress
+        // NOTE: cannot distinguish get and update here. Is it important ?
+
+        on_query_in_progress: function()
+        {
+            this.spin();
+        },
+
+        // D : Data present
+        // - on_clear_records (Get)
+        // - on_new_record (shared with AD) XXX
+        // - on_query_done
+        // NOTE: cannot distinguish get and update here. Is it important ?
+        // NOTE: Would record key be sufficient for update ?
+
+        on_clear_records: function()
+        {
+            this.clear();
+        },
+
+        on_new_record: function(record)
+        {
+        },
+
+        on_query_done: function()
+        {
+            this.unspin();
+        },
+
+        // PC : Pending changes
+        // NOTE: record_key could be sufficient 
+        on_added_record: function(record)
+        {
+            this.set_record_state(record, RECORD_STATE_ADDED);
+        },
+
+        on_removed_record: function(record_key)
+        {
+            this.set_record_state(RECORD_STATE_REMOVED);
+        },
+
+        // PU : Pending update
+        // - on_query_in_progress (already done)
+        
+        // PCA : Pending change with annotation
+        // NOTE: Manifold will inform the plugin about updates, and thus won't
+        // call new record, even if the same channel UUID is used...
+        // - TODO on_updated_record
+        // - Key and confirmation could be sufficient, or key and record state
+        // XXX move record state to the manifold plugin API
+
+        on_field_state_changed: function(request, key, value, status)
+        {
+            this.set_state(request, key, value, status);
+        },
+
+        // XXX we will have the requests for change
+        // XXX + the requests to move into the query cycle = the buttons aforementioned
+
+        // XXX what happens in case of updates ? not implemented yet
+        // XXX we want resources and leases
+        // listen for SET_ADD and SET_REMOVE for slice query
+
+        /************************** PRIVATE METHODS ***************************/
+
+        _close_click: function(e)
+        {
+            var self = e.data;
+
+            //jQuery.publish('selected', 'add/'+key_value);
+            // this.parentNode is <td> this.parentNode.parentNode is <tr> 
+            // this.parentNode.parentNode.firstChild is the first cell <td> of this line <tr>
+            // this.parentNode.parentNode.firstChild.firstChild is the text in that cell
+            //var firstCellVal=this.parentNode.parentNode.firstChild.firstChild.data;
+            var remove_urn = this.id; 
+            var current_resources = event.data.instance.current_resources;
+            var list_resources = $.grep(current_resources, function(x) {return x.urn != remove_urn});
+            //jQuery.publish('selected', 'cancel/'+this.id+'/'+get_value(firstCellVal));
+            $.publish('/update-set/' + event.data.instance.options.resource_query_uuid, [list_resources, true]);
+        },
+
+        /******************************** TODO ********************************/
+
+        update_resources: function(resources, change)
+        {
             console.log("update_resources");
             var my_oTable = this.table.dataTable();
             var prev_resources = this.current_resources; 
-            /*      \ this.initial_resources
-             *           \
-             * this.          \
-             * current_resources  \    YES    |   NO
-             * --------------------+----------+---------
-             *       YES           | attached | added
-             *       NO            | removed  |   /
-             */
 
             /*
              * The first time the query is advertised, don't do anything.  The
              /* Allow the user to update the slice */
              //jQuery('#updateslice-' + data.ResourceSelected.plugin_uuid).prop('disabled', false);
 
-        } // update_resources
-
-        this.record_handler = function(e, event_type, record)
-        {
-            // elements in set
-            switch(event_type) {
-                case NEW_RECORD:
-                    /* NOTE in fact we are doing a join here */
-                    if (object.received_all)
-                        // update checkbox for record
-                        object.set_checkbox(record);
-                    else
-                        // store for later update of checkboxes
-                        object.in_set_buffer.push(record);
-                    break;
-                case CLEAR_RECORDS:
-                    // nothing to do here
-                    break;
-                case IN_PROGRESS:
-                    manifold.spin($(this));
-                    break;
-                case DONE:
-                    if (object.received_all)
-                        manifold.spin($(this), false);
-                    object.received_set = true;
-                    break;
-            }
-        };
-
-        this.record_handler_all = function(e, event_type, record)
-        {
-            // all elements
-            switch(event_type) {
-                case NEW_RECORD:
-                    // Add the record to the table
-                    object.new_record(record);
-                    break;
-                case CLEAR_RECORDS:
-                    object.table.fnClearTable();
-                    break;
-                case IN_PROGRESS:
-                    manifold.spin($(this));
-                    break;
-                case DONE:
-                    if (object.received_set) {
-                        /* XXX needed ? XXX We uncheck all checkboxes ... */
-                        $("[id^='datatables-checkbox-" + object.options.plugin_uuid +"']").attr('checked', false);
-
-                        /* ... and check the ones specified in the resource list */
-                        $.each(object.in_set_buffer, function(i, record) {
-                            object.set_checkbox(record);
-                        });
-
-                        manifold.spin($(this), false);
-                    }
-                    object.received_all = true;
-                    break;
-            }
-        };
+        }, // update_resources
 
-        this.query_handler = function(e, event_type, data)
-        {
-            // This replaces the complex set_query function
-            // The plugin does not need to remember the query anymore
-            switch(event_type) {
-                // Filters
-                case FILTER_ADDED:
-                case FILTER_REMOVED:
-                case CLEAR_FILTERS:
-                    // XXX Here we might need to maintain the list of filters !
-                    /* Process updates in filters / current_query must be updated before this call for filtering ! */
-                    object.table.fnDraw();
-                    break;
+    });
 
-                // Fields
-                /* Hide/unhide columns to match added/removed fields */
-                case FIELD_ADDED:
-                    var field = data;
-                    var oSettings = object.table.fnSettings();
-                    var cols = oSettings.aoColumns;
-                    var index = object.getColIndex(field,cols);
-                    if(index != -1)
-                        object.table.fnSetColumnVis(index, true);
-                    break;
-                case FIELD_REMOVED:
-                    var field = data;
-                    var oSettings = object.table.fnSettings();
-                    var cols = oSettings.aoColumns;
-                    var index = object.getColIndex(field,cols);
-                    if(index != -1)
-                        object.table.fnSetColumnVis(index, false);
-                    break;
-                case CLEAR_FIELDS:
-                    alert('Hazelnut::clear_fields() not implemented');
-                    break;
-            } // switch
-        }
-
-    } // ResourcesSelected
-
-
-    /***************************************************************************
-     * Private methods
-     ***************************************************************************/
-
-    /* Callbacks */    
-    function close_click(event){
-        //jQuery.publish('selected', 'add/'+key_value);
-        // this.parentNode is <td> this.parentNode.parentNode is <tr> 
-        // this.parentNode.parentNode.firstChild is the first cell <td> of this line <tr>
-        // this.parentNode.parentNode.firstChild.firstChild is the text in that cell
-        //var firstCellVal=this.parentNode.parentNode.firstChild.firstChild.data;
-        var remove_urn = this.id; 
-        var current_resources = event.data.instance.current_resources;
-        var list_resources = $.grep(current_resources, function(x) {return x.urn != remove_urn});
-        //jQuery.publish('selected', 'cancel/'+this.id+'/'+get_value(firstCellVal));
-        $.publish('/update-set/' + event.data.instance.options.resource_query_uuid, [list_resources, true]);
-    }
+    $.plugin('ResourcesSelected', ResourcesSelected);
 
 })(jQuery);
index 00ac3ec..a4450eb 100644 (file)
@@ -1,9 +1,10 @@
-<table class='display' id='table-{{ domid }}'>
+<table class='display' id='{{domid}}__table'>
   <thead>
     <tr>
+      <th>action</th>
+      <th>key</th>
+      <th>value</th>
       <th>status</th>
-      <th>urn</th>
-      <th>slot</th>
       <th>+/-</th>
     </tr>
   </thead>
index b165d6a..be17ee2 100644 (file)
@@ -18,7 +18,7 @@ from plugins.querycode.querycode        import QueryCode
 from plugins.raw.raw                    import Raw
 from plugins.messages.messages          import Messages
 from plugins.hazelnut                   import Hazelnut
-from plugins.updater.updater            import Updater
+from plugins.updater                    import Updater
 
 from myslice.viewutils                  import topmenu_items, the_user
 from myslice.viewutils                  import hard_wired_slice_names, hard_wired_list, lorem_p, lorem, quickfilter_criterias
index 632aec4..4afd625 100644 (file)
@@ -180,17 +180,6 @@ def _slice_view (request, slicename):
 
     stack_resources.insert(tab_resource_plugins)
 
-    # --------------------------------------------------------------------------
-    # ResourcesSelected
-    #
-    stack_resources.insert(ResourcesSelected(
-        page                = page,
-        title               = 'Pending operations',
-        resource_query_uuid = sq_resource,
-        lease_query_uuid    = sq_lease,
-        togglable           = True,
-    ))
-
     sq_plugin.insert(stack_resources)
 
     ############################################################################
@@ -253,6 +242,16 @@ def _slice_view (request, slicename):
 
     main_plugin.insert(sq_plugin)
 
+    # --------------------------------------------------------------------------
+    # ResourcesSelected
+    #
+    main_plugin.insert(ResourcesSelected(
+        page                = page,
+        title               = 'Pending operations',
+        query               = main_query,
+        togglable           = True,
+    ))
+
     main_plugin.insert(Messages(
         page   = page,
         title  = "Runtime messages for slice %s"%slicename,