Improved testbed plugin to support facility_name and testbed_name filters
[unfold.git] / plugins / testbeds / static / js / testbeds.js
index f26602e..e628a67 100644 (file)
  * License:     GPLv3
  */
 
-(function($){
+// XXX Inherit from an AngularPlugin class ?
+(function (ng, app) {
 
-    var TestbedsPlugin = Plugin.extend({
+    // Define our Controller constructor.
+    function Controller($scope) {
+        /* Contructor */
 
-        /** XXX to check
-         * @brief Plugin constructor
-         * @param options : an associative array of setting values
-         * @param element : 
-         * @return : a jQuery collection of objects on which the plugin is
-         *     applied, which allows to maintain chainability of calls
-         */
-        init: function(options, element) {
-               // for debugging tools
-               this.classname="testbedsplugin";
-            // Call the parent constructor, see FAQ when forgotten
-            this._super(options, element);
+        /* Plugin instance */
+        $scope.instance = null;
 
-            /* Member variables */
-            this.filters = Array();
+        $scope.facility_names = Array();
+        $scope.testbed_names = new Object();
 
-            /* Plugin events */
+        /* Models */
+        //$scope.testbeds = Array();
+        $scope._facility_active = new Object();
+        $scope._testbed_active  = new Object();
 
-            /* Setup query and record handlers */
+        $scope.is_facility_active = function(facility)
+        {
+            return (($scope._facility_active[facility] === undefined) || $scope._facility_active[facility]);
+        };
 
-            // Explain this will allow query events to be handled
-            // What happens when we don't define some events ?
-            // Some can be less efficient
-            this.listen_query(options.query_uuid);
-            this.listen_query(options.query_all_uuid, 'all');
-            this.listen_query(options.query_network_uuid, 'network');
+        $scope.is_testbed_active = function(facility, testbed)
+        {
+            return (($scope._testbed_active[facility] === undefined) || 
+                    ($scope._testbed_active[facility][testbed] === undefined) || 
+                    ($scope._testbed_active[facility][testbed]));
+        };
 
-            /* GUI setup and event binding */
-            // call function
+        $scope.set_facility_active = function(facility, value)
+        {
+            $scope._facility_active[facility] = value;
+        };
 
-        },
+        $scope.set_testbed_active = function(facility, testbed, value)
+        {
+            if ($scope._testbed_active[facility] === undefined)
+                $scope._testbed_active[facility] = new Object();
+            $scope._testbed_active[facility][testbed] = value;
+        };
+    
+        /* Click event */
+
+        $scope.select_facility = function(facility)
+        {
+            var selected, prev_selected, num, num_selected, num_prev_selected, filter;
 
-        /* PLUGIN EVENTS */
-        // on_show like in querytable
+            prev_selected = $.map($scope.facility_names, function(x, i) {
+                return $scope.is_facility_active(x) ? x : null;
+            });
 
+            $scope.set_facility_active(facility, ! $scope.is_facility_active(facility));
 
-        /* GUI EVENTS */
+            selected = $.map($scope.facility_names, function(x, i) {
+                return $scope.is_facility_active(x) ? x : null;
+            });
 
-        // a function to bind events here: click change
-        // how to raise manifold events
+            num = $scope.facility_names.length;
+            prev_num_selected = prev_selected.length;
+            num_selected = selected.length;
 
+            if ((prev_num_selected != 0) && (prev_num_selected != num)) {
+                // Remove previous filter
+                filter = ['facility_name', 'included', prev_selected];
+                manifold.raise_event($scope.instance.options.query_uuid, FILTER_REMOVED, filter);
+            }
 
-        /* GUI MANIPULATION */
+            if (num_selected != num) {
+                filter = ['facility_name', 'included', selected];
+                manifold.raise_event($scope.instance.options.query_uuid, FILTER_ADDED, filter);
+            }
+        };
 
-        // We advise you to write function to change behaviour of the GUI
-        // Will use naming helpers to access content _inside_ the plugin
-        // always refer to these functions in the remaining of the code
+        $scope.select_testbed = function(facility, testbed)
+        {
+            var selected, prev_selected, num, num_selected, num_prev_selected, filter;
+
+            prev_selected = Array();
+            $.each($scope.facility_names, function(i, facility_name) {
+                $.each($scope.testbed_names[facility_name], function(j, testbed_name) {
+                    if ($scope.is_testbed_active(facility_name, testbed_name)) {
+                        // XXX We should have a joint facility/testbed filter
+                        prev_selected.push(testbed_name);
+                    }
+                });
+
+            });
+
+            $scope.set_testbed_active(facility, testbed, ! $scope.is_testbed_active(facility, testbed));
+
+            selected = Array();
+            $.each($scope.facility_names, function(i, facility_name) {
+                $.each($scope.testbed_names[facility_name], function(j, testbed_name) {
+                    if ($scope.is_testbed_active(facility_name, testbed_name)) {
+                        // XXX We should have a joint facility/testbed filter
+                        selected.push(testbed_name);
+                    }
+                });
+
+            });
+
+            num = 0;
+            $.each($scope.facility_names, function(i, facility_name) {
+                num += $scope.testbed_names[facility_name].length;
+            });
+            prev_num_selected = prev_selected.length;
+            num_selected = selected.length;
+
+            if ((prev_num_selected != 0) && (prev_num_selected != num)) {
+                // Remove previous filter
+                // XXX We should have a joint facility/testbed filter
+                filter = ['testbed_name', 'included', prev_selected];
+                manifold.raise_event($scope.instance.options.query_uuid, FILTER_REMOVED, filter);
+            }
 
-        show_hide_button: function() 
+            if (num_selected != num) {
+                // XXX We should have a joint facility/testbed filter
+                filter = ['testbed_name', 'included', selected];
+                manifold.raise_event($scope.instance.options.query_uuid, FILTER_ADDED, filter);
+            }
+        };
+
+        /* Return object reference */
+        return (this);
+    }
+
+    // Define the Controller as the constructor function.
+    app.controller("TestbedsCtrl", Controller);
+
+})(angular, ManifoldApp);
+
+(function($){
+    var TestbedsPlugin = Plugin.extend({
+
+        /** XXX to check
+         * @brief Plugin constructor
+         * @param options : an associative array of setting values
+         * @param element : 
+         * @return : a jQuery collection of objects on which the plugin is
+         *     applied, which allows to maintain chainability of calls
+         */
+        init: function(options, element) 
         {
-            // this.id, this.el, this.cl, this.elts
-            // same output as a jquery selector with some guarantees
-        },
+            // Call the parent constructor, see FAQ when forgotten
+            this._super(options, element);
 
-        /* TEMPLATES */
+            /* Member variables */
+            this.testbeds = Array();
 
-        // see in the html template
-        // How to load a template, use of mustache
+            this._get_scope().instance = this;
 
-        /* QUERY HANDLERS */
+            /* Handlers */
+            this.listen_query(options.query_uuid);
+            this.listen_query(options.query_networks_uuid, 'networks');
+        },
 
-        // How to make sure the plugin is not desynchronized
-        // He should manifest its interest in filters, fields or records
-        // functions triggered only if the proper listen is done
 
-        // no prefix
+        /* HANDLERS */
 
         /* When a filter is added/removed, update the list of filters local to the plugin */
+        /*
         on_filter_added: function(filter)
         {
             this.filters.push(filter);
                 }else if(filter[1]=='=' || filter[1]=='=='){
                     $("#testbeds-filter_"+filter[2]).addClass("active");
                 }
+                // XXX NAMING
+                // XXX How to display unsupported filters
+                // XXX Constants for operators
             }
         },
         on_filter_removed: function(filter)
                 }
             }
         },
-
+        */
         // ... be sure to list all events here
 
-        /* RECORD HANDLERS */
-        on_network_new_record: function(record)
+        on_query_done: function()
         {
-            row  = '<a href="#" class="list-group-item sl-platform" id="testbeds-filter_'+record["network_hrn"]+'" data-platform="'+record["network_hrn"]+'">';
-            row += '<span class="list-group-item-heading">'+record["platform"]+'</span>';
-            //row += '<span class="list-group-item-heading">'+record["network_hrn"]+'</span></a>';
-            row += '<p class="list-group-item-text">'+record["network_hrn"]+'</p></a>';
-            $('#testbeds-filter').append(row);
+            var scope, query_ext, resources;
+            scope = this._get_scope();
+            query_ext = manifold.query_store.find_analyzed_query_ext(this.options.query_uuid);
+            resources = query_ext.records.values();
+
+            $.each(resources, function(i, resource) {
+                if ($.inArray(resource.facility_name, scope.facility_names) == -1)
+                    scope.facility_names.push(resource.facility_name);
+                if (scope.testbed_names[resource.facility_name] === undefined)
+                    scope.testbed_names[resource.facility_name] = Array();
+                if ($.inArray(resource.testbed_name, scope.testbed_names[resource.facility_name]) == -1)
+                    scope.testbed_names[resource.facility_name].push(resource.testbed_name);
+            });
+
+            scope.$apply();
         },
 
-        /* When the network query is done, add the click event to the elements  */
-        on_network_query_done: function() {
-            var self = this;
-            console.log('query network DONE');
-            $("[id^='testbeds-filter_']").on('click',function(e) {
-                $(this).toggleClass("active");
-
-                // avoid multiple calls when an event is raised to manifold.js
-                e.stopPropagation();
-
-                value = this.dataset['platform'];
-                // handle the hrn that include . in their name (has to be in sync with the data from SFA)
-                value = value.replace(/\./g,"\\.");
-                key = "network_hrn";
-                op = "included";
-                return $(this).hasClass('active') ? self._addFilter(key, op, value) : self._removeFilter(key, op, value);
-            });
-           
+        /*
+        on_networks_query_done: function()
+        {
+            var scope = this._get_scope();
+            var query_ext = manifold.query_store.find_analyzed_query_ext(this.options.query_networks_uuid);
+            scope.testbeds = query_ext.records.values();
+            $.each(scope.testbeds, function(i, testbed) { testbed.active = true });
+            scope.$apply();
         },
+*/
 
         /* INTERNAL FUNCTIONS */
-        _dummy: function() {
-            // only convention, not strictly enforced at the moment
+
+        _get_scope : function()
+        {
+            return angular.element('[ng-controller=TestbedsCtrl]').scope()
         },
+
+/*
         _addFilter: function(key, op, value)
         {
-            console.log("add "+value);
-            var self = this;
             values = Array();
             // get the previous list of values for this key, ex: [ple,nitos]
             // remove the previous filter
             if(network_filter.length > 0){
                 $.each(network_filter, function(i,f){
                     values = f[2];
-                    manifold.raise_event(self.options.query_uuid, FILTER_REMOVED, [key, op, values]);
                 });
             }
             // Add the new value to list of values, ex: wilab
             // Update the filter with the new list of values, ex: [ple,nitos,wilab]
             manifold.raise_event(this.options.query_uuid, FILTER_ADDED, [key, op, values]);
         },
+
         _removeFilter: function(key, op, value)
         {
             console.log("remove "+value);
                 manifold.raise_event(this.options.query_uuid, FILTER_ADDED, [key, op, values]);
             }
         }
-
+*/
     });
 
     /* Plugin registration */