You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@falcon.apache.org by sr...@apache.org on 2015/04/01 13:10:40 UTC
[13/21] falcon git commit: FALCON-790 Falcon UI to enable
entity/process/feed edits and management. Contributed by Armando
Reyna/Kenneth Ho
http://git-wip-us.apache.org/repos/asf/falcon/blob/c4df0a5e/falcon-ui/app/js/app.js
----------------------------------------------------------------------
diff --git a/falcon-ui/app/js/app.js b/falcon-ui/app/js/app.js
new file mode 100644
index 0000000..1705cb4
--- /dev/null
+++ b/falcon-ui/app/js/app.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';
+
+ var app = angular.module('app', [
+ 'ui.bootstrap', 'ui.router', 'ngCookies', 'ngAnimate', 'ngMessages', 'checklist-model', 'app.controllers', 'app.directives', 'app.services'
+ ]);
+
+ app.config(["$stateProvider", "$urlRouterProvider", "$httpProvider", function ($stateProvider, $urlRouterProvider, $httpProvider) {
+
+ $httpProvider.defaults.headers.common['X-CSRF-Token'] = $('meta[name=csrf-token]').attr('content');
+
+ $httpProvider.defaults.headers.common["X-Requested-By"] = 'X-Requested-By';
+
+ $urlRouterProvider.otherwise("/");
+
+ $stateProvider
+ .state('main', {
+ url: '/',
+ templateUrl: 'html/mainTpl.html',
+ controller: 'DashboardCtrl'
+ })
+ .state('entityDetails', {
+ controller: 'EntityDetailsCtrl',
+ templateUrl: 'html/entityDetailsTpl.html'
+ })
+ .state('forms', {
+ templateUrl: 'html/formsTpl.html'
+ })
+ .state('forms.cluster', {
+ controller: 'ClusterFormCtrl',
+ templateUrl: 'html/cluster/clusterFormTpl.html'
+ })
+ .state('forms.cluster.general', {
+ templateUrl: 'html/cluster/clusterFormGeneralStepTpl.html'
+ })
+ .state('forms.cluster.summary', {
+ templateUrl: 'html/cluster/clusterFormSummaryStepTpl.html'
+ })
+ .state('forms.feed', {
+ templateUrl: 'html/feed/feedFormTpl.html',
+ controller: 'FeedController'
+ })
+ .state('forms.feed.general', {
+ templateUrl: 'html/feed/feedFormGeneralStepTpl.html',
+ controller: 'FeedGeneralInformationController'
+ })
+ .state('forms.feed.properties', {
+ templateUrl: 'html/feed/feedFormPropertiesStepTpl.html',
+ controller: 'FeedPropertiesController'
+ })
+ .state('forms.feed.location', {
+ templateUrl: 'html/feed/feedFormLocationStepTpl.html',
+ controller: 'FeedLocationController'
+ })
+ .state('forms.feed.clusters', {
+ templateUrl: 'html/feed/feedFormClustersStepTpl.html',
+ controller: 'FeedClustersController',
+ resolve: {
+ clustersList: ['Falcon', function(Falcon) {
+ return Falcon.getEntities('cluster').then(
+ function(response) {
+ return response.data;
+ });
+ }]
+ }
+ })
+ .state('forms.feed.summary', {
+ templateUrl: 'html/feed/feedFormSummaryStepTpl.html',
+ controller: 'FeedSummaryController'
+ })
+ .state('forms.process', {
+ templateUrl: 'html/process/processFormTpl.html',
+ controller: 'ProcessRootCtrl'
+ })
+ .state('forms.process.general', {
+ templateUrl: 'html/process/processFormGeneralStepTpl.html',
+ controller: 'ProcessGeneralInformationCtrl'
+ })
+ .state('forms.process.properties', {
+ templateUrl: 'html/process/processFormPropertiesStepTpl.html',
+ controller: 'ProcessPropertiesCtrl'
+ })
+ .state('forms.process.clusters', {
+ templateUrl: 'html/process/processFormClustersStepTpl.html',
+ controller: 'ProcessClustersCtrl',
+ resolve: {
+ clustersList: ['Falcon', function(Falcon) {
+ return Falcon.getEntities('cluster').then(
+ function(response) {
+ return response.data;
+ });
+ }]
+ }
+ })
+ .state('forms.process.io', {
+ templateUrl: 'html/process/processFormInputsAndOutputsStepTpl.html',
+ controller: 'ProcessInputsAndOutputsCtrl',
+ resolve: {
+ feedsList: ['Falcon', function(Falcon) {
+ return Falcon.getEntities('feed').then(
+ function(response) {
+ return response.data;
+ });
+ }]
+ }
+ })
+ .state('forms.process.summary', {
+ templateUrl: 'html/process/processFormSummaryStepTpl.html',
+ controller: 'ProcessSummaryCtrl'
+ });
+
+ }]);
+
+ app.run(['$rootScope',
+ function ($rootScope) {
+
+ $rootScope.$on('$stateChangeError',
+ function(event, toState, toParams, fromState, fromParams, error){
+ console.log('Manual log of stateChangeError: ' + error);
+ });
+
+ }]);
+
+})();
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/falcon/blob/c4df0a5e/falcon-ui/app/js/controllers/cluster/cluster-module.js
----------------------------------------------------------------------
diff --git a/falcon-ui/app/js/controllers/cluster/cluster-module.js b/falcon-ui/app/js/controllers/cluster/cluster-module.js
new file mode 100644
index 0000000..d00a937
--- /dev/null
+++ b/falcon-ui/app/js/controllers/cluster/cluster-module.js
@@ -0,0 +1,306 @@
+/**
+ * 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.FeedController
+ * @requires EntityModel the entity model to copy the feed entity from
+ * @requires Falcon the falcon service to talk with the Falcon REST API
+ */
+ var clusterModule = angular.module('app.controllers.cluster', [ 'app.services' ]);
+
+ clusterModule.controller('ClusterFormCtrl', [
+ "$scope", "$interval", "Falcon", "EntityModel", "$state", "X2jsService", "ValidationService",
+ function ($scope, $interval, Falcon, EntityModel, $state, X2jsService, validationService) {
+
+ $scope.clusterEntity = EntityModel;
+ $scope.xmlPreview = { edit: false };
+ $scope.secondStep = false;
+
+ function normalizeModel() {
+ //------------INTERFACE-----------//
+ var requiredInterfaceFields = ["readonly", "write", "execute", "workflow", "messaging", "registry"],
+ requiredLocationFields = ["staging", "temp", "working", ""],
+ modelInterfaceArray = $scope.clusterEntity.clusterModel.cluster.interfaces.interface,
+ modelLocationsArray = $scope.clusterEntity.clusterModel.cluster.locations.location;
+
+ modelInterfaceArray.forEach(function (element) {
+ requiredInterfaceFields.forEach(function (requiredField) {
+ if (element._type === requiredField) { requiredInterfaceFields.splice(requiredField, 1); }
+ });
+ });
+ $scope.registry = { check: true };
+ requiredInterfaceFields.forEach(function (fieldToPush) {
+ var fieldObject = { _type: fieldToPush, _endpoint: "", _version: "" };
+ if (fieldToPush === "registry") { $scope.registry = { check: false }; }
+ modelInterfaceArray.push(fieldObject);
+ });
+ //--------------TAGS--------------//
+ if ($scope.clusterEntity.clusterModel.cluster.tags === "" ||
+ $scope.clusterEntity.clusterModel.cluster.tags === undefined) {
+ $scope.clusterEntity.clusterModel.cluster.tags = "";
+ $scope.tagsArray = [{key: null, value: null}];
+ } else {
+ $scope.splitTags();
+ }
+ //-------------ACL----------------//
+ if (!$scope.clusterEntity.clusterModel.cluster.ACL) {
+ $scope.clusterEntity.clusterModel.cluster.ACL = {
+ _owner: "", _group: "", _permission: ""
+ };
+ }
+ //------------Location------------//
+ modelLocationsArray.forEach(function(element) {
+ requiredLocationFields.forEach(function(requiredField) {
+ if(element._name === requiredField) { requiredLocationFields.splice(requiredField, 1); }
+ });
+ });
+ requiredLocationFields.forEach(function(fieldToPush) {
+ var fieldObject = {_name: fieldToPush, _path: ""};
+ modelLocationsArray.push(fieldObject);
+ });
+ //----------Properties -------------//
+ if(!$scope.clusterEntity.clusterModel.cluster.properties) {
+ $scope.clusterEntity.clusterModel.cluster.properties = { property : [{ _name: "", _value: ""}] };
+ }
+
+ }
+
+ function cleanModel() {
+ //if registry check is false backups the object and removes it from array
+ if (!$scope.registry.check) {
+ $scope.clusterEntity.clusterModel.cluster.interfaces.interface.forEach(function(registry, index) {
+ if (registry._type === "registry") {
+ $scope.backupRegistryObject = $scope.clusterEntity.clusterModel.cluster.interfaces.interface[index];
+ $scope.clusterEntity.clusterModel.cluster.interfaces.interface.splice(index, 1);
+ }
+ });
+ }
+ //deletes property empty last object and array if empty
+ var lastOne = $scope.clusterEntity.clusterModel.cluster.properties.property.length - 1;
+ if (
+ $scope.clusterEntity.clusterModel.cluster.properties.property[lastOne]._name === "" ||
+ $scope.clusterEntity.clusterModel.cluster.properties.property[lastOne]._name === undefined ||
+ $scope.clusterEntity.clusterModel.cluster.properties.property[lastOne]._value === "" ||
+ $scope.clusterEntity.clusterModel.cluster.properties.property[lastOne]._value === undefined
+ ) {
+
+ $scope.removeProperty(lastOne);
+ }
+ if ($scope.clusterEntity.clusterModel.cluster.properties.property.length === 0) {
+ delete $scope.clusterEntity.clusterModel.cluster.properties;
+ }
+ var lastLocationIndex = $scope.clusterEntity.clusterModel.cluster.locations.location.length - 1;
+ if (
+ $scope.clusterEntity.clusterModel.cluster.locations.location[lastLocationIndex]._name === "" ||
+ $scope.clusterEntity.clusterModel.cluster.locations.location[lastLocationIndex]._name === undefined ||
+ $scope.clusterEntity.clusterModel.cluster.locations.location[lastLocationIndex]._path === "" ||
+ $scope.clusterEntity.clusterModel.cluster.locations.location[lastLocationIndex]._path === undefined
+ ) {
+ $scope.removeLocation(lastLocationIndex);
+ }
+ //deletes ACL if empty
+ if ($scope.clusterEntity.clusterModel.cluster.ACL &&
+ $scope.clusterEntity.clusterModel.cluster.ACL._owner === "") {
+ delete $scope.clusterEntity.clusterModel.cluster.ACL;
+ }
+ //deletes tags if empty
+ if ($scope.clusterEntity.clusterModel.cluster.tags.length === 0) {
+ delete $scope.clusterEntity.clusterModel.cluster.tags;
+ }
+ //moves properties to be the last element if acl exists
+ $scope.arrangeFieldsOrder();
+ }
+ $scope.arrangeFieldsOrder = function () {
+ var BK = $scope.clusterEntity.clusterModel.cluster,
+ orderedObj = {};
+
+ orderedObj._xmlns = 'uri:falcon:cluster:0.1';
+ orderedObj._name = BK._name;
+ orderedObj._description = BK._description;
+ orderedObj._colo = BK._colo;
+
+ if (BK.tags) { orderedObj.tags = BK.tags; }
+ if (BK.interfaces) { orderedObj.interfaces = BK.interfaces; }
+ if (BK.locations) { orderedObj.locations = BK.locations; }
+ if (BK.ACL) { orderedObj.ACL = BK.ACL; }
+ if (BK.properties) { orderedObj.properties = BK.properties; }
+
+ delete $scope.clusterEntity.clusterModel.cluster;
+ $scope.clusterEntity.clusterModel.cluster = orderedObj;
+
+ };
+ //--------------TAGS------------------------//
+
+ $scope.convertTags = function () {
+ var result = [];
+ $scope.tagsArray.forEach(function(element) {
+ if(element.key && element.value) {
+ result.push(element.key + "=" + element.value);
+ }
+ });
+ result = result.join(",");
+ $scope.clusterEntity.clusterModel.cluster.tags = result;
+ };
+ $scope.splitTags = function () {
+ $scope.tagsArray = [];
+ $scope.clusterEntity.clusterModel.cluster.tags.split(",").forEach(function (fieldToSplit) {
+ var splittedString = fieldToSplit.split("=");
+ $scope.tagsArray.push({key: splittedString[0], value: splittedString[1]});
+ });
+ };
+ $scope.addTag = function () {
+ $scope.tagsArray.push({key: null, value: null});
+ };
+ $scope.removeTag = function (index) {
+ if (!isNaN(index) && index !== undefined && index !== null) {
+ $scope.tagsArray.splice(index, 1);
+ $scope.convertTags();
+ }
+ };
+ //-------------------------------------//
+ //----------LOCATION-------------------//
+
+ $scope.addLocation = function () {
+ var lastOneIndex = $scope.clusterEntity.clusterModel.cluster.locations.location.length - 1;
+
+ if (!$scope.clusterEntity.clusterModel.cluster.locations.location[lastOneIndex]._name ||
+ !$scope.clusterEntity.clusterModel.cluster.locations.location[lastOneIndex]._path) {
+ //console.log('location empty');
+ } else {
+ $scope.clusterEntity.clusterModel.cluster.locations.location.push({_name: "", _path: ""});
+ }
+ };
+ $scope.removeLocation = function (index) {
+ if(!isNaN(index) && index !== undefined && index !== null) {
+ $scope.clusterEntity.clusterModel.cluster.locations.location.splice(index, 1);
+ }
+ };
+ //-----------PROPERTIES----------------//
+ $scope.addProperty = function () {
+ var lastOne = $scope.clusterEntity.clusterModel.cluster.properties.property.length - 1;
+ if($scope.clusterEntity.clusterModel.cluster.properties.property[lastOne]._name && $scope.clusterEntity.clusterModel.cluster.properties.property[lastOne]._value){
+ $scope.clusterEntity.clusterModel.cluster.properties.property.push({ _name: "", _value: ""});
+ // $scope.tempPropModel = { _name: "", _value: ""};
+ }
+ };
+ $scope.removeProperty = function(index) {
+ if(index !== null && $scope.clusterEntity.clusterModel.cluster.properties.property[index]) {
+ $scope.clusterEntity.clusterModel.cluster.properties.property.splice(index, 1);
+ }
+ };
+ //--------------------------------------//
+ $scope.goSummaryStep = function (formInvalid) {
+ if (!$scope.validations.nameAvailable || formInvalid) {
+ validationService.displayValidations.show = true;
+ validationService.displayValidations.nameShow = true;
+ return;
+ }
+ cleanModel();
+ $scope.secondStep = true;
+ $state.go("forms.cluster.summary");
+
+ };
+ $scope.goGeneralStep = function () {
+ $scope.secondStep = false;
+ validationService.displayValidations.show = false;
+ validationService.displayValidations.nameShow = false;
+ $scope.validations.nameAvailable = true;
+ if(!$scope.registry.check) {
+ //recovers previously deleted registry object
+ $scope.clusterEntity.clusterModel.cluster.interfaces.interface.push($scope.backupRegistryObject);
+ }
+ if(!$scope.clusterEntity.clusterModel.cluster.tags) {
+ $scope.clusterEntity.clusterModel.cluster.tags = "";
+ }
+ if(!$scope.clusterEntity.clusterModel.cluster.properties) {
+ $scope.clusterEntity.clusterModel.cluster.properties = {property : [{ _name: "", _value: ""}]};
+ }
+ var lastLocationIndex = $scope.clusterEntity.clusterModel.cluster.locations.location.length - 1;
+ if($scope.clusterEntity.clusterModel.cluster.locations.location[lastLocationIndex]._name !== "") {
+ $scope.addLocation();
+ }
+ };
+ $scope.saveCluster = function () {
+ $scope.saveModelBuffer();
+ Falcon.logRequest();
+ Falcon.postSubmitEntity($scope.jsonString, "cluster").success(function (response) {
+ Falcon.logResponse('success', response, false);
+ $state.go('main');
+ }).error(function (err) {
+ Falcon.logResponse('error', err, false);
+ });
+ };
+
+ //--------------------------------------//
+ //----------XML preview-----------------//
+
+ $scope.xmlPreview.editXML = function () {
+ $scope.xmlPreview.edit = !$scope.xmlPreview.edit;
+ };
+ $scope.showInPreview = function() {
+ var xmlStr = X2jsService.json2xml_str(angular.copy($scope.clusterEntity.clusterModel));
+ $scope.prettyXml = X2jsService.prettifyXml(xmlStr);
+ $scope.xml = xmlStr;
+ };
+ $scope.transformBack = function() {
+ try {
+ var xmlObj = X2jsService.xml_str2json($scope.prettyXml);
+ $scope.clusterEntity.clusterModel = xmlObj;
+
+ if($scope.clusterEntity.clusterModel.cluster.properties && $scope.clusterEntity.clusterModel.cluster.properties.property[0] === '') {
+ $scope.clusterEntity.clusterModel.cluster.properties.property=[];
+ }
+ }
+ catch(err) {
+ console.log('xml malformed');
+ }
+ };
+ $scope.saveModelBuffer = function () {
+ $scope.jsonString = angular.toJson($scope.clusterEntity.clusterModel);
+ //goes back to js to have x2js parse it correctly
+ $scope.jsonString = JSON.parse($scope.jsonString);
+ $scope.jsonString = X2jsService.json2xml_str($scope.jsonString);
+ };
+ function xmlPreviewCallback() {
+ if ($state.current.name !== 'forms.cluster.general' && $state.current.name !== 'forms.cluster.summary') {
+ $interval.cancel(refresher);
+ }
+ if(!$scope.xmlPreview.edit) {
+ if($scope.clusterEntity.clusterModel.cluster.tags !== undefined) { $scope.convertTags(); }
+ $scope.showInPreview();
+ }
+ else {
+ $scope.splitTags();
+ $scope.transformBack();
+ }
+ }
+ var refresher = $interval(xmlPreviewCallback, 1000);
+
+
+ //------------init------------//
+ normalizeModel();
+ }
+ ]);
+})();
+
+
+
+
http://git-wip-us.apache.org/repos/asf/falcon/blob/c4df0a5e/falcon-ui/app/js/controllers/controllers.js
----------------------------------------------------------------------
diff --git a/falcon-ui/app/js/controllers/controllers.js b/falcon-ui/app/js/controllers/controllers.js
new file mode 100644
index 0000000..9fa878e
--- /dev/null
+++ b/falcon-ui/app/js/controllers/controllers.js
@@ -0,0 +1,32 @@
+/*
+ * 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';
+
+ angular.module('app.controllers', [
+ 'app.controllers.navHeader',
+ 'app.controllers.rootCtrl',
+ 'app.controllers.dashboardCtrl',
+ 'app.controllers.view',
+ 'app.controllers.cluster',
+ 'app.controllers.feed',
+ 'app.controllers.process',
+ 'app.controllers.entity'
+ ]);
+
+})();
http://git-wip-us.apache.org/repos/asf/falcon/blob/c4df0a5e/falcon-ui/app/js/controllers/dashboard-controller.js
----------------------------------------------------------------------
diff --git a/falcon-ui/app/js/controllers/dashboard-controller.js b/falcon-ui/app/js/controllers/dashboard-controller.js
new file mode 100644
index 0000000..bd60736
--- /dev/null
+++ b/falcon-ui/app/js/controllers/dashboard-controller.js
@@ -0,0 +1,143 @@
+/**
+ * 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';
+
+ var dashboardCtrlModule = angular.module('app.controllers.dashboardCtrl', ['app.services']);
+
+ dashboardCtrlModule.controller('DashboardCtrl', [ "$scope", "Falcon", "EntityModel", "FileApi", "$state", "X2jsService",
+ function ($scope, Falcon, EntityModel, FileApi, $state, X2jsService) {
+
+ $scope.$parent.refreshLists();
+
+ $scope.deleteEntity = function (type, name) {
+ type = type.toLowerCase(); //new sandbox returns uppercase type
+ Falcon.logRequest();
+ Falcon.deleteEntity(type, name)
+ .success(function (data) {
+ Falcon.logResponse('success', data, type);
+ $scope.$parent.refreshList(type);
+ })
+ .error(function (err) {
+
+ Falcon.logResponse('error', err, type);
+ });
+ };
+ $scope.cloneEntity = function (type, name) {
+ type = type.toLowerCase(); //new sandbox returns uppercase type
+
+ Falcon.logRequest();
+ Falcon.getEntityDefinition(type, name)
+ .success(function (data) {
+ Falcon.logResponse('success', data, false, true);
+ var modelName = type + "Model",
+ entityModel = X2jsService.xml_str2json(data);
+
+ EntityModel[modelName] = entityModel;
+ EntityModel[modelName][type]._name = "";
+ $scope.models[modelName] = angular.copy(entityModel);
+ $scope.cloningMode = true; // dont know utility of this
+ $scope.$parent.cloningMode = true;
+ $state.go('forms.' + type + ".general");
+ })
+ .error(function (err) {
+ Falcon.logResponse('error', err, false, true);
+ });
+ };
+ $scope.editEntity = function (type, name) {
+ type = type.toLowerCase(); //new sandbox returns uppercase type
+
+ Falcon.logRequest();
+ Falcon.getEntityDefinition(type, name)
+ .success(function (data) {
+ Falcon.logResponse('success', data, false, true);
+ var entityModel = X2jsService.xml_str2json(data);
+ var modelName = type + "Model";
+ EntityModel[modelName] = entityModel;
+ $scope.models[modelName] = angular.copy(entityModel);
+ $scope.editingMode = true;// dont know utility of this
+ $scope.$parent.cloningMode = false;
+ $state.go('forms.' + type + ".general");
+ })
+ .error(function (err) {
+ Falcon.logResponse('error', err, false, true);
+ });
+ };
+ //-----------------------------------------//
+ $scope.entityDetails = function (name, type) {
+ type = type.toLowerCase(); //new sandbox returns uppercase type
+
+ Falcon.logRequest();
+ Falcon.getEntityDefinition(type, name)
+ .success(function (data) {
+ Falcon.logResponse('success', data, false, true);
+ var entityModel = X2jsService.xml_str2json(data);
+ var modelName = type + "Model";
+ EntityModel[modelName] = entityModel;
+ $scope.models[modelName] = angular.copy(entityModel);
+ $scope.editingMode = true;// dont know utility of this
+ $scope.$parent.cloningMode = false;
+ //$state.go('forms.' + type + ".general");
+ $state.go('entityDetails');
+ })
+ .error(function (err) {
+ Falcon.logResponse('error', err, false, true);
+ });
+ };
+ //----------------------------------------//
+ $scope.resumeEntity = function (type, name) {
+ Falcon.logRequest();
+ Falcon.postResumeEntity(type, name).success(function (data) {
+ Falcon.logResponse('success', data, type);
+ $scope.$parent.refreshList(type);
+ })
+ .error(function (err) {
+ Falcon.logResponse('error', err, type);
+ });
+ };
+ $scope.scheduleEntity = function (type, name) {
+ Falcon.logRequest();
+ Falcon.postScheduleEntity(type, name).success(function (data) {
+ Falcon.logResponse('success', data, type);
+ $scope.$parent.refreshList(type);
+ })
+ .error(function (err) {
+ Falcon.logResponse('error', err, type);
+ });
+ };
+
+ $scope.suspendEntity = function (type, name) {
+ Falcon.logRequest();
+ Falcon.postSuspendEntity(type, name)
+ .success(function (message) {
+ Falcon.logResponse('success', message, type);
+ $scope.$parent.refreshList(type);
+ })
+ .error(function (err) {
+ Falcon.logResponse('error', err, type);
+
+ });
+ };
+ $scope.relationsEntity = function (type, name) {
+ console.log("relations " + type + " - " + name);
+ };
+
+
+ }]);
+
+})();
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/falcon/blob/c4df0a5e/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
new file mode 100644
index 0000000..cb36b45
--- /dev/null
+++ b/falcon-ui/app/js/controllers/entity/entity-module.js
@@ -0,0 +1,48 @@
+/**
+ * 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';
+
+ var entityModule = angular.module('app.controllers.entity',[ 'app.services' ]);
+
+ entityModule.controller('EntityRootCtrl',
+ [ '$scope',
+ function($scope) {
+
+ $scope.baseInit = function() {
+ $scope.editXmlDisabled = true;
+ };
+
+ $scope.toggleEditXml = function() {
+ $scope.editXmlDisabled = !$scope.editXmlDisabled;
+ };
+
+ $scope.capitalize = function(input) {
+ return input.charAt(0).toUpperCase() + input.slice(1);
+ };
+
+ $scope.cancel = function() {
+ var type = $scope.entityType;
+ $scope[type] = null;
+ };
+
+ }
+ ]
+ );
+
+})();
http://git-wip-us.apache.org/repos/asf/falcon/blob/c4df0a5e/falcon-ui/app/js/controllers/entity/entity-view.js
----------------------------------------------------------------------
diff --git a/falcon-ui/app/js/controllers/entity/entity-view.js b/falcon-ui/app/js/controllers/entity/entity-view.js
new file mode 100644
index 0000000..d58f7f6
--- /dev/null
+++ b/falcon-ui/app/js/controllers/entity/entity-view.js
@@ -0,0 +1,221 @@
+/**
+ * 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.FeedController
+ * @requires EntityModel the entity model to copy the feed entity from
+ * @requires Falcon the falcon service to talk with the Falcon REST API
+ */
+ var clusterModule = angular.module('app.controllers.view', [ 'app.services' ]);
+
+ clusterModule.controller('EntityDetailsCtrl', [
+ "$scope", "$interval", "Falcon", "EntityModel", "$state", "X2jsService",
+ function ($scope, $interval, Falcon, EntityModel, $state, X2jsService) {
+
+ $scope.clusterEntity = EntityModel;
+ $scope.xmlPreview = { edit: false };
+ $scope.secondStep = false;
+
+ function normalizeModel() {
+ //------------INTERFACE-----------//
+ var requiredInterfaceFields = ["readonly", "write", "execute", "workflow", "messaging", "registry"],
+ requiredLocationFields = ["staging", "temp", "working", ""],
+ modelInterfaceArray = $scope.clusterEntity.clusterModel.cluster.interfaces.interface,
+ modelLocationsArray = $scope.clusterEntity.clusterModel.cluster.locations.location;
+
+ modelInterfaceArray.forEach(function (element) {
+ requiredInterfaceFields.forEach(function (requiredField) {
+ if (element._type === requiredField) { requiredInterfaceFields.splice(requiredField, 1); }
+ });
+ });
+ $scope.registry = { check: true };
+ requiredInterfaceFields.forEach(function (fieldToPush) {
+ var fieldObject = { _type: fieldToPush, _endpoint: "", _version: "" };
+ if (fieldToPush === "registry") { $scope.registry = { check: false }; }
+ modelInterfaceArray.push(fieldObject);
+ });
+ //--------------TAGS--------------//
+ if ($scope.clusterEntity.clusterModel.cluster.tags === "" ||
+ $scope.clusterEntity.clusterModel.cluster.tags === undefined) {
+ $scope.clusterEntity.clusterModel.cluster.tags = "";
+ $scope.tagsArray = [{key: null, value: null}];
+ } else {
+ $scope.splitTags();
+ }
+ //-------------ACL----------------//
+ if (!$scope.clusterEntity.clusterModel.cluster.ACL) {
+ $scope.clusterEntity.clusterModel.cluster.ACL = {
+ _owner: "", _group: "", _permission: ""
+ };
+ }
+ //------------Location------------//
+ modelLocationsArray.forEach(function(element) {
+ requiredLocationFields.forEach(function(requiredField) {
+ if(element._name === requiredField) { requiredLocationFields.splice(requiredField, 1); }
+ });
+ });
+ requiredLocationFields.forEach(function(fieldToPush) {
+ var fieldObject = {_name: fieldToPush, _path: ""};
+ modelLocationsArray.push(fieldObject);
+ });
+ //----------Properties -------------//
+ if(!$scope.clusterEntity.clusterModel.cluster.properties) {
+ $scope.clusterEntity.clusterModel.cluster.properties = { property : [{ _name: "", _value: ""}] };
+ }
+
+ }
+
+ $scope.arrangeFieldsOrder = function () {
+ var BK = $scope.clusterEntity.clusterModel.cluster,
+ orderedObj = {};
+
+ orderedObj._xmlns = 'uri:falcon:cluster:0.1';
+ orderedObj._name = BK._name;
+ orderedObj._description = BK._description;
+ orderedObj._colo = BK._colo;
+
+ if (BK.tags) { orderedObj.tags = BK.tags; }
+ if (BK.interfaces) { orderedObj.interfaces = BK.interfaces; }
+ if (BK.locations) { orderedObj.locations = BK.locations; }
+ if (BK.ACL) { orderedObj.ACL = BK.ACL; }
+ if (BK.properties) { orderedObj.properties = BK.properties; }
+
+ delete $scope.clusterEntity.clusterModel.cluster;
+ $scope.clusterEntity.clusterModel.cluster = orderedObj;
+
+ };
+ //--------------TAGS------------------------//
+
+ $scope.convertTags = function () {
+ var result = [];
+ $scope.tagsArray.forEach(function(element) {
+ if(element.key && element.value) {
+ result.push(element.key + "=" + element.value);
+ }
+ });
+ result = result.join(",");
+ $scope.clusterEntity.clusterModel.cluster.tags = result;
+ };
+ $scope.splitTags = function () {
+ $scope.tagsArray = [];
+ $scope.clusterEntity.clusterModel.cluster.tags.split(",").forEach(function (fieldToSplit) {
+ var splittedString = fieldToSplit.split("=");
+ $scope.tagsArray.push({key: splittedString[0], value: splittedString[1]});
+ });
+ };
+ $scope.addTag = function () {
+ $scope.tagsArray.push({key: null, value: null});
+ };
+ $scope.removeTag = function (index) {
+ if (!isNaN(index) && index !== undefined && index !== null) {
+ $scope.tagsArray.splice(index, 1);
+ $scope.convertTags();
+ }
+ };
+ //-------------------------------------//
+ //----------LOCATION-------------------//
+
+ $scope.addLocation = function () {
+ var lastOneIndex = $scope.clusterEntity.clusterModel.cluster.locations.location.length - 1;
+
+ if (!$scope.clusterEntity.clusterModel.cluster.locations.location[lastOneIndex]._name ||
+ !$scope.clusterEntity.clusterModel.cluster.locations.location[lastOneIndex]._path) {
+ //console.log('location empty');
+ } else {
+ $scope.clusterEntity.clusterModel.cluster.locations.location.push({_name: "", _path: ""});
+ }
+ };
+ $scope.removeLocation = function (index) {
+ if(!isNaN(index) && index !== undefined && index !== null) {
+ $scope.clusterEntity.clusterModel.cluster.locations.location.splice(index, 1);
+ }
+ };
+ //-----------PROPERTIES----------------//
+ $scope.addProperty = function () {
+ var lastOne = $scope.clusterEntity.clusterModel.cluster.properties.property.length - 1;
+ if($scope.clusterEntity.clusterModel.cluster.properties.property[lastOne]._name && $scope.clusterEntity.clusterModel.cluster.properties.property[lastOne]._value){
+ $scope.clusterEntity.clusterModel.cluster.properties.property.push({ _name: "", _value: ""});
+ // $scope.tempPropModel = { _name: "", _value: ""};
+ }
+ };
+ $scope.removeProperty = function(index) {
+ if(index !== null && $scope.clusterEntity.clusterModel.cluster.properties.property[index]) {
+ $scope.clusterEntity.clusterModel.cluster.properties.property.splice(index, 1);
+ }
+ };
+
+ //--------------------------------------//
+ //----------XML preview-----------------//
+
+ $scope.xmlPreview.editXML = function () {
+ $scope.xmlPreview.edit = !$scope.xmlPreview.edit;
+ };
+ $scope.showInPreview = function() {
+ var xmlStr = X2jsService.json2xml_str(angular.copy($scope.clusterEntity.clusterModel));
+ $scope.prettyXml = X2jsService.prettifyXml(xmlStr);
+ $scope.xml = xmlStr;
+ };
+ $scope.transformBack = function() {
+ try {
+ var xmlObj = X2jsService.xml_str2json($scope.prettyXml);
+ $scope.clusterEntity.clusterModel = xmlObj;
+
+ if($scope.clusterEntity.clusterModel.cluster.properties && $scope.clusterEntity.clusterModel.cluster.properties.property[0] === '') {
+ $scope.clusterEntity.clusterModel.cluster.properties.property=[];
+ }
+ }
+ catch(err) {
+ console.log('xml malformed');
+ }
+ };
+ $scope.saveModelBuffer = function () {
+ $scope.jsonString = angular.toJson($scope.clusterEntity.clusterModel);
+ //goes back to js to have x2js parse it correctly
+ $scope.jsonString = JSON.parse($scope.jsonString);
+ $scope.jsonString = X2jsService.json2xml_str($scope.jsonString);
+ };
+ function xmlPreviewCallback() {
+ if ($state.current.name !== 'forms.cluster.general' && $state.current.name !== 'forms.cluster.summary') {
+ $interval.cancel(refresher);
+ }
+ if(!$scope.xmlPreview.edit) {
+ if($scope.clusterEntity.clusterModel.cluster.tags !== undefined) { $scope.convertTags(); }
+ $scope.showInPreview();
+ }
+ else {
+ $scope.splitTags();
+ $scope.transformBack();
+ }
+ }
+ var refresher = $interval(xmlPreviewCallback, 1000);
+
+ //xmlPreviewCallback();
+
+
+ //------------init------------//
+ normalizeModel();
+ }
+ ]);
+})();
+
+
+
+
http://git-wip-us.apache.org/repos/asf/falcon/blob/c4df0a5e/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
new file mode 100644
index 0000000..55a5651
--- /dev/null
+++ b/falcon-ui/app/js/controllers/feed/feed-clusters-controller.js
@@ -0,0 +1,117 @@
+/**
+ * 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.FeedController
+ * @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('FeedClustersController', ["$scope","clustersList", "EntityFactory",
+
+ function($scope, clustersList, entityFactory) {
+
+ unwrapClusters(clustersList);
+
+ $scope.updateRetention = function() {
+ if($scope.selectedCluster.retention.action === 'archive' && $scope.selectedCluster.type === 'source') {
+ $scope.allClusters.length = 0;
+ $scope.allClusters.concat($scope.feed.clusters);
+
+ $scope.feed.clusters.length = 0;
+ $scope.feed.clusters.push($scope.sourceCluster);
+ $scope.feed.clusters.push($scope.archiveCluster);
+
+ $scope.sourceCluster.selected = false;
+ $scope.archiveCluster.selected = true;
+ $scope.archiveCluster.active = true;
+ $scope.selectedCluster = $scope.archiveCluster;
+ }
+
+ if($scope.selectedCluster.retention.action !== 'archive'&& $scope.selectedCluster.type === 'source' && $scope.archiveCluster.active) {
+ $scope.archiveCluster.selected = false;
+ $scope.feed.clusters.length = 0;
+ $scope.allClusters.length = 0;
+ $scope.feed.clusters.push($scope.sourceCluster);
+ $scope.sourceCluster.selected = true;
+ $scope.archiveCluster.active = false;
+ }
+ };
+
+ $scope.addCluster = function() {
+ $scope.selectedCluster.selected = false;
+ var cluster = $scope.newCluster(true);
+ $scope.feed.clusters.push(cluster);
+ $scope.selectedCluster = cluster;
+ };
+
+ $scope.newCluster = function(selected) {
+ return entityFactory.newCluster('target', selected);
+ };
+
+ $scope.handleCluster = function(cluster, index) {
+ if(cluster.selected) {
+ $scope.removeCluster(index);
+ } else {
+ $scope.selectCluster(cluster);
+ }
+ };
+
+ $scope.selectCluster = function (cluster) {
+ $scope.selectedCluster.selected = false;
+ cluster.selected = true;
+ $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 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");
+ }
+ }
+
+
+ $scope.selectedCluster = $scope.selectedCluster || $scope.feed.clusters[0];
+ $scope.sourceCluster = $scope.sourceCluster || $scope.feed.clusters[0];
+ $scope.archiveCluster = $scope.newCluster(false);
+ $scope.archiveCluster.active = false;
+ $scope.allClusters = [];
+
+
+ }]);
+
+})();
http://git-wip-us.apache.org/repos/asf/falcon/blob/c4df0a5e/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
new file mode 100644
index 0000000..40dbdbc
--- /dev/null
+++ b/falcon-ui/app/js/controllers/feed/feed-general-information-controller.js
@@ -0,0 +1,48 @@
+/**
+ * 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.FeedController
+ * @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('FeedGeneralInformationController', [ "$scope", function ($scope) {
+
+ $scope.nameValid = false;
+
+ $scope.addTag = function () {
+ $scope.feed.tags.push({key: null, value: null});
+ };
+
+ $scope.removeTag = function (index) {
+ if (index >= 0 && $scope.feed.tags.length > 1) {
+ $scope.feed.tags.splice(index, 1);
+ }
+ };
+
+ }]);
+
+
+}());
http://git-wip-us.apache.org/repos/asf/falcon/blob/c4df0a5e/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
new file mode 100644
index 0000000..bbb488b
--- /dev/null
+++ b/falcon-ui/app/js/controllers/feed/feed-location-controller.js
@@ -0,0 +1,44 @@
+/**
+ * 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.FeedController
+ * @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('FeedLocationController', [ "$scope",function($scope) {
+
+ $scope.toggleStorage = function() {
+ toggle($scope.feed.storage.fileSystem);
+ toggle($scope.feed.storage.catalog);
+ };
+
+ function toggle(storage) {
+ storage.active = !storage.active;
+ }
+
+ }]);
+
+
+})();
http://git-wip-us.apache.org/repos/asf/falcon/blob/c4df0a5e/falcon-ui/app/js/controllers/feed/feed-module.js
----------------------------------------------------------------------
diff --git a/falcon-ui/app/js/controllers/feed/feed-module.js b/falcon-ui/app/js/controllers/feed/feed-module.js
new file mode 100644
index 0000000..4ad3308
--- /dev/null
+++ b/falcon-ui/app/js/controllers/feed/feed-module.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.FeedController
+ * @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
+ */
+ angular.module('app.controllers.feed',
+ [
+ 'app.controllers.entity',
+ 'app.services'
+ ]);
+
+})();
http://git-wip-us.apache.org/repos/asf/falcon/blob/c4df0a5e/falcon-ui/app/js/controllers/feed/feed-properties-controller.js
----------------------------------------------------------------------
diff --git a/falcon-ui/app/js/controllers/feed/feed-properties-controller.js b/falcon-ui/app/js/controllers/feed/feed-properties-controller.js
new file mode 100644
index 0000000..0f10ac9
--- /dev/null
+++ b/falcon-ui/app/js/controllers/feed/feed-properties-controller.js
@@ -0,0 +1,42 @@
+/**
+ * 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.FeedController
+ * @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('FeedPropertiesController', [ "$scope",function($scope) {
+ $scope.addCustomProperty = function () {
+ $scope.feed.customProperties.push({key: null, value: null});
+ };
+
+ $scope.removeCustomProperty = function (index) {
+ if(index >= 0 && $scope.feed.customProperties.length > 1) {
+ $scope.feed.customProperties.splice(index, 1);
+ }
+ };
+ }]);
+
+})();
http://git-wip-us.apache.org/repos/asf/falcon/blob/c4df0a5e/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
new file mode 100644
index 0000000..27dad77
--- /dev/null
+++ b/falcon-ui/app/js/controllers/feed/feed-root-ctrl.js
@@ -0,0 +1,178 @@
+/**
+ * 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.FeedController
+ * @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('FeedController',
+ [ '$scope', '$state', '$timeout',
+ 'Falcon', 'X2jsService',
+ 'JsonTransformerFactory', 'EntityFactory',
+ 'EntitySerializer', '$interval',
+ '$controller', "ValidationService",
+ function($scope, $state, $timeout, Falcon,
+ X2jsService, transformerFactory, entityFactory,
+ serializer, $interval, $controller, validationService) {
+
+ $scope.entityType = 'feed';
+
+ //extending root controller
+ $controller('EntityRootCtrl', {
+ $scope: $scope
+ });
+
+ $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);
+ };
+
+ $scope.init = function() {
+ $scope.baseInit();
+ var type = $scope.entityType;
+ $scope[type] = $scope.loadOrCreateEntity();
+ $scope.dateFormat ='dd-MMMM-yyyy';
+ };
+
+ $scope.openDatePicker = function($event, container) {
+ $event.preventDefault();
+ $event.stopPropagation();
+ container.opened = true;
+ };
+
+ $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;
+ };
+
+ $scope.saveEntity = function() {
+ var type = $scope.entityType;
+ if(!$scope.$parent.cloningMode) {
+ Falcon.logRequest();
+ Falcon.postUpdateEntity($scope.xml, $scope.entityType, $scope[type].name)
+ .success(function (response) {
+ Falcon.logResponse('success', response, false);
+ $state.go('main');
+ })
+ .error(function(err) {
+ Falcon.logResponse('error', err, false);
+ });
+ } else {
+ Falcon.logRequest();
+ Falcon.postSubmitEntity($scope.xml, $scope.entityType)
+ .success(function (response) {
+ Falcon.logResponse('success', response, false);
+ $state.go('main');
+ })
+ .error(function(err) {
+ Falcon.logResponse('error', err, false);
+ });
+ }
+
+ $scope.editingMode = false;
+ $scope.cloningMode = false;
+ };
+
+ $scope.isActive = function (route) {
+ return route === $state.$current.name;
+ };
+
+ $scope.parseDate = function(input) {
+ return input ? input.split('T')[0] : input;
+ };
+
+ $scope.parseTime = function(input) {
+ if (input) {
+ var partialTime = input.split('T')[1].split(':');
+ partialTime = partialTime[0] + ':' + partialTime[1];
+ return partialTime;
+ }
+ return 'Not defined';
+ };
+
+ $scope.appendVariable = function(timeVariable, holder, fieldName) {
+ holder[fieldName] = holder[fieldName] ? (holder[fieldName] + '-' + timeVariable) : timeVariable;
+ holder.focused = false;
+ };
+
+ 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);
+ } catch (exception) {
+ console.log('user entered xml incorrect format');
+ console.log(exception);
+ }
+ }
+
+ };
+
+ var xmlPreviewWorker = $interval(xmlPreviewCallback, 1000);
+
+ $scope.$on('$destroy', function () {
+ $interval.cancel(xmlPreviewWorker);
+ });
+
+ //$scope.nameValid = $scope.$parent.nameValid;
+ /*
+ * needed for validation
+ * */
+ $scope.goNext = function (formInvalid, stateName) {
+ if (!validationService.nameAvailable || formInvalid) {
+ validationService.displayValidations.show = true;
+ validationService.displayValidations.nameShow = true;
+ return;
+ }
+ validationService.displayValidations.show = false;
+ validationService.displayValidations.nameShow = false;
+ $state.go(stateName);
+ };
+ $scope.goBack = function (stateName) {
+ validationService.displayValidations.show = false;
+ validationService.displayValidations.nameShow = false;
+ $state.go(stateName);
+ };
+
+ }]);
+
+
+
+
+})();
http://git-wip-us.apache.org/repos/asf/falcon/blob/c4df0a5e/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
new file mode 100644
index 0000000..77e1dcc
--- /dev/null
+++ b/falcon-ui/app/js/controllers/feed/feed-summary-controller.js
@@ -0,0 +1,48 @@
+/**
+ * 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.FeedController
+ * @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('FeedSummaryController', [ "$scope", "$filter", function($scope, $filter) {
+
+ if($scope.transform) {
+ $scope.transform();
+ }
+
+ $scope.hasTags = function() {
+ var filteredTags = $filter('filter')($scope.feed.tags, {key: '!!'});
+ return filteredTags.length > 0;
+ };
+
+ $scope.optional = function(input, output) {
+ return input ? (output || input) : 'Not specified';
+ };
+
+ }]);
+
+
+})();
http://git-wip-us.apache.org/repos/asf/falcon/blob/c4df0a5e/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
new file mode 100644
index 0000000..5039b99
--- /dev/null
+++ b/falcon-ui/app/js/controllers/header-controller.js
@@ -0,0 +1,59 @@
+/**
+ * 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';
+
+ var navHeaderModule = angular.module('app.controllers.navHeader', [
+ 'app.services.entity.model',
+ 'app.services.validation',
+ 'ngCookies'
+ ]);
+
+ navHeaderModule.controller('HeaderController', [
+ '$rootScope', '$scope', '$state', '$cookieStore', 'EntityModel', 'ValidationService',
+ function ($rootScope, $scope, $state, $cookieStore, EntityModel, validationService) {
+
+ $scope.resetCluster = function () {
+ validationService.displayValidations = {show: false, nameShow: false};
+ EntityModel.clusterModel = { cluster: { tags: "", interfaces: { interface: [
+ { _type: "readonly", _endpoint: "hftp://sandbox.hortonworks.com:50070", _version: "2.2.0"},
+ { _type: "write", _endpoint: "hdfs://sandbox.hortonworks.com:8020", _version: "2.2.0"},
+ { _type: "execute", _endpoint: "sandbox.hortonworks.com:8050", _version: "2.2.0"},
+ { _type: "workflow", _endpoint: "http://sandbox.hortonworks.com:11000/oozie/", _version: "4.0.0"},
+ { _type: "messaging", _endpoint: "tcp://sandbox.hortonworks.com:61616?daemon=true", _version: "5.1.6"}
+ ]}, locations: { location: [{ _name: "staging", _path: ""}, { _name: "temp", _path: ""}, { _name: "working", _path: ""}]},
+ ACL: { _owner: "", _group: "", _permission: ""}, properties: { property: [{ _name: "", _value: ""}]},
+ _xmlns: "uri:falcon:cluster:0.1", _name: "", _description: "", _colo: ""}};
+ $state.go("forms.cluster.general");
+ };
+
+ $scope.resetProcess = function () {
+ validationService.displayValidations = {show: false, nameShow: false};
+ $scope.cloningMode = true;
+ $state.go("forms.process.general");
+ };
+
+ $scope.resetFeed = function () {
+ validationService.displayValidations = {show: false, nameShow: false};
+ $scope.cloningMode = true;
+ $state.go("forms.feed.general");
+ };
+
+ }]);
+
+})();
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/falcon/blob/c4df0a5e/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
new file mode 100644
index 0000000..b588c84
--- /dev/null
+++ b/falcon-ui/app/js/controllers/process/process-clusters-ctrl.js
@@ -0,0 +1,71 @@
+/**
+ * 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.FeedController
+ * @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.process');
+
+ feedModule.controller('ProcessClustersCtrl',
+ ['$scope', 'clustersList', 'EntityFactory', function($scope, clustersList, entityFactory) {
+
+ $scope.init = function() {
+ $scope.dateFormat = 'dd-MMMM-yyyy';
+ };
+
+ $scope.openDatePicker = function($event, container) {
+ $event.preventDefault();
+ $event.stopPropagation();
+ container.opened = true;
+ };
+
+ $scope.addCluster = function() {
+ $scope.process.clusters.push(entityFactory.newCluster());
+ };
+
+ $scope.removeCluster = function(index) {
+ if(index >= 0 && $scope.process.clusters.length > 1) {
+ $scope.process.clusters.splice(index, 1);
+ }
+ };
+
+ unwrapClusters(clustersList);
+
+ 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");
+ }
+ }
+
+ $scope.init();
+
+ }]);
+
+})();
http://git-wip-us.apache.org/repos/asf/falcon/blob/c4df0a5e/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
new file mode 100644
index 0000000..ec689f3
--- /dev/null
+++ b/falcon-ui/app/js/controllers/process/process-general-information-ctrl.js
@@ -0,0 +1,66 @@
+/**
+ * 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.FeedController
+ * @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.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']
+ };
+ $scope.nameValid = false;
+
+ $scope.init = function() {
+ $scope.versions = [];
+ };
+
+ $scope.addTag = function() {
+ $scope.process.tags.push({key: null, value: null});
+ };
+
+ $scope.removeTag = function(index) {
+ if(index >= 0 && $scope.process.tags.length > 1) {
+ $scope.process.tags.splice(index, 1);
+ }
+ };
+
+ $scope.selectWorkflow = function() {
+
+ if($scope.process.workflow) {
+ var engine = $scope.process.workflow.engine;
+ $scope.versions = availableVerions[engine];
+ }
+ };
+
+ $scope.init();
+ $scope.selectWorkflow();
+
+ }]);
+
+
+})();
http://git-wip-us.apache.org/repos/asf/falcon/blob/c4df0a5e/falcon-ui/app/js/controllers/process/process-inputs-and-outputs-ctrl.js
----------------------------------------------------------------------
diff --git a/falcon-ui/app/js/controllers/process/process-inputs-and-outputs-ctrl.js b/falcon-ui/app/js/controllers/process/process-inputs-and-outputs-ctrl.js
new file mode 100644
index 0000000..c9b22d0
--- /dev/null
+++ b/falcon-ui/app/js/controllers/process/process-inputs-and-outputs-ctrl.js
@@ -0,0 +1,76 @@
+/**
+ * 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.FeedController
+ * @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.process');
+
+ feedModule.controller('ProcessInputsAndOutputsCtrl',
+
+ ['$scope', 'EntityFactory', 'feedsList', function($scope, entityFactory, feedsList) {
+
+ $scope.init = function() {
+
+ };
+
+ $scope.addInput = function() {
+ $scope.process.inputs.push(entityFactory.newInput());
+ };
+
+ $scope.removeInput = function(index) {
+ if(index >= 0) {
+ $scope.process.inputs.splice(index, 1);
+ }
+ };
+
+ $scope.addOutput = function() {
+ $scope.process.outputs.push(entityFactory.newOutput());
+ };
+
+ $scope.removeOutput = function(index) {
+ if(index >= 0) {
+ $scope.process.outputs.splice(index, 1);
+ }
+ };
+
+
+ unwrapClusters(feedsList);
+
+ function unwrapClusters(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");
+ }
+ }
+
+ $scope.init();
+
+ }]);
+})();
http://git-wip-us.apache.org/repos/asf/falcon/blob/c4df0a5e/falcon-ui/app/js/controllers/process/process-module.js
----------------------------------------------------------------------
diff --git a/falcon-ui/app/js/controllers/process/process-module.js b/falcon-ui/app/js/controllers/process/process-module.js
new file mode 100644
index 0000000..dbbcc6f
--- /dev/null
+++ b/falcon-ui/app/js/controllers/process/process-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.feed.FeedController
+ * @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
+ */
+ angular.module('app.controllers.process', [
+ 'app.services',
+ 'app.controllers.entity'
+ ]);
+
+})();
http://git-wip-us.apache.org/repos/asf/falcon/blob/c4df0a5e/falcon-ui/app/js/controllers/process/process-properties-controller.js
----------------------------------------------------------------------
diff --git a/falcon-ui/app/js/controllers/process/process-properties-controller.js b/falcon-ui/app/js/controllers/process/process-properties-controller.js
new file mode 100644
index 0000000..d4e747c
--- /dev/null
+++ b/falcon-ui/app/js/controllers/process/process-properties-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.FeedController
+ * @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.process');
+
+ feedModule.controller('ProcessPropertiesCtrl', [ '$scope', function() {
+
+ }]);
+
+})();
http://git-wip-us.apache.org/repos/asf/falcon/blob/c4df0a5e/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
new file mode 100644
index 0000000..ba69705
--- /dev/null
+++ b/falcon-ui/app/js/controllers/process/process-root-ctrl.js
@@ -0,0 +1,117 @@
+/**
+ * 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.FeedController
+ * @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.process');
+
+ feedModule.controller('ProcessRootCtrl', [
+ '$scope', '$state', '$interval', '$controller', 'EntityFactory',
+ 'EntitySerializer', 'X2jsService', 'ValidationService',
+ function ($scope, $state, $interval, $controller, entityFactory, serializer, X2jsService, validationService) {
+
+ $scope.entityType = 'process';
+
+ //extending root controller
+ $controller('EntityRootCtrl', {
+ $scope: $scope
+ });
+
+ $scope.init = function() {
+ $scope.baseInit();
+ var type = $scope.entityType;
+ $scope[type] = $scope.loadOrCreateEntity();
+ };
+
+ $scope.isActive = function (route) {
+ return route === $state.$current.name;
+ };
+
+ $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);
+ }
+ return entityFactory.newEntity(type);
+ };
+
+ $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);
+ } catch (exception) {
+ console.log('user entered xml incorrect format');
+ console.log(exception);
+ }
+ }
+
+ };
+
+ var xmlPreviewWorker = $interval(xmlPreviewCallback, 1000);
+
+ $scope.$on('$destroy', function() {
+ $interval.cancel(xmlPreviewWorker);
+ });
+
+ //---------------------------------//
+ $scope.goNext = function (formInvalid, stateName) {
+ if (!validationService.nameAvailable || formInvalid) {
+ validationService.displayValidations.show = true;
+ validationService.displayValidations.nameShow = true;
+ return;
+ }
+ validationService.displayValidations.show = false;
+ validationService.displayValidations.nameShow = false;
+ $state.go(stateName);
+ };
+ $scope.goBack = function (stateName) {
+ validationService.displayValidations.show = false;
+ validationService.displayValidations.nameShow = false;
+ $state.go(stateName);
+ };
+ }
+ ]);
+
+}());
http://git-wip-us.apache.org/repos/asf/falcon/blob/c4df0a5e/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
new file mode 100644
index 0000000..d81bb62
--- /dev/null
+++ b/falcon-ui/app/js/controllers/process/process-summary-ctrl.js
@@ -0,0 +1,83 @@
+/**
+ * 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.FeedController
+ * @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.process');
+
+ feedModule.controller('ProcessSummaryCtrl', [ '$scope', '$state', '$timeout', '$filter', 'Falcon',
+ function($scope, $state, $timeout, $filter, Falcon) {
+
+ $scope.init = function() {
+ if($scope.transform) {
+ $scope.transform();
+ }
+ };
+
+ $scope.hasTags = function() {
+ var filteredTags = $filter('filter')($scope.process.tags, {key: '!!'});
+ return filteredTags.length > 0;
+ };
+
+ $scope.optional = function(input, output) {
+ return input ? (output || input) : 'Not specified';
+ };
+
+ $scope.saveEntity = function() {
+ var type = $scope.entityType;
+ if(!$scope.$parent.cloningMode) {
+ Falcon.logRequest();
+ Falcon.postUpdateEntity($scope.xml, $scope.entityType, $scope[type].name)
+ .success(function (response) {
+ Falcon.logResponse('success', response, false);
+ $state.go('main');
+
+ })
+ .error(function (err) {
+ Falcon.logResponse('error', err, false);
+ });
+ }
+ else {
+ Falcon.logRequest();
+ Falcon.postSubmitEntity($scope.xml, $scope.entityType)
+ .success(function (response) {
+ Falcon.logResponse('success', response, false);
+ $state.go('main');
+
+ })
+ .error(function (err) {
+ Falcon.logResponse('error', err, false);
+ });
+ }
+
+ $scope.editingMode = false;
+ $scope.cloningMode = false;
+ };
+
+ $scope.init();
+
+ }]);
+
+})();
http://git-wip-us.apache.org/repos/asf/falcon/blob/c4df0a5e/falcon-ui/app/js/controllers/root-controller.js
----------------------------------------------------------------------
diff --git a/falcon-ui/app/js/controllers/root-controller.js b/falcon-ui/app/js/controllers/root-controller.js
new file mode 100644
index 0000000..9a71d30
--- /dev/null
+++ b/falcon-ui/app/js/controllers/root-controller.js
@@ -0,0 +1,91 @@
+/**
+ * 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';
+
+ var app = angular.module('app.controllers.rootCtrl', ['app.services']);
+
+ app.controller('RootCtrl', [
+ "$scope", "$timeout", "Falcon", "FileApi", "EntityModel", "$state", "X2jsService", "ValidationService",
+ function ($scope, $timeout, Falcon, FileApi, EntityModel, $state, X2jsService, validationService) {
+
+ $scope.server = Falcon;
+ $scope.validations = validationService;
+ $scope.models = {};
+
+ $scope.handleFile = function (evt) {
+ Falcon.logRequest();
+ FileApi.loadFile(evt).then(function () {
+ Falcon.postSubmitEntity(FileApi.fileRaw, EntityModel.type).success(function (response) {
+ Falcon.logResponse('success', response, false);
+ $scope.refreshList(EntityModel.type);
+ }).error(function (err) {
+ Falcon.logResponse('error', err, false);
+ });
+ });
+ };
+
+ $scope.lists = {};
+ $scope.lists.feedList = [];
+ $scope.lists.clusterList = [];
+ $scope.lists.processList = [];
+
+ $scope.refreshList = function (type) {
+ type = type.toLowerCase();
+ Falcon.responses.listLoaded[type] = false;
+ if (Falcon.responses.multiRequest[type] > 0) { return; }
+
+ Falcon.logRequest();
+
+ Falcon.getEntities(type)
+ .success(function (data) {
+
+ Falcon.logResponse('success', data, false, true);
+ Falcon.responses.listLoaded[type] = true;
+ $scope.lists[type + 'List'] = [];
+
+ if (data === null) {
+ $scope.lists[type + 'List'] = [];
+ }else{
+ var typeOfData = Object.prototype.toString.call(data.entity);
+ if (typeOfData === "[object Array]") {
+ $scope.lists[type + 'List'] = data.entity;
+ } else if (typeOfData === "[object Object]") {
+ $scope.lists[type + 'List'][0] = data.entity;
+ } else {
+ console.log("type of data not recognized");
+ }
+ }
+ })
+ .error(function (err) {
+ Falcon.logResponse('error', err);
+ });
+ };
+
+ $scope.refreshLists = function () {
+ $scope.refreshList('cluster');
+ $scope.refreshList('feed');
+ $scope.refreshList('process');
+ };
+ $scope.closeAlert = function (index) {
+ Falcon.removeMessage(index);
+ };
+
+ }]);
+
+}());
\ No newline at end of file