Commit 4f61fff2 by Suma Shivaprasad

ATLAS-188 Provide Ability to Add Tag to Entity (sanjayp via sumasai)

parent 461a2a4e
/*
* 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
...@@ -34,6 +34,7 @@ ...@@ -34,6 +34,7 @@
<link rel="stylesheet" href="/css/common.css"> <link rel="stylesheet" href="/css/common.css">
<link rel="stylesheet" href="/css/details.css"> <link rel="stylesheet" href="/css/details.css">
<link rel="stylesheet" href="/css/lineage.css"> <link rel="stylesheet" href="/css/lineage.css">
<link rel="stylesheet" href="/css/tags.css">
<link rel="stylesheet" href="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/css/bootstrap.min.css"> <link rel="stylesheet" href="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/css/bootstrap.min.css">
</head> </head>
......
...@@ -27,7 +27,9 @@ angular.module('dgc', ['ngCookies', ...@@ -27,7 +27,9 @@ angular.module('dgc', ['ngCookies',
'dgc.about', 'dgc.about',
'dgc.search', 'dgc.search',
'dgc.navigation', 'dgc.navigation',
'dgc.tags' 'dgc.tags',
'dgc.tags.instance',
'dgc.tags.definition'
]); ]);
angular.module('dgc.system', ['dgc.system.notification']); angular.module('dgc.system', ['dgc.system.notification']);
......
...@@ -36,7 +36,6 @@ angular.module('dgc.details').controller('DetailsController', ['$window', '$scop ...@@ -36,7 +36,6 @@ angular.module('dgc.details').controller('DetailsController', ['$window', '$scop
$scope.isNumber = angular.isNumber; $scope.isNumber = angular.isNumber;
$scope.isString = angular.isString; $scope.isString = angular.isString;
$scope.onActivate = function tabActivate(tabname) { $scope.onActivate = function tabActivate(tabname) {
$scope.$broadcast('render-lineage', { $scope.$broadcast('render-lineage', {
type: tabname, type: tabname,
...@@ -47,6 +46,5 @@ angular.module('dgc.details').controller('DetailsController', ['$window', '$scop ...@@ -47,6 +46,5 @@ angular.module('dgc.details').controller('DetailsController', ['$window', '$scop
$scope.goBack = function() { $scope.goBack = function() {
$window.history.back(); $window.history.back();
}; };
} }
]); ]);
...@@ -28,6 +28,10 @@ angular.module('dgc.details').factory('DetailsResource', ['$resource', function( ...@@ -28,6 +28,10 @@ angular.module('dgc.details').factory('DetailsResource', ['$resource', function(
} }
}, },
responseType: 'json' responseType: 'json'
},
saveTag: {
method: 'POST',
url: '/api/atlas/entity/:id/traits'
} }
}); });
......
...@@ -41,6 +41,7 @@ ...@@ -41,6 +41,7 @@
</tr> </tr>
</tbody> </tbody>
</table> </table>
<ng-include src="'/modules/tags/instance/views/tags.html'"/>
</tab> </tab>
<tab data-heading="Schema" data-ng-if="isTable"><ng-include src="'/modules/details/views/schema.html'"/></tab> <tab data-heading="Schema" data-ng-if="isTable"><ng-include src="'/modules/details/views/schema.html'"/></tab>
<!-- <tab data-heading="Output" data-ng-if="isTable" data-disable="!tableName" data-select="onActivate('outputs')"><ng-include data-table-type="outputs" src="'/modules/lineage/views/lineage.html'"/></tab> <!-- <tab data-heading="Output" data-ng-if="isTable" data-disable="!tableName" data-select="onActivate('outputs')"><ng-include data-table-type="outputs" src="'/modules/lineage/views/lineage.html'"/></tab>
......
...@@ -55,7 +55,7 @@ ...@@ -55,7 +55,7 @@
<a href ng-show="isCollapsed && (keyLength > 4)" ng-click="doToggle($event,isCollapsed)">..show more</a> <a href ng-show="isCollapsed && (keyLength > 4)" ng-click="doToggle($event,isCollapsed)">..show more</a>
<a href ng-show="!isCollapsed" ng-click="doToggle($event,isCollapsed)">..show less</a> <a href ng-show="!isCollapsed" ng-click="doToggle($event,isCollapsed)">..show less</a>
<h5 ng-show="!dataTransitioned">Tags : <a ng-repeat="(key, value) in result['$traits$']" data-ui-sref="search({query: key})">{{key}}</a></h5> <h5 ng-show="!dataTransitioned">Tags : <a ng-repeat="(key, value) in result['$traits$']" data-ui-sref="search({query: key})">{{key}}<span ng-show="!{{$last}}">,</span> </a></h5>
</li> </li>
</ul> </ul>
......
...@@ -18,7 +18,7 @@ ...@@ -18,7 +18,7 @@
'use strict'; 'use strict';
angular.module('dgc.tags').controller('TagsController', ['$scope', '$resource', '$state', '$stateParams', 'lodash', 'AttributeDefinition', 'TagClasses', 'TagsResource', 'NotificationService', angular.module('dgc.tags.definition').controller('DefinitionTagsController', ['$scope', '$resource', '$state', '$stateParams', 'lodash', 'AttributeDefinition', 'TagClasses', 'TagsResource', 'NotificationService',
function($scope, $resource, $state, $stateParams, _, AttributeDefinition, Categories, TagsResource, NotificationService) { function($scope, $resource, $state, $stateParams, _, AttributeDefinition, Categories, TagsResource, NotificationService) {
$scope.categoryList = Categories; $scope.categoryList = Categories;
$scope.category = 'TRAIT'; $scope.category = 'TRAIT';
......
/*
* 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.definition', []);
...@@ -18,7 +18,7 @@ ...@@ -18,7 +18,7 @@
'use strict'; 'use strict';
angular.module('dgc.tags').service('AttributeDefinition', function Attribute() { angular.module('dgc.tags.definition').service('AttributeDefinition', function Attribute() {
this.getModel = function getJson() { this.getModel = function getJson() {
return { return {
name: null, name: null,
......
...@@ -16,7 +16,7 @@ ...@@ -16,7 +16,7 @@
~ limitations under the License. ~ limitations under the License.
--> -->
<div class="container"> <div class="container">
<div class="appForm" data-ng-controller="TagsController"> <div class="appForm" data-ng-controller="DefinitionTagsController">
<h4>Tag Definition</h4> <h4>Tag Definition</h4>
<form data-name="tagForm" class="form-horizontal" novalidate role="form"> <form data-name="tagForm" class="form-horizontal" novalidate role="form">
......
/*
* 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');
};
}
]);
/*
* 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);
}
]);
/*
* 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', []);
<div class="modal-header">
<h4 class="modal-title">Add tag</h4>
</div>
<div class="modal-body">
<div class="form-group">
<div align="center" class="error col-sm-12" ng-if="isError">
{{error}}
</div>
</div>
<form name="tagDefinitionform" class="css-form" novalidate>
<div class="form-group hide">
<label for="category" class="col-sm-4 control-label">Category</label>
<div class="col-sm-8 input-spacing">
<select class="form-control" id="category" name="category"
ng-model="category" ng-change="categoryChange()" required>
<option value="{{key}}"
ng-repeat="(key, value) in categoryList"
ng-selected="{{key===category}}">{{key}}</option>
</select>
</div>
</div>
<div class="form-group" ng-class="{'has-error': (tagDefinitionform.tagDefinition.$invalid && tagDefinitionform.tagDefinition.$dirty)}">
<label class="control-label col-sm-4" for="tagDefinition">Tag definition</label>
<div class="col-sm-8 input-spacing">
<select ng-model="selectedType" class="form-control" id="tagDefinition" name="tagDefinition"
ng-change="getAttributeDefinations(); isError =false" required>
<option ng-repeat="data in typesList">{{data}}</option>
</select>
</div>
</div>
<div class="form-group" ng-repeat="(key, value) in propertiesList" ng-class="{'has-error': (tagDefinitionform.propertyId_{{$index}}.$invalid && tagDefinitionform.propertyId_{{$index}}.$dirty)}">
<label class="control-label col-sm-4" for="propertyId_{{$index}}">{{key}}</label>
<div class="col-sm-8 input-spacing">
<input type="text" class="form-control" id="propertyId_{{$index}}" name="propertyId_{{$index}}" ng-model="propertiesList[key]" ng-required="isRequired[key]"/>
</div>
</div>
<div class="modal-footer">
<button class="btn btn-success" type="submit" ng-click="ok(tagDefinitionform)" ng-disabled="tagDefinitionform.$invalid">Save</button>
<button class="btn btn-warning" type="button" ng-click="cancel()">Cancel</button>
</div>
</form>
</div>
<!--
~ 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.
-->
<div data-ng-controller="InstanceTagController">
<div class="container tag-list">
<h4>Tags</h4>
<ul>
<li ng-repeat="trait in traitsList" class="list-group-item">
{{trait}},</li>
<li class="list-group-item"><a ng-click="openAddTag()" href=""
class="add-tag">Add tag</a></li>
</ul>
</div>
</div>
\ No newline at end of file
...@@ -35,6 +35,13 @@ angular.module('dgc.tags').factory('TagClasses', ['lodash', function ClassFactor ...@@ -35,6 +35,13 @@ angular.module('dgc.tags').factory('TagClasses', ['lodash', function ClassFactor
CLASS: 'org.apache.atlas.typesystem.types.ClassType' CLASS: 'org.apache.atlas.typesystem.types.ClassType'
}; };
var instanceRespons = {
ENUM: 'enumTypes',
STRUCT: 'structTypes',
TRAIT: 'traitTypes',
SUPER: 'superTypes'
};
function Class(classId, className) { function Class(classId, className) {
this.tags = []; this.tags = [];
this.id = classId; this.id = classId;
...@@ -65,6 +72,10 @@ angular.module('dgc.tags').factory('TagClasses', ['lodash', function ClassFactor ...@@ -65,6 +72,10 @@ angular.module('dgc.tags').factory('TagClasses', ['lodash', function ClassFactor
output[classTypeKey] = this.tags; output[classTypeKey] = this.tags;
return output; return output;
}; };
this.instanceInfo = function() {
return instanceRespons[classId];
};
} }
return _.chain(classes) return _.chain(classes)
......
...@@ -22,7 +22,24 @@ angular.module('dgc.tags').config(['$stateProvider', ...@@ -22,7 +22,24 @@ angular.module('dgc.tags').config(['$stateProvider',
function($stateProvider) { function($stateProvider) {
$stateProvider.state('tags', { $stateProvider.state('tags', {
url: '/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('^');
});
}]
}); });
} }
]); ]);
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment