various fixes to slice page plugins
authorJordan Augé <jordan.auge@lip6.fr>
Mon, 7 Jul 2014 15:30:25 +0000 (17:30 +0200)
committerJordan Augé <jordan.auge@lip6.fr>
Mon, 7 Jul 2014 15:30:25 +0000 (17:30 +0200)
manifoldapi/static/js/manifold.js
plugins/filter_status/static/js/filter_status.js
plugins/filter_status/templates/filter_status.html
plugins/googlemap/static/js/googlemap.js
plugins/querytable/static/js/querytable.js
plugins/querytable/templates/querytable.html
plugins/queryupdater/static/js/queryupdater.js
plugins/scheduler2/static/js/scheduler2.js
portal/sliceresourceview.py

index b6d2d21..48e80a6 100644 (file)
@@ -44,11 +44,10 @@ var CLEAR_RECORDS  = 8;
  *
  * Parameters:
  *   dict :
- *      .request    : ???? used to be FIELD_REQUEST_ADD / FIELD_REQUEST_REMOVE
+ *      .state      : ???? used to be FIELD_REQUEST_ADD / FIELD_REQUEST_REMOVE
  *      .key        : ??? the key fields of the record
- *      .value      : the key of the record who has received an update
- *      .status     : the new state of the record
- *        TODO rename to state, and use values from STATE_SET            
+ *      .op         : the key of the record who has received an update
+ *      .value      : the new state of the record
  */
 var FIELD_STATE_CHANGED = 9;
 
@@ -57,29 +56,19 @@ var DONE           = 102;
 
 /* Update requests related to subqueries */
 
-/**
- * event: SET_ADD
- *
- * Parameters:
- *    string : The key of the element being added
- */
+/*
 var SET_ADD        = 201;
-
-/**
- * event: SET_REMOVED
- *
- * Parameters:
- *    string : The key of the element being removed
- */
 var SET_REMOVED    = 202;
-
+*/
 
 // request
+/*
 var FIELD_REQUEST_CHANGE  = 301;
 var FIELD_REQUEST_ADD     = 302;
 var FIELD_REQUEST_REMOVE  = 303;
 var FIELD_REQUEST_ADD_RESET = 304;
 var FIELD_REQUEST_REMOVE_RESET = 305;
+*/
 // status (XXX Should be deprecated)
 var FIELD_REQUEST_PENDING = 401;
 var FIELD_REQUEST_SUCCESS = 402;
@@ -127,8 +116,15 @@ var QUERY_STATE_DONE        = 2;
  ******************************************************************************/
 
 var STATE_SET       = 0;
-var STATE_WARNINGS  = 1;
-var STATE_VISIBLE   = 2;
+var STATE_VALUE     = 1;
+var STATE_WARNINGS  = 2;
+var STATE_VISIBLE   = 3;
+
+// ACTIONS
+var STATE_SET_CHANGE = 0;
+var STATE_SET_ADD    = 1;
+var STATE_SET_REMOVE = 2;
+var STATE_SET_CLEAR  = 3;
 
 // STATE_SET : enum
 var STATE_SET_IN            = 0;
@@ -139,6 +135,9 @@ var STATE_SET_IN_SUCCESS    = 4;
 var STATE_SET_OUT_SUCCESS   = 5;
 var STATE_SET_IN_FAILURE    = 6;
 var STATE_SET_OUT_FAILURE   = 7;
+var STATE_VALUE_CHANGE_PENDING    = 8;
+var STATE_VALUE_CHANGE_SUCCESS    = 9;
+var STATE_VALUE_CHANGE_FAILURE    = 10;
 
 // STATE_WARNINGS : dict
 
@@ -150,6 +149,8 @@ var STATE_SET_OUT_FAILURE   = 7;
 
 var CONSTRAINT_RESERVABLE_LEASE     = 0;
 
+var CONSTRAINT_RESERVABLE_LEASE_MSG = "Configuration required: this resource needs to be scheduled";
+
 // A structure for storing queries
 
 function QueryExt(query, parent_query_ext, main_query_ext, update_query_ext, disabled, domain_query_ext) {
@@ -1216,10 +1217,10 @@ var manifold = {
                         throw "Internal error";
 
                     data = {
-                        request: FIELD_REQUEST_CHANGE,
+                        state : STATE_SET,
                         key   : field,
-                        value : update_value,
-                        status: (update_value == result_value) ? FIELD_REQUEST_SUCCESS : FIELD_REQUEST_FAILURE,
+                        op    : update_value,
+                        value : (update_value == result_value) ? STATE_VALUE_CHANGE_SUCCESS : STATE_VALUE_CHANGE_FAILURE,
                     }
                     manifold.raise_record_event(query_uuid, FIELD_STATE_CHANGED, data);
 
@@ -1454,8 +1455,201 @@ var manifold = {
         manifold.raise_event_handler('record', query_uuid, event_type, value);
     },
 
+    /**
+     * Event handler helpers
+     */
+    _get_next_state_add: function(prev_state, event_type)
+    {
+        switch (prev_state) {
+            case STATE_SET_OUT:
+            case STATE_SET_OUT_SUCCESS:
+            case STATE_SET_IN_FAILURE:
+                new_state = STATE_SET_IN_PENDING;
+                break;
+
+            case STATE_SET_OUT_PENDING:
+                new_state = STATE_SET_IN;
+                break;
+
+            case STATE_SET_IN:
+            case STATE_SET_IN_PENDING:
+            case STATE_SET_IN_SUCCESS:
+            case STATE_SET_OUT_FAILURE:
+                console.log("Inconsistent state: already in");
+                return;
+        }
+        return new_state;
+    },
+
+    _get_next_state_remove: function(prev_state, event_type)
+    {
+        switch (prev_state) {
+            case STATE_SET_IN:
+            case STATE_SET_IN_SUCCESS:
+            case STATE_SET_OUT_FAILURE:
+                new_state = STATE_SET_OUT_PENDING;
+                break;
+
+            case STATE_SET_IN_PENDING:
+                new_state = STATE_SET_OUT;
+                break;  
+
+            case STATE_SET_OUT:
+            case STATE_SET_OUT_PENDING:
+            case STATE_SET_OUT_SUCCESS:
+            case STATE_SET_IN_FAILURE:
+                console.log("Inconsistent state: already out");
+                return;
+        }
+        return new_state;
+    },
+
+    _grep_active_lease_callback: function(lease_query, resource_key) {
+        return function(lease_key_lease) {
+            var state, lease_key, lease;
+
+            lease_key = lease_key_lease[0];
+            lease = lease_key_lease[1];
+
+            if (lease['resource'] != resource_key)
+                return false;
+
+            state = manifold.query_store.get_record_state(lease_query.query_uuid, lease_key, STATE_SET);;
+            switch(state) {
+                case STATE_SET_IN:
+                case STATE_SET_IN_PENDING:
+                case STATE_SET_IN_SUCCESS:
+                case STATE_SET_OUT_FAILURE:
+                    return true;
+                case STATE_SET_OUT:
+                case STATE_SET_OUT_PENDING:
+                case STATE_SET_OUT_SUCCESS:
+                case STATE_SET_IN_FAILURE:
+                    return false;
+            }
+        }
+    },
+
+    _enforce_constraints: function(query_ext, record, resource_key, event_type)
+    {
+        var query, data;
+
+        query = query_ext.query;
+
+        switch(query.object) {
+
+            case 'resource':
+                // CONSTRAINT_RESERVABLE_LEASE
+                // 
+                // +) If a reservable node is added to the slice, then it should have a corresponding lease
+                // XXX Not always a resource
+                var is_reservable = (record.exclusive == true);
+                if (is_reservable) {
+                    var warnings = manifold.query_store.get_record_state(query.query_uuid, resource_key, STATE_WARNINGS);
+
+                    if (event_type == STATE_SET_ADD) {
+                        // We should have a lease_query associated
+                        var lease_query = query_ext.parent_query_ext.query.subqueries['lease']; // in  options
+                        var lease_query_ext = manifold.query_store.find_analyzed_query_ext(lease_query.query_uuid);
+                        // Do we have lease records (in) with this resource
+                        var lease_records = $.grep(lease_query_ext.records.entries(), this._grep_active_lease_callback(lease_query, resource_key));
+                        if (lease_records.length == 0) {
+                            // Sets a warning
+                            // XXX Need for a better function to manage warnings
+                            var warn = CONSTRAINT_RESERVABLE_LEASE_MSG;
+                            warnings[CONSTRAINT_RESERVABLE_LEASE] = warn;
+                        } else {
+                            // Lease are defined, delete the warning in case it was set previously
+                            delete warnings[CONSTRAINT_RESERVABLE_LEASE];
+                        }
+                    } else {
+                        // Remove warnings attached to this resource
+                        delete warnings[CONSTRAINT_RESERVABLE_LEASE];
+                    }
+
+                    manifold.query_store.set_record_state(query.query_uuid, resource_key, STATE_WARNINGS, warnings);
+                }
+
+                manifold.query_store.recount(query.query_uuid); 
+                manifold.query_store.recount(lease_query.query_uuid); 
+
+                // Signal the change to plugins (even if the constraint does not apply, so that the plugin can display a checkmark)
+                data = {
+                    state:  STATE_WARNINGS,
+                    key   : resource_key,
+                    op    : null,
+                    value : warnings
+                }
+                manifold.raise_record_event(query.query_uuid, FIELD_STATE_CHANGED, data);
+                break;
+
+            case 'lease':
+                var resource_key = record.resource;
+                var resource_query = query_ext.parent_query_ext.query.subqueries['resource'];
+                var warnings = manifold.query_store.get_record_state(resource_query.query_uuid, resource_key, STATE_WARNINGS);
+
+                if (event_type == STATE_SET_ADD) {
+                     // A lease is added, it removes the constraint
+                    delete warnings[CONSTRAINT_RESERVABLE_LEASE];
+                } else {
+                    // A lease is removed, it might trigger the warning
+                    var lease_records = $.grep(query_ext.records.entries(), this._grep_active_lease_callback(query, resource_key));
+                    if (lease_records.length == 0) { // XXX redundant cases
+                        // Sets a warning
+                        // XXX Need for a better function to manage warnings
+                        var warn = CONSTRAINT_RESERVABLE_LEASE_MSG;
+                        warnings[CONSTRAINT_RESERVABLE_LEASE] = warn;
+                    } else {
+                        // Lease are defined, delete the warning in case it was set previously
+                        delete warnings[CONSTRAINT_RESERVABLE_LEASE];
+                    }
+                    
+                }
+
+                manifold.query_store.recount(query.query_uuid); 
+                manifold.query_store.recount(resource_query.query_uuid); 
+
+                // Signal the change to plugins (even if the constraint does not apply, so that the plugin can display a checkmark)
+                data = {
+                    state:  STATE_WARNINGS,
+                    key   : resource_key,
+                    op    : null,
+                    value : warnings
+                }
+                manifold.raise_record_event(resource_query.query_uuid, FIELD_STATE_CHANGED, data);
+                break;
+        }
+
+        // -) When a lease is added, it might remove the warning associated to a reservable node
+
+        // If a NITOS node is reserved, then at least a NITOS channel should be reserved
+        // - When a NITOS channel is added, it might remove a warning associated to all NITOS nodes
+
+        // If a NITOS channel is reserved, then at least a NITOS node should be reserved
+        // - When a NITOS node is added, it might remove a warning associated to all NITOS channels
+
+        // A lease is present while the resource has been removed => Require warnings on nodes not in set !
+
+    },
+
+    _get_query_path: function(query_ext) {
+        var path = "";
+        var sq = query_ext;
+        while (sq.parent_query_ext) {
+            if (path != "")
+                path = '.' + path;
+            path = sq.query.object + path;
+            sq = sq.parent_query_ext;
+        }
+        return path;
+    },
+
 
-    raise_event: function(query_uuid, event_type, value) {
+    /**
+     * Handling events raised by plugins
+     */
+    raise_event: function(query_uuid, event_type, data) 
+    {
         var query, query_ext;
 
         // Query uuid has been updated with the key of a new element
@@ -1464,7 +1658,9 @@ var manifold = {
 
         switch(event_type) {
 
+            // XXX At some point, should be renamed to RECORD_STATE_CHANGED
             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
@@ -1476,269 +1672,132 @@ var manifold = {
                 update_query      = query_ext.main_query_ext.update_query_ext.query;
                 update_query_orig = query_ext.main_query_ext.update_query_orig_ext.query;
 
-                switch(value.request) {
-                    case FIELD_REQUEST_CHANGE:
-                        if (update_query.params[value.key] === undefined)
-                            update_query.params[value.key] = Array();
-                        update_query.params[value.key] = value.value;
-                        break;
-                    case FIELD_REQUEST_ADD:
-                        if ($.inArray(value.value, update_query_orig.params[value.key]) != -1)
-                            value.request = FIELD_REQUEST_ADD_RESET;
-                        if (update_query.params[value.key] === undefined)
-                            update_query.params[value.key] = Array();
-                        update_query.params[value.key].push(value.value);
-                        break;
-                    case FIELD_REQUEST_REMOVE:
-                        if ($.inArray(value.value, update_query_orig.params[value.key]) == -1)
-                            value.request = FIELD_REQUEST_REMOVE_RESET;
-
-                        var arr = update_query.params[value.key];
-                        arr = $.grep(arr, function(x) { return x != value.value; });
-                        if (update_query.params[value.key] === undefined)
-                            update_query.params[value.key] = Array();
-                        update_query.params[value.key] = arr;
+                switch(data.state) {
+            
+                    case STATE_VALUE:
+                        switch(data.op) {
+                            case STATE_CHANGE:
+                                /* Set parameter data.key in the update_query to VALUE */
+                                if (update_query.params[data.key] === undefined)
+                                    update_query.params[data.key] = Array();
+                                update_query.params[data.key] = value.value;
+                                break;
 
+                        }
                         break;
-                    case FIELD_REQUEST_ADD_RESET:
-                    case FIELD_REQUEST_REMOVE_RESET:
-                        // XXX We would need to keep track of the original query
-                        throw "Not implemented";
-                        break;
-                }
-
-                // 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)
-                // Let's unfold 
-                var path_array = value.key.split('.');
-                var value_key = value.key.split('.');
-
-                var cur_query = query;
-                if (cur_query.analyzed_query)
-                    cur_query = cur_query.analyzed_query;
-                $.each(path_array, function(i, method) {
-                    cur_query = cur_query.subqueries[method];
-                    value_key.shift(); // XXX check that method is indeed shifted
-                });
-                value.key = value_key;
-
-                manifold.query_store.recount(cur_query.query_uuid);
-                manifold.raise_record_event(cur_query.query_uuid, event_type, value);
 
+                    case STATE_SET:
 
-                // XXX make this DOT a global variable... could be '/'
-                break;
-
-            case SET_ADD:
-            case SET_REMOVED:
-
-                /* An object has been added to / removed from a set : its
-                 * status become pending or reset to the original state. We
-                 * update the record status in the analyzed queries.
-                 *
-                 * XXX Shall we update something in the main_query ?
-                 */
-                var prev_state, new_state;
-
-                prev_state = manifold.query_store.get_record_state(query_uuid, value, STATE_SET);
-                if (prev_state === null)
-                    prev_state = STATE_SET_OUT;
-
-                if (event_type == SET_ADD) {
-                    switch (prev_state) {
-                        case STATE_SET_OUT:
-                        case STATE_SET_OUT_SUCCESS:
-                        case STATE_SET_IN_FAILURE:
-                            new_state = STATE_SET_IN_PENDING;
-                            break;
-
-                        case STATE_SET_OUT_PENDING:
-                            new_state = STATE_SET_IN;
-                            break;
-
-                        case STATE_SET_IN:
-                        case STATE_SET_IN_PENDING:
-                        case STATE_SET_IN_SUCCESS:
-                        case STATE_SET_OUT_FAILURE:
-                            console.log("Inconsistent state: already in");
-                            return;
-                    }
-                } else { // SET_REMOVE
-                    switch (prev_state) {
-                        case STATE_SET_IN:
-                        case STATE_SET_IN_SUCCESS:
-                        case STATE_SET_OUT_FAILURE:
-                            new_state = STATE_SET_OUT_PENDING;
-                            break;
-
-                        case STATE_SET_IN_PENDING:
-                            new_state = STATE_SET_OUT;
-                            break;  
-
-                        case STATE_SET_OUT:
-                        case STATE_SET_OUT_PENDING:
-                        case STATE_SET_OUT_SUCCESS:
-                        case STATE_SET_IN_FAILURE:
-                            console.log("Inconsistent state: already out");
-                            return;
-                    }
-                }
+                        switch(data.op) {
+                            case STATE_SET_ADD:
+                                if (!data.key) {
+                                    var prev_state, new_state;
+                                    var main_query, record, new_data;
+                    
+                                    prev_state = manifold.query_store.get_record_state(query_uuid, data.value, STATE_SET);
+                                    if (prev_state === null)
+                                        prev_state = STATE_SET_OUT;
+                                    new_state = this._get_next_state_add(prev_state, data.state);
+                    
+                                    /* data.value containts the resource key */
+                                    manifold.query_store.add_record(query_uuid, data.value, new_state);
+                                    record = manifold.query_store.get_record(query_uuid, data.value);
+                                    this._enforce_constraints(query_ext, record, data.value, STATE_SET_ADD);
+                    
+                                    /* Inform the parent query: important for update */
+                                    new_data = {
+                                        state : STATE_SET,
+                                        key   : this._get_query_path(query_ext),
+                                        op    : STATE_SET_IN_PENDING,
+                                        value : data.value,
+                                    };
+                                    main_query = query_ext.main_query_ext.query;
+                                    this.raise_event(main_query.query_uuid, FIELD_STATE_CHANGED, new_data);
+                    
+                                    /*
+                                     * Propagate the event to other plugins subscribed to the query
+                                     */
+                                    manifold.raise_query_event(query_uuid, event_type, data);
+                                } else {
+                                    // mainquery: proceed to update
 
-                
-                var resource_key = value;
+                                    //if ($.inArray(data.value, update_query_orig.params[data.key]) != -1)
+                                    //    value.request = FIELD_REQUEST_ADD_RESET;
 
-                if (event_type == SET_ADD)
-                    manifold.query_store.add_record(query_uuid, resource_key, new_state);
-                else
-                    manifold.query_store.remove_record(query_uuid, resource_key, new_state);
-
-                var record = manifold.query_store.get_record(query_uuid, resource_key);
-
-                /* CONSTRAINTS */
-
-                // XXX When we add a lease we must update the warnings
-
-                switch(query.object) {
-
-                    case 'resource':
-                        // CONSTRAINT_RESERVABLE_LEASE
-                        // 
-                        // +) If a reservable node is added to the slice, then it should have a corresponding lease
-                        // XXX Not always a resource
-                        var is_reservable = (record.exclusive == true);
-                        if (is_reservable) {
-                            var warnings = manifold.query_store.get_record_state(query_uuid, resource_key, STATE_WARNINGS);
-
-                            if (event_type == SET_ADD) {
-                                // We should have a lease_query associated
-                                var lease_query = query_ext.parent_query_ext.query.subqueries['lease']; // in  options
-                                var lease_query_ext = manifold.query_store.find_analyzed_query_ext(lease_query.query_uuid);
-                                // Do we have lease records with this resource
-                                var lease_records = $.grep(lease_query_ext.records, function(lease_key, lease) {
-                                    return lease['resource'] == value;
-                                });
-                                if (lease_records.length == 0) {
-                                    // Sets a warning
-                                    // XXX Need for a better function to manage warnings
-                                    var warn = "No lease defined for this reservable resource.";
-                                    warnings[CONSTRAINT_RESERVABLE_LEASE] = warn;
-                                } else {
-                                    // Lease are defined, delete the warning in case it was set previously
-                                    delete warnings[CONSTRAINT_RESERVABLE_LEASE];
+                                    if (update_query.params[data.key] === undefined)
+                                        update_query.params[data.key] = Array();
+                                    update_query.params[data.key].push(data.value);
                                 }
-                            } else {
-                                // Remove warnings attached to this resource
-                                delete warnings[CONSTRAINT_RESERVABLE_LEASE];
-                            }
+                                break;
 
-                            manifold.query_store.set_record_state(query_uuid, resource_key, STATE_WARNINGS, warnings);
-                            break;
-                        }
-
-                        // Signal the change to plugins (even if the constraint does not apply, so that the plugin can display a checkmark)
-                        data = {
-                            request: null,
-                            key   : null,
-                            value : resource_key,
-                            status: STATE_WARNINGS
-                        };
-                        manifold.raise_record_event(query_uuid, FIELD_STATE_CHANGED, data);
+                            case STATE_SET_REMOVE:
+                                if (!data.key) {
+                                    var prev_state, new_state;
+                                    var main_query, record, new_data;
+                    
+                                    prev_state = manifold.query_store.get_record_state(query_uuid, data.value, STATE_SET);
+                                    if (prev_state === null)
+                                        prev_state = STATE_SET_OUT;
+                                    new_state = this._get_next_state_remove(prev_state, data.state);
+                    
+                                    /* data.value contains the resource key */
+                                    manifold.query_store.remove_record(query_uuid, data.value, new_state);
+                                    record = manifold.query_store.get_record(query_uuid, data.value);
+                                    this._enforce_constraints(query_ext, record, data.value, STATE_SET_REMOVE);
+                    
+                                    /* Inform the parent query: important for update */
+                                    new_data = {
+                                        state : STATE_SET,
+                                        key   : this._get_query_path(query_ext),
+                                        op    : STATE_SET_OUT_PENDING,
+                                        value : data.value,
+                                    };
+                                    main_query = query_ext.main_query_ext.query;
+                                    this.raise_event(main_query.query_uuid, FIELD_STATE_CHANGED, new_data);
+                    
+                                    /* Propagate the event to other plugins subscribed to the query */
+                                    manifold.raise_query_event(query_uuid, event_type, data);
+                    
+                                } else {
+                                    // main query: proceed to update
 
-                    case 'lease':
-                    /*
-                        var resource_key = record.resource;
-                        var resource_query = query_ext.parent_query_ext.query.subqueries['resource'];
-                        var warnings = manifold.query_store.get_record_state(resource_query.query_uuid, resource_key, STATE_WARNINGS);
+                                    //if ($.inArray(data.value, update_query_orig.params[data.key]) == -1)
+                                    //    value.request = FIELD_REQUEST_REMOVE_RESET;
 
-                        if (event_type == SET_ADD) {
-                             // A lease is added, it removes the constraint
-                            delete warnings[CONSTRAINT_RESERVABLE_LEASE];
-                        } else {
-                            // A lease is removed, it might trigger the warning
-                            var lease_records = $.grep(query_ext.records, function(lease_key, lease) {
-                                return lease['resource'] == value;
-                            });
-                            if (lease_records.length == 0) { // XXX redundant cases
-                                // Sets a warning
-                                // XXX Need for a better function to manage warnings
-                                var warn = "No lease defined for this reservable resource.";
-                                warnings[CONSTRAINT_RESERVABLE_LEASE] = warn;
-                            } else {
-                                // Lease are defined, delete the warning in case it was set previously
-                                delete warnings[CONSTRAINT_RESERVABLE_LEASE];
-                            }
-                            
+                                    var arr = update_query.params[data.key];
+                                    arr = $.grep(arr, function(x) { return x != data.value; });
+                                    if (update_query.params[data.key] === undefined)
+                                        update_query.params[data.key] = Array();
+                                    update_query.params[data.key] = arr;
+                                }
+                                break;
                         }
-
-                        // Signal the change to plugins (even if the constraint does not apply, so that the plugin can display a checkmark)
-                        data = {
-                            request: null,
-                            key   : null,
-                            value : resource_key,
-                            status: STATE_WARNINGS
-                        };
-                        manifold.raise_record_event(resource_query.query_uuid, FIELD_STATE_CHANGED, data);
                         break;
-                    */
                 }
 
+                // 3. Inform others about the change
+                // a) the main query...
+                manifold.raise_record_event(query_uuid, event_type, data);
 
-                // -) When a lease is added, it might remove the warning associated to a reservable node
-
-                // If a NITOS node is reserved, then at least a NITOS channel should be reserved
-                // - When a NITOS channel is added, it might remove a warning associated to all NITOS nodes
-
-                // If a NITOS channel is reserved, then at least a NITOS node should be reserved
-                // - When a NITOS node is added, it might remove a warning associated to all NITOS channels
-
-                // A lease is present while the resource has been removed => Require warnings on nodes not in set !
+                // b) subqueries eventually (dot in the key)
+                // Let's unfold 
 
-                /* END CONSTRAINTS */
+                var cur_query = query;
+                if (cur_query.analyzed_query)
+                    cur_query = cur_query.analyzed_query;
 
-                // 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
-                // 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;
-                while (sq.parent_query_ext) {
-                    if (path != "")
-                        path = '.' + path;
-                    path = sq.query.object + path;
-                    sq = sq.parent_query_ext;
+                if (data.key) {
+                    var path_array = data.key.split('.');
+                    var value_key = data.key.split('.');
+                    $.each(path_array, function(i, method) {
+                        cur_query = cur_query.subqueries[method];
+                        value_key.shift(); // XXX check that method is indeed shifted
+                    });
+                    data.key = value_key;
                 }
 
-                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: STATE_SET, // XXX used to be FIELD_REQUEST_PENDING, and not new_state
-                };
-                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 ?)
-
-                // if everything is done right, update_query should not be null. 
-                // It is updated when we received results from the get query
-                // 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);
+                manifold.query_store.recount(cur_query.query_uuid);
+                manifold.raise_record_event(cur_query.query_uuid, event_type, data);
 
                 break;
 
@@ -1746,52 +1805,54 @@ var manifold = {
                 manifold.run_query(query_ext.main_query_ext.update_query_ext.query);
                 break;
 
-            /* FILTERS */
+            /* QUERY STATE CHANGED */
+            
+            // FILTERS
 
             case FILTER_ADDED: 
                 /* Update internal record state */
-                manifold.query_store.add_filter(query_uuid, value);
+                manifold.query_store.add_filter(query_uuid, data);
 
                 /* Propagate the message to plugins */
-                manifold.raise_query_event(query_uuid, event_type, value);
+                manifold.raise_query_event(query_uuid, event_type, data);
 
                 break;
 
             case FILTER_REMOVED:
                 /* Update internal record state */
-                manifold.query_store.remove_filter(query_uuid, value);
+                manifold.query_store.remove_filter(query_uuid, data);
 
                 /* Propagate the message to plugins */
-                manifold.raise_query_event(query_uuid, event_type, value);
+                manifold.raise_query_event(query_uuid, event_type, data);
 
                 break;
 
             case FIELD_ADDED:
                 main_query = query_ext.main_query_ext.query;
                 main_update_query = query_ext.main_query_ext.update_query;
-                query.select(value);
+                query.select(data);
 
                 // Here we need the full path through all subqueries
                 path = ""
                 // XXX We might need the query name in the QueryExt structure
-                main_query.select(value);
+                main_query.select(data);
 
                 // XXX When is an update query associated ?
                 // XXX main_update_query.select(value);
 
-                manifold.raise_query_event(query_uuid, event_type, value);
+                manifold.raise_query_event(query_uuid, event_type, data);
                 break;
 
             case FIELD_REMOVED:
                 query = query_ext.query;
                 main_query = query_ext.main_query_ext.query;
                 main_update_query = query_ext.main_query_ext.update_query;
-                query.unselect(value);
-                main_query.unselect(value);
+                query.unselect(data);
+                main_query.unselect(data);
 
                 // We need to inform about changes in these queries to the respective plugins
                 // Note: query & main_query have the same UUID
-                manifold.raise_query_event(query_uuid, event_type, value);
+                manifold.raise_query_event(query_uuid, event_type, data);
                 break;
         }
         // We need to inform about changes in these queries to the respective plugins
index d5a13be..3bcd15c 100644 (file)
@@ -70,8 +70,9 @@
     {
         var query_ext;
         
-        switch (data.status) {
+        switch (data.state) {
             case STATE_SET:
+            case STATE_WARNINGS:
                 /* Get the number of pending / unconfigured resources */
                 /* Let's store it in query_ext */
                 query_ext = manifold.query_store.find_analyzed_query_ext(this.options.query_uuid);
index b6ce25d..3b40d29 100644 (file)
@@ -25,7 +25,7 @@
      style='display: inline-block !important;' 
      id="{{ domid }}__unconfigured" 
      data-status="unconfigured"
-     title="View resources that you have selected to add to your slice, that require configuration before they can be reserved. Hover you mouse over the symbol aside the checkbox for more details."
+     title="View resources that you have selected to add to your slice, that require configuration before they can be reserved. Hover you mouse over the symbol next to the checkbox for more details."
      rel='tooltip'>
        <p class="list-group-item-heading">Unconfigured</p>
        <span class="badge" id="badge-unconfigured" style="display:none;"></span></a>
@@ -35,7 +35,7 @@
      style='display: inline-block !important;' 
      id="{{ domid }}__pending" 
      data-status="pending"
-     title="View pending changes to your slice, resources that you have selected to add, and resources that you have selected to remove. Click on the Apply button to apply those changes, and on the Cancel button to cancel them."
+     title="View pending changes to your slice: resources that you have selected to add, and resources that you have selected to remove. Click on the Apply button to apply those changes, or on the Cancel button to cancel them."
      rel='tooltip'>
        <p class="list-group-item-heading">Pending</p>
        <span class="badge" id="badge-pending" style="display:none;"></span></a>
index f6248ab..5a15a3d 100644 (file)
@@ -138,7 +138,7 @@ GOOGLEMAP_BGCOLOR_REMOVED = 2;
          */
         create_record_checkbox: function (record, ul, checked)
         {
-            var key, key_value;
+            var key, key_value, data;
 
             var checkbox = $("<input>", {type:'checkbox', checked:checked, class:'geo'});
             var id = record[this.canonical_key];
@@ -170,7 +170,13 @@ GOOGLEMAP_BGCOLOR_REMOVED = 2;
              */
             var self=this;
             checkbox.change( function (e) {
-                manifold.raise_event (self.options.query_uuid, this.checked ? SET_ADD : SET_REMOVED, id);
+                data = {
+                    state: STATE_SET,
+                    key  : null,
+                    op   : this.checked ? SET_ADD : SET_REMOVED,
+                    value: id
+                }
+                manifold.raise_event(self.options.query_uuid, FIELD_STATE_CHANGED, data);
             });
             return checkbox;
         },
@@ -381,16 +387,34 @@ GOOGLEMAP_BGCOLOR_REMOVED = 2;
 
         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);
+            switch(data.state) {
+                case STATE_SET:
+                    switch(data.value) {
+                        case STATE_SET_IN:
+                        case STATE_SET_IN_SUCCESS:
+                        case STATE_SET_OUT_FAILURE:
+                            this.set_checkbox_from_data(data.key, true);
+                            this.set_bgcolor(data.key, QUERYTABLE_BGCOLOR_RESET);
+                            break;  
+                        case STATE_SET_OUT:
+                        case STATE_SET_OUT_SUCCESS:
+                        case STATE_SET_IN_FAILURE:
+                            this.set_checkbox_from_data(data.key, false);
+                            this.set_bgcolor(data.key, QUERYTABLE_BGCOLOR_RESET);
+                            break;
+                        case STATE_SET_IN_PENDING:
+                            this.set_checkbox_from_data(data.key, true);
+                            this.set_bgcolor(data.key, QUERYTABLE_BGCOLOR_ADDED);
+                            break;  
+                        case STATE_SET_OUT_PENDING:
+                            this.set_checkbox_from_data(data.key, false);
+                            this.set_bgcolor(data.key, QUERYTABLE_BGCOLOR_REMOVED);
+                            break;
+                    }
                     break;
-                default:
+
+                case STATE_WARNINGS:
+                    //this.change_status(data.key, data.value);
                     break;
             }
         },
index 623a1e1..15477a4 100644 (file)
@@ -450,35 +450,37 @@ QUERYTABLE_BGCOLOR_REMOVED = 2;
         
         on_field_state_changed: function(data)
         {
-            var state = manifold.query_store.get_record_state(this.options.query_uuid, data.value, data.status);
-            switch(data.status) {
+            // XXX We could get this from data.value
+            // var state = manifold.query_store.get_record_state(this.options.query_uuid, data.value, data.state);
+
+            switch(data.state) {
                 case STATE_SET:
-                    switch(state) {
+                    switch(data.value) {
                         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, QUERYTABLE_BGCOLOR_RESET);
+                            this.set_checkbox_from_data(data.key, true);
+                            this.set_bgcolor(data.key, QUERYTABLE_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, QUERYTABLE_BGCOLOR_RESET);
+                            this.set_checkbox_from_data(data.key, false);
+                            this.set_bgcolor(data.key, QUERYTABLE_BGCOLOR_RESET);
                             break;
                         case STATE_SET_IN_PENDING:
-                            this.set_checkbox_from_data(data.value, true);
-                            this.set_bgcolor(data.value, QUERYTABLE_BGCOLOR_ADDED);
+                            this.set_checkbox_from_data(data.key, true);
+                            this.set_bgcolor(data.key, QUERYTABLE_BGCOLOR_ADDED);
                             break;  
                         case STATE_SET_OUT_PENDING:
-                            this.set_checkbox_from_data(data.value, false);
-                            this.set_bgcolor(data.value, QUERYTABLE_BGCOLOR_REMOVED);
+                            this.set_checkbox_from_data(data.key, false);
+                            this.set_bgcolor(data.key, QUERYTABLE_BGCOLOR_REMOVED);
                             break;
                     }
                     break;
 
                 case STATE_WARNINGS:
-                    this.change_status(data.value, state);
+                    this.change_status(data.key, data.value);
                     break;
             }
         },
@@ -551,14 +553,18 @@ QUERYTABLE_BGCOLOR_REMOVED = 2;
 
         _check_click: function(e) 
         {
-            e.stopPropagation();
-
+            var data;
             var self = e.data;
-        var id=this.id;
 
-            // this.id = key of object to be added... what about multiple keys ?
-        if (debug) messages.debug("querytable._check_click key="+this.canonical_key+"->"+id+" checked="+this.checked);
-            manifold.raise_event(self.options.query_uuid, this.checked?SET_ADD:SET_REMOVED, id);
+            e.stopPropagation();
+
+            data = {
+                state: STATE_SET,
+                key  : null,
+                op   : this.checked ? STATE_SET_ADD : STATE_SET_REMOVE,
+                value: this.id
+            }
+            manifold.raise_event(self.options.query_uuid, FIELD_STATE_CHANGED, data);
             //return false; // prevent checkbox to be checked, waiting response from manifold plugin api
             
         },
index a1792b4..03e17c8 100644 (file)
@@ -3,7 +3,7 @@
     <thead>
       <tr>
        {% if checkboxes %}<th class="checkbox"><input type="checkbox" disabled/></th>{% endif %}
-        <th></th>
+        <th>&#9888;</th>
         {% for column, field in columns.items %} <th>{{ column }}</th> {% endfor %} 
         {% for column, field in hidden_columns.items %} <th>{{ column }}</th> {% endfor %}
       </tr>
@@ -13,7 +13,7 @@
     <tfoot>
       <tr>
        {% if checkboxes %} <th><input type="checkbox" disabled/></th> {% endif %}
-        <th></th>
+        <th>&#9888;</th>
         {% for column, field in columns.items %} <th>{{ column }}</th> {% endfor %} 
         {% for column, field in hidden_columns.items %} <th>{{ column }}</th> {% endfor %} 
       </tr>
index 0cab4e0..f3ba672 100644 (file)
             this.selected_resources = Array();
 
             this.table = this.elmt('table').dataTable({
-// the original querytable layout was
-//                sDom: "<'row'<'col-xs-5'l><'col-xs-1'r><'col-xs-6'f>>t<'row'<'col-xs-5'i><'col-xs-7'p>>",
-// however the bottom line with 'showing blabla...' and the navigation widget are not really helpful
                 sDom: "<'row'<'col-xs-5'l><'col-xs-1'r><'col-xs-6'f>>t>",
-// so this does not matter anymore now that the pagination area is turned off
-//                sPaginationType: 'bootstrap',
-                     bAutoWidth: true,
-//                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);
-//                }
-             });
+                       bAutoWidth: true,
+            });
             
-            // XXX This should not be done at init...
-            this.elmt('update').click(this, this.do_checksla);
-            this.elmt('refresh').click(this, this.do_refresh);
-            this.elmt('reset').click(this, this.do_reset);
-            this.elmt('clear_annotations').click(this, this.do_clear_annotations);
+            this.elmt('update').click(this, this.do_ok);
+            this.elmt('refresh').click(this, this.do_cancel);
 
             this.listen_query(options.query_uuid);
         },
 
         /***************************** GUI EVENTS *****************************/
 
-        do_checksla: function(e) {
-            var username = e.data.options.username;
-            var urn = data.value;
-            var arrayselectedresources = data.selected_resources;
-
-            var accepted_sla = Array();
-            var count = 0;
-            var self = e.data;
-            // XXX check that the query is not disabled
-
-            console.log("DATA VALUE: " + data.value);
-            
-            //<p>SLA description</p>
-            //<p>Testbed guarantees 0.99 Uptime rate for 0.99 rate of the VirtualWall resources during the sliver lifetime</p>
-            //<p>SLA description</p>
-            //<p>Testbed guarantees 0.99 Uptime rate for 0.99 rate of the WiLab2 resources during the sliver lifetime</p>
-            var promt = $('#modal-body');
-            
-            // id="myModalLabel"
-            var flagVW = false;
-            var  flagWi = false;
-
-            promt.append('<p>SLA description</p>');
-            
-            var wilabForm = "";
-            wilabForm += "<ul>";
-            for(var iter = 0; iter < arrayselectedresources.length; iter++){
-                var list = '<li class="wi'+iter+'" name=wi"'+iter+'">'+arrayselectedresources[iter].toLowerCase()+'</li>';
-                
-                if (arrayselectedresources[iter].toLowerCase().indexOf("wilab2") >= 0){
-
-                    accepted_sla.push({"wilab2":false}); 
-                    wilabForm += list;   
-                    flagWi = true;             
-
-                }
-
-            }
-            wilabForm += "</ul>";
-
-            //var wallmessage = '<p>SLA description</p><p>Testbed guarantees 0.99 Uptime rate for 0.99 rate of the VirtualWall resources during the sliver lifetime</p>';
-
-            var wallForm = "";
-            wallForm += "<ul>";
-            for(var iter = 0; iter < arrayselectedresources.length; iter++){
-                var list = '<li class="wall'+iter+'" name=wall"'+iter+'" >'+arrayselectedresources[iter].toLowerCase()+'</li>';
-                
-                if (arrayselectedresources[iter].toLowerCase().indexOf("wall2") >= 0){
-
-                    accepted_sla.push({"wall2":false});
-                    wallForm += list;
-                    flagVW = true;
-                    
-                }
-
-            }
-            wallForm += "</ul>";
-            
-            var flagDouble = false;
-            if(flagWi)
-            {
-                flagDouble = true;
-                promt.append('<p>Testbed guarantees 0.99 Uptime rate for 0.99 rate of the WiLab2 resources during the sliver lifetime</p>');
-                promt.append(wilabForm);
-                promt.append('<br />');
-            }
-            if(flagVW)
-            {
-                //promt.append(wallmessage);
-                flagDouble = true;
-                promt.append('<p>Testbed guarantees 0.99 Uptime rate for 0.99 rate of the VirtualWall resources during the sliver lifetime</p>');
-                promt.append(wallForm);
-                promt.append('<br />');
-            }
-
-                        
-            // var wimessage = '<p>SLA description</p><p>Testbed guarantees 0.99 Uptime rate for 0.99 rate of the VirtualWall resources during the sliver lifetime</p>'
-
-            if(flagWi || flagVW){
-                $('#sla_dialog').show();
-
-                    $('#slamodal-wilab2').modal('show');
-            }
-            else
-            {
-                
-
-                var username = e.data.options.username;
-                var urn = data.value;
-                // XXX check that the query is not disabled
-
-                self.spin();
-                // XXX check that the query is not disabled
-                manifold.raise_event(self.options.query_uuid, RUN_UPDATE);
-                return;
-            }
-                    
-                        $("#accept_sla_wilab2").click(function(){
-                            console.log("SLA ACCEPTED");
-                            console.log("With username: " + username);
-
-                            // var promt = $('#modal-body');
-                            // var notchecked = true;
-                            // for (var i=0;i<50;i++)
-                            // {
-                            //     var wielement = $('#wi'+i);
-                            //     var wallElement = $('#wall'+i);
-                            //     if(wielement != null && !wielement.checked)
-                            //     {
-                            //         notchecked = false;
-                            //     }
-                            //     if(wallElement!= null && !wallElement.checked)
-                            //     {
-                            //         notchecked = false;
-                            //     }
-                            // }
-            
-                                                       
-                                if(flagDouble)
-                                {
-                                    $.post("/sla/agreements/simplecreate", 
-                                        { "template_id": "iMindsServiceWiLab2",
-                                          "user": username,
-                                          "expiration_time": new Date().toISOString()
-                                       });
-                                     $.post("/sla/agreements/simplecreate", 
-                                        { "template_id": "iMindsServiceVirtualwall",
-                                          "user": username,
-                                          "expiration_time": new Date().toISOString()
-                                       });
-                            
-                                    $('#slamodal-wilab2').modal('hide');
-                                accepted_sla["wilab2"] = true;
-                            
-                                manifold.raise_event(self.options.query_uuid, RUN_UPDATE);
-                            }
-                            $('#modal-body').empty();
-                        }); 
-                    
-                        $("#dismiss_sla_wilab2").click(function(){
-                            console.log("SLA NOT ACCEPTED");
-                            $('#slamodal-wilab2').modal('hide');
-                            $('#modal-body').empty();
-                        }); 
-                
-            // } else {
-            //     this.do_update(e);
-            // }
-
-            // for(var iter = 0; iter < arrayselectedresources.length; iter++){
-            //     var list = '<input type="checkbox" name="'+iter+'" >'+arrayselectedresources[iter].toLowerCase()+'<br>';
-            //     promt.append(list);
-            //     if (arrayselectedresources[iter].toLowerCase().indexOf("wall2") >= 0){
-
-
-                    
-            //         accepted_sla.push({"wall2":false});
-
-            //         $('#sla_dialog').show();
-            //         $('#slamodal-virtualwall').modal('show');
-                    
-                    
-            //             $("#accept_sla_vwall").click(function(){
-            //                 console.log("SLA ACCEPTED");
-            //                 console.log("With username: " + username);
-                        
-            //                 $.post("/sla/agreements/simplecreate", 
-            //                     { "template_id": "iMindsServiceVirtualwall",
-            //                       "user": username,
-            //                       "expiration_time": new Date()
-            //                     });
-                        
-            //                 $('#slamodal-virtualwall').modal('hide');
-            //                 accepted_sla["wall2"] = true;
-            //             }); 
-
-            //             $("#dismiss_sla_vwall").click(function(){
-            //                 console.log("SLA NOT ACCEPTED");
-            //                 $('#slamodal-vir').modal('hide');
-            //             }); 
-                    
-            //     }
-
-            //     if (arrayselectedresources[iter].toLowerCase().indexOf("wilab2") >= 0){
-
-            //         accepted_sla.push({"wilab2":false});
-
-            //         $('#sla_dialog').show();
-            //         $('#slamodal-wilab2').modal('show');
-                    
-                    
-            //             $("#accept_sla_wilab2").click(function(){
-            //                 console.log("SLA ACCEPTED");
-            //                 console.log("With username: " + username);
-                        
-            //                 $.post("/sla/agreements/simplecreate", 
-            //                     { "template_id": "iMindsServiceWiLab2",
-            //                       "user": username,
-            //                       "expiration_time": new Date()
-            //                     });
-                        
-            //                 $('#slamodal-wilab2').modal('hide');
-            //                 accepted_sla["wilab2"] = true;
-            //             }); 
-                    
-            //             $("#dismiss_sla_wilab2").click(function(){
-            //                 console.log("SLA NOT ACCEPTED");
-            //                 $('#slamodal-wilab2').modal('hide');
-            //             }); 
-                    
-
-            //     }
-
-            // }
-
-            // for(var sla in accepted_sla){
-            //     if(accepted_sla[sla] == true){
-            //         count += 1;
-            //     }
-            // }
-
-            // if(count == accepted_sla.length){
-            //     this.do_update(e);
-            // }
-        },
-
-     
         /************************** GUI MANIPULATION **************************/
 
         populate_table: function()
         {
+            var state;
+
             // Loop over records and display pending ones
             manifold.query_store.iter_records(this.options.query_uuid, function (record_key, record) {
+                state = manifold.query_store.get_record_state(this.options.query_uuid, null, STATE_SET);
+            
             });
         },
         
             return cols[0];
         },
 
-        set_state: function(data)
-        {
-            var action;
-            var msg;
-            var button = '';
-
-            var row;
-           
-           // make sure the change is visible : toggle on the whole plugin
-           // this might have to be made an 'auto-toggle' option of this plugin..
-           // also it might be needed to be a little finer-grained here
-
-        // XXX we don't want to show automaticaly the pending when a checkbox is checked
-           //this.toggle_on();
-
-            switch (data.status) {
-                case STATE_SET_IN_PENDING:
-                    action = 'ADD';
-                    msg   = 'PENDING';
-                    button = "<span class='glyphicon glyphicon-remove ResourceSelectedClose' id='" + data.key + "'/>";
-                    break;
-                case STATE_SET_OUT_PENDING:
-                    action = 'REMOVE';
-                    msg   = 'PENDING';
-                    button = "<span class='glyphicon glyphicon-remove ResourceSelectedClose' id='" + data.key + "'/>";
-                    break;
-                case STATE_SET_IN:
-                case STATE_SET_OUT:
-                    // find line and delete it
-                    // XXX Naming is incorrect for badge-pending !!!!
-                    // XXX What is this badge ?
-                    row = this.find_row(data.value);
-                    if (row)
-                        this.table.fnDeleteRow(row.nTr);
-                        /* indent was wrong !!
-                        $("#badge-pending").data('number', $("#badge-pending").data('number') - 1 );
-                        $("#badge-pending").text($("#badge-pending").data('number'));
-                        */
-                    return;
-                    break;  
-                case STATE_SET_IN_SUCCESS:
-                case STATE_SET_OUT_SUCCESS:
-                    msg   = 'SUCCESS';
-                    break;
-                case STATE_SET_IN_FAILURE:
-                case STATE_SET_OUT_FAILURE:
-                    msg   = 'FAILURE';
-                    break;
-                case STATE_CHANGE:
-                    action = 'UPDATE';
-                    break;
-                
-            }
-
-            var status = msg + status;
-
-            // find line
-            // if no, create it, else replace it
-            // XXX it's not just about adding lines, but sometimes removing some
-            // XXX how do we handle status reset ?
-
-            // Jordan : I don't understand this. I added this test otherwise we have string = ""..."" double quoted twice.
-            if (typeof(data.value) !== "string")
-                data.value = JSON.stringify(data.value);
-            data.selected_resources = this.selected_resources;
-            row = this.find_row(data.value);
-            newline = [
-                action,
-                data.key,
-                data.value,
-                msg,
-                button
-            ];
-            if (!row) {
-                // XXX second parameter refresh = false can improve performance. todo in querytable also
-                this.table.fnAddData(newline);
-                row = this.find_row(data.value);
-                /*
-                $("#badge-pending").data('number', $("#badge-pending").data('number') + 1 );
-                $("#badge-pending").text($("#badge-pending").data('number'));
-                */
-            } else {
-                // Update row text...
-                this.table.fnUpdate(newline, row.nTr);
-            }
-
-            // Change cell color according to status
-            if (row) {
-                $(row.nTr).removeClass('add remove')
-                var cls = action.toLowerCase();
-                if (cls)
-                    $(row.nTr).addClass(cls);
-            }
-        },
-
         do_update: function(e) {
             var self = e.data;
 
 
         },
 
-        // related buttons are also disabled in the html template
-        do_refresh: function(e)
-        {
-            throw 'resource_selected.do_refresh Not implemented';
-        },
-
-        do_reset: function(e)
+        do_ok: function(e)
         {
             throw 'queryupdater.do_reset Not implemented';
         },
 
-        do_clear_annotations: function(e)
+        do_cancel: function(e)
         {
             throw 'queryupdater.do_clear_annotations Not implemented';
         },
             this.spin();
         },
 
+        on_query_done: function()
+        {
+            this.populate_table();
+            this.unspin();
+        },
+
         // D : Data present
         // - on_clear_records (Get)
         // - on_new_record (shared with AD) XXX
         // - 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(result)
+        on_field_state_changed: function(data)
         {
+            /*
             if(result.request == FIELD_REQUEST_ADD){
                 this.selected_resources.push(result.value);
             } else if(result.request == FIELD_REQUEST_REMOVE_RESET){
                 }
             }
             this.set_state(result);
+            */
+
+            var action, msg, row, status, button = '';
+
+            switch(data.state) {
+                case STATE_VALUE:
+                    switch(data.op) {
+                        // XXX other events missing !!
+                        case STATE_VALUE_CHANGE_PENDING:
+                            action = 'UPDATE';
+                            break;
+                    }
+                    break;
+
+                case STATE_SET:
+                    switch(data.op) {
+                        case STATE_SET_IN_PENDING:
+                            action = 'ADD';
+                            msg   = 'PENDING';
+                            button = "<span class='glyphicon glyphicon-remove ResourceSelectedClose' id='" + data.key + "'/>";
+                            break;  
+
+                        case STATE_SET_OUT_PENDING:
+                            action = 'REMOVE';
+                            msg   = 'PENDING';
+                            button = "<span class='glyphicon glyphicon-remove ResourceSelectedClose' id='" + data.key + "'/>";
+                            break;
+
+                        case STATE_SET_IN:
+                        case STATE_SET_OUT:
+                            // find line and delete it
+                            row = this.find_row(data.value);
+                            if (row)
+                                this.table.fnDeleteRow(row.nTr);
+                            return;
+
+                        case STATE_SET_IN_SUCCESS:
+                        case STATE_SET_OUT_SUCCESS:
+                            msg   = 'SUCCESS';
+                            break;
+
+                        case STATE_SET_IN_FAILURE:
+                        case STATE_SET_OUT_FAILURE:
+                            msg   = 'FAILURE';
+                            break;
+
+                    }
+                    break;
+
+                default:
+                    return;
+            }
+
+            status = msg + status;
+
+            // find line
+            // if no, create it, else replace it
+            // XXX it's not just about adding lines, but sometimes removing some
+            // XXX how do we handle status reset ?
+
+            // Jordan : I don't understand this. I added this test otherwise we have string = ""..."" double quoted twice.
+            if (typeof(data.value) !== "string")
+                data.value = JSON.stringify(data.value);
+            data.selected_resources = this.selected_resources;
+            row = this.find_row(data.value);
+            newline = [action, data.key, data.value, msg, button];
+            if (!row) {
+                // XXX second parameter refresh = false can improve performance. todo in querytable also
+                this.table.fnAddData(newline);
+                row = this.find_row(data.value);
+            } else {
+                // Update row text...
+                this.table.fnUpdate(newline, row.nTr);
+            }
+
+            // Change cell color according to status
+            if (row) {
+                $(row.nTr).removeClass('add remove')
+                var cls = action.toLowerCase();
+                if (cls)
+                    $(row.nTr).addClass(cls);
+            }
         },
 
         // XXX we will have the requests for change
index 5f35a0f..77545c0 100755 (executable)
@@ -176,7 +176,7 @@ var SCHEDULER_COLWIDTH = 50;
 \r
         $scope._create_new_lease = function(resource_urn, start_time, end_time)\r
         {\r
-            var lease_key, new_lease;\r
+            var lease_key, new_lease, data;\r
 \r
             lease_key = manifold.metadata.get_key('lease');\r
 \r
@@ -190,7 +190,13 @@ var SCHEDULER_COLWIDTH = 50;
             new_lease.hashCode = manifold.record_hashcode(lease_key.sort());\r
             new_lease.equals   = manifold.record_equals(lease_key);\r
 \r
-            manifold.raise_event($scope.instance.options.query_lease_uuid, SET_ADD, new_lease);\r
+            data = {\r
+                state: STATE_SET,\r
+                key  : null,\r
+                op   : STATE_SET_ADD,\r
+                value: new_lease\r
+            }\r
+            manifold.raise_event($scope.instance.options.query_lease_uuid, FIELD_STATE_CHANGED, data);\r
             /* Add to local cache also, unless we listen to events from outside */\r
             if (!(resource_urn in $scope._leases_by_resource))\r
                 $scope._leases_by_resource[resource_urn] = [];\r
@@ -199,7 +205,7 @@ var SCHEDULER_COLWIDTH = 50;
 \r
         $scope._remove_lease = function(other)\r
         {\r
-            var lease_key, other_key;\r
+            var lease_key, other_key, data;\r
 \r
             lease_key = manifold.metadata.get_key('lease');\r
 \r
@@ -212,7 +218,13 @@ var SCHEDULER_COLWIDTH = 50;
             other_key.hashCode = manifold.record_hashcode(lease_key.sort());\r
             other_key.equals   = manifold.record_equals(lease_key);\r
 \r
-            manifold.raise_event($scope.instance.options.query_lease_uuid, SET_REMOVED, other_key);\r
+            data = {\r
+                state: STATE_SET,\r
+                key  : null,\r
+                op   : STATE_SET_REMOVE,\r
+                value: other_key\r
+            }\r
+            manifold.raise_event($scope.instance.options.query_lease_uuid, FIELD_STATE_CHANGED, data);\r
             /* Remove from local cache also, unless we listen to events from outside */\r
             $.grep($scope._leases_by_resource[other.resource], function(x) { return x != other; });\r
 \r
@@ -220,6 +232,8 @@ var SCHEDULER_COLWIDTH = 50;
 \r
         $scope.select = function(index, model_lease, model_resource)\r
         {\r
+            var data;\r
+\r
             console.log("Selected", index, model_lease, model_resource);\r
 \r
             var day_timestamp = SchedulerDateSelected.getTime() / 1000;\r
@@ -256,7 +270,13 @@ var SCHEDULER_COLWIDTH = 50;
                             other_key.hashCode = manifold.record_hashcode(lease_key.sort());\r
                             other_key.equals   = manifold.record_equals(lease_key);\r
         \r
-                            manifold.raise_event($scope.instance.options.query_lease_uuid, SET_REMOVED, other_key);\r
+                            data = {\r
+                                state: STATE_SET,\r
+                                key  : null,\r
+                                op   : STATE_SET_REMOVE,\r
+                                value: other_key\r
+                            }\r
+                            manifold.raise_event($scope.instance.options.query_lease_uuid, FIELD_STATE_CHANGED, data);\r
                             /* Remove from local cache also, unless we listen to events from outside */\r
                             $.grep($scope._leases_by_resource[model_resource.urn], function(x) { return x != other; });\r
                             return false; // ~ break\r
@@ -270,7 +290,6 @@ var SCHEDULER_COLWIDTH = 50;
                             /* The lease 'other' is just after, and there should not exist\r
                              * any other lease after it */\r
                             end_time = other.end_time;\r
-                            // XXX SET_ADD and SET_REMOVE should accept full objects\r
                             other_key = {\r
                                 resource:   other.resource,\r
                                 start_time: other.start_time,\r
@@ -280,7 +299,13 @@ var SCHEDULER_COLWIDTH = 50;
                             other_key.hashCode = manifold.record_hashcode(lease_key.sort());\r
                             other_key.equals   = manifold.record_equals(lease_key);\r
         \r
-                            manifold.raise_event($scope.instance.options.query_lease_uuid, SET_REMOVED, other_key);\r
+                            data = {\r
+                                state: STATE_SET,\r
+                                key  : null,\r
+                                op   : STATE_SET_REMOVE,\r
+                                value: other_key\r
+                            }\r
+                            manifold.raise_event($scope.instance.options.query_lease_uuid, FIELD_STATE_CHANGED, other_key);\r
                             /* Remove from local cache also, unless we listen to events from outside */\r
                             $.grep($scope._leases_by_resource[model_resource.urn], function(x) { return x != other; });\r
                             return false; // ~ break\r
@@ -337,7 +362,7 @@ var SCHEDULER_COLWIDTH = 50;
             }\r
             \r
 \r
-            //$scope._dump_leases();\r
+            $scope._dump_leases();\r
         };\r
   \r
         $scope._dump_leases = function()\r
@@ -686,54 +711,6 @@ var SCHEDULER_COLWIDTH = 50;
                 $("#plugin-scheduler").show();\r
             },\r
 \r
-        // GUI EVENTS\r
-\r
-        // TO BE REMOVED\r
-        _on_submit : function()\r
-        {\r
-            var leasesForCommit = new Array();\r
-            var tmpDateTime = SchedulerDateSelected;\r
-            for (var i = 0; i < SchedulerData.length; i++)\r
-            {\r
-                var tpmR = SchedulerData[i];\r
-                //for capturing start and end of the lease\r
-                var newLeaseStarted = false;\r
-                for (var j = 0; j < tpmR.leases.length; j++) {\r
-                    var tpmL = tpmR.leases[j];\r
-                    if (newLeaseStarted == false && tpmL.status == 'selected') {\r
-                        //get date of the slot\r
-                        tmpDateTime = schedulerGetDateTimeFromSlotId(tpmL.id, tmpDateTime);\r
-                        var unixStartTime = tmpDateTime.getTime() / 1000;\r
-                        //add lease object\r
-                        leasesForCommit.push({\r
-                            resource: tpmR.id,\r
-                            //granularity: tpmR.granularity,\r
-                            //lease_type: null,\r
-                            //slice: null,\r
-                            start_time: unixStartTime,\r
-                            end_time: null,\r
-                            //duration: null\r
-                        });\r
-                        console.log(tpmR.id);\r
-                        newLeaseStarted = true;\r
-                    } else if (newLeaseStarted == true && tpmL.status != 'selected') {\r
-                        //get date of the slot\r
-                        tmpDateTime = schedulerGetDateTimeFromSlotId(tpmL.id, tmpDateTime);\r
-                        var unixEndTime = tmpDateTime.getTime() / 1000;\r
-                        //upate end_time\r
-                        var tmpCL = leasesForCommit[leasesForCommit.length - 1];\r
-                        tmpCL.end_time = unixEndTime;\r
-                        //tmpCL.duration = schedulerFindDuration(tmpCL.start_time, tmpCL.end_time, tmpCL.granularity);\r
-                        newLeaseStarted = false;\r
-                    }\r
-                }\r
-            }\r
-            console.log(leasesForCommit);\r
-            for (var i = 0; i < leasesForCommit.length; i++) {\r
-                manifold.raise_event(scheduler2Instance.options.query_lease_uuid, SET_ADD, leasesForCommit[i]);\r
-            }\r
-        },\r
-        \r
         // PRIVATE METHODS\r
 \r
         /**\r
index da362d3..8fc5ceb 100644 (file)
@@ -230,7 +230,7 @@ class SliceResourceView (LoginRequiredView, ThemeView):
         apply = ApplyPlugin(
             page            = page,
             domid           = "apply",
-            query           = sq_resource,
+            query           = main_query #sq_resource,
         )