http://git-wip-us.apache.org/repos/asf/incubator-griffin/blob/a8ba6ba9/griffin-ui/js/controllers/createrule-ac-ctrl.js
----------------------------------------------------------------------
diff --git a/griffin-ui/js/controllers/createrule-ac-ctrl.js 
b/griffin-ui/js/controllers/createrule-ac-ctrl.js
new file mode 100644
index 0000000..a3a5f0e
--- /dev/null
+++ b/griffin-ui/js/controllers/createrule-ac-ctrl.js
@@ -0,0 +1,494 @@
+/*
+       Copyright (c) 2016 eBay Software Foundation.
+       Licensed under the Apache License, Version 2.0 (the "License");
+       you may not use this file except in compliance with the License.
+       You may obtain a copy of the License at
+
+           http://www.apache.org/licenses/LICENSE-2.0
+
+       Unless required by applicable law or agreed to in writing, software
+       distributed under the License is distributed on an "AS IS" BASIS,
+       WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+       See the License for the specific language governing permissions and
+       limitations under the License.
+*/
+define(['./module'], function(controllers) {
+    'use strict';
+    controllers.controller('CreateRuleACCtrl', ['$scope', '$http', '$config', 
'$location', 'toaster', '$timeout', '$route', '$filter', function($scope, 
$http, $config, $location, toaster, $timeout, $route, $filter) {
+        console.log('Create rule controller');
+        $scope.currentStep = 1;
+        //for dev purpose
+        //the selected columns for step 1
+        $scope.selection = [];
+        $scope.selectionTarget = [];
+        $scope.selectionPK = [];
+        $scope.mappings = [];
+        $scope.matches = [];
+        // $scope.pk = '';
+
+        var dbtreeUrl = $config.uri.dbtree;
+        var schemaDefinitionUrl = $config.uri.schemadefinition;
+
+        $http.get(dbtreeUrl).success(function(data) {
+            var dbList = [];
+            if (data && data.length > 0) {
+                data.forEach(function(db) {
+                    var dbNode = {
+                        name: db.platform,
+                        l1: true,
+                        children: []
+                    };
+                    dbList.push(dbNode);
+                    if (db.systems && db.systems.length > 0) {
+                        db.systems.forEach(function(system) {
+                            var dsNode = {
+                                name: system.name,
+                                l2: true,
+                                children: []
+                            };
+                            dbNode.children.push(dsNode);
+                            dsNode.parent = db;
+
+
+                            if (system.assets && system.assets.length > 0) {
+                                system.assets.sort(function(a, b){
+                                  return 
(a.name<b.name?-1:(a.name>b.name?1:0));
+                                });
+                                system.assets.forEach(function(schema) {
+                                    var schemaNode = {
+                                        id: schema.id,
+                                        name: schema.name,
+                                        l3: true
+                                    };
+                                    schemaNode.parent = dsNode;
+                                    dsNode.children.push(schemaNode);
+                                });
+                            }
+                        });
+                    }
+
+                });
+            }
+            $scope.dbList = dbList;
+            $scope.dbListTarget = angular.copy(dbList);
+        });
+
+        //trigger after select schema for src
+        $scope.$watch('currentNode', function(newValue) {
+            console.log(newValue);
+            $scope.selection = [];
+            $scope.selectedAll = false;
+
+            // $scope.schemaCollection = null;
+            if (newValue && newValue.l3) {
+
+                //retrieve the schema definition and display the table
+                $http.get(schemaDefinitionUrl + '/' + 
newValue.id).success(function(data) {
+
+                    $scope.schemaCollection = data.schema;
+                });
+            }
+        });
+
+        $scope.selectNodeLabelTarget = function(selectedNode) {
+
+            //remove highlight from previous node
+            if ($scope.currentNodeTarget && $scope.currentNodeTarget.selected) 
{
+                $scope.currentNodeTarget.selected = undefined;
+            }
+
+            if (selectedNode.children && selectedNode.children.length > 0) {
+                $scope.selectNodeHead(selectedNode);
+            } else {
+                //set highlight to selected node
+                selectedNode.selected = 'selected';
+            }
+
+            //set currentNode
+            $scope.currentNodeTarget = selectedNode;
+        }
+        ;
+
+        //trigger after select schema
+        $scope.$watch('currentNodeTarget', function(newValue) {
+            console.log(newValue);
+            $scope.selectionTarget = [];
+            $scope.selectedAllTarget = false;
+
+            // $scope.schemaCollection = null;
+            if (newValue) {
+
+                //retrieve the schema definition and display the table
+                if(newValue.l3){//System selected
+                  var sysName = newValue.parent.name;
+                  $scope.form.basic.system = $filter('stridx')(sysName, 
'modelsystem') + '';
+                  $http.get(schemaDefinitionUrl + '/' + 
newValue.id).success(function(data) {
+
+                      $scope.schemaCollectionTarget = data.schema;
+                  });
+                }
+
+
+            }
+        });
+
+        // $scope.$watch('selectionTarget', function(newValue) {
+        //     if (newValue && newValue.length > 0) {
+        //         $scope.pk = newValue[0];
+        //         // console.log('-----$scope.pk: ' + $scope.pk);
+        //     }
+        // });
+
+        //column selection
+
+        $scope.toggleSelection = function toggleSelection($event) {
+            var value = $event.target.value;
+            var idx = $scope.selection.indexOf(value);
+            // is currently selected
+            if (idx > -1) {
+                $scope.selection.splice(idx, 1);
+                $scope.selectedAll = false;
+            }
+            // is newly selected
+
+            else {
+                $scope.selection.push(value);
+            }
+        }
+        ;
+
+        $scope.toggleAll = function() {
+            if ($scope.selectedAll) {
+                $scope.selectedAll = true;
+            } else {
+                $scope.selectedAll = false;
+            }
+
+            $scope.selection = [];
+            angular.forEach($scope.schemaCollection, function(item) {
+                item.selected = $scope.selectedAll;
+                if ($scope.selectedAll) {
+                    $scope.selection.push($scope.currentNode.name + '.' + 
item.name);
+                }
+            });
+        }
+
+        $scope.toggleSelectionTarget = function($event) {
+            var value = $event.target.value;
+            var idx = $scope.selectionTarget.indexOf(value);
+            // is currently selected
+            if (idx > -1) {
+                $scope.selectionTarget.splice(idx, 1);
+                $scope.selectedAllTarget = false;
+            }
+            // is newly selected
+
+            else {
+                $scope.selectionTarget.push(value);
+            }
+        }
+        ;
+
+        $scope.toggleAllTarget = function() {
+            if ($scope.selectedAllTarget) {
+                $scope.selectedAllTarget = true;
+            } else {
+                $scope.selectedAllTarget = false;
+            }
+
+            $scope.selectionTarget = [];
+            angular.forEach($scope.schemaCollectionTarget, function(item) {
+                item.selected = $scope.selectedAllTarget;
+                if ($scope.selectedAllTarget) {
+                    $scope.selectionTarget.push($scope.currentNodeTarget.name 
+ '.' + item.name);
+                }
+            });
+        }
+
+        $scope.toggleSelectionPK = function($event) {
+            var value = $event.target.value;
+            var idx = $scope.selectionPK.indexOf(value);
+            // is currently selected
+            if (idx > -1) {
+                $scope.selectionPK.splice(idx, 1);
+                $scope.selectedAllPK = false;
+            }
+            // is newly selected
+
+            else {
+                $scope.selectionPK.push(value);
+            }
+        };
+
+        $scope.toggleAllPK = function() {
+            $scope.selectionPK = [];
+            if ($scope.selectedAllPK) {
+                $scope.selectedAllPK = true;
+                angular.forEach($scope.selectionTarget, function(item) {
+                    $scope.selectionPK.push(item);
+                });
+            } else {
+                $scope.selectedAllPK = false;
+            }
+        };
+
+        $scope.$on('$viewContentLoaded', function() {
+            // console.log($('#footerwrap').css('height'));
+            // console.log($('.formStep').offset());
+            $scope.$emit('initReq');
+            resizeWindow();
+
+            //  $('#confirm').on('hidden.bs.modal', function (e) {
+            //    console.log('hidden');
+            //   //  $('#confirm').off('hidden.bs.modal');
+            //    $location.path('/rules');
+            //   });
+
+            // $('.formStep').css({height: 800});
+        });
+
+        $scope.$on('resizeHandler', function(e) {
+            if ($route.current.$$route.controller == "CreateRuleACCtrl") {
+                $scope.$emit('initReq');
+                resizeWindow();
+            }
+        });
+
+
+        function resizeWindow() {
+                    var stepSelection = '.formStep[id=step-' + 
$scope.currentStep + ']';
+                    $(stepSelection).css({
+                        height: window.innerHeight - 
$(stepSelection).offset().top - $('#footerwrap').outerHeight()
+                    });
+                    $('fieldset').height($(stepSelection).height() - 
$(stepSelection + '>.stepDesc').height() - $('.btn-container').height() - 80);
+                    $('.y-scrollable').css({
+                        'max-height': $('fieldset').height()- 
$('.add-dataset').outerHeight()
+                    });
+
+        }
+
+        $scope.ruleTypes = $filter('strarr')('modeltype');//['Accuracy', 
'Validity', 'Anomaly Detection', 'Publish Metrics'];
+        $scope.scheduleTypes = $filter('strarr')('scheduletype');//['Daily', 
'Weekly', 'Monthly', 'Hourly'];
+        $scope.ruleSystems = $filter('strarr')('modelsystem');//['Bullseye', 
'GPS', 'Hadoop', 'PDS', 'IDLS', 'Pulsar', 'Kafka'];
+        $scope.matchFunctions = ['LENGTH', 'LOWER', 'UPPER', 'TRIM'];
+
+        // $scope.ruleType = function(index){
+        //   var types = ['', 'Accuracy', 'Validity', 'Anomaly Detection', 
'Publish Metrics'];
+        //   return types[index];
+        // }
+        //
+        // $scope.scheduleType = function(index){
+        //   var types = ['', 'Daily', 'Weekly', 'Monthly', 'Hourly'];
+        //   return types[index];
+        // }
+        //
+        // $scope.ruleSystem = function(index){
+        //   var sys = ['', 'Bullseye', 'GPS', 'Hadoop', 'PDS', 'IDLS', 
'Pulsar', 'Kafka'];
+        //   return sys[index];
+        // }
+
+        // Initial Value
+        $scope.form = {
+
+            next: function(form) {
+
+                if (formValidation()) {
+                    // form.$setPristine();
+                    nextStep();
+                } else {
+                    var field = null
+                      , firstError = null ;
+                    for (field in form) {
+                        if (field[0] != '$') {
+                            if (firstError === null  && !form[field].$valid) {
+                                firstError = form[field].$name;
+                            }
+
+                            if (form[field].$pristine) {
+                                form[field].$dirty = true;
+                            }
+                        }
+                    }
+
+                    //  angular.element('.ng-invalid[name=' + firstError + 
']').focus();
+                    errorMessage($scope.currentStep);
+                }
+            },
+            prev: function(form) {
+                //$scope.toTheTop();
+                prevStep();
+            },
+            goTo: function(form, i) {
+                if (parseInt($scope.currentStep) > parseInt(i)) {
+                    // $scope.toTheTop();
+                    goToStep(i);
+
+                } else {
+                    if (formValidation()) {
+                        //   $scope.toTheTop();
+                        if(i - parseInt($scope.currentStep) == 1){
+                          goToStep(i);
+                        }
+
+                    } else {
+                        errorMessage($scope.currentStep);
+                    }
+                }
+            },
+            submit: function(form) {
+                if (!form.$valid) {
+                    var field = null
+                      , firstError = null ;
+                    for (field in form) {
+                        if (field[0] != '$') {
+                            if (firstError === null  && !form[field].$valid) {
+                                firstError = form[field].$name;
+                            }
+
+                            if (form[field].$invalid) {
+                                form[field].$dirty = true;
+                            }
+                        }
+                    }
+                    angular.element('.ng-invalid[name=' + firstError + 
']').focus();
+                    errorMessage($scope.currentStep);
+                } else {
+                    //  $location.path('/rules');
+                    form.$setPristine();
+                    this.data={
+                      basic: this.basic,
+                      extra: {
+                        srcDb: $scope.currentNode.parent.parent.platform,
+                        srcDataSet: $scope.currentNode.parent.name,
+                        targetDb: 
$scope.currentNodeTarget.parent.parent.platform,
+                        targetDataSet: $scope.currentNodeTarget.parent.name
+                      },
+                      mappings:[]
+                    };
+
+                    this.data.basic.dataaset = $scope.currentNodeTarget.name;
+                    this.data.basic.dataasetId = $scope.currentNodeTarget.id;
+
+                    for(var i =0; i < $scope.selectionTarget.length; i ++){
+                      
this.data.mappings.push({target:$scope.selectionTarget[i],
+                                      src:$scope.mappings[i],
+                                      matchMethod: $scope.matches[i],
+                                      isPk: 
($scope.selectionPK.indexOf($scope.selectionTarget[i])>-1)?true:false});
+                    }
+
+                    $('#confirm').modal('show');
+                }
+            },
+
+            save: function() {
+
+
+                //::TODO: Need to save the data to backend with POST/PUT method
+                console.log(JSON.stringify($scope.form.data));
+
+                var newModel = $config.uri.newAccuracyModel;
+                $http.post(newModel, this.data).success(function(data) {
+                       // if(data.status=='0')
+                       // {
+                         $('#confirm').on('hidden.bs.modal', function(e) {
+                             $('#confirm').off('hidden.bs.modal');
+                             $location.path('/rules').replace();
+                             $scope.$apply();
+                         });
+                               $('#confirm').modal('hide');
+                       // }
+                       // else
+                       // {
+                       //      errorMessage(0, data.result);
+                       // }
+                }).error(function(data){
+                  // errorMessage(0, 'Save model failed, please try again!');
+                  toaster.pop('error', 'Save model failed, please try again!', 
data.message);
+                });
+
+            },
+
+            // reset: function() {
+            //
+            // },
+            //
+            // ruleType: 1
+        }
+
+
+        var nextStep = function() {
+            $scope.currentStep++;
+            $timeout(function(){
+                resizeWindow();
+            }, 0);
+        }
+
+        var prevStep = function() {
+            $scope.currentStep--;
+            $timeout(function(){
+                resizeWindow();
+            }, 0);
+        }
+
+        var goToStep = function(i) {
+            $scope.currentStep = i;
+
+            $timeout(function(){
+                resizeWindow();
+            }, 0);
+        }
+
+        $scope.$watch('currentStep', function(newValue){
+          if(newValue == 3){ //step 3
+            if($scope.selectionTarget.length < $scope.mappings.length){
+              $scope.mappings.splice($scope.selectionTarget.length);
+            }
+          }
+        });
+
+        var existDuplicatedElement = function(arr){
+
+            for (var i = 0; i < arr.length; i++) {
+                for (var j = i+1; j < arr.length; j++) {
+                    if(arr[i] == arr[j]){
+                        return true;
+                    }
+                };
+            };
+            return false;
+        };
+
+        //validation only happens when going forward
+        var formValidation = function(step) {
+            //  return true;//for dev purpose
+            if (step == undefined) {
+                step = $scope.currentStep;
+            }
+            if (step == 1) {
+                return $scope.selection && $scope.selection.length > 0;
+            } else if (step == 2) {
+                return ($scope.selectionTarget && 
$scope.selectionTarget.length > 0)//at least one target is selected
+                        && !(($scope.currentNode.name == 
$scope.currentNodeTarget.name)&&($scope.currentNode.parent.name == 
$scope.currentNodeTarget.parent.name));//target and source should be different
+            } else if (step == 3) {
+                return $scope.selectionTarget && $scope.selectionTarget.length 
== $scope.mappings.length
+                        && $scope.mappings.indexOf('') == -1 && 
!existDuplicatedElement($scope.mappings)
+                        && $scope.selectionPK && $scope.selectionPK.length>0;
+            } else if (step == 4) {
+
+            }
+
+            return false;
+        }
+
+        var errorMessage = function(i, msg) {
+            var errorMsgs = ['Please select at least one attribute!', 'Please 
select at least one attribute in target, make sure target is different from 
source!', 'Please make sure to map each target to a unique source and select at 
least one primary key.', 'please complete the form in this step before 
proceeding'];
+            if (!msg) {
+                toaster.pop('error', 'Error', errorMsgs[i - 1], 0);
+            } else {
+                toaster.pop('error', 'Error', msg, 0);
+            }
+        }
+        ;
+    }
+    ]);
+});

http://git-wip-us.apache.org/repos/asf/incubator-griffin/blob/a8ba6ba9/griffin-ui/js/controllers/createrule-an-ctrl.js
----------------------------------------------------------------------
diff --git a/griffin-ui/js/controllers/createrule-an-ctrl.js 
b/griffin-ui/js/controllers/createrule-an-ctrl.js
new file mode 100644
index 0000000..891c23e
--- /dev/null
+++ b/griffin-ui/js/controllers/createrule-an-ctrl.js
@@ -0,0 +1,298 @@
+/*
+       Copyright (c) 2016 eBay Software Foundation.
+       Licensed under the Apache License, Version 2.0 (the "License");
+       you may not use this file except in compliance with the License.
+       You may obtain a copy of the License at
+
+           http://www.apache.org/licenses/LICENSE-2.0
+
+       Unless required by applicable law or agreed to in writing, software
+       distributed under the License is distributed on an "AS IS" BASIS,
+       WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+       See the License for the specific language governing permissions and
+       limitations under the License.
+*/
+define(['./module'], function(controllers) {
+    'use strict';
+    controllers.controller('CreateRuleANCtrl', ['$scope', '$http', '$config', 
'$location', 'toaster', '$timeout', '$route', '$filter', function($scope, 
$http, $config, $location, toaster, $timeout, $route, $filter) {
+        console.log('CreateRuleANCtrl');
+        $scope.currentStep = 1;
+
+        var dbtreeUrl = $config.uri.dbtree;
+        var schemaDefinitionUrl = $config.uri.schemadefinition;
+
+        $http.get(dbtreeUrl).success(function(data) {
+            var dbList = [];
+            if (data && data.length > 0) {
+                data.forEach(function(db) {
+                    var dbNode = {
+                        name: db.platform,
+                        l1: true,
+                        children: []
+                    };
+                    dbList.push(dbNode);
+                    if (db.systems && db.systems.length > 0) {
+                        db.systems.forEach(function(system) {
+                            var dsNode = {
+                                name: system.name,
+                                l2: true,
+                                children: []
+                            };
+                            dbNode.children.push(dsNode);
+                            dsNode.parent = db;
+
+
+                            if (system.assets && system.assets.length > 0) {
+                                system.assets.sort(function(a, b){
+                                  return 
(a.name<b.name?-1:(a.name>b.name?1:0));
+                                });
+                                system.assets.forEach(function(schema) {
+                                    var schemaNode = {
+                                        id: schema.id,
+                                        name: schema.name,
+                                        l3: true
+                                    };
+                                    schemaNode.parent = dsNode;
+                                    dsNode.children.push(schemaNode);
+                                });
+                            }
+                        });
+                    }
+
+                });
+            }
+            $scope.dbList = dbList;
+        });
+
+
+        //trigger after select schema for src
+        $scope.$watch('currentNode', function(newValue) {
+            // $scope.schemaCollection = null;
+            if (newValue && newValue.l3) {
+
+                var sysName = newValue.parent.name;
+                $scope.form.basic.system = $filter('stridx')(sysName, 
'modelsystem') + '';
+
+                //retrieve the schema definition and display the table
+                $http.get(schemaDefinitionUrl + '/' + 
newValue.id).success(function(data) {
+                    $scope.schemaCollection = data.schema;
+                });
+            }
+        });
+
+
+
+
+        $scope.$on('$viewContentLoaded', function() {
+            $scope.$emit('initReq');
+            resizeWindow();
+        });
+
+        $scope.$on('resizeHandler', function(e) {
+            if ($route.current.$$route.controller == "CreateRuleANCtrl") {
+                $scope.$emit('initReq');
+                resizeWindow();
+            }
+        });
+
+
+        function resizeWindow() {
+                    var stepSelection = '.formStep[id=step-' + 
$scope.currentStep + ']';
+                    $(stepSelection).css({
+                        height: window.innerHeight - 
$(stepSelection).offset().top - $('#footerwrap').outerHeight()
+                    });
+                    $('fieldset').height($(stepSelection).height() - 
$(stepSelection + '>.stepDesc').height() - $('.btn-container').height() - 80);
+                    $('.y-scrollable').css({
+                        'max-height': $('fieldset').height() - 
$('.add-dataset').outerHeight()
+                    });
+                    //error message box position
+                    $('.formula-text-mid').css({
+                        'padding-top': (($('.formula-text-up').height() - 
$('.formula-text-mid').height()) + $('.formula-text-mid').height() / 2) + 'px'
+                    });
+
+        }
+
+        $scope.ruleTypes = $filter('strarr')('modeltype');//['Accuracy', 
'Validity', 'Anomaly Detection', 'Publish Metrics'];
+        $scope.scheduleTypes = $filter('strarr')('scheduletype');//['Daily', 
'Weekly', 'Monthly', 'Hourly'];
+        $scope.ruleSystems = $filter('strarr')('modelsystem');//['Bullseye', 
'GPS', 'Hadoop', 'PDS', 'IDLS', 'Pulsar', 'Kafka'];
+        $scope.anTypes = ['', 'History Trend Detection', 'Bollinger Bands 
Detection', 'Deviation Detection'];
+        // $scope.ruleType = function(index){
+        //   var types = ['', 'Accuracy', 'Validity', 'Anomaly Detection', 
'Publish Metrics'];
+        //   return types[index];
+        // }
+
+        // $scope.scheduleType = function(index){
+        //   var types = ['', 'Daily', 'Weekly', 'Monthly', 'Hourly'];
+        //   return types[index];
+        // }
+        //
+        // $scope.ruleSystem = function(index){
+        //   var sys = ['', 'Bullseye', 'GPS', 'Hadoop', 'PDS', 'IDLS', 
'Pulsar', 'Kafka'];
+        //   return sys[index];
+        // }
+
+        // Initial Value
+        $scope.form = {
+
+            next: function(form) {
+
+                if (formValidation()) {
+                    // form.$setPristine();
+                    nextStep();
+                } else {
+                    var field = null
+                      , firstError = null ;
+                    for (field in form) {
+                        if (field[0] != '$') {
+                            if (firstError === null  && !form[field].$valid) {
+                                firstError = form[field].$name;
+                            }
+
+                            if (form[field].$pristine) {
+                                form[field].$dirty = true;
+                            }
+                        }
+                    }
+
+                    //  angular.element('.ng-invalid[name=' + firstError + 
']').focus();
+                    errorMessage($scope.currentStep);
+                }
+            },
+            prev: function(form) {
+                //$scope.toTheTop();
+                prevStep();
+            },
+            goTo: function(form, i) {
+                if (parseInt($scope.currentStep) > parseInt(i)) {
+                    // $scope.toTheTop();
+                    goToStep(i);
+
+                } else {
+                    if (formValidation()) {
+                        //   $scope.toTheTop();
+                        if(i - parseInt($scope.currentStep) == 1){
+                          goToStep(i);
+                        }
+
+                    } else {
+                        errorMessage($scope.currentStep);
+                    }
+                }
+            },
+            submit: function(form) {
+                if (!form.$valid) {
+                    var field = null
+                      , firstError = null ;
+                    for (field in form) {
+                        if (field[0] != '$') {
+                            if (firstError === null  && !form[field].$valid) {
+                                firstError = form[field].$name;
+                            }
+
+                            if (form[field].$invalid) {
+                                form[field].$dirty = true;
+                            }
+                        }
+                    }
+                    angular.element('.ng-invalid[name=' + firstError + 
']').focus();
+                    errorMessage($scope.currentStep);
+                } else {
+                    form.$setPristine();
+                    this.data={
+                      basic: this.basic,
+                      extra: {
+                        srcDb: $scope.currentNode.parent.parent.platform,
+                        srcDataSet: $scope.currentNode.parent.name,
+                        anType: this.anType
+                      }
+                    };
+
+                    this.data.basic.dataaset = $scope.currentNode.name;
+                    this.data.basic.dataasetId = $scope.currentNode.id;
+                    // this.data.anType = this.anType;
+
+                    $('#confirm-an').modal('show');
+                }
+            },
+
+            save: function() {
+
+                //::TODO: Need to save the data to backend with POST/PUT method
+                console.log(JSON.stringify($scope.form.data));
+
+                var newModel = $config.uri.newAnomalyModel;
+                $http.post(newModel, this.data).success(function(data) {
+                       // if(data.status=='0')
+                       // {
+                         $('#confirm-an').on('hidden.bs.modal', function(e) {
+                             $('#confirm-an').off('hidden.bs.modal');
+                             $location.path('/rules');
+                             $scope.$apply();
+                         });
+                               $('#confirm-an').modal('hide');
+                       // }
+                       // else
+                       // {
+                       //      errorMessage(0, data.result);
+                       // }
+                }).error(function(data){
+                  // errorMessage(0, 'Save model failed, please try again!');
+                  toaster.pop('error', 'Save model failed, please try again!', 
data.message);
+                });
+            },
+
+        };
+
+
+        var nextStep = function() {
+            $scope.currentStep++;
+            $timeout(function(){
+                resizeWindow();
+            }, 0);
+        }
+        ;
+        var prevStep = function() {
+            $scope.currentStep--;
+            $timeout(function(){
+                resizeWindow();
+            }, 0);
+        }
+        ;
+        var goToStep = function(i) {
+            $scope.currentStep = i;
+            $timeout(function(){
+                resizeWindow();
+            }, 0);
+        }
+        ;
+
+        //validation only happens when going forward
+        var formValidation = function(step) {
+            //  return true;//for dev purpose
+            if (step == undefined) {
+                step = $scope.currentStep;
+            }
+            if (step == 1) {
+                return $scope.currentNode?true:false;
+            } else if (step == 2) {
+                return true;
+            } else if (step == 3) {
+                return true;
+                //::TODO: also need to check if duplicated mappings or empty 
mappings
+            }
+
+            return false;
+        }
+
+        var errorMessage = function(i, msg) {
+            var errorMsgs = ['Please select one schema!','', 'please complete 
the form in this step before proceeding'];
+            if (!msg) {
+                toaster.pop('error', 'Error', errorMsgs[i - 1], 0);
+            } else {
+                toaster.pop('error', 'Error', msg, 0);
+            }
+        }
+        ;
+    }
+    ]);
+});

http://git-wip-us.apache.org/repos/asf/incubator-griffin/blob/a8ba6ba9/griffin-ui/js/controllers/createrule-pu-ctrl.js
----------------------------------------------------------------------
diff --git a/griffin-ui/js/controllers/createrule-pu-ctrl.js 
b/griffin-ui/js/controllers/createrule-pu-ctrl.js
new file mode 100644
index 0000000..1786fb3
--- /dev/null
+++ b/griffin-ui/js/controllers/createrule-pu-ctrl.js
@@ -0,0 +1,161 @@
+/*
+       Copyright (c) 2016 eBay Software Foundation.
+       Licensed under the Apache License, Version 2.0 (the "License");
+       you may not use this file except in compliance with the License.
+       You may obtain a copy of the License at
+
+           http://www.apache.org/licenses/LICENSE-2.0
+
+       Unless required by applicable law or agreed to in writing, software
+       distributed under the License is distributed on an "AS IS" BASIS,
+       WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+       See the License for the specific language governing permissions and
+       limitations under the License.
+*/
+define(['./module'], function(controllers) {
+    'use strict';
+    controllers.controller('CreateRulePUCtrl', ['$scope', '$http', '$config', 
'$location', 'toaster', '$timeout', '$route', '$filter', function($scope, 
$http, $config, $location, toaster, $timeout, $route, $filter) {
+        console.log('Create rule controller');
+        $scope.currentStep = 1;
+
+        // var publishBasic = 'https://bark.vip.ebay.com/api/v1/metrics';
+        var publishBasic = document.location.origin;
+        // $scope.form.publishUrl = publishBasic;
+        $scope.$watch('form.basic.name', function(newValue){
+          $scope.form.publishUrl = publishBasic;// + (newValue?newValue:'');
+        });
+
+        $scope.$on('$viewContentLoaded', function() {
+            $scope.$emit('initReq');
+            resizeWindow();
+        });
+
+        var dbtreeUrl = $config.uri.dbtree;
+          $http.get(dbtreeUrl).success(function(data) {
+            // console.log(data);
+            angular.forEach(data, function(p){
+              if(p.platform == 'Apollo'){ //::TODO:Only Apollo is supported 
cussrently
+                $scope.allSystem = {};
+                angular.forEach(p.systems, function(sys){ //retrieve all 
systems
+                  $scope.allSystem[sys.name] = sys.assets;
+                });
+              }
+            });
+
+            $scope.sysChange();
+
+          });
+
+        $scope.sysChange = function(){
+          console.log($scope.form.basic.system);
+          var sys = $scope.form.basic.system;
+          var sysName = $filter('strmap')(sys, 'modelsystem');
+          $scope.assets = $scope.allSystem[sysName];
+
+        }
+
+        $scope.$on('resizeHandler', function(e) {
+            if ($route.current.$$route.controller == "CreateRulePUCtrl") {
+                resizeWindow();
+            }
+        });
+
+        function resizeWindow() {
+                    var stepSelection = '.formStep[id=step-' + 
$scope.currentStep + ']';
+                    $(stepSelection).css({
+                        height: window.innerHeight - 
$(stepSelection).offset().top - $('#footerwrap').outerHeight()
+                    });
+                    $('fieldset').height($(stepSelection).height() - 
$(stepSelection + '>.stepDesc').height() - $('.btn-container').height() - 80);
+                    $('.y-scrollable').css({
+                        'max-height': $('fieldset').height()
+                    });
+        }
+
+        $scope.ruleTypes = $filter('strarr')('modeltype');//['Accuracy', 
'Validity', 'Anomaly Detection', 'Publish Metrics'];
+        $scope.scheduleTypes = $filter('strarr')('scheduletype');//['Daily', 
'Weekly', 'Monthly', 'Hourly'];
+        $scope.ruleSystems = $filter('strarr')('modelsystem');//['Bullseye', 
'GPS', 'Hadoop', 'PDS', 'IDLS', 'Pulsar', 'Kafka'];
+
+        // Initial Value
+        $scope.form = {
+            submit: function(form) {
+                if (!form.$valid) {
+                    var field = null
+                      , firstError = null ;
+                    for (field in form) {
+                        if (field[0] != '$') {
+                            if (firstError === null  && !form[field].$valid) {
+                                firstError = form[field].$name;
+                            }
+
+                            if (form[field].$invalid) {
+                                form[field].$dirty = true;
+                            }
+                        }
+                    }
+                    angular.element('.ng-invalid[name=' + firstError + 
']').focus();
+                    errorMessage($scope.currentStep);
+                } else {
+                  if(this.basic.system == -1){
+                    errorMessage(0, 'Please select Organization');
+                  }else{
+                    form.$setPristine();
+                    if(this.basic.dataaset == '-1'){
+                      this.basic.dataaset = undefined;
+                    }
+                    this.data={
+                      basic: this.basic,
+                      extra: {publishUrl: this.publishUrl}
+                    };
+
+                    if($scope.assets){
+                      for(var i = 0; i < $scope.assets.length; i ++){
+                        var aset = $scope.assets[i];
+                        if(aset.name == this.basic.dataaset){
+                          this.data.basic.dataasetId = aset.id;
+
+                        }
+                      }
+                    }
+
+                    $('#confirm-pu').modal('show');
+                  }
+                }
+            },
+
+            save: function() {
+
+
+                //::TODO: Need to save the data to backend with POST/PUT method
+                console.log(JSON.stringify($scope.form.data));
+
+
+                var newModel = $config.uri.newPublishModel;
+                $http.post(newModel, this.data).success(function() {
+
+                    $('#confirm-pu').on('hidden.bs.modal', function(e) {
+                        $('#confirm-pu').off('hidden.bs.modal');
+                        $location.path('/rules');
+                        $scope.$apply();
+                    });
+                       $('#confirm-pu').modal('hide');
+
+                }).error(function(data){
+                  // errorMessage(0, 'Save model failed, please try again!');
+                  toaster.pop('error', 'Save model failed, please try again!', 
data.message);
+                });
+            },
+
+        };
+
+        var errorMessage = function(i, msg) {
+            var errorMsgs = ['Please fill in all required fields'];
+            if (!msg) {
+                toaster.pop('error', 'Error', errorMsgs[i - 1], 0);
+            } else {
+                toaster.pop('error', 'Error', msg, 0);
+            }
+        }
+        ;
+    }
+    ]);
+});

http://git-wip-us.apache.org/repos/asf/incubator-griffin/blob/a8ba6ba9/griffin-ui/js/controllers/createrule-va-ctrl.js
----------------------------------------------------------------------
diff --git a/griffin-ui/js/controllers/createrule-va-ctrl.js 
b/griffin-ui/js/controllers/createrule-va-ctrl.js
new file mode 100644
index 0000000..882f807
--- /dev/null
+++ b/griffin-ui/js/controllers/createrule-va-ctrl.js
@@ -0,0 +1,331 @@
+/*
+       Copyright (c) 2016 eBay Software Foundation.
+       Licensed under the Apache License, Version 2.0 (the "License");
+       you may not use this file except in compliance with the License.
+       You may obtain a copy of the License at
+
+           http://www.apache.org/licenses/LICENSE-2.0
+
+       Unless required by applicable law or agreed to in writing, software
+       distributed under the License is distributed on an "AS IS" BASIS,
+       WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+       See the License for the specific language governing permissions and
+       limitations under the License.
+*/
+define(['./module'], function(controllers) {
+    'use strict';
+    controllers.controller('CreateRuleVACtrl', ['$scope', '$http', '$config', 
'$location', 'toaster', '$timeout', '$route', '$filter', function($scope, 
$http, $config, $location, toaster, $timeout, $route, $filter) {
+        console.log('Create rule controller');
+        $scope.currentStep = 1;
+
+        var dbtreeUrl = $config.uri.dbtree;
+        var schemaDefinitionUrl = $config.uri.schemadefinition;
+
+
+        $http.get(dbtreeUrl).success(function(data) {
+            var dbList = [];
+            if (data && data.length > 0) {
+                data.forEach(function(db) {
+                    var dbNode = {
+                        name: db.platform,
+                        l1: true,
+                        children: []
+                    };
+                    dbList.push(dbNode);
+                    if (db.systems && db.systems.length > 0) {
+                        db.systems.forEach(function(system) {
+                            var dsNode = {
+                                name: system.name,
+                                l2: true,
+                                children: []
+                            };
+                            dbNode.children.push(dsNode);
+                            dsNode.parent = db;
+
+
+                            if (system.assets && system.assets.length > 0) {
+                                system.assets.sort(function(a, b){
+                                  return 
(a.name<b.name?-1:(a.name>b.name?1:0));
+                                });
+                                system.assets.forEach(function(schema) {
+                                    var schemaNode = {
+                                        id: schema.id,
+                                        name: schema.name,
+                                        l3: true
+                                    };
+                                    schemaNode.parent = dsNode;
+                                    dsNode.children.push(schemaNode);
+                                });
+                            }
+                        });
+                    }
+
+                });
+            }
+            $scope.dbList = dbList;
+        });
+
+
+        //trigger after select schema for src
+        $scope.$watch('currentNode', function(newValue) {
+            // $scope.schemaCollection = null;
+            if (newValue) {
+                if(newValue.l3){//System selected
+                  var sysName = newValue.parent.name;
+                  $scope.form.basic.system = $filter('stridx')(sysName, 
'modelsystem') + '';
+
+                  //retrieve the schema definition and display the table
+                  $http.get(schemaDefinitionUrl + '/' + 
newValue.id).success(function(data) {
+                      $scope.schemaCollection = data.schema;
+                  });
+                }
+
+            }
+        });
+
+
+
+
+        $scope.$on('$viewContentLoaded', function() {
+            $scope.$emit('initReq');
+            resizeWindow();
+        });
+
+        $scope.$on('resizeHandler', function(e) {
+            if ($route.current.$$route.controller == "CreateRuleVACtrl") {
+                $scope.$emit('initReq');
+                resizeWindow();
+            }
+        });
+
+        function resizeWindow() {
+                    var stepSelection = '.formStep[id=step-' + 
$scope.currentStep + ']';
+                    $(stepSelection).css({
+                        height: window.innerHeight - 
$(stepSelection).offset().top - $('#footerwrap').outerHeight()
+                    });
+                    $('fieldset').height($(stepSelection).height() - 
$(stepSelection + '>.stepDesc').height() - $('.btn-container').height() - 80);
+                    console.log($('fieldset').height());
+                    $('.y-scrollable').css({
+                        'max-height': $('fieldset').height()- 
$('.add-dataset').outerHeight()
+                    });
+                    //error message box position
+                    $('.formula-text-mid').css({
+                        'padding-top': (($('.formula-text-up').height() - 
$('.formula-text-mid').height()) + $('.formula-text-mid').height() / 2) + 'px'
+                    });
+
+        }
+
+        $scope.ruleTypes = $filter('strarr')('modeltype');//['Accuracy', 
'Validity', 'Anomaly Detection', 'Publish Metrics'];
+        $scope.scheduleTypes = $filter('strarr')('scheduletype');//['Daily', 
'Weekly', 'Monthly', 'Hourly'];
+        $scope.ruleSystems = $filter('strarr')('modelsystem');//['Bullseye', 
'GPS', 'Hadoop', 'PDS', 'IDLS', 'Pulsar', 'Kafka'];
+        $scope.vaTypes = $filter('strarr')('vatype');
+        //$scope.vaTypes = ['', '', 'Null Count', 'Unique Count', 'Duplicate 
Count', 'Maximum', 'Minimum', 'Mean', 'Median', 'Regular Expression Matching', 
'Pattern Frequency'];
+
+        // $scope.ruleType = function(index){
+        //   var types = ['', 'Accuracy', 'Validity', 'Anomaly Detection', 
'Publish Metrics'];
+        //   return types[index];
+        // }
+
+        // $scope.scheduleType = function(index){
+        //   var types = ['', 'Daily', 'Weekly', 'Monthly', 'Hourly'];
+        //   return types[index];
+        // }
+        //
+        // $scope.ruleSystem = function(index){
+        //   var sys = ['', 'Bullseye', 'GPS', 'Hadoop', 'PDS', 'IDLS', 
'Pulsar', 'Kafka'];
+        //   return sys[index];
+        // }
+
+        // Initial Value
+        $scope.form = {
+
+            next: function(form) {
+
+                if (formValidation()) {
+                    // form.$setPristine();
+                    nextStep();
+                } else {
+                    var field = null
+                      , firstError = null ;
+                    for (field in form) {
+                        if (field[0] != '$') {
+                            if (firstError === null  && !form[field].$valid) {
+                                firstError = form[field].$name;
+                            }
+
+                            if (form[field].$pristine) {
+                                form[field].$dirty = true;
+                            }
+                        }
+                    }
+
+                    //  angular.element('.ng-invalid[name=' + firstError + 
']').focus();
+                    errorMessage($scope.currentStep);
+                }
+            },
+            prev: function(form) {
+                //$scope.toTheTop();
+                prevStep();
+            },
+            goTo: function(form, i) {
+                if (parseInt($scope.currentStep) > parseInt(i)) {
+                    // $scope.toTheTop();
+                    goToStep(i);
+
+                } else {
+                    if (formValidation()) {
+                        //   $scope.toTheTop();
+                        if(i - parseInt($scope.currentStep) == 1){
+                          goToStep(i);
+                        }
+
+                    } else {
+                        errorMessage($scope.currentStep);
+                    }
+                }
+            },
+            submit: function(form) {
+                if (!form.$valid || form['regex'].$invalid) {
+                    var field = null
+                      , firstError = null ;
+                    for (field in form) {
+                        if (field[0] != '$') {
+                            if (firstError === null  && !form[field].$valid) {
+                                firstError = form[field].$name;
+                            }
+
+                            if (form[field].$invalid) {
+                                form[field].$dirty = true;
+                            }
+                        }
+                    }
+                    angular.element('.ng-invalid[name=' + firstError + 
']').focus();
+                    errorMessage($scope.currentStep);
+                } else {
+                    form.$setPristine();
+
+                    this.data={
+                      basic: this.basic,
+                      extra: {
+                        srcDb: $scope.currentNode.parent.parent.platform,
+                        srcDataSet: $scope.currentNode.parent.name,
+                        vaType: this.vaType,
+                        column: this.selection
+                      }
+                    };
+
+                    this.data.basic.dataaset = $scope.currentNode.name;
+                    this.data.basic.dataasetId = $scope.currentNode.id;
+                    // this.data.vaType = this.vaType;
+                    // this.data.column = this.selection;
+
+                    $('#confirm-va').modal('show');
+                }
+            },
+
+            save: function() {
+
+
+
+
+                //::TODO: Need to save the data to backend with POST/PUT method
+                console.log(JSON.stringify($scope.form.data));
+
+                var newModel = $config.uri.newValidityModel;
+                $http.post(newModel, this.data).success(function(data) {
+                       // if(data.status=='0')
+                       // {
+                         $('#confirm-va').on('hidden.bs.modal', function(e) {
+                             $('#confirm-va').off('hidden.bs.modal');
+                             $location.path('/rules');
+                             $scope.$apply();
+                         });
+                               $('#confirm-va').modal('hide');
+                       // }
+                       // else
+                       // {
+                       //      errorMessage(0, data.result);
+                       // }
+                }).error(function(data){
+                  // errorMessage(0, 'Save model failed, please try again!');
+                  toaster.pop('error', 'Save model failed, please try again!', 
data.message);
+                });
+            },
+            testRegex : function(form) {
+                if($scope.form.basic.regex == undefined || 
$scope.form.basic.regex == ''){
+                    form['regex'].$invalid = true;
+                    form['regex'].$valid = false;
+                    return;
+                }
+                try{
+                    var re = new RegExp($scope.form.basic.regex);
+                    form['regex'].$invalid = false;
+                    form['regex'].$valid = true;
+                    var str = $scope.form.basic.regexTestStr;
+                    var m;
+                    if(str == undefined) {
+                        $scope.regexTestResult = '';
+                    }else if ((m = re.exec(str)) !== null) {
+                        $scope.regexTestResult = 'Matched';
+                    } else {
+                        $scope.regexTestResult = 'Unmatched';
+                    }
+                } catch(err) {
+                    form['regex'].$invalid = true;
+                    form['regex'].$valid = false;
+                }
+            }
+        };
+
+        var nextStep = function() {
+            $scope.currentStep++;
+            $timeout(function(){
+                resizeWindow();
+            }, 0);
+        }
+        ;
+        var prevStep = function() {
+            $scope.currentStep--;
+            $timeout(function(){
+                resizeWindow();
+            }, 0);
+        }
+        ;
+        var goToStep = function(i) {
+            $scope.currentStep = i;
+            $timeout(function(){
+                resizeWindow();
+            }, 0);
+        }
+        ;
+
+        //validation only happens when going forward
+        var formValidation = function(step) {
+            //  return true;//for dev purpose
+            if (step == undefined) {
+                step = $scope.currentStep;
+            }
+            if (step == 1) {
+                return $scope.form.selection?true:false;
+            } else if (step == 2) {
+                return true;
+            } else if (step == 3) {
+                return true;
+                //::TODO: also need to check if duplicated mappings or empty 
mappings
+            }
+
+            return false;
+        }
+
+        var errorMessage = function(i, msg) {
+            var errorMsgs = ['Please select one attribute!', 'Please select at 
least one attribute!', 'Please make sure to map all fields and select primary 
key'];
+            if (!msg) {
+                toaster.pop('error', 'Error', errorMsgs[i - 1], 0);
+            } else {
+                toaster.pop('error', 'Error', msg, 0);
+            }
+        }
+        ;
+    }
+    ]);
+});

http://git-wip-us.apache.org/repos/asf/incubator-griffin/blob/a8ba6ba9/griffin-ui/js/controllers/createrule0-ctrl.js
----------------------------------------------------------------------
diff --git a/griffin-ui/js/controllers/createrule0-ctrl.js 
b/griffin-ui/js/controllers/createrule0-ctrl.js
new file mode 100644
index 0000000..241445a
--- /dev/null
+++ b/griffin-ui/js/controllers/createrule0-ctrl.js
@@ -0,0 +1,41 @@
+/*
+       Copyright (c) 2016 eBay Software Foundation.
+       Licensed under the Apache License, Version 2.0 (the "License");
+       you may not use this file except in compliance with the License.
+       You may obtain a copy of the License at
+
+           http://www.apache.org/licenses/LICENSE-2.0
+
+       Unless required by applicable law or agreed to in writing, software
+       distributed under the License is distributed on an "AS IS" BASIS,
+       WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+       See the License for the specific language governing permissions and
+       limitations under the License.
+*/
+define(['./module'], function (controllers) {
+    'use strict';
+    controllers.controller('CreateRule0Ctrl', ['$scope', '$http', '$config', 
'$location', 'toaster', '$timeout', '$route',  function ($scope, $http, 
$config, $location, toaster, $timeout, $route) {
+      console.log('Create rule 0 controller');
+      $scope.publishURL = document.location.origin;
+
+      $scope.click = function(type){
+        $location.path('/createrule-' + type);
+      }
+      $scope.$on('$viewContentLoaded', function(){
+        $scope.$emit('initReq');
+        resizeWindow();
+      });
+
+      $scope.$on('resizeHandler', function(e) {
+        if($route.current.$$route.controller == 'CreateRule0Ctrl'){
+            console.log('createrule0 resize');
+            resizeWindow();
+        }
+      });
+
+      function resizeWindow(){
+        $('#panel-2 >.panel-body').css({height: $('#panel-1 
>.panel-body').outerHeight() + $('#panel-1 >.panel-footer').outerHeight() - 
$('#panel-2 >.panel-footer').outerHeight()});
+        $('#panel-4 >.panel-body').css({height: $('#panel-3 
>.panel-body').outerHeight() + $('#panel-3 >.panel-footer').outerHeight() - 
$('#panel-4 >.panel-footer').outerHeight()});
+      }
+    }]);
+});

http://git-wip-us.apache.org/repos/asf/incubator-griffin/blob/a8ba6ba9/griffin-ui/js/controllers/dataassets-ctrl.js
----------------------------------------------------------------------
diff --git a/griffin-ui/js/controllers/dataassets-ctrl.js 
b/griffin-ui/js/controllers/dataassets-ctrl.js
new file mode 100644
index 0000000..110da44
--- /dev/null
+++ b/griffin-ui/js/controllers/dataassets-ctrl.js
@@ -0,0 +1,124 @@
+/*
+       Copyright (c) 2016 eBay Software Foundation.
+       Licensed under the Apache License, Version 2.0 (the "License");
+       you may not use this file except in compliance with the License.
+       You may obtain a copy of the License at
+
+           http://www.apache.org/licenses/LICENSE-2.0
+
+       Unless required by applicable law or agreed to in writing, software
+       distributed under the License is distributed on an "AS IS" BASIS,
+       WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+       See the License for the specific language governing permissions and
+       limitations under the License.
+*/
+define(['./module'], function (controllers) {
+    'use strict';
+    controllers.controller('DataAssetsCtrl', ['$scope', '$http', '$config', 
'$location', 'toaster', '$timeout', '$route', '$filter', function ($scope, 
$http, $config, $location, toaster, $timeout, $route, $filter) {
+
+      var allModels = $config.uri.dataassetlist;
+      var ts = null;
+      var start = 0;
+      var number = 10;
+      var originalRowCollection = undefined;
+
+      $scope.paging = function(tableState){
+        console.log(tableState);
+        ts = tableState;
+        // tableState.pagination.numberOfPages = 
$scope.rowCollection.length/10 + 1;
+        start = tableState.pagination.start || 0;
+        number = tableState.pagination.number || 10;
+
+        if(start == 0 && !$scope.rowCollection){
+          $http.get(allModels).success(function(data) {
+            if(data){
+              data.sort(function(a,b){
+                return -(a.timestamp - b.timestamp);
+              });
+            }
+
+            originalRowCollection = angular.copy(data);
+            $scope.rowCollection = angular.copy(data);
+            // $scope.rowCollection.sort(function(a,b){
+            //   return 
(a.assetName<b.assetName?-1:(a.assetName>b.assetName?1:0));
+            // });
+
+            $scope.displayed = $scope.rowCollection.slice(start, start+number);
+            tableState.pagination.numberOfPages = 
Math.ceil($scope.rowCollection.length/number);
+          });
+        }else{
+          $scope.displayed = $scope.rowCollection.slice(start, start+number);
+        }
+      }
+
+      var include = function(keyword, str) {
+        if(keyword == undefined || keyword == null){
+          return true;
+        } else if(str == undefined || str == null){
+          return false;
+        } else{
+          var value = keyword.trim().toLowerCase();
+          return str.trim().toLowerCase().includes(value);
+        }
+      };
+
+      var findValue = function(keyword, assetItem) {
+        var date = $filter('date')(assetItem.timestamp, 'M/d/yy h:mm a', 
'-0700')
+        return include(keyword, assetItem.assetName)
+          || include(keyword, assetItem.assetType)
+          || include(keyword, assetItem.owner)
+          || include(keyword, assetItem.system)
+          || include(keyword, assetItem.assetHDFSPath)
+          || include(keyword, date);
+      };
+
+      $scope.$watch('keyword', function(newValue){
+        if(originalRowCollection){
+          start = 0;
+          if(newValue == undefined || newValue == ''){
+            $scope.rowCollection = angular.copy(originalRowCollection);
+          }else{
+            var result = [];
+            for (var i = 0; i < originalRowCollection.length; i++) {
+              var item = originalRowCollection[i];
+              if(findValue(newValue, item)){
+                result.push(item);
+              }
+            };
+            $scope.rowCollection = angular.copy(result);
+          }
+          $scope.displayed = $scope.rowCollection.slice(start, start+number);
+          ts.pagination.numberOfPages = 
Math.ceil($scope.rowCollection.length/number);
+        }
+      });
+
+               $scope.remove = function(row) {
+                       $scope.selectedRow = row;
+                       $('#confirm-delete').modal('show');
+
+               };
+
+               $scope.sendDeleteRequest = function() {
+                       
$http.delete($config.uri.deletedataasset+'/'+$scope.selectedRow._id).success(function(data){
+
+                                       $('#confirm-delete').modal('hide');
+          var index = $scope.rowCollection.indexOf($scope.selectedRow);
+          $scope.rowCollection.splice(index, 1);
+
+          index = $scope.displayed.indexOf($scope.selectedRow);
+          $scope.displayed.splice(index, 1);
+
+                       }).error(function(data, status){
+        toaster.pop('error', 'Error when deleting record', data);
+      });
+
+               }
+
+    $scope.$on('$viewContentLoaded', function() {
+        $scope.$emit('initReq');
+    });
+
+  }]);
+
+
+});

http://git-wip-us.apache.org/repos/asf/incubator-griffin/blob/a8ba6ba9/griffin-ui/js/controllers/downloadSample-ctrl.js
----------------------------------------------------------------------
diff --git a/griffin-ui/js/controllers/downloadSample-ctrl.js 
b/griffin-ui/js/controllers/downloadSample-ctrl.js
new file mode 100644
index 0000000..aa1ad89
--- /dev/null
+++ b/griffin-ui/js/controllers/downloadSample-ctrl.js
@@ -0,0 +1,36 @@
+/*
+       Copyright (c) 2016 eBay Software Foundation.
+       Licensed under the Apache License, Version 2.0 (the "License");
+       you may not use this file except in compliance with the License.
+       You may obtain a copy of the License at
+
+           http://www.apache.org/licenses/LICENSE-2.0
+
+       Unless required by applicable law or agreed to in writing, software
+       distributed under the License is distributed on an "AS IS" BASIS,
+       WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+       See the License for the specific language governing permissions and
+       limitations under the License.
+*/
+define(['./module'], function(controllers) {
+    'use strict';
+    controllers.controller('DownloadSampleCtrl', ['$scope', '$http', 
'$config', '$filter', '$timeout', '$compile', '$routeParams', '$barkChart', 
'$rootScope', function($scope, $http, $config, $filter, $timeout, $compile, 
$routeParams, $barkChart, $rootScope) {
+
+        $scope.downloadUrl = $config.uri.metricdownload;
+
+        $scope.$on('downloadSample', function(e, itemName) {
+            $scope.selectedModelName = itemName;
+            var sampleUrl = $config.uri.metricsample + '/' + itemName;
+            $http.get(sampleUrl).success(function(data){
+                $scope.sample = data;
+                $('#download-sample').modal('show');
+                $('#viewsample-content').css({
+                    'max-height': window.innerHeight - 
$('.modal-content').offset().top - $('.modal-header').outerHeight() - 
$('.modal-footer').outerHeight() - 250
+                });
+
+            });
+        });
+
+    }
+    ]);
+});
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-griffin/blob/a8ba6ba9/griffin-ui/js/controllers/editdataasset-ctrl.js
----------------------------------------------------------------------
diff --git a/griffin-ui/js/controllers/editdataasset-ctrl.js 
b/griffin-ui/js/controllers/editdataasset-ctrl.js
new file mode 100644
index 0000000..718525c
--- /dev/null
+++ b/griffin-ui/js/controllers/editdataasset-ctrl.js
@@ -0,0 +1,213 @@
+/*
+       Copyright (c) 2016 eBay Software Foundation.
+       Licensed under the Apache License, Version 2.0 (the "License");
+       you may not use this file except in compliance with the License.
+       You may obtain a copy of the License at
+
+           http://www.apache.org/licenses/LICENSE-2.0
+
+       Unless required by applicable law or agreed to in writing, software
+       distributed under the License is distributed on an "AS IS" BASIS,
+       WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+       See the License for the specific language governing permissions and
+       limitations under the License.
+*/
+define(['./module'], function (controllers) {
+    'use strict';
+    controllers.controller('EditDataAssetCtrl', ['$scope', '$http', '$config', 
'$location', 'toaster', '$timeout', '$route', '$routeParams', '$filter', 
function ($scope, $http, $config, $location, toaster, $timeout, $route, 
$routeParams, $filter) {
+        $scope.assetId = $routeParams.assetId;
+        $scope.currentStep = 1;
+        $scope.form = {};
+        $scope.form.basic = {};
+
+        // $scope.platformOptions = ['Teradata', 'Apollo'];
+        // $scope.systemOptions = ['Sojourner', 'SiteSpeed', 'Bullseye', 
'PDS', 'GPS'];
+        $scope.systemOptions = $filter('strarr')('modelsystem');//['Bullseye', 
'GPS', 'Hadoop', 'PDS', 'IDLS', 'Pulsar', 'Kafka'];
+        $scope.assetTypeOptions = ['hdfsfile', 'hivetable'];
+
+        $scope.formatTypeOptions = ['yyyyMMdd', 'yyyy-MM-dd','HH'];
+
+        $scope.$on('$viewContentLoaded', function() {
+            $scope.$emit('initReq');
+            resizeWindow();
+
+        });
+
+        $scope.$on('resizeHandler', function(e) {
+            if ($route.current.$$route.controller == "EditDataAssetCtrl") {
+                resizeWindow();
+            }
+        });
+
+        function resizeWindow() {
+                    $('.formStep').height(window.innerHeight  -  
$('.formStep').offset().top - $('#footerwrap').outerHeight());
+                    $('fieldset').height(window.innerHeight  -  
$('fieldset').offset().top - $('#footerwrap').outerHeight()- 
$('.btn-container').height() -80);
+                    $('.y-scrollable').css({
+                        'max-height': $('fieldset').height()
+                    });
+
+        }
+
+        // var dbtree = $config.uri.dbtree;
+        // $http.get(dbtree).success(function(data) {
+        //     $scope.platformOptions = data;
+        //     $scope.getDataAsset();
+        // });
+
+        var assetUri = $config.uri.getdataasset + '/' + $scope.assetId;
+        $scope.getDataAsset = function(){
+            $http.get(assetUri).success(function(data) {
+                $scope.form.basic.assetName = data.assetName;
+                $scope.form.basic.path = data.assetHDFSPath;
+                $scope.form.basic.type = 
$scope.assetTypeOptions.indexOf(data.assetType).toString();
+                $scope.form.basic.platform = data.platform;
+                //$scope.getSystemOptions($scope.form.basic.platform);
+                $scope.form.basic.system = 
$scope.getSystemIndex(data.system).toString();
+                $scope.form.basic.schema = data.schema;
+                $scope.form.basic.partitions = data.partitions;
+            });
+        };
+
+        $scope.getDataAsset();
+
+        // $scope.getPlatformIndex = function(platform) {
+        //     for (var i = 0; i < $scope.platformOptions.length; i++) {
+        //         if($scope.platformOptions[i].platform == platform){
+        //             return i;
+        //         }
+        //     };
+        //     return -1;
+        // };
+
+        $scope.getSystemIndex = function(system) {
+            for (var i = 0; i < $scope.systemOptions.length; i++) {
+                if($scope.systemOptions[i] == system) {
+                    return i;
+                }
+            };
+            return -1;
+        }
+
+        // $scope.getSystemOptions = function(platformIndex){
+        //     if(platformIndex==undefined){
+        //         $scope.systemOptions = [];
+        //     }else{
+        //         $scope.systemOptions = 
$scope.platformOptions[platformIndex].systems;
+        //     }
+        // };
+
+        $scope.updateHdfsPath = function(typeIndex){
+            if(typeIndex != 0 ){
+                $scope.form.basic.path = '';
+            }
+        };
+
+           $scope.addSchema = function() {
+               $scope.form.basic.schema.push({
+                   name: '',
+                   type: 'string',
+                   desc: '',
+                   sample: ''
+               });
+           };
+
+      $scope.addPatitionColumn = function() {
+               $scope.form.basic.partitions.push({
+                   name: '',
+                   format: "yyyyMMdd"
+               });
+           };
+
+           $scope.deleteSchema = function(index) {
+               $scope.form.basic.schema.splice(index, 1);
+           };
+
+      $scope.deletePartition = function(index) {
+               $scope.form.basic.partitions.splice(index, 1);
+           };
+
+           // Initial Value
+        $scope.form = {
+            basic: {
+                schema: [{
+                    name: '',
+                    type: 'string',
+                    desc: '',
+                    sample: ''
+                }],
+                partitions: []
+            },
+            submit: function(form) {
+                if (!form.$valid) {
+                    var field = null
+                      , firstError = null ;
+                    for (field in form) {
+                        if (field[0] != '$') {
+                            if (firstError === null  && !form[field].$valid) {
+                                firstError = form[field].$name;
+                            }
+
+                            if (form[field].$invalid) {
+                                form[field].$dirty = true;
+                            }
+                        }
+                    }
+                    angular.element('.ng-invalid[name=' + firstError + 
']').focus();
+                    errorMessage($scope.currentStep);
+                } else {
+                    form.$setPristine();
+                    this.data={
+                      basic: this.basic,
+                      extra: {publishUrl: this.publishUrl}
+                    };
+
+
+
+                    $('#confirm-pu').modal('show');
+                }
+            },
+
+            save: function() {
+                $('#confirm-pu').on('hidden.bs.modal', function(e) {
+                    $('#confirm-pu').off('hidden.bs.modal');
+                    $location.path('/dataassets');
+                    $scope.$apply();
+                });
+
+                console.log(JSON.stringify($scope.form.basic));
+                var msg = {
+                       'system' : 
$scope.systemOptions[$scope.form.basic.system],
+                       'assetType' : 
$scope.assetTypeOptions[$scope.form.basic.type],
+                    'assetName' : $scope.form.basic.assetName,
+                       'assetHDFSPath' : $scope.form.basic.path,
+                       'platform' : $scope.form.basic.platform,
+                       'schema' : $scope.form.basic.schema,
+                    'owner' : $scope.form.basic.owner,
+                    'partitions' : $scope.form.basic.partitions
+                }
+
+                $http.put($config.uri.updatedataasset, 
msg).success(function(data) {
+                       if(data.result=='success')
+                       {
+                       $('#confirm-pu').modal('hide');
+                    }
+                       else
+                       {
+                               errorMessage(0, data.result);
+                       }
+                });
+            },
+
+        };
+
+        var errorMessage = function(i, msg) {
+            var errorMsgs = ['Please fill in all required fields'];
+            if (!msg) {
+                toaster.pop('error', 'Error', errorMsgs[i - 1]);
+            } else {
+                toaster.pop('error', 'Error', msg);
+            }
+        };
+
+    }]);
+});

http://git-wip-us.apache.org/repos/asf/incubator-griffin/blob/a8ba6ba9/griffin-ui/js/controllers/footer-ctrl.js
----------------------------------------------------------------------
diff --git a/griffin-ui/js/controllers/footer-ctrl.js 
b/griffin-ui/js/controllers/footer-ctrl.js
new file mode 100644
index 0000000..7eb9e13
--- /dev/null
+++ b/griffin-ui/js/controllers/footer-ctrl.js
@@ -0,0 +1,56 @@
+/*
+       Copyright (c) 2016 eBay Software Foundation.
+       Licensed under the Apache License, Version 2.0 (the "License");
+       you may not use this file except in compliance with the License.
+       You may obtain a copy of the License at
+
+           http://www.apache.org/licenses/LICENSE-2.0
+
+       Unless required by applicable law or agreed to in writing, software
+       distributed under the License is distributed on an "AS IS" BASIS,
+       WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+       See the License for the specific language governing permissions and
+       limitations under the License.
+*/
+define(['./module'], function (controllers) {
+    'use strict';
+    controllers.controller('FooterCtrl', ['$scope', '$http', '$config', 
'$location', '$cookies', '$interval', function ($scope, $http, $config, 
$location, $cookies, $interval) {
+      console.log('Footer controller');
+      $scope.timestamp = new Date();
+
+      var start = 0, number = 3;
+      retrieveNotifications();
+      $interval(retrieveNotifications, 60000);
+
+      // $interval(function(){
+      //   if($scope.allNotifications){
+      //     var length = $scope.allNotifications.length;
+      //     if(length == 0){
+      //       return;
+      //     }else if(length <= number){
+      //       $scope.notifications = $scope.allNotifications;
+      //       return;
+      //     }
+      //     var index = start%length;
+      //     var end = index + number;
+
+      //     $scope.notifications = $scope.allNotifications.slice(index, end);
+
+      //     if(end > length){
+      //       $scope.notifications = 
$scope.notifications.concat($scope.allNotifications.slice(0, end-length ));
+      //     }
+      //     start ++;
+      //   }
+
+      // }, 2000);
+
+      function retrieveNotifications(){
+        var notificationUrl = $config.uri.getnotifications;
+        $http.get(notificationUrl).success(function(data) {
+          // $scope.allNotifications = data.slice(0, 15);
+          $scope.notifications = data.slice(0, 3);
+        });
+      }
+
+    }]);
+});

http://git-wip-us.apache.org/repos/asf/incubator-griffin/blob/a8ba6ba9/griffin-ui/js/controllers/health-ctrl.js
----------------------------------------------------------------------
diff --git a/griffin-ui/js/controllers/health-ctrl.js 
b/griffin-ui/js/controllers/health-ctrl.js
new file mode 100644
index 0000000..019f26a
--- /dev/null
+++ b/griffin-ui/js/controllers/health-ctrl.js
@@ -0,0 +1,191 @@
+/*
+       Copyright (c) 2016 eBay Software Foundation.
+       Licensed under the Apache License, Version 2.0 (the "License");
+       you may not use this file except in compliance with the License.
+       You may obtain a copy of the License at
+
+           http://www.apache.org/licenses/LICENSE-2.0
+
+       Unless required by applicable law or agreed to in writing, software
+       distributed under the License is distributed on an "AS IS" BASIS,
+       WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+       See the License for the specific language governing permissions and
+       limitations under the License.
+*/
+define(['./module'], function (controllers) {
+    'use strict';
+    controllers.controller('HealthCtrl', ['$scope', '$http', '$config', 
'$location','$timeout', '$route', '$barkChart', '$rootScope', function ($scope, 
$http, $config, $location, $timeout, $route, $barkChart, $rootScope) {
+      console.log('health controller');
+      // var url="/js/controllers/heatmap.json";
+
+        var echarts = require('echarts');
+        var formatUtil = echarts.format;
+
+        pageInit();
+
+        function pageInit() {
+            $scope.$emit('initReq');
+
+            var url = $config.uri.heatmap;
+            $http.get(url).success(function(res) {
+                renderTreeMap(res);
+            });
+        }
+
+        function renderTreeMap(res) {
+
+
+                function parseData(data) {
+                    var sysId = 0;
+                    var metricId = 0;
+                    var result = [];
+                    angular.forEach(res,function(sys,key){
+                        console.log(sys);
+
+                        var item = {};
+                        item.id = 'id_'+sysId;
+                        item.name = sys.name;
+
+                        if (sys.metrics != undefined) {
+                            item.children = [];
+                            angular.forEach(sys.metrics,function(metric,key){
+                                var itemChild = {
+                                    id: 'id_' + sysId + '_' + metricId,
+                                    name: metric.name,// + '(' + metric.dq + 
'%)',
+                                    // value: metric.dq,
+                                    value: 1,
+                                    dq: metric.dq,
+                                    sysName: sys.name,
+                                    itemStyle: {
+                                        normal: {
+                                            color: '#4c8c6f'
+                                        }
+                                    }
+                                };
+                                if (metric.dqfail == 1) {
+                                    itemChild.itemStyle.normal.color = 
'#ae5732';
+                                } else {
+                                    itemChild.itemStyle.normal.color = 
'#005732';
+                                }
+                                item.children.push(itemChild);
+                                metricId++;
+                            });
+                        }
+
+                        result.push(item);
+
+                        sysId ++;
+                    });
+                    return result;
+                }
+
+                var data = parseData(res);
+                console.log(data);
+
+                function getLevelOption() {
+                    return [
+                        {
+                            itemStyle: {
+                                normal: {
+                                    borderWidth: 0,
+                                    gapWidth: 6,
+                                    borderColor: '#000'
+                                }
+                            }
+                        },
+
+                        {
+                            itemStyle: {
+                                normal: {
+                                    gapWidth: 1,
+                                    borderColor: '#fff'
+                                }
+                            }
+                        }
+                    ];
+                }
+
+                var option = {
+
+                    title: {
+                        text: 'Data Quality Metrics Heatmap',
+                        left: 'center'
+                    },
+
+                    backgroundColor: 'transparent',
+
+                    tooltip: {
+                        formatter: function(info) {
+                            var dqFormat = info.data.dq>100?'':'%';
+                            return [
+                                '<span style="font-size:1.8em;">' + 
formatUtil.encodeHTML(info.data.sysName) + ' &gt; </span>',
+                                '<span style="font-size:1.5em;">' + 
formatUtil.encodeHTML(info.data.name)+'</span><br>',
+                                '<span style="font-size:1.5em;">dq : ' + 
info.data.dq.toFixed(2) + dqFormat + '</span>'
+                            ].join('');
+                        }
+                    },
+
+                    series: [
+                        {
+                            name:'System',
+                            type:'treemap',
+                            itemStyle: {
+                                normal: {
+                                    borderColor: '#fff'
+                                }
+                            },
+                            levels: getLevelOption(),
+                            breadcrumb: {
+                                show: false
+                            },
+                            roam: false,
+                            nodeClick: false,
+                            data: data,
+                            // leafDepth: 1,
+                            width: '95%',
+                            bottom : 0
+                        }
+                    ]
+                };
+
+                resizeTreeMap();
+                $scope.myChart = 
echarts.init(document.getElementById('chart1'), 'dark');
+                $scope.myChart.setOption(option);
+
+                $scope.myChart.on('click', function(param) {
+                    // if (param.data.sysName) {
+                    //     $location.path('/metrics/' + param.data.sysName);
+                    //     $scope.$apply();
+                    //     return false;
+                    // }
+                    // param.event.event.preventDefault();
+                    if (param.data.name) {
+
+                        showBig(param.data.name);
+                        // return false;
+                    }
+                });
+
+        }
+
+        var showBig = function(metricName){
+          var metricDetailUrl = $config.uri.metricdetail + '/' + metricName;
+          $http.get(metricDetailUrl).success(function (data){
+            $rootScope.showBigChart($barkChart.getOptionBig(data));
+          });
+        }
+
+        $scope.$on('resizeHandler', function(e) {
+            if($route.current.$$route.controller == 'HealthCtrl'){
+                console.log('health resize');
+                resizeTreeMap();
+                $scope.myChart.resize();
+            }
+        });
+
+        function resizeTreeMap() {
+            $('#chart1').height( $('#mainWindow').height() - 
$('.bs-component').outerHeight() );
+        }
+
+    }]);
+});

http://git-wip-us.apache.org/repos/asf/incubator-griffin/blob/a8ba6ba9/griffin-ui/js/controllers/index.js
----------------------------------------------------------------------
diff --git a/griffin-ui/js/controllers/index.js 
b/griffin-ui/js/controllers/index.js
new file mode 100644
index 0000000..a374161
--- /dev/null
+++ b/griffin-ui/js/controllers/index.js
@@ -0,0 +1,40 @@
+/*
+       Copyright (c) 2016 eBay Software Foundation.
+       Licensed under the Apache License, Version 2.0 (the "License");
+       you may not use this file except in compliance with the License.
+       You may obtain a copy of the License at
+
+           http://www.apache.org/licenses/LICENSE-2.0
+
+       Unless required by applicable law or agreed to in writing, software
+       distributed under the License is distributed on an "AS IS" BASIS,
+       WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+       See the License for the specific language governing permissions and
+       limitations under the License.
+*/
+
+define([
+    './nav-ctrl',
+    './sidebar-ctrl',
+    './health-ctrl',
+    './rule-ctrl',
+    './createrule0-ctrl',
+    './createrule-ac-ctrl',
+    './createrule-va-ctrl',
+    './createrule-an-ctrl',
+    './createrule-pu-ctrl',
+    './viewrule-ctrl',
+    './metrics-ctrl',
+    './dataassets-ctrl',
+    './createdataasset-ctrl',
+    './editdataasset-ctrl',
+    './footer-ctrl',
+    './mydashboard-ctrl',
+    './subscribemodel-ctrl',
+    './bigChart-ctrl',
+    './main-ctrl',
+    './downloadSample-ctrl'
+    // './my-ctrl-2'
+], function () {
+  // console.log('my controller 1');
+});

http://git-wip-us.apache.org/repos/asf/incubator-griffin/blob/a8ba6ba9/griffin-ui/js/controllers/main-ctrl.js
----------------------------------------------------------------------
diff --git a/griffin-ui/js/controllers/main-ctrl.js 
b/griffin-ui/js/controllers/main-ctrl.js
new file mode 100644
index 0000000..37274af
--- /dev/null
+++ b/griffin-ui/js/controllers/main-ctrl.js
@@ -0,0 +1,36 @@
+/*
+       Copyright (c) 2016 eBay Software Foundation.
+       Licensed under the Apache License, Version 2.0 (the "License");
+       you may not use this file except in compliance with the License.
+       You may obtain a copy of the License at
+
+           http://www.apache.org/licenses/LICENSE-2.0
+
+       Unless required by applicable law or agreed to in writing, software
+       distributed under the License is distributed on an "AS IS" BASIS,
+       WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+       See the License for the specific language governing permissions and
+       limitations under the License.
+*/
+define(['./module'], function(controllers) {
+    'use strict';
+    controllers.controller('MainCtrl', ['$scope', '$http', '$config', 
'$location', '$routeParams', '$timeout', '$compile', '$route', '$barkChart', 
'$rootScope', function($scope, $http, $config, $location, $routeParams, 
$timeout, $compile, $route, $barkChart, $rootScope) {
+
+        $scope.resizeMainWindow = function() {
+            $('#mainWindow').height(window.innerHeight-56-90);
+        }
+
+        $(window).resize(function() {
+
+            console.log('main resize');
+            $scope.resizeMainWindow();
+
+            $scope.$broadcast('resizeHandler');
+        });
+
+        $scope.$on('initReq', function(e) {
+            $scope.resizeMainWindow();
+        })
+    }
+    ]);
+});
\ No newline at end of file

Reply via email to