blob: 97d33e0528ca8cc0b2243a5a30da26011f09b6af [file] [log] [blame]
/*-
* 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.dataAsset = '';
$scope.basic = {};
$scope.rules = '';
// $scope.pk = '';
var dbtreeUrl = $config.uri.dbtree;
var schemaDefinitionUrl = $config.uri.schemadefinition;
$http.get(dbtreeUrl).then(function successCallback(data) {
var dbList = [];
if (data.data) {
angular.forEach(data.data,function(db,key){
console.log(db);
var dbNode = {
name: key,
l1: true,
children: []
};
dbList.push(dbNode);
if (db) {
angular.forEach(db,function(table){
// console.log(table);
// console.log(typeof(table));
var dsNode = {
name: table.tableName,
l2: true,
children: []
};
dbNode.children.push(dsNode);
dsNode.parent = db;
if (table.sd.cols) {
table.sd.cols.sort(function(a, b){
return (a.name<b.name?-1:(a.name>b.name?1:0));
});
angular.forEach(table.sd.cols,function(col) {
var schemaNode = {
name: col.name,
type: col.type,
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) {
$http.get(schemaDefinitionUrl+ '/' + newValue.parent[0].dbName+'/table/'+newValue.name).then(function successCallback(data) {
console.log(data);
$scope.schemaCollection = data.data.sd.cols;
console.log($scope.schemaCollection);
});
}
});
$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;
console.log('currentNodeTarget');
console.log($scope.currentNodeTarget);
$scope.dataAsset = $scope.currentNodeTarget.name + ',' + $scope.currentNode.name;
console.log($scope.dataAsset);
}
;
//trigger after select schema
$scope.$watch('currentNodeTarget', function(newValue) {
console.log('currentNodeTarget');
console.log($scope.currentNodeTarget);
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;
// });
// }
//
//
// }
if (newValue) {
$http.get(schemaDefinitionUrl + '/' + newValue.parent[0].dbName+'/table/'+newValue.name).then(function successCallback(data) {
console.log(data);
$scope.schemaCollectionTarget = data.data.sd.cols;
console.log($scope.schemaCollectionTarget);
});
}
if($scope.currentNodeTarget)
$scope.dataAsset = $scope.currentNodeTarget.name + ',' + $scope.currentNode.name;
console.log($scope.dataAsset);
});
// $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);
console.log('currentNodeTarget');
console.log($scope.currentNodeTarget);
console.log($scope.currentNodeTarget.parent);
}
});
}
$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);
document.getElementByTag('fieldset').style.minHeight = $(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 = ['==', '!==', '>', '>=','<',"<="];
// $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();
var rule = '';
this.data={
"name":$scope.basic.name,
"description":$scope.basic.desc,
"organization":$scope.basic.system,
"type":$scope.basic.type,
"source":{
"type":"HIVE",
"version":"1.2",
"config":{
"database":$scope.currentNode.parent[0].dbName,
"table.name":$scope.currentNode.name,
},
},
"target":{
"type":"HIVE",
"version":"1.2",
"config":{
"database":$scope.currentNodeTarget.parent[0].dbName,
"table.name":$scope.currentNodeTarget.name,
},
},
"evaluateRule":{
"rules":'',
},
"owner":$scope.basic.owner,
mappings:[],
};
$scope.dataAsset = $scope.currentNodeTarget.name + ',' + $scope.currentNode.name;
var mappingRule = function(src, tgt, matches) {
var s = src.split('.');
var t = tgt.split('.');
return "$source['" + s[1] + "'] " + matches + " $target['" + t[1] + "']";
}
var rules = $scope.selectionTarget.map(function(item, i) {
return mappingRule($scope.selection[i], item, $scope.matches[i]);
});
rule = rules.join(" AND ");
// for(var i = 0;i<$scope.selectionTarget.length;i++){
// console.log($scope.selection[i]);
// var s =$scope.selection[i].split('.');
// var t = $scope.selectionTarget[i].split('.');
//
// console.log( $scope.matches[i]);
// rule += "${source}['" + s[1] + "'] "+ $scope.matches[i]+" ${target}['" + t[1] + "'];" ;
// }
$scope.rules = rule;
this.data.evaluateRule.rules = rule;
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.addModels;
$http.post(newModel, this.data).then(function successCallback(data) {
// if(data.status=='0')
// {
console.log(data);
if(data.data=='CREATE_MEASURE_FAIL_DUPLICATE'){
toaster.pop('error', 'Please modify the name of measure, because there is already a same measure in database ', data.message);
return;
}
$('#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 measure failed, please try again!', data.message);
// });
},function errorCallback(response) {
toaster.pop('error', 'Save measure failed, please try again!', response.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.', '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);
}
}
;
}
]);
});