From 4f61fff2b7467d9fa82c2dd7f81624b2ab885281 Mon Sep 17 00:00:00 2001 From: Suma Shivaprasad Date: Sat, 10 Oct 2015 10:04:01 +0530 Subject: [PATCH] ATLAS-188 Provide Ability to Add Tag to Entity (sanjayp via sumasai) --- dashboard/public/css/details.css | 2 +- dashboard/public/css/tags.css | 51 +++++++++++++ dashboard/public/index.html | 1 + dashboard/public/js/app.js | 4 +- .../modules/details/detailsController.js | 4 +- .../public/modules/details/detailsResource.js | 4 ++ .../public/modules/details/views/details.html | 1 + .../public/modules/search/views/search.html | 2 +- .../definitionTagsController.js} | 2 +- .../tags/definition/definitionTagsModule.js | 21 ++++++ .../tagAttributeDefinition.js | 2 +- .../tags/{ => definition}/views/add.html | 2 +- .../tags/instance/createTagController.js | 72 +++++++++++++++++++ .../tags/instance/instanceTagsController.js | 40 +++++++++++ .../tags/instance/instanceTagsModule.js | 21 ++++++ .../tags/instance/views/createTag.html | 42 +++++++++++ .../modules/tags/instance/views/tags.html | 28 ++++++++ dashboard/public/modules/tags/tagClasses.js | 11 +++ dashboard/public/modules/tags/tagsRoutes.js | 19 ++++- 19 files changed, 319 insertions(+), 10 deletions(-) create mode 100644 dashboard/public/css/tags.css rename dashboard/public/modules/tags/{tagsController.js => definition/definitionTagsController.js} (92%) create mode 100644 dashboard/public/modules/tags/definition/definitionTagsModule.js rename dashboard/public/modules/tags/{ => definition}/tagAttributeDefinition.js (92%) rename dashboard/public/modules/tags/{ => definition}/views/add.html (99%) create mode 100644 dashboard/public/modules/tags/instance/createTagController.js create mode 100644 dashboard/public/modules/tags/instance/instanceTagsController.js create mode 100644 dashboard/public/modules/tags/instance/instanceTagsModule.js create mode 100644 dashboard/public/modules/tags/instance/views/createTag.html create mode 100644 dashboard/public/modules/tags/instance/views/tags.html diff --git a/dashboard/public/css/details.css b/dashboard/public/css/details.css index 156d5f682..6c62bcfa8 100644 --- a/dashboard/public/css/details.css +++ b/dashboard/public/css/details.css @@ -18,4 +18,4 @@ .tab-content .table-bordered { border-top: none; -} \ No newline at end of file +} diff --git a/dashboard/public/css/tags.css b/dashboard/public/css/tags.css new file mode 100644 index 000000000..21aa89dc1 --- /dev/null +++ b/dashboard/public/css/tags.css @@ -0,0 +1,51 @@ +/* + * 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. + */ + +.add-tag { + text-decoration: underline; +} + +.input-spacing{ + padding-bottom: 10px!important; +} + +.create-tag-entity .modal-footer{ + border-top: 0; +} + +.tag-list{ + border:1px solid #ddd; + padding:10px; + background-color: #F5F5F5; +} + +.tag-list ul{ + padding-left: 0px; +} + +.error{ + color:red; +} + +.tag-list ul li{ + display: inline; + line-height: 30px; + border:none; + padding: 0px; + background-color: inherit; +} \ No newline at end of file diff --git a/dashboard/public/index.html b/dashboard/public/index.html index 5ce839dde..4190b5cbf 100644 --- a/dashboard/public/index.html +++ b/dashboard/public/index.html @@ -34,6 +34,7 @@ + diff --git a/dashboard/public/js/app.js b/dashboard/public/js/app.js index 82171c63d..3ef1794be 100644 --- a/dashboard/public/js/app.js +++ b/dashboard/public/js/app.js @@ -27,7 +27,9 @@ angular.module('dgc', ['ngCookies', 'dgc.about', 'dgc.search', 'dgc.navigation', - 'dgc.tags' + 'dgc.tags', + 'dgc.tags.instance', + 'dgc.tags.definition' ]); angular.module('dgc.system', ['dgc.system.notification']); diff --git a/dashboard/public/modules/details/detailsController.js b/dashboard/public/modules/details/detailsController.js index c469c37b3..538d2625e 100644 --- a/dashboard/public/modules/details/detailsController.js +++ b/dashboard/public/modules/details/detailsController.js @@ -36,7 +36,6 @@ angular.module('dgc.details').controller('DetailsController', ['$window', '$scop $scope.isNumber = angular.isNumber; $scope.isString = angular.isString; - $scope.onActivate = function tabActivate(tabname) { $scope.$broadcast('render-lineage', { type: tabname, @@ -47,6 +46,5 @@ angular.module('dgc.details').controller('DetailsController', ['$window', '$scop $scope.goBack = function() { $window.history.back(); }; - } -]); \ No newline at end of file +]); diff --git a/dashboard/public/modules/details/detailsResource.js b/dashboard/public/modules/details/detailsResource.js index a559e6fc9..a76559547 100644 --- a/dashboard/public/modules/details/detailsResource.js +++ b/dashboard/public/modules/details/detailsResource.js @@ -28,6 +28,10 @@ angular.module('dgc.details').factory('DetailsResource', ['$resource', function( } }, responseType: 'json' + }, + saveTag: { + method: 'POST', + url: '/api/atlas/entity/:id/traits' } }); diff --git a/dashboard/public/modules/details/views/details.html b/dashboard/public/modules/details/views/details.html index 26d81ec81..f53f94d82 100644 --- a/dashboard/public/modules/details/views/details.html +++ b/dashboard/public/modules/details/views/details.html @@ -41,6 +41,7 @@

Lineage:
-
+

Tag Definition

diff --git a/dashboard/public/modules/tags/instance/createTagController.js b/dashboard/public/modules/tags/instance/createTagController.js new file mode 100644 index 000000000..e6df24cdf --- /dev/null +++ b/dashboard/public/modules/tags/instance/createTagController.js @@ -0,0 +1,72 @@ +/* + * 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. + */ + +'use strict'; + +angular.module('dgc.tags.instance').controller('CreateTagController', ['$scope', 'DetailsResource', '$modalInstance', 'typesList', 'lodash', 'TagsResource', '$stateParams', '$rootScope', 'TagClasses', 'NotificationService', + function($scope, DetailsResource, $modalInstance, typesList, _, TagsResource, $stateParams, $rootScope, Categories, NotificationService) { + if (typesList) { + $scope.typesList = typesList; + } + $scope.categoryList = Categories; + $scope.category = 'TRAIT'; + + $scope.getAttributeDefinations = function() { + TagsResource.get({ + id: $scope.selectedType + }, function(data) { + var instanceType = Categories[$scope.category].instanceInfo(); + if (instanceType) { + var traitTypes = angular.fromJson(data.definition)[instanceType][0]; + if (traitTypes) { + $scope.propertiesList = {}; + $scope.isRequired = {}; + _.each(traitTypes.attributeDefinitions, function(value) { + $scope.propertiesList[value.name] = ''; + $scope.isRequired[value.name] = value.isRequired; + }); + } + } + + }); + }; + $scope.ok = function(tagDefinitionform) { + if (tagDefinitionform.$valid) { + var requestObject = { + "jsonClass": "org.apache.atlas.typesystem.json.InstanceSerialization$_Struct", + "typeName": $scope.selectedType, + "values": $scope.propertiesList + }; + DetailsResource.saveTag({ + id: $stateParams.id + }, requestObject).$promise.then(function() { + $rootScope.$broadcast('refreshResourceData'); + NotificationService.info('Tag "' + $scope.selectedType + '" has been added to entity', true); + $modalInstance.close(true); + }).catch(function(err) { + $scope.isError = true; + $scope.error = err.data.error; + }); + } + }; + + $scope.cancel = function() { + $modalInstance.dismiss('cancel'); + }; + } +]); diff --git a/dashboard/public/modules/tags/instance/instanceTagsController.js b/dashboard/public/modules/tags/instance/instanceTagsController.js new file mode 100644 index 000000000..663a8d06d --- /dev/null +++ b/dashboard/public/modules/tags/instance/instanceTagsController.js @@ -0,0 +1,40 @@ +/* + * 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. + */ + +'use strict'; + +angular.module('dgc.tags.instance').controller('InstanceTagController', ['$scope', 'DetailsResource', '$stateParams', '$state', + function($scope, DetailsResource, $stateParams, $state) { + $scope.id = $stateParams.id; + + function getResourceData() { + DetailsResource.get({ + id: $stateParams.id + }, function(data) { + $scope.traitsList = data.traitNames; + }); + } + $scope.openAddTag = function() { + $state.go('addTag', { + id: $scope.id + }); + }; + getResourceData(); + $scope.$on('refreshResourceData', getResourceData); + } +]); diff --git a/dashboard/public/modules/tags/instance/instanceTagsModule.js b/dashboard/public/modules/tags/instance/instanceTagsModule.js new file mode 100644 index 000000000..5f7083d21 --- /dev/null +++ b/dashboard/public/modules/tags/instance/instanceTagsModule.js @@ -0,0 +1,21 @@ +/* + * 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. + */ + +'use strict'; + +angular.module('dgc.tags.instance', []); diff --git a/dashboard/public/modules/tags/instance/views/createTag.html b/dashboard/public/modules/tags/instance/views/createTag.html new file mode 100644 index 000000000..f4db1ce9e --- /dev/null +++ b/dashboard/public/modules/tags/instance/views/createTag.html @@ -0,0 +1,42 @@ + +
diff --git a/dashboard/public/modules/tags/instance/views/tags.html b/dashboard/public/modules/tags/instance/views/tags.html new file mode 100644 index 000000000..33904b0ec --- /dev/null +++ b/dashboard/public/modules/tags/instance/views/tags.html @@ -0,0 +1,28 @@ + +
+
+

Tags

+ +
+
\ No newline at end of file diff --git a/dashboard/public/modules/tags/tagClasses.js b/dashboard/public/modules/tags/tagClasses.js index 81ad77c40..416acaad0 100644 --- a/dashboard/public/modules/tags/tagClasses.js +++ b/dashboard/public/modules/tags/tagClasses.js @@ -35,6 +35,13 @@ angular.module('dgc.tags').factory('TagClasses', ['lodash', function ClassFactor CLASS: 'org.apache.atlas.typesystem.types.ClassType' }; + var instanceRespons = { + ENUM: 'enumTypes', + STRUCT: 'structTypes', + TRAIT: 'traitTypes', + SUPER: 'superTypes' + }; + function Class(classId, className) { this.tags = []; this.id = classId; @@ -65,6 +72,10 @@ angular.module('dgc.tags').factory('TagClasses', ['lodash', function ClassFactor output[classTypeKey] = this.tags; return output; }; + + this.instanceInfo = function() { + return instanceRespons[classId]; + }; } return _.chain(classes) diff --git a/dashboard/public/modules/tags/tagsRoutes.js b/dashboard/public/modules/tags/tagsRoutes.js index a15c3baac..5d768a58d 100755 --- a/dashboard/public/modules/tags/tagsRoutes.js +++ b/dashboard/public/modules/tags/tagsRoutes.js @@ -22,7 +22,24 @@ angular.module('dgc.tags').config(['$stateProvider', function($stateProvider) { $stateProvider.state('tags', { url: '/tags', - templateUrl: '/modules/tags/views/add.html' + templateUrl: '/modules/tags/definition/views/add.html' + }); + $stateProvider.state('addTag', { + parent: 'details', + onEnter: ['$stateParams', '$state', '$modal', 'NavigationResource', function($stateParams, $state, $modal, NavigationResource) { + $modal.open({ + templateUrl: '/modules/tags/instance/views/createTag.html', + controller: 'CreateTagController', + windowClass: 'create-tag-entity', + resolve: { + typesList: function() { + return NavigationResource.get().$promise; + } + } + }).result.finally(function() { + $state.go('^'); + }); + }] }); } ]);