http://git-wip-us.apache.org/repos/asf/falcon/blob/76dc2e18/falcon-ui/app/js/controllers/datasource/datasource-advanced-controller.js ---------------------------------------------------------------------- diff --git a/falcon-ui/app/js/controllers/datasource/datasource-advanced-controller.js b/falcon-ui/app/js/controllers/datasource/datasource-advanced-controller.js new file mode 100644 index 0000000..a9f975b --- /dev/null +++ b/falcon-ui/app/js/controllers/datasource/datasource-advanced-controller.js @@ -0,0 +1,34 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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. + */ +(function () { + 'use strict'; + + /*** + * @ngdoc controller + * @name app.controllers.datasource.DatasourceGeneralInformationController + * @requires EntityModel the entity model to copy the datasource entity from + * @requires Falcon the falcon entity service + */ + var datasourceModule = angular.module('app.controllers.datasource'); + + datasourceModule.controller('DatasourceAdvancedController', [ "$scope", function ($scope) { + + }]); + + +}());
http://git-wip-us.apache.org/repos/asf/falcon/blob/76dc2e18/falcon-ui/app/js/controllers/datasource/datasource-general-information-controller.js ---------------------------------------------------------------------- diff --git a/falcon-ui/app/js/controllers/datasource/datasource-general-information-controller.js b/falcon-ui/app/js/controllers/datasource/datasource-general-information-controller.js new file mode 100644 index 0000000..1299b15 --- /dev/null +++ b/falcon-ui/app/js/controllers/datasource/datasource-general-information-controller.js @@ -0,0 +1,141 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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. + */ +(function () { + 'use strict'; + + /*** + * @ngdoc controller + * @name app.controllers.datasource.DatasourceGeneralInformationController + * @requires EntityModel the entity model to copy the datasource entity from + * @requires Falcon the falcon entity service + */ + var datasourceModule = angular.module('app.controllers.datasource'); + + datasourceModule.controller('DatasourceGeneralInformationController', [ "$scope", function ($scope) { + $scope.addTag = function () { + $scope.datasource.tags.push({key: null, value: null}); + }; + + $scope.removeTag = function (index) { + if (index >= 0 && $scope.datasource.tags.length > 1) { + $scope.datasource.tags.splice(index, 1); + } + }; + + $scope.addParameter = function () { + $scope.datasource.parameters.push({name: null, value: null}); + }; + + $scope.removeParameter = function (index) { + if (index >= 0 && $scope.datasource.parameters.length > 0) { + $scope.datasource.parameters.splice(index, 1); + } + }; + + $scope.addProperty = function () { + $scope.datasource.customProperties.push({name: null, value: null}); + }; + + $scope.removeProperty = function (index) { + if (index >= 0 && $scope.datasource.customProperties.length > 0) { + $scope.datasource.customProperties.splice(index, 1); + } + }; + + $scope.addDriverJar = function () { + var lastOne = $scope.datasource.driver.jar.length - 1; + if($scope.datasource.driver.jar[lastOne].value) { + $scope.datasource.driver.jar.push({value:""}); + } + }; + + $scope.removeDriverJar = function(index) { + if(index !== null && $scope.datasource.driver.jar[index]) { + $scope.datasource.driver.jar.splice(index, 1); + } + }; + + $scope.getDatabaseDefaultDetails = function() { + switch ($scope.datasource.type) { + case "postgres": + $scope.datasource.interfaces.interfaces[0].endpoint = "jdbc:postgresql://db_host:5433/test"; + $scope.datasource.driver.clazz = "org.postgresql.Driver"; + return; + case "mysql": + $scope.datasource.interfaces.interfaces[0].endpoint = "jdbc:mysql://db_host:3306"; + $scope.datasource.driver.clazz = "com.mysql.jdbc.Driver"; + return; + case "hsql": + $scope.datasource.interfaces.interfaces[0].endpoint = "jdbc:hsqldb:hsql://db_host:9001"; + $scope.datasource.driver.clazz = "org.hsqldb.jdbcDriver"; + return; + case "oracle": + $scope.datasource.interfaces.interfaces[0].endpoint = "jdbc:oracle:thin@db_host:1526:oracle_sid"; + $scope.datasource.driver.clazz = "oracle.jdbc.driver.OracleDriver"; + return; + case "teradata": + $scope.datasource.interfaces.interfaces[0].endpoint = "jdbc:teradata://db_host"; + $scope.datasource.driver.clazz = "com.teradata.jdbc.TeraDriver"; + return; + case "db2": + $scope.datasource.interfaces.interfaces[0].endpoint = "jdbc:db2://db_host:50000/SAMPLE"; + $scope.datasource.driver.clazz = "com.ibm.db2.jcc.DB2Driver"; + return; + case "netezza": + $scope.datasource.interfaces.interfaces[0].endpoint = "jdbc:netezza://db_host:5480/test"; + $scope.datasource.driver.clazz = "org.netezza.Driver"; + return; + default: + $scope.datasource.interfaces.interfaces[0].endpoint = "jdbc:" + $scope.datasource.driver.clazz = "org.apache.sqoop.connector.jdbc.GenericJdbcConnector"; + return; + } + } + + // $scope.datasource.interfaces.interfaces[0].endpoint = $scope.datasource.type; + + // $scope.$watchCollection( + // "[datasource.type, datasource.host, datasource.port, datasource.databaseName]", function() { + // var connectionString; + // switch ($scope.datasource.type) { + // case "sqlserver": + // connectionString = "jdbc:jtds:sqlserver://"; + // case "mysql": + // connectionString = "jdbc:mysql://"; + // case "postgresql": + // connectionString = "jdbc:postgresql://"; + // case "oracle": + // connectionString = "jdbc:oracle:thin:@//"; + // case "teradata": + // connectionString = "jdbc:teradata://"; + // case "db2": + // connectionString = "jdbc:db2://"; + // default: + // connectionString = "jdbc://"; + // }; + // $scope.datasource.interfaces.interfaces[0].endpoint = connectionString + // + $scope.datasource.host + ":" + // + $scope.datasource.port + "/" + // + $scope.datasource.databaseName; + // + // }); + // + }]); + + +}()); http://git-wip-us.apache.org/repos/asf/falcon/blob/76dc2e18/falcon-ui/app/js/controllers/datasource/datasource-module.js ---------------------------------------------------------------------- diff --git a/falcon-ui/app/js/controllers/datasource/datasource-module.js b/falcon-ui/app/js/controllers/datasource/datasource-module.js new file mode 100644 index 0000000..c8b40f3 --- /dev/null +++ b/falcon-ui/app/js/controllers/datasource/datasource-module.js @@ -0,0 +1,33 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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. + */ +(function () { + 'use strict'; + + /*** + * @ngdoc controller + * @name app.controllers.datasouurce.DatasourceController + * @requires EntityModel the entity model to copy the datasource entity from + * @requires Falcon the falcon entity service + */ + angular.module('app.controllers.datasource', + [ + 'app.controllers.entity', + 'app.services' + ]); + +})(); http://git-wip-us.apache.org/repos/asf/falcon/blob/76dc2e18/falcon-ui/app/js/controllers/datasource/datasource-root-ctrl.js ---------------------------------------------------------------------- diff --git a/falcon-ui/app/js/controllers/datasource/datasource-root-ctrl.js b/falcon-ui/app/js/controllers/datasource/datasource-root-ctrl.js new file mode 100644 index 0000000..2d38208 --- /dev/null +++ b/falcon-ui/app/js/controllers/datasource/datasource-root-ctrl.js @@ -0,0 +1,249 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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. + */ +(function () { + 'use strict'; + + /*** + * @ngdoc controller + * @name app.controllers.datasource.DatasourceController + * @requires EntityModel the entity model to copy the datasource entity from + * @requires Falcon the falcon entity service + */ + var datasourceModule = angular.module('app.controllers.datasource'); + + datasourceModule.controller('DatasourceController', + [ '$scope', '$state', '$timeout', "RouteHelper", + 'Falcon', 'X2jsService', + 'JsonTransformerFactory', 'EntityFactory', + 'EntitySerializer', '$interval', + '$controller', "ValidationService", + "SpinnersFlag", "$rootScope", "DatasourceModel", + function($scope, $state, $timeout, RouteHelper, Falcon, + X2jsService, transformerFactory, entityFactory, + serializer, $interval, $controller, + validationService, SpinnersFlag, $rootScope, datasourceModel) { + + $scope.entityType = 'datasource'; + var stateMatrix = { + general : {previous : '', next : 'summary'}, + summary : {previous : 'general', next : ''} + }; + //extending root controller + $controller('EntityRootCtrl', { + $scope: $scope + }); + + $scope.skipUndo = false; + $scope.secureMode = $rootScope.secureMode; + + $scope.$on('$destroy', function () { + + // if (!$scope.skipUndo && !angular.equals($scope.UIModel, EntityModel.defaultValues.datasourceModel)) { + // if($scope.clone){ + // EntityModel.datasourceModel.UIModel.clone = true; + // } + // if($scope.editingMode){ + // EntityModel.datasourceModel.UIModel.edit = true; + // } + // $scope.$parent.cancel('datasource', $rootScope.previousState); + // } + }); + + $scope.loadOrCreateEntity = function() { + var type = $scope.entityType; + if(!datasourceModel && $scope.$parent.models.datasourceModel){ + datasourceModel = $scope.$parent.models.datasourceModel; + } + $scope.$parent.models.datasourceModel = null; + return datasourceModel ? serializer.preDeserialize(datasourceModel, type) : entityFactory.newEntity(type); + }; + + $scope.init = function() { + $scope.baseInit(); + var type = $scope.entityType; + $scope[type] = $scope.loadOrCreateEntity(); + if(datasourceModel && datasourceModel.clone === true){ + $scope.cloningMode = true; + $scope.editingMode = false; + $scope[type].name = ""; + }else if(datasourceModel && datasourceModel.edit === true){ + $scope.editingMode = true; + $scope.cloningMode = false; + }else{ + $scope.editingMode = false; + $scope.cloningMode = false; + } + } + + $scope.init(); + + $scope.transform = function() { + var type = $scope.entityType; + var xml = serializer.serialize($scope[type], $scope.entityType); + $scope.prettyXml = X2jsService.prettifyXml(xml); + $scope.xml = xml; + return xml; + }; + + var xmlPreviewCallback = function() { + var type = $scope.entityType; + if($scope.editXmlDisabled) { + try { + $scope.transform(); + } catch (exception) { + console.log('error when transforming xml'); + console.log(exception); + } + } else { + try { + $scope[type] = serializer.deserialize($scope.prettyXml, type); + $scope.invalidXml = false; + } catch (exception) { + $scope.invalidXml = true; + console.log('user entered xml incorrect format'); + console.log(exception); + } + } + }; + + $scope.$watch('datasource', xmlPreviewCallback, true); + $scope.$watch('prettyXml', xmlPreviewCallback, true); + $scope.$watch('datasource.interfaces', function() { + if ($scope.datasource.interfaces.interfaces[0] + && $scope.datasource.interfaces.interfaces[0].credential) { + $scope.datasource.interfaces.credential = $scope.datasource.interfaces.interfaces[0].credential; + } + }, true); + + $scope.toggleclick = function () { + $('.formBoxContainer').toggleClass('col-xs-14 '); + $('.xmlPreviewContainer ').toggleClass('col-xs-10 hide'); + $('.preview').toggleClass('pullOver pullOverXml'); + ($('.preview').hasClass('pullOver')) ? $('.preview').find('button').html('Preview XML') : $('.preview').find('button').html('Hide XML'); + ($($("textarea")[0]).attr("ng-model") == "prettyXml" ) ? $($("textarea")[0]).css("min-height", $(".formBoxContainer").height() - 40 ) : ''; + }; + + $scope.isActive = function (route) { + return route === $state.current.name; + }; + + $scope.isCompleted = function (route) { + return $state.get(route).data && $state.get(route).data.completed; + }; + + $scope.goNext = function (formInvalid) { + $state.current.data = $state.current.data || {}; + $state.current.data.completed = !formInvalid; + + SpinnersFlag.show = true; + if (!validationService.nameAvailable || formInvalid) { + validationService.displayValidations.show = true; + validationService.displayValidations.nameShow = true; + SpinnersFlag.show = false; + return; + } + validationService.displayValidations.show = false; + validationService.displayValidations.nameShow = false; + $state.go(RouteHelper.getNextState($state.current.name, stateMatrix)); + angular.element('body, html').animate({scrollTop: 0}, 500); + }; + + $scope.goBack = function () { + SpinnersFlag.backShow = true; + validationService.displayValidations.show = false; + validationService.displayValidations.nameShow = false; + $state.go(RouteHelper.getPreviousState($state.current.name, stateMatrix)); + angular.element('body, html').animate({scrollTop: 0}, 500); + }; + + function cleanXml (xml) { + var obj = X2jsService.xml_str2json(xml); + //feed properties + // if (obj.datasource.properties.property.length === 1 && obj.feed.properties.property[0] === "") { + // delete obj.datasource.properties; + // } + + return X2jsService.json2xml_str(obj); + } + + $scope.validate = function() { + var type = $scope.entityType; + var cleanedXml = cleanXml($scope.xml); + SpinnersFlag.validateShow = true; + Falcon.logRequest(); + + Falcon.postValidateEntity('<?xml version="1.0" encoding="UTF-8" standalone="yes"?>' + cleanedXml, $scope.entityType, $scope[type].name) + .success(function (response) { + Falcon.logResponse('success', response, false); + SpinnersFlag.validateShow = false; + angular.element('body, html').animate({scrollTop: 0}, 300); + }) + .error(function(err) { + Falcon.logResponse('error', err, false); + SpinnersFlag.validateShow = false; + angular.element('body, html').animate({scrollTop: 0}, 300); + }); + } + + $scope.saveEntity = function() { + var type = $scope.entityType; + var cleanedXml = cleanXml($scope.xml); + SpinnersFlag.show = true; + + if($scope.editingMode) { + Falcon.logRequest(); + + Falcon.postUpdateEntity('<?xml version="1.0" encoding="UTF-8" standalone="yes"?>' + cleanedXml, $scope.entityType, $scope[type].name) + .success(function (response) { + $scope.skipUndo = true; + Falcon.logResponse('success', response, false); + $state.go('main'); + }) + .error(function(err) { + Falcon.logResponse('error', err, false); + SpinnersFlag.show = false; + angular.element('body, html').animate({scrollTop: 0}, 300); + }); + } else { + Falcon.logRequest(); + Falcon.postSubmitEntity('<?xml version="1.0" encoding="UTF-8" standalone="yes"?>' + cleanedXml, $scope.entityType) + .success(function (response) { + $scope.skipUndo = true; + Falcon.logResponse('success', response, false); + $state.go('main'); + }) + .error(function(err) { + Falcon.logResponse('error', err, false); + SpinnersFlag.show = false; + angular.element('body, html').animate({scrollTop: 0}, 300); + }); + } + + $scope.editingMode = false; + $scope.cloningMode = false; + }; + + if($state.current.name !== "forms.datasource.general"){ + $state.go("forms.datasource.general"); + } + + } + ]); + + +})(); http://git-wip-us.apache.org/repos/asf/falcon/blob/76dc2e18/falcon-ui/app/js/controllers/datasource/datasource-summary-controller.js ---------------------------------------------------------------------- diff --git a/falcon-ui/app/js/controllers/datasource/datasource-summary-controller.js b/falcon-ui/app/js/controllers/datasource/datasource-summary-controller.js new file mode 100644 index 0000000..8440f13 --- /dev/null +++ b/falcon-ui/app/js/controllers/datasource/datasource-summary-controller.js @@ -0,0 +1,39 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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. + */ +(function () { + 'use strict'; + + /*** + * @ngdoc controller + * @name app.controllers.datasource.DatasourceSummaryController + * @requires EntityModel the entity model to copy the datasource entity from + * @requires Falcon the falcon entity service + */ + var datasourceModule = angular.module('app.controllers.datasource'); + + datasourceModule.controller('DatasourceSummaryController', [ "$scope", "$timeout", + function($scope, $timeout) { + + if($scope.transform) { + $scope.transform(); + } + + }]); + + +})(); http://git-wip-us.apache.org/repos/asf/falcon/blob/76dc2e18/falcon-ui/app/js/controllers/entity/entity-details.js ---------------------------------------------------------------------- diff --git a/falcon-ui/app/js/controllers/entity/entity-details.js b/falcon-ui/app/js/controllers/entity/entity-details.js index 217bb9b..6670dbb 100644 --- a/falcon-ui/app/js/controllers/entity/entity-details.js +++ b/falcon-ui/app/js/controllers/entity/entity-details.js @@ -27,10 +27,12 @@ var clusterModule = angular.module('app.controllers.view', [ 'app.services' ]); clusterModule.controller('EntityDetailsCtrl', [ - "$scope", "$timeout", "$interval", "Falcon", "EntityModel", "$state", "X2jsService", 'EntitySerializer', 'InstanceFalcon', - function ($scope, $timeout, $interval, Falcon, EntityModel, $state, X2jsService, serializer, InstanceFalcon) { + "$scope", "$timeout","$window", "$interval", "Falcon", "EntityModel","EntityScheduler", "$state", + "X2jsService", 'EntitySerializer', 'InstanceFalcon', 'entity', 'ExtensionSerializer', '$rootScope', + function ($scope, $timeout, $window, $interval, Falcon, EntityModel, EntityScheduler, + $state, X2jsService, serializer, InstanceFalcon, entity, extensionSerializer, $rootScope) { - $scope.entity = EntityModel; + $scope.entity = entity; var resultsPerPage = 10; var visiblePages = 3; @@ -39,7 +41,15 @@ $scope.pages = []; $scope.nextPages = false; - $scope.mirrorTag = "_falcon_mirroring_type"; + $scope.mirrorTag = "_falcon_extension_name"; + + $scope.isSafeMode = function() { + return $rootScope.safeMode; + }; + + $scope.isSuperUser = function() { + return $rootScope.superUser; + }; $scope.isMirror = function(tags){ var flag = false; @@ -49,22 +59,49 @@ return flag; }; + $scope.getMirrorType = function(tags) { + if (tags.search('_falcon_extension_name=HDFS-MIRRORING') !== -1) { + return "hdfs-mirror"; + } else if (tags.search('_falcon_extension_name=HDFS-SNAPSHOT-MIRRORING') !== -1) { + return "snapshot"; + } else if (tags.search('_falcon_extension_name=HIVE-MIRRORING') !== -1) { + return "hive-mirror"; + } + }; + if($scope.entity.type === "feed"){ + $scope.entityTypeLabel = "Feed"; $scope.feed = serializer.preDeserialize($scope.entity.model, "feed"); $scope.feed.name = $scope.entity.name; $scope.feed.type = $scope.entity.type; $scope.entity.start = $scope.entity.model.feed.clusters.cluster[0].validity._start; $scope.entity.end = $scope.entity.model.feed.clusters.cluster[0].validity._end; - }else{ + } else if($scope.entity.type === "cluster"){ + $scope.entityTypeLabel = "Cluster"; + $scope.cluster = serializer.preDeserialize($scope.entity.model, "cluster"); + $scope.cluster.name = $scope.entity.name; + $scope.cluster.type = $scope.entity.type; + }else if($scope.entity.type === "process"){ var tags = $scope.entity.model.process.tags; if($scope.isMirror(tags)){ - $scope.entityTypeLabel = "Mirror"; + var mirrorType = $scope.getMirrorType(tags); + if (mirrorType === "snapshot") { + $scope.entityTypeLabel = "Snapshot"; + } if (mirrorType === "hdfs-mirror") { + $scope.entityTypeLabel = "HDFS Mirror"; + } else if (mirrorType === "hive-mirror") { + $scope.entityTypeLabel = "Hive Mirror"; + } + $scope.extension = extensionSerializer.serializeExtensionModel( + $scope.entity.model, mirrorType, $rootScope.secureMode); + } else { + $scope.entityTypeLabel = "Process"; + $scope.process = serializer.preDeserialize($scope.entity.model, "process"); + $scope.process.name = $scope.entity.name; + $scope.process.type = $scope.entity.type; + $scope.entity.start = $scope.entity.model.process.clusters.cluster[0].validity._start; + $scope.entity.end = $scope.entity.model.process.clusters.cluster[0].validity._end; } - $scope.process = serializer.preDeserialize($scope.entity.model, "process"); - $scope.process.name = $scope.entity.name; - $scope.process.type = $scope.entity.type; - $scope.entity.start = $scope.entity.model.process.clusters.cluster[0].validity._start; - $scope.entity.end = $scope.entity.model.process.clusters.cluster[0].validity._end; } $scope.capitalize = function(input) { @@ -141,7 +178,10 @@ if(type === "FEED"){ $scope.entityTypeLabel = "Feed"; return "entypo download"; - }else if(type === "PROCESS"){ + } else if(type === "CLUSTER"){ + $scope.entityTypeLabel = "Cluster"; + return "entypo archive"; + } else if(type === "PROCESS"){ var tags = model.process.tags; if($scope.isMirror(tags)){ $scope.entityTypeLabel = "Mirror"; @@ -156,6 +196,62 @@ } }; + $scope.deleteEntity = function () { + EntityScheduler.deleteEntity($scope.entity.type, $scope.entity.name).then(function(status){ + if(status === "DELETED"){ + $state.go("main"); + } + }); + }; + $scope.cloneEntity = function () { + var type = $scope.entity.type.toLowerCase(); + if(type === 'process' && $scope.isMirror($scope.entity.model.process.tags)){ + type = $scope.getMirrorType($scope.entity.model.process.tags); + if (type === 'hdfs-mirror' || type === 'hive-mirror') { + type = 'dataset'; + } + } + var state = 'forms.' + type; + $state.go(state, {'name' : $scope.entity.name, 'action' : 'clone'}); + }; + + $scope.editEntity = function () { + var type = $scope.entity.type.toLowerCase(); + if (type === 'cluster' && (!$rootScope.safeMode || !$rootScope.superUser)) { + return; + } + if(type === 'process' && $scope.isMirror($scope.entity.model.process.tags)){ + type = $scope.getMirrorType($scope.entity.model.process.tags); + if (type === 'hdfs-mirror' || type === 'hive-mirror') { + type = 'dataset'; + } + } + var state = 'forms.' + type; + $state.go(state, {'name' : $scope.entity.name, 'action' : 'edit'}); + }; + + $scope.resumeEntity = function () { + EntityScheduler.resumeEntity($scope.entity.type, $scope.entity.name).then(function(status){ + $scope.entity.status = status; + }); + }; + + $scope.scheduleEntity = function () { + EntityScheduler.scheduleEntity($scope.entity.type, $scope.entity.name).then(function(status){ + $scope.entity.status = status; + }); + }; + + $scope.suspendEntity = function () { + EntityScheduler.suspendEntity($scope.entity.type, $scope.entity.name).then(function(status){ + $scope.entity.status = status; + }); + }; + + $scope.downloadEntity = function () { + EntityScheduler.downloadEntity($scope.entity.type, $scope.entity.name); + }; + } ]); http://git-wip-us.apache.org/repos/asf/falcon/blob/76dc2e18/falcon-ui/app/js/controllers/entity/entity-module.js ---------------------------------------------------------------------- diff --git a/falcon-ui/app/js/controllers/entity/entity-module.js b/falcon-ui/app/js/controllers/entity/entity-module.js index cb36b45..aa5a4fd 100644 --- a/falcon-ui/app/js/controllers/entity/entity-module.js +++ b/falcon-ui/app/js/controllers/entity/entity-module.js @@ -21,8 +21,21 @@ var entityModule = angular.module('app.controllers.entity',[ 'app.services' ]); entityModule.controller('EntityRootCtrl', - [ '$scope', - function($scope) { + [ '$scope', 'ValidationService', + function($scope, validationService) { + + $scope.invalidXml = false; + $scope.isFrequencyValid = true; + + $scope.checkMininumFrequency = function(quantity, unit, field){ + $scope.isFrequencyValid = quantity ? true : false; + if (quantity && unit === 'minutes') { + $scope.isFrequencyValid = validationService.checkMininum(quantity); + } else if (unit !== 'minutes' && quantity && parseInt(quantity) === 0) { + $scope.isFrequencyValid = false; + } + field.$setValidity('required', $scope.isFrequencyValid); + }; $scope.baseInit = function() { $scope.editXmlDisabled = true; @@ -32,6 +45,11 @@ $scope.editXmlDisabled = !$scope.editXmlDisabled; }; + $scope.revertXml = function() { + $scope.transform(); + $scope.invalidXml = false; + }; + $scope.capitalize = function(input) { return input.charAt(0).toUpperCase() + input.slice(1); }; http://git-wip-us.apache.org/repos/asf/falcon/blob/76dc2e18/falcon-ui/app/js/controllers/entity/instance-details.js ---------------------------------------------------------------------- diff --git a/falcon-ui/app/js/controllers/entity/instance-details.js b/falcon-ui/app/js/controllers/entity/instance-details.js index 0775d61..5800aba 100644 --- a/falcon-ui/app/js/controllers/entity/instance-details.js +++ b/falcon-ui/app/js/controllers/entity/instance-details.js @@ -27,12 +27,13 @@ var clusterModule = angular.module('app.controllers.instance', ['app.services']); clusterModule.controller('InstanceDetailsCtrl', [ - "$scope", "$interval", "Falcon", "EntityModel", "$state", "X2jsService", 'EntitySerializer', - function ($scope, $interval, Falcon, EntityModel, $state, X2jsService) { + "$scope", "$interval", "Falcon", "EntityModel", "$state", "X2jsService", 'DateHelper', + function ($scope, $interval, Falcon, EntityModel, $state, X2jsService, DateHelper) { $scope.instance = EntityModel.model; $scope.instance.type = EntityModel.type; $scope.instance.name = EntityModel.name; + $scope.dateFormat = DateHelper.getLocaleDateFormat() +'HH:mm'; $scope.backToEntity = function () { var type = $scope.instance.type.toLowerCase(); @@ -45,7 +46,7 @@ EntityModel.type = type; EntityModel.name = name; EntityModel.model = entityModel; - $state.go('entityDetails'); + $state.go('entityDetails',{'name' : name, 'type' : type}); }) .error(function (err) { Falcon.logResponse('error', err, false, true); http://git-wip-us.apache.org/repos/asf/falcon/blob/76dc2e18/falcon-ui/app/js/controllers/feed/feed-advanced-controller.js ---------------------------------------------------------------------- diff --git a/falcon-ui/app/js/controllers/feed/feed-advanced-controller.js b/falcon-ui/app/js/controllers/feed/feed-advanced-controller.js new file mode 100644 index 0000000..4d80cc7 --- /dev/null +++ b/falcon-ui/app/js/controllers/feed/feed-advanced-controller.js @@ -0,0 +1,34 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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. + */ +(function () { + 'use strict'; + + /*** + * @ngdoc controller + * @name app.controllers.feed.FeedAdvancedController + * @requires clusters the list of clusters to display for selection of source + * @requires EntityModel the entity model to copy the feed entity from + * @requires Falcon the falcon entity service + */ + var feedModule = angular.module('app.controllers.feed'); + + feedModule.controller('FeedAdvancedController', [ "$scope",function($scope) { + + }]); + +})(); http://git-wip-us.apache.org/repos/asf/falcon/blob/76dc2e18/falcon-ui/app/js/controllers/feed/feed-clusters-controller.js ---------------------------------------------------------------------- diff --git a/falcon-ui/app/js/controllers/feed/feed-clusters-controller.js b/falcon-ui/app/js/controllers/feed/feed-clusters-controller.js index 64c6892..6d829b9 100644 --- a/falcon-ui/app/js/controllers/feed/feed-clusters-controller.js +++ b/falcon-ui/app/js/controllers/feed/feed-clusters-controller.js @@ -30,14 +30,38 @@ feedModule.controller('FeedClustersController', [ "$scope", "clustersList", "EntityFactory", "$timeout", function($scope, clustersList, entityFactory, $timeout) { - function focusOnElement () { - $timeout(function () { - angular.element('#clusterNameSelect').trigger('focus'); - }, 500); + unwrapClusters(clustersList); + $scope.sourceClusterName; + $scope.sourceClusterNotSelected = false; + $scope.sourceClusterExists = false; + $scope.targetClusterName; + $scope.targetClusterNotSelected = false; + $scope.targetClusterExists = false; + + function preparePartitionString() { + $scope.feedPartitions = ""; + $scope.feed.partitions.forEach(function(partition, index){ + $scope.feedPartitions = $scope.feedPartitions.concat(partition.name); + if (index < $scope.feed.partitions.length - 1) { + $scope.feedPartitions = $scope.feedPartitions.concat(","); + } + }); } - focusOnElement(); - unwrapClusters(clustersList); + $scope.$watch("feed.partitions",function(){ + preparePartitionString(); + $scope.$broadcast("createClusterPartitions"); + }, true); + + $scope.createFeedClusterPartitions = function() { + if ($scope.feedPartitions != undefined) { + var currentPartitions = ($scope.feedPartitions.trim() === "") ? [] : $scope.feedPartitions.split(","); + $scope.feed.partitions = []; + currentPartitions.forEach(function(element) { + $scope.feed.partitions.push(entityFactory.newPartition(element)); + }); + } + }; $scope.updateRetention = function() { if($scope.selectedCluster.retention.action === 'archive' && $scope.selectedCluster.type === 'source') { @@ -64,15 +88,75 @@ } }; - $scope.addCluster = function() { - $scope.selectedCluster.selected = false; - var cluster = $scope.newCluster(true); + function openClusterInAccordion(object, flagValue) { + object.isAccordionOpened = flagValue; + } + + $scope.feed.clusters.forEach(function(cluster) { + openClusterInAccordion(cluster, false); + }); + + function findClusterExists(clusterList, newClusterName, newClusterType) { + var clusterExists = false; + clusterList.forEach(function (cluster) { + if (cluster.name === newClusterName && cluster.type === newClusterType) { + clusterExists = true; + return; + } + }); + return clusterExists; + } + + $scope.clearSourceClusterFlags = function() { + $scope.sourceClusterNotSelected = false; + $scope.sourceClusterExists = false; + } + + $scope.clearTargetClusterFlags = function() { + $scope.targetClusterNotSelected = false; + $scope.targetClusterExists = false; + } + + $scope.addSourceCluster = function() { + $scope.clearSourceClusterFlags(); + if ($scope.sourceClusterName == undefined) { + $scope.sourceClusterNotSelected = true; + } else if (!findClusterExists($scope.feed.clusters, $scope.sourceClusterName, 'source')) { + $scope.addCluster('source', $scope.sourceClusterName); + } else { + $scope.sourceClusterExists = true; + } + }; + + $scope.addTargetCluster = function() { + if ($scope.targetClusterName == undefined) { + $scope.targetClusterNotSelected = true; + } else if (!findClusterExists($scope.feed.clusters, $scope.targetClusterName, 'target')) { + $scope.addCluster('target', $scope.targetClusterName); + } else { + $scope.targetClusterExists = true; + } + }; + + $scope.addCluster = function(clusterType, clusterName) { + var cluster = $scope.newCluster(clusterType, true, clusterName); + if($scope.feed.storage.catalog.active){ + cluster.storage.catalog.catalogTable.uri = $scope.feed.storage.catalog.catalogTable.uri + } + cluster.storage.fileSystem.locations.forEach(function (location) { + if (location.type === 'data') { + var dataLocation = $scope.feed.storage.fileSystem.locations.filter(function(obj) { + return obj.type == 'data'; + })[0]; + location.path = (dataLocation != undefined) ? dataLocation.path : ''; + } + }); + openClusterInAccordion(cluster, true); $scope.feed.clusters.push(cluster); - $scope.selectedCluster = cluster; }; - $scope.newCluster = function(selected) { - return entityFactory.newCluster('target', selected); + $scope.newCluster = function(clusterType, selected, clusterName, partition) { + return entityFactory.newCluster(clusterType, selected, clusterName, partition); }; $scope.handleCluster = function(cluster, index) { @@ -89,12 +173,27 @@ $scope.selectedCluster = cluster; }; - $scope.removeCluster = function(index) { - if(index >= 0 && $scope.feed.clusters.length > 1 && - $scope.feed.clusters[index].type !== 'source' && - !$scope.archiveCluster.active) { - $scope.feed.clusters.splice(index, 1); - $scope.selectCluster($scope.sourceCluster); + function findClusterIndex(atIndex, ofType) { + var index = -1; + for (var i=0,len=$scope.feed.clusters.length;i<len;i++){ + var cluster=$scope.feed.clusters[i]; + if (cluster.type === ofType) { + index++; + if (index === atIndex) { + return i; + } + } + } + return -1; + }; + + $scope.removeCluster = function(clusterIndex, clusterType) { + if (clusterIndex >= 0 && $scope.feed.clusters.length > 0 + && !$scope.archiveCluster.active) { + var clusterTypeIndex = findClusterIndex(clusterIndex, clusterType); + if (clusterTypeIndex > -1) { + $scope.feed.clusters.splice(clusterTypeIndex, 1); + } } }; http://git-wip-us.apache.org/repos/asf/falcon/blob/76dc2e18/falcon-ui/app/js/controllers/feed/feed-general-information-controller.js ---------------------------------------------------------------------- diff --git a/falcon-ui/app/js/controllers/feed/feed-general-information-controller.js b/falcon-ui/app/js/controllers/feed/feed-general-information-controller.js index 40dbdbc..bb45bbd 100644 --- a/falcon-ui/app/js/controllers/feed/feed-general-information-controller.js +++ b/falcon-ui/app/js/controllers/feed/feed-general-information-controller.js @@ -28,8 +28,18 @@ var feedModule = angular.module('app.controllers.feed'); - feedModule.controller('FeedGeneralInformationController', [ "$scope", function ($scope) { + feedModule.controller('FeedGeneralInformationController', [ "$scope","clustersList",'EntityFactory', + function ($scope, clustersList, entityFactory) { + $scope.propPlaceholders = { + queueName: 'default', + jobPriority: '', + parallel: 3, + maxMaps: 8, + mapBandwidthKB: 1024 + }; + + unwrapClusters(clustersList); $scope.nameValid = false; $scope.addTag = function () { @@ -42,7 +52,120 @@ } }; - }]); + function unwrapClusters(clusters) { + if(clusters !== undefined && clusters !== null && clusters !== "null"){ + $scope.clustersList = []; + var typeOfData = Object.prototype.toString.call(clusters.entity); + if(typeOfData === "[object Array]") { + $scope.clustersList = clusters.entity; + } else if(typeOfData === "[object Object]") { + $scope.clustersList = [clusters.entity]; + } else { + //console.log("type of data not recognized"); + } + } + } + + function findClusterExists(clusterList, newClusterName, newClusterType) { + var clusterExists = false; + clusterList.forEach(function (cluster) { + if (cluster.name === newClusterName && cluster.type === newClusterType) { + clusterExists = true; + return; + } + }); + return clusterExists; + } + + $scope.onTypeChange = function(value){ + $scope.feed.clusters = []; + if (value === 'hive' || value ==='hdfs') { + $scope.feed.sourceClusterLocationType = value; + $scope.feed.targetClusterLocationType = value; + $scope.feed.clusters.push( + entityFactory.newCluster('source', $scope.feed.sourceClusterLocationType, "", null)); + $scope.feed.clusters.push( + entityFactory.newCluster('target', $scope.feed.targetClusterLocationType, "", null)); + } else if (value === 'import') { + $scope.feed.targetClusterLocationType = "hdfs"; + $scope.feed.clusters.push( + entityFactory.newCluster('source', $scope.feed.targetClusterLocationType, "", null)) + } else if (value === 'export') { + $scope.feed.sourceClusterLocationType = "hdfs"; + $scope.feed.clusters.push( + entityFactory.newCluster('source', $scope.feed.sourceClusterLocationType, "", null)); + } + }; + $scope.addClusterStorage = function(clusterDetails){ + var cluster = entityFactory.newCluster(clusterDetails.type, clusterDetails.dataTransferType, "", null); + if($scope.feed.clusters.length > 1 + && findClusterExists($scope.feed.clusters,cluster.name,cluster.type)){ + if(cluster.type === 'source'){ + $scope.sourceClusterExists = true; + }else{ + $scope.targetClusterExists = true; + } + return; + }else{ + $scope.sourceClusterExists = false; + $scope.targetClusterExists = false; + } + if(cluster.storage.fileSystem) { + cluster.storage.fileSystem.locations = []; + cluster.storage.fileSystem.locations.push({'type':'data','path':''}); + cluster.storage.fileSystem.locations.push({'type':'stats','path':'/'}); + } + $scope.feed.clusters.unshift(cluster); + }; + $scope.toggleClusterStorage = function(type){ + if(type === 'source'){ + $scope.showSourceClusterStorage = !$scope.showSourceClusterStorage; + }else if(type === 'target'){ + $scope.showTargetClusterStorage = !$scope.showTargetClusterStorage; + } + }; + + $scope.$watch("feed.import.source.includesCSV",function(){ + if($scope.feed.dataTransferType === 'import' && $scope.feed.import.source.includesCSV){ + $scope.feed.import.source.fields = { 'includes' : $scope.feed.import.source.includesCSV.split(",") }; + } + }, true); + $scope.$watch("feed.import.source.excludesCSV",function(){ + if($scope.feed.dataTransferType === 'import' && $scope.feed.import.source.excludesCSV){ + $scope.feed.import.source.fields = { 'excludes' : $scope.feed.import.source.excludesCSV.split(",") }; + } + }, true); + $scope.$watch("feed.export.target.includesCSV",function(){ + if($scope.feed.dataTransferType === 'export' && $scope.feed.export.target.includesCSV){ + $scope.feed.export.target.fields = { 'includes' : $scope.feed.export.target.includesCSV.split(",") }; + } + }, true); + $scope.$watch("feed.export.target.excludesCSV",function(){ + if($scope.feed.dataTransferType === 'export' && $scope.feed.export.target.excludesCSV){ + $scope.feed.export.target.fields = { 'excludes' : $scope.feed.export.target.excludesCSV.split(",") }; + } + }, true); + + $scope.$watch("feed.sourceClusterLocationType", function(){ + var sourceClusters = $scope.feed.clusters.filter(function(obj) { + return obj.type == 'source'; + }); + if(sourceClusters.length < 1){ + var cluster = entityFactory.newCluster('source', $scope.feed.sourceClusterLocationType, "", null); + $scope.feed.clusters.push(cluster) + } + }); + + $scope.$watch("feed.targetClusterLocationType", function(){ + var targetClusters = $scope.feed.clusters.filter(function(obj) { + return obj.type == 'target'; + }); + if(targetClusters.length < 1 && $scope.feed.dataTransferType !== 'import'){ + var cluster = entityFactory.newCluster('target', $scope.feed.targetClusterLocationType, "", null); + $scope.feed.clusters.push(cluster) + } + }); + }]); }()); http://git-wip-us.apache.org/repos/asf/falcon/blob/76dc2e18/falcon-ui/app/js/controllers/feed/feed-location-controller.js ---------------------------------------------------------------------- diff --git a/falcon-ui/app/js/controllers/feed/feed-location-controller.js b/falcon-ui/app/js/controllers/feed/feed-location-controller.js index 055436d..7030be4 100644 --- a/falcon-ui/app/js/controllers/feed/feed-location-controller.js +++ b/falcon-ui/app/js/controllers/feed/feed-location-controller.js @@ -29,22 +29,9 @@ feedModule.controller('FeedLocationController', [ "$scope", "$timeout", function ($scope, $timeout) { - function focusOnElement () { - $timeout(function () { - if ($scope.feed.storage.catalog.active) { - angular.element('.catalogStorageInput').trigger('focus'); - } - else { - angular.element('.firstInput').trigger('focus'); - } - }, 500); - } - focusOnElement(); - $scope.toggleStorage = function() { toggle($scope.feed.storage.fileSystem); toggle($scope.feed.storage.catalog); - focusOnElement(); }; function toggle(storage) { http://git-wip-us.apache.org/repos/asf/falcon/blob/76dc2e18/falcon-ui/app/js/controllers/feed/feed-root-ctrl.js ---------------------------------------------------------------------- diff --git a/falcon-ui/app/js/controllers/feed/feed-root-ctrl.js b/falcon-ui/app/js/controllers/feed/feed-root-ctrl.js index 9282ea4..4be1360 100644 --- a/falcon-ui/app/js/controllers/feed/feed-root-ctrl.js +++ b/falcon-ui/app/js/controllers/feed/feed-root-ctrl.js @@ -28,36 +28,63 @@ var feedModule = angular.module('app.controllers.feed'); feedModule.controller('FeedController', - [ '$scope', '$state', '$timeout', + [ '$scope', '$state', '$timeout', "RouteHelper", "DateHelper", 'Falcon', 'X2jsService', 'JsonTransformerFactory', 'EntityFactory', 'EntitySerializer', '$interval', '$controller', "ValidationService", - "SpinnersFlag", "$rootScope", - function($scope, $state, $timeout, Falcon, + "SpinnersFlag", "$rootScope", "FeedModel", "datasourcesList", + function($scope, $state, $timeout, RouteHelper, DateHelper, Falcon, X2jsService, transformerFactory, entityFactory, serializer, $interval, $controller, - validationService, SpinnersFlag, $rootScope) { + validationService, SpinnersFlag, $rootScope, feedModel, datasourcesList) { $scope.entityType = 'feed'; - + var stateMatrix = { + general : {previous : '', next : 'summary'}, + summary : {previous : 'general', next : ''} + }; //extending root controller $controller('EntityRootCtrl', { $scope: $scope }); + unwrapDatasources(datasourcesList); $scope.loadOrCreateEntity = function() { var type = $scope.entityType; - var model = $scope.models[type + 'Model']; - $scope.models[type + 'Model'] = null; - return model ? serializer.preDeserialize(model, type) : entityFactory.newEntity(type); + if(!feedModel && $scope.$parent.models.feedModel){ + feedModel = $scope.$parent.models.feedModel; + } + $scope.$parent.models.feedModel = null; + if (feedModel) { + var feedEntity = serializer.preDeserialize(feedModel, type); + // if (feedEntity && feedEntity.clusters) { + // feedEntity.clusters.forEach(function (feedCluster) { + // feedCluster.storage = feedEntity.storage; + // }); + // } + return feedEntity; + } else { + return entityFactory.newEntity(type) + } }; $scope.init = function() { $scope.baseInit(); var type = $scope.entityType; $scope[type] = $scope.loadOrCreateEntity(); - $scope.dateFormat ='MM/dd/yyyy'; + if(feedModel && feedModel.clone === true){ + $scope.cloningMode = true; + $scope.editingMode = false; + $scope[type].name = ""; + }else if(feedModel && feedModel.edit === true){ + $scope.editingMode = true; + $scope.cloningMode = false; + }else{ + $scope.editingMode = false; + $scope.cloningMode = false; + } + $scope.dateFormat = DateHelper.getLocaleDateFormat(); }; $scope.openDatePicker = function($event, container) { @@ -68,6 +95,19 @@ $scope.init(); + // $scope.$watch("feed.storage.fileSystem.locations",function(){ + // $scope.feed.clusters.forEach(function (feedCluster) { + // feedCluster.storage.fileSystem.locations.forEach(function (location) { + // if (location.type === 'data') { + // var dataLocation = $scope.feed.storage.fileSystem.locations.filter(function(obj) { + // return obj.type == 'data'; + // })[0]; + // location.path = (dataLocation != undefined) ? dataLocation.path : ''; + // } + // }); + // }); + // }, true); + $scope.transform = function() { var type = $scope.entityType; var xml = serializer.serialize($scope[type], $scope.entityType); @@ -76,23 +116,28 @@ return xml; }; - $scope.saveEntity = function() { + $scope.saveEntity = function(formInvalid) { var type = $scope.entityType; var cleanedXml = cleanXml($scope.xml); - SpinnersFlag.show = true; + SpinnersFlag.saveShow = true; + if (!validateFeedForm(formInvalid)) { + SpinnersFlag.saveShow = false; + return; + } - if(!$scope.$parent.cloningMode) { + if($scope.editingMode) { Falcon.logRequest(); Falcon.postUpdateEntity('<?xml version="1.0" encoding="UTF-8" standalone="yes"?>' + cleanedXml, $scope.entityType, $scope[type].name) .success(function (response) { $scope.skipUndo = true; Falcon.logResponse('success', response, false); + SpinnersFlag.saveShow = false; $state.go('main'); }) .error(function(err) { Falcon.logResponse('error', err, false); - SpinnersFlag.show = false; + SpinnersFlag.saveShow = false; angular.element('body, html').animate({scrollTop: 0}, 300); }); } else { @@ -101,21 +146,23 @@ .success(function (response) { $scope.skipUndo = true; Falcon.logResponse('success', response, false); + SpinnersFlag.saveShow = false; $state.go('main'); }) .error(function(err) { Falcon.logResponse('error', err, false); - SpinnersFlag.show = false; + SpinnersFlag.saveShow = false; angular.element('body, html').animate({scrollTop: 0}, 300); }); } - - $scope.editingMode = false; - $scope.cloningMode = false; }; $scope.isActive = function (route) { - return route === $state.$current.name; + return route === $state.current.name; + }; + + $scope.isCompleted = function (route) { + return $state.get(route).data && $state.get(route).data.completed; }; $scope.parseDate = function(input) { @@ -141,6 +188,7 @@ if($scope.editXmlDisabled) { try { $scope.transform(); + $scope.feed.storage = $scope.feed.clusters[0].storage; } catch (exception) { console.log('error when transforming xml'); console.log(exception); @@ -148,7 +196,10 @@ } else { try { $scope[type] = serializer.deserialize($scope.prettyXml, type); + $scope.invalidXml = false; + joinIncludesExcludes(); } catch (exception) { + $scope.invalidXml = true; console.log('user entered xml incorrect format'); console.log(exception); } @@ -156,7 +207,38 @@ }; - var xmlPreviewWorker = $interval(xmlPreviewCallback, 1000); + var joinIncludesExcludes = function(){ + if($scope.feed.dataTransferType === 'import'){ + $scope.dataSourceType = 'source'; + if($scope.feed.import.source.includesCSV){ + $scope.feed.import.source.columnsType = 'include'; + } else if($scope.feed.import.source.excludesCSV){ + $scope.feed.import.source.columnsType = 'exclude'; + } else { + $scope.feed.import.source.columnsType = 'all'; + } + } + if($scope.feed.dataTransferType === 'export'){ + $scope.dataSourceType = 'target'; + if($scope.feed.export.target.includesCSV){ + $scope.feed.export.target.columnsType = 'include'; + } else if($scope.export.import.target.excludesCSV){ + $scope.feed.export.target.columnsType = 'exclude'; + } else { + $scope.feed.export.target.columnsType = 'all'; + } + } + }; + $scope.$watch('feed', function(){ + if($scope.editXmlDisabled) { + xmlPreviewCallback(); + } + }, true); + $scope.$watch('prettyXml', function(){ + if(!$scope.editXmlDisabled) { + xmlPreviewCallback(); + } + }, true); $scope.skipUndo = false; $scope.$on('$destroy', function () { @@ -168,38 +250,72 @@ ACLIsEqual = angular.equals($scope.feed.ACL, defaultFeed.ACL), schemaIsEqual = angular.equals($scope.feed.schema, defaultFeed.schema); - $interval.cancel(xmlPreviewWorker); - if (!$scope.skipUndo && (!nameIsEqual || !groupsIsEqual || !descriptionIsEqual || !ACLIsEqual || !schemaIsEqual)) { $scope.$parent.models.feedModel = angular.copy(X2jsService.xml_str2json($scope.xml)); + if($scope.cloningMode){ + $scope.$parent.models.feedModel.clone = true; + } + if($scope.editingMode){ + $scope.$parent.models.feedModel.edit = true; + } $scope.$parent.cancel('feed', $rootScope.previousState); } }); - $scope.goNext = function (formInvalid, stateName) { - - SpinnersFlag.show = true; + function validateFeedForm(formInvalid) { + $state.current.data = $state.current.data || {}; + $state.current.data.completed = !formInvalid; if (!validationService.nameAvailable || formInvalid) { validationService.displayValidations.show = true; validationService.displayValidations.nameShow = true; - SpinnersFlag.show = false; - return; + if ($scope.currentState == 'forms.feed.clusters') { + $scope.$broadcast('forms.feed.clusters:submit'); + } + return false; + } + + // Duplicate Cluster Check + if ($scope.feed.clusters) { + var clusterNames = $scope.feed.clusters.map(function(item){ return item.name }); + var isDuplicateClusterExists = clusterNames.some(function(item, index){ + return clusterNames.indexOf(item) != index + }); + if(isDuplicateClusterExists) { + return false; + } } validationService.displayValidations.show = false; validationService.displayValidations.nameShow = false; - - $state.go(stateName); - - + return true; + } + $scope.goNext = function (formInvalid) { + SpinnersFlag.show = true; + if (validateFeedForm(formInvalid)) { + SpinnersFlag.show = false; + $state.go(RouteHelper.getNextState($state.current.name, stateMatrix)); + } + SpinnersFlag.show = false; }; - $scope.goBack = function (stateName) { + $scope.goBack = function () { SpinnersFlag.backShow = true; validationService.displayValidations.show = false; validationService.displayValidations.nameShow = false; - $state.go(stateName); + $state.go(RouteHelper.getPreviousState($state.current.name, stateMatrix)); }; - + function unwrapDatasources(datasources) { + if(datasources !== undefined && datasources !== null && datasources !== "null"){ + $scope.datasourceList = []; + var typeOfData = Object.prototype.toString.call(datasources.entity); + if(typeOfData === "[object Array]") { + $scope.datasourceList = datasources.entity; + } else if(typeOfData === "[object Object]") { + $scope.datasourceList = [datasources.entity]; + } else { + //console.log("type of data not recognized"); + } + } + } function cleanXml (xml) { @@ -208,11 +324,13 @@ feedLocationsArray = []; // cluster locations - obj.feed.clusters.cluster[0].locations.location.forEach(function (item) { - if (item._path) { - clusterLocationsArray.push(item); - } - }); + if(obj.feed.clusters.cluster[0].locations){ + obj.feed.clusters.cluster[0].locations.location.forEach(function (item) { + if (item._path) { + clusterLocationsArray.push(item); + } + }); + } if (clusterLocationsArray.length === 0) { delete obj.feed.clusters.cluster[0].locations; @@ -221,11 +339,13 @@ } // feed locations - obj.feed.locations.location.forEach(function (item) { - if (item._path) { - feedLocationsArray.push(item); - } - }); + if(obj.feed.locations){ + obj.feed.locations.location.forEach(function (item) { + if (item._path) { + feedLocationsArray.push(item); + } + }); + } if (feedLocationsArray.length === 0) { delete obj.feed.locations; @@ -234,7 +354,8 @@ } //feed properties - if (obj.feed.properties.property.length === 1 && obj.feed.properties.property[0] === "") { + if (obj.feed.properties && obj.feed.properties.property.length === 1 + && obj.feed.properties.property[0] === "") { delete obj.feed.properties; } @@ -242,6 +363,21 @@ } + $scope.toggleclick = function () { + $('.formBoxContainer').toggleClass('col-xs-14 '); + $('.xmlPreviewContainer ').toggleClass('col-xs-10 hide'); + $('.preview').toggleClass('pullOver pullOverXml'); + ($('.preview').hasClass('pullOver')) ? $('.preview').find('button').html('Preview XML') : $('.preview').find('button').html('Hide XML'); + ($($("textarea")[0]).attr("ng-model") == "prettyXml" ) ? $($("textarea")[0]).css("min-height", $(".formBoxContainer").height() - 40 ) : ''; + }; + + $scope.emptyClusterName = function (cluster) { + return !(cluster.name === null || cluster.name.trim().length === 0); + }; + + if($state.current.name !== "forms.feed.general"){ + $state.go("forms.feed.general"); + } }]); http://git-wip-us.apache.org/repos/asf/falcon/blob/76dc2e18/falcon-ui/app/js/controllers/feed/feed-summary-controller.js ---------------------------------------------------------------------- diff --git a/falcon-ui/app/js/controllers/feed/feed-summary-controller.js b/falcon-ui/app/js/controllers/feed/feed-summary-controller.js index 249b8da..1eb6c90 100644 --- a/falcon-ui/app/js/controllers/feed/feed-summary-controller.js +++ b/falcon-ui/app/js/controllers/feed/feed-summary-controller.js @@ -27,12 +27,8 @@ */ var feedModule = angular.module('app.controllers.feed'); - feedModule.controller('FeedSummaryController', [ "$scope", "$filter", "$timeout", - function($scope, $filter, $timeout) { - - $timeout(function () { - angular.element('.nextBtn').trigger('focus'); - }, 500); + feedModule.controller('FeedSummaryController', [ "$scope", "$filter", "$timeout", "DateHelper", + function($scope, $filter, $timeout, DateHelper) { if($scope.transform) { $scope.transform(); @@ -47,6 +43,10 @@ return input ? (output || input) : 'Not specified'; }; + $scope.getDateTimeString = function (date,time) { + return DateHelper.getDateTimeString(date,time); + }; + }]); http://git-wip-us.apache.org/repos/asf/falcon/blob/76dc2e18/falcon-ui/app/js/controllers/header-controller.js ---------------------------------------------------------------------- diff --git a/falcon-ui/app/js/controllers/header-controller.js b/falcon-ui/app/js/controllers/header-controller.js index b2dcaea..a0a0a20 100644 --- a/falcon-ui/app/js/controllers/header-controller.js +++ b/falcon-ui/app/js/controllers/header-controller.js @@ -41,36 +41,67 @@ }; $scope.resetCluster = function () { + $scope.clearTags(); validationService.displayValidations = {show: false, nameShow: false}; angular.copy(EntityModel.defaultValues.cluster, EntityModel.clusterModel); - $state.go("forms.cluster.general"); + $state.go("forms.cluster"); }; $scope.resetProcess = function () { + $scope.clearTags(); validationService.displayValidations = {show: false, nameShow: false}; $scope.cloningMode = true; $scope.models.processModel = null; - $state.go("forms.process.general"); + $state.go("forms.process"); }; $scope.resetFeed = function () { + $scope.clearTags(); validationService.displayValidations = {show: false, nameShow: false}; $scope.cloningMode = true; $scope.models.feedModel = null; - $state.go("forms.feed.general"); + $state.go("forms.feed"); }; - $scope.resetDataset = function () { + $scope.resetDataset = function (mirrorType) { + $scope.clearTags(); validationService.displayValidations = {show: false, nameShow: false}; EntityModel.datasetModel.toImportModel = undefined; angular.copy(EntityModel.defaultValues.MirrorUIModel, EntityModel.datasetModel.UIModel); + EntityModel.datasetModel.UIModel.type = mirrorType; $scope.cloningMode = true; - $scope.models.feedModel = null; - $state.go("forms.dataset.general"); + if($rootScope.currentState === 'forms.dataset.general') { + $state.reload("forms.dataset"); + } else if($rootScope.currentState === 'forms.dataset.summary') { + EntityModel.datasetModel.UIModel.ACL.owner = $cookieStore.get('userToken').user; + $state.go("forms.dataset.general"); + } else { + $state.go("forms.dataset"); + } + }; + + $scope.resetSnapshot = function () { + $scope.clearTags(); + validationService.displayValidations = {show: false, nameShow: false}; + $scope.cloningMode = true; + $scope.models.snapshotModel = null; + $state.go("forms.snapshot"); + }; + + $scope.isMirror = function(mirrorType) { + return EntityModel.datasetModel.UIModel && EntityModel.datasetModel.UIModel.type === mirrorType; + }; + + $scope.resetDatasource = function () { + $scope.clearTags(); + validationService.displayValidations = {show: false, nameShow: false}; + $scope.cloningMode = true; + $scope.models.dataSource = null; + $state.go("forms.datasource"); }; $scope.userLogged = function () { - if($rootScope.isSecureMode()){ + if($rootScope.isSecureMode() || $rootScope.ambariView()){ return true; }else if($rootScope.userLogged()){ if(angular.isDefined($cookieStore.get('userToken')) && $cookieStore.get('userToken') !== null){ @@ -94,7 +125,7 @@ }; $scope.restore = function(state) { - $state.go(state); + $state.go(state, {name : null, action : null}); }; $scope.notify = function() { http://git-wip-us.apache.org/repos/asf/falcon/blob/76dc2e18/falcon-ui/app/js/controllers/process/process-advanced-ctrl.js ---------------------------------------------------------------------- diff --git a/falcon-ui/app/js/controllers/process/process-advanced-ctrl.js b/falcon-ui/app/js/controllers/process/process-advanced-ctrl.js new file mode 100644 index 0000000..a5c871b --- /dev/null +++ b/falcon-ui/app/js/controllers/process/process-advanced-ctrl.js @@ -0,0 +1,34 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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. + */ +(function () { + 'use strict'; + + /*** + * @ngdoc controller + * @name app.controllers.process.ProcessAdvancedCtrl + * @requires EntityModel the entity model to copy the process entity from + * @requires Falcon the falcon entity service + */ + var processModule = angular.module('app.controllers.process'); + + processModule.controller('ProcessAdvancedCtrl', ['$scope', 'EntityFactory', '$timeout', 'DateHelper', + function($scope, entityFactory, $timeout, DateHelper) { + + }]); + +})(); http://git-wip-us.apache.org/repos/asf/falcon/blob/76dc2e18/falcon-ui/app/js/controllers/process/process-clusters-ctrl.js ---------------------------------------------------------------------- diff --git a/falcon-ui/app/js/controllers/process/process-clusters-ctrl.js b/falcon-ui/app/js/controllers/process/process-clusters-ctrl.js index 5605268..4f93dc8 100644 --- a/falcon-ui/app/js/controllers/process/process-clusters-ctrl.js +++ b/falcon-ui/app/js/controllers/process/process-clusters-ctrl.js @@ -27,15 +27,15 @@ */ var feedModule = angular.module('app.controllers.process'); - feedModule.controller('ProcessClustersCtrl', ['$scope', 'clustersList', 'EntityFactory', '$timeout', - function($scope, clustersList, entityFactory, $timeout) { + feedModule.controller('ProcessClustersCtrl', ['$scope', 'clustersList', 'EntityFactory', '$timeout', 'DateHelper', + function($scope, clustersList, entityFactory, $timeout, DateHelper) { $timeout(function () { angular.element('.firstSelectClusterStep').trigger('focus'); }, 500); $scope.init = function() { - $scope.dateFormat = 'MM/dd/yyyy'; + $scope.dateFormat = DateHelper.getLocaleDateFormat(); }; $scope.openDatePicker = function($event, container) { http://git-wip-us.apache.org/repos/asf/falcon/blob/76dc2e18/falcon-ui/app/js/controllers/process/process-general-information-ctrl.js ---------------------------------------------------------------------- diff --git a/falcon-ui/app/js/controllers/process/process-general-information-ctrl.js b/falcon-ui/app/js/controllers/process/process-general-information-ctrl.js index bda465d..9ded878 100644 --- a/falcon-ui/app/js/controllers/process/process-general-information-ctrl.js +++ b/falcon-ui/app/js/controllers/process/process-general-information-ctrl.js @@ -27,18 +27,46 @@ */ var feedModule = angular.module('app.controllers.process'); - feedModule.controller('ProcessGeneralInformationCtrl', [ '$scope', function($scope) { - var availableVerions = { - oozie: ['3.1.3-incubating', '3.2.0-incubating', '3.3.0', '3.3.1', '3.3.2', '4.0.0', '4.0.1'], - pig: ['pig-0.10.0', 'pig-0.10.1', 'pig-0.11.0', 'pig-0.11.1', 'pig-0.12.0', 'pig-0.12.1', 'pig-0.13.0', 'pig-0.8.0', 'pig-0.8.1', ' pig-0.9.0', ' pig-0.9.1', 'pig-0.9.2'], - hive: ['hive-0.10.0', 'hive-0.11.0', 'hive-0.12.0', 'hive-0.13.0', 'hive-0.13.1', 'hive-0.6.0', 'hive-0.7.0', 'hive-0.8.0', 'hive-0.8.1', 'hive-0.9.0'] - }; + feedModule.controller('ProcessGeneralInformationCtrl', [ + '$scope', 'clustersList', 'feedsList', 'EntityFactory', 'Falcon', 'X2jsService','DateHelper', + function($scope, clustersList, feedsList, entityFactory, Falcon, X2jsService, DateHelper) { + $scope.nameValid = false; - + + $scope.$watch('process.workflow.spark.jar',function(){ + if($scope.process.workflow.spark.jar && $scope.process.workflow.spark.jar.endsWith('.py')){ + $scope.isPython = true; + }else{ + $scope.isPython = false; + } + },true); + $scope.init = function() { - $scope.versions = []; + unwrapClusters(clustersList); + unwrapFeeds(feedsList); + $scope.dateFormat = DateHelper.getLocaleDateFormat(); + }; + + $scope.openDatePicker = function($event, container) { + $event.preventDefault(); + $event.stopPropagation(); + container.opened = true; + }; + + $scope.validateStartEndDate = function () { + delete $scope.invalidEndDate; + if (this.input.start && this.input.end) { + var startDate = new Date(this.input.start), + endDate = new Date(this.input.end); + if (endDate.toString !== 'Invalid Date' && startDate.toString !== 'Invalid Date') { + if (startDate > endDate) { + $scope.invalidEndDate = "ng-dirty ng-invalid"; + } + } + } }; + // TAGS $scope.addTag = function() { $scope.process.tags.push({key: null, value: null}); }; @@ -49,16 +77,101 @@ } }; - $scope.selectWorkflow = function() { - if($scope.process.workflow) { - var engine = $scope.process.workflow.engine; - $scope.process.workflow.version = ""; - $scope.versions = availableVerions[engine]; + // inputs + $scope.addInput = function () { + $scope.process.inputs.push(entityFactory.newInput()); + }; + + $scope.removeInput = function (index) { + if (index >= 0) { + $scope.process.inputs.splice(index, 1); + } + }; + + // OUTPUTS + $scope.addOutput = function () { + $scope.process.outputs.push(entityFactory.newOutput()); + }; + + $scope.removeOutput = function (index) { + if (index >= 0) { + $scope.process.outputs.splice(index, 1); } }; $scope.init(); - $scope.selectWorkflow(); + + $scope.getSourceDefinition = function (clusterName) { + Falcon.getEntityDefinition("cluster", clusterName) + .success(function (data) { + $scope.sourceClusterModel = X2jsService.xml_str2json(data); + var sparkInterface = $scope.sourceClusterModel.cluster.interfaces.interface.filter( + function(clusterInterface) { return clusterInterface._type === 'spark'; } + )[0]; + if (sparkInterface) { + var sparkEndpoint = sparkInterface._endpoint.trim(); + if (sparkEndpoint.indexOf('yarn') != '-1') { + $scope.process.workflow.spark.master = 'yarn'; + $scope.process.workflow.spark.mode = sparkEndpoint.substring(5); + } else if (sparkEndpoint === 'local') { + $scope.process.workflow.spark.master = 'local'; + } + } + }) + .error(function (err) { + Falcon.logResponse('error', err, false, true); + }); + }; + + //-----------PROPERTIES----------------// + $scope.addProperty = function () { + var lastOne = $scope.process.properties.length - 1; + if($scope.process.properties[lastOne].name && $scope.process.properties[lastOne].value) { + $scope.process.properties.push(entityFactory.newProperty("", "")); + } + }; + + $scope.removeProperty = function(index) { + if(index !== null && $scope.process.properties[index]) { + $scope.process.properties.splice(index, 1); + } + }; + + $scope.policyChange = function(){ + if($scope.process.retry.policy === 'final'){ + $scope.process.retry.delay.quantity = '0'; + $scope.process.retry.delay.unit = 'minutes'; + $scope.process.retry.attempts = '0'; + }else{ + $scope.process.retry.delay.quantity = '30'; + $scope.process.retry.delay.unit = 'minutes'; + $scope.process.retry.attempts = '3'; + } + } + + function unwrapClusters(clusters) { + $scope.clusterList = []; + var typeOfData = Object.prototype.toString.call(clusters.entity); + if(typeOfData === "[object Array]") { + $scope.clusterList = clusters.entity; + } else if(typeOfData === "[object Object]") { + $scope.clusterList = [clusters.entity]; + } else { + //console.log("type of data not recognized"); + } + } + + function unwrapFeeds(feeds) { + $scope.feedsList = []; + var typeOfData = Object.prototype.toString.call(feeds.entity); + if (typeOfData === "[object Array]") { + $scope.feedsList = feeds.entity; + } else if (typeOfData === "[object Object]") { + $scope.feedsList = [feeds.entity]; + } else { + //console.log("type of data not recognized"); + } + } }]); http://git-wip-us.apache.org/repos/asf/falcon/blob/76dc2e18/falcon-ui/app/js/controllers/process/process-root-ctrl.js ---------------------------------------------------------------------- diff --git a/falcon-ui/app/js/controllers/process/process-root-ctrl.js b/falcon-ui/app/js/controllers/process/process-root-ctrl.js index 7d461ba..f527383 100644 --- a/falcon-ui/app/js/controllers/process/process-root-ctrl.js +++ b/falcon-ui/app/js/controllers/process/process-root-ctrl.js @@ -28,13 +28,18 @@ var processModule = angular.module('app.controllers.process'); processModule.controller('ProcessRootCtrl', [ - '$scope', '$state', '$interval', '$controller', 'EntityFactory', - 'EntitySerializer', 'X2jsService', 'ValidationService', 'SpinnersFlag', '$rootScope', - function ($scope, $state, $interval, $controller, entityFactory, - serializer, X2jsService, validationService, SpinnersFlag, $rootScope) { + '$scope', '$state', '$interval', '$controller', 'EntityFactory', 'RouteHelper', + 'EntitySerializer', 'X2jsService', 'ValidationService', 'SpinnersFlag', '$rootScope', 'ProcessModel', 'Falcon', + function ($scope, $state, $interval, $controller, entityFactory, RouteHelper, + serializer, X2jsService, validationService, SpinnersFlag, $rootScope, processModel, Falcon) { $scope.entityType = 'process'; + var stateMatrix = { + general : {previous : '', next : 'summary'}, + summary : {previous : 'general', next : ''} + }; + //extending root controller $controller('EntityRootCtrl', { $scope: $scope @@ -44,20 +49,34 @@ $scope.baseInit(); var type = $scope.entityType; $scope[type] = $scope.loadOrCreateEntity(); + if(processModel && processModel.clone === true){ + $scope.cloningMode = true; + $scope.editingMode = false; + $scope[type].name = ""; + }else if(processModel && processModel.edit === true){ + $scope.editingMode = true; + $scope.cloningMode = false; + }else{ + $scope.editingMode = false; + $scope.cloningMode = false; + } }; $scope.isActive = function (route) { - return route === $state.$current.name; + return route === $state.current.name; + }; + + $scope.isCompleted = function (route) { + return $state.get(route).data && $state.get(route).data.completed; }; $scope.loadOrCreateEntity = function() { var type = $scope.entityType; - var model = $scope.models[type + 'Model']; - $scope.models[type + 'Model'] = null; - if(model) { - return serializer.preDeserialize(model, type); + if(!processModel && $scope.$parent.models.processModel){ + processModel = $scope.$parent.models.processModel; } - return entityFactory.newEntity(type); + $scope.$parent.models.processModel = null; + return processModel ? serializer.preDeserialize(processModel, type) : entityFactory.newEntity(type); }; $scope.init(); @@ -82,7 +101,9 @@ } else { try { $scope[type] = serializer.deserialize($scope.prettyXml, type); + $scope.invalidXml = false; } catch (exception) { + $scope.invalidXml = true; console.log('user entered xml incorrect format'); console.log(exception); } @@ -90,7 +111,17 @@ }; - var xmlPreviewWorker = $interval(xmlPreviewCallback, 1000); + $scope.$watch('process', function(){ + if($scope.editXmlDisabled) { + xmlPreviewCallback(); + } + }, true); + $scope.$watch('prettyXml', function(){ + if(!$scope.editXmlDisabled) { + xmlPreviewCallback(); + } + }, true); + $scope.skipUndo = false; $scope.$on('$destroy', function() { @@ -100,16 +131,22 @@ ACLIsEqual = angular.equals($scope.process.ACL, defaultProcess.ACL), workflowIsEqual = angular.equals($scope.process.workflow, defaultProcess.workflow); - $interval.cancel(xmlPreviewWorker); - if (!$scope.skipUndo && (!nameIsEqual || !ACLIsEqual || !workflowIsEqual)) { $scope.$parent.models.processModel = angular.copy(X2jsService.xml_str2json($scope.xml)); + if($scope.cloningMode){ + $scope.$parent.models.processModel.clone = true; + } + if($scope.editingMode){ + $scope.$parent.models.processModel.edit = true; + } $scope.$parent.cancel('process', $rootScope.previousState); } }); //---------------------------------// - $scope.goNext = function (formInvalid, stateName) { + $scope.goNext = function (formInvalid) { + $state.current.data = $state.current.data || {}; + $state.current.data.completed = !formInvalid; SpinnersFlag.show = true; if (!validationService.nameAvailable || formInvalid) { validationService.displayValidations.show = true; @@ -119,20 +156,69 @@ } validationService.displayValidations.show = false; validationService.displayValidations.nameShow = false; - $state.go(stateName); + $state.go(RouteHelper.getNextState($state.current.name, stateMatrix)); }; - $scope.goBack = function (stateName) { + $scope.goBack = function () { SpinnersFlag.backShow = true; validationService.displayValidations.show = false; validationService.displayValidations.nameShow = false; - $state.go(stateName); + $state.go(RouteHelper.getPreviousState($state.current.name, stateMatrix)); }; $scope.goTest = function (formInvalid) { console.log(formInvalid); }; + $scope.toggleclick = function () { + $('.formBoxContainer').toggleClass('col-xs-14 '); + $('.xmlPreviewContainer ').toggleClass('col-xs-10 hide'); + $('.preview').toggleClass('pullOver pullOverXml'); + ($('.preview').hasClass('pullOver')) ? $('.preview').find('button').html('Preview XML') : $('.preview').find('button').html('Hide XML'); + ($($("textarea")[0]).attr("ng-model") == "prettyXml" ) ? $($("textarea")[0]).css("min-height", $(".formBoxContainer").height() - 40 ) : ''; + }; + + $scope.saveEntity = function() { + var type = $scope.entityType; + SpinnersFlag.saveShow = true; + + if($scope.editingMode) { + Falcon.logRequest(); + Falcon.postUpdateEntity('<?xml version="1.0" encoding="UTF-8" standalone="yes"?>' + $scope.xml, $scope.entityType, $scope[type].name) + .success(function (response) { + $scope.skipUndo = true; + Falcon.logResponse('success', response, false); + SpinnersFlag.saveShow = false; + $state.go('main'); + + }) + .error(function (err) { + Falcon.logResponse('error', err, false); + SpinnersFlag.saveShow = false; + angular.element('body, html').animate({scrollTop: 0}, 300); + }); + } + else { + Falcon.logRequest(); + Falcon.postSubmitEntity('<?xml version="1.0" encoding="UTF-8" standalone="yes"?>' + $scope.xml, $scope.entityType) + .success(function (response) { + $scope.skipUndo = true; + Falcon.logResponse('success', response, false); + SpinnersFlag.saveShow = false; + $state.go('main'); + + }) + .error(function (err) { + Falcon.logResponse('error', err, false); + SpinnersFlag.saveShow = false; + angular.element('body, html').animate({scrollTop: 0}, 300); + }); + } + }; + + if($state.current.name !== "forms.process.general"){ + $state.go("forms.process.general"); + } } ]); http://git-wip-us.apache.org/repos/asf/falcon/blob/76dc2e18/falcon-ui/app/js/controllers/process/process-summary-ctrl.js ---------------------------------------------------------------------- diff --git a/falcon-ui/app/js/controllers/process/process-summary-ctrl.js b/falcon-ui/app/js/controllers/process/process-summary-ctrl.js index 494c249..b68b055 100644 --- a/falcon-ui/app/js/controllers/process/process-summary-ctrl.js +++ b/falcon-ui/app/js/controllers/process/process-summary-ctrl.js @@ -49,45 +49,6 @@ return input ? (output || input) : 'Not specified'; }; - $scope.saveEntity = function() { - var type = $scope.entityType; - SpinnersFlag.show = true; - - if(!$scope.$parent.cloningMode) { - Falcon.logRequest(); - Falcon.postUpdateEntity('<?xml version="1.0" encoding="UTF-8" standalone="yes"?>' + $scope.xml, $scope.entityType, $scope[type].name) - .success(function (response) { - $scope.$parent.skipUndo = true; - Falcon.logResponse('success', response, false); - $state.go('main'); - - }) - .error(function (err) { - SpinnersFlag.show = false; - Falcon.logResponse('error', err, false); - angular.element('body, html').animate({scrollTop: 0}, 300); - }); - } - else { - Falcon.logRequest(); - Falcon.postSubmitEntity('<?xml version="1.0" encoding="UTF-8" standalone="yes"?>' + $scope.xml, $scope.entityType) - .success(function (response) { - $scope.$parent.skipUndo = true; - Falcon.logResponse('success', response, false); - $state.go('main'); - - }) - .error(function (err) { - Falcon.logResponse('error', err, false); - SpinnersFlag.show = false; - angular.element('body, html').animate({scrollTop: 0}, 300); - }); - } - - $scope.editingMode = false; - $scope.cloningMode = false; - }; - $scope.init(); }]);
