Repository: incubator-atlas Updated Branches: refs/heads/master 461a2a4e3 -> 4f61fff2b
ATLAS-188 Provide Ability to Add Tag to Entity (sanjayp via sumasai) Project: http://git-wip-us.apache.org/repos/asf/incubator-atlas/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-atlas/commit/4f61fff2 Tree: http://git-wip-us.apache.org/repos/asf/incubator-atlas/tree/4f61fff2 Diff: http://git-wip-us.apache.org/repos/asf/incubator-atlas/diff/4f61fff2 Branch: refs/heads/master Commit: 4f61fff2b7467d9fa82c2dd7f81624b2ab885281 Parents: 461a2a4 Author: Suma Shivaprasad <[email protected]> Authored: Sat Oct 10 10:04:01 2015 +0530 Committer: Suma Shivaprasad <[email protected]> Committed: Sat Oct 10 10:04:01 2015 +0530 ---------------------------------------------------------------------- dashboard/public/css/details.css | 2 +- dashboard/public/css/tags.css | 51 +++++++ dashboard/public/index.html | 1 + dashboard/public/js/app.js | 4 +- .../public/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 +- .../tags/definition/definitionTagsController.js | 63 +++++++++ .../tags/definition/definitionTagsModule.js | 21 +++ .../tags/definition/tagAttributeDefinition.js | 33 +++++ .../modules/tags/definition/views/add.html | 134 +++++++++++++++++++ .../tags/instance/createTagController.js | 72 ++++++++++ .../tags/instance/instanceTagsController.js | 40 ++++++ .../modules/tags/instance/instanceTagsModule.js | 21 +++ .../modules/tags/instance/views/createTag.html | 42 ++++++ .../modules/tags/instance/views/tags.html | 28 ++++ .../modules/tags/tagAttributeDefinition.js | 33 ----- dashboard/public/modules/tags/tagClasses.js | 11 ++ dashboard/public/modules/tags/tagsController.js | 63 --------- dashboard/public/modules/tags/tagsRoutes.js | 19 ++- dashboard/public/modules/tags/views/add.html | 134 ------------------- 22 files changed, 546 insertions(+), 237 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/4f61fff2/dashboard/public/css/details.css ---------------------------------------------------------------------- diff --git a/dashboard/public/css/details.css b/dashboard/public/css/details.css index 156d5f6..6c62bcf 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 +} http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/4f61fff2/dashboard/public/css/tags.css ---------------------------------------------------------------------- diff --git a/dashboard/public/css/tags.css b/dashboard/public/css/tags.css new file mode 100644 index 0000000..21aa89d --- /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 http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/4f61fff2/dashboard/public/index.html ---------------------------------------------------------------------- diff --git a/dashboard/public/index.html b/dashboard/public/index.html index 5ce839d..4190b5c 100644 --- a/dashboard/public/index.html +++ b/dashboard/public/index.html @@ -34,6 +34,7 @@ <link rel="stylesheet" href="/css/common.css"> <link rel="stylesheet" href="/css/details.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"> </head> http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/4f61fff2/dashboard/public/js/app.js ---------------------------------------------------------------------- diff --git a/dashboard/public/js/app.js b/dashboard/public/js/app.js index 82171c6..3ef1794 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']); http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/4f61fff2/dashboard/public/modules/details/detailsController.js ---------------------------------------------------------------------- diff --git a/dashboard/public/modules/details/detailsController.js b/dashboard/public/modules/details/detailsController.js index c469c37..538d262 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 +]); http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/4f61fff2/dashboard/public/modules/details/detailsResource.js ---------------------------------------------------------------------- diff --git a/dashboard/public/modules/details/detailsResource.js b/dashboard/public/modules/details/detailsResource.js index a559e6f..a765595 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' } }); http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/4f61fff2/dashboard/public/modules/details/views/details.html ---------------------------------------------------------------------- diff --git a/dashboard/public/modules/details/views/details.html b/dashboard/public/modules/details/views/details.html index 26d81ec..f53f94d 100644 --- a/dashboard/public/modules/details/views/details.html +++ b/dashboard/public/modules/details/views/details.html @@ -41,6 +41,7 @@ </tr> </tbody> </table> + <ng-include src="'/modules/tags/instance/views/tags.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> http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/4f61fff2/dashboard/public/modules/search/views/search.html ---------------------------------------------------------------------- diff --git a/dashboard/public/modules/search/views/search.html b/dashboard/public/modules/search/views/search.html index 389364d..d5bc6c6 100644 --- a/dashboard/public/modules/search/views/search.html +++ b/dashboard/public/modules/search/views/search.html @@ -55,7 +55,7 @@ <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> - <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> </ul> http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/4f61fff2/dashboard/public/modules/tags/definition/definitionTagsController.js ---------------------------------------------------------------------- diff --git a/dashboard/public/modules/tags/definition/definitionTagsController.js b/dashboard/public/modules/tags/definition/definitionTagsController.js new file mode 100755 index 0000000..099695d --- /dev/null +++ b/dashboard/public/modules/tags/definition/definitionTagsController.js @@ -0,0 +1,63 @@ +/* + * 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').controller('DefinitionTagsController', ['$scope', '$resource', '$state', '$stateParams', 'lodash', 'AttributeDefinition', 'TagClasses', 'TagsResource', 'NotificationService', + function($scope, $resource, $state, $stateParams, _, AttributeDefinition, Categories, TagsResource, NotificationService) { + $scope.categoryList = Categories; + $scope.category = 'TRAIT'; + $scope.tagModel = { + typeName: null, + attributeDefinitions: [] + }; + + $scope.addAttribute = function AddAttribute() { + $scope.tagModel.attributeDefinitions.push(AttributeDefinition.getModel()); + }; + + $scope.categoryChange = function CategorySwitched() { + $scope.categoryInst = Categories[$scope.category].clearTags(); + }; + + $scope.save = function saveTag(form) { + $scope.savedTag = null; + if (form.$valid) { + $scope.categoryInst = Categories[$scope.category]; + $scope.categoryInst.clearTags().addTag($scope.tagModel); + + NotificationService.reset(); + $scope.saving = true; + + TagsResource.save($scope.categoryInst.toJson()).$promise + .then(function TagCreateSuccess() { + NotificationService.info('"' + $scope.tagModel.typeName + '" has been created', false); + return TagsResource.get({ + id: $scope.tagModel.typeName + }).$promise; + }).then(function TagFound(res) { + $scope.savedTag = JSON.parse(res.definition); + }).catch(function TagCreateFailed(error) { + NotificationService.error(error.data.error, false); + }).finally(function() { + $scope.saving = false; + }); + } + }; + } +]); http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/4f61fff2/dashboard/public/modules/tags/definition/definitionTagsModule.js ---------------------------------------------------------------------- diff --git a/dashboard/public/modules/tags/definition/definitionTagsModule.js b/dashboard/public/modules/tags/definition/definitionTagsModule.js new file mode 100644 index 0000000..eb2059f --- /dev/null +++ b/dashboard/public/modules/tags/definition/definitionTagsModule.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.definition', []); http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/4f61fff2/dashboard/public/modules/tags/definition/tagAttributeDefinition.js ---------------------------------------------------------------------- diff --git a/dashboard/public/modules/tags/definition/tagAttributeDefinition.js b/dashboard/public/modules/tags/definition/tagAttributeDefinition.js new file mode 100644 index 0000000..3c2094d --- /dev/null +++ b/dashboard/public/modules/tags/definition/tagAttributeDefinition.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. + */ + +'use strict'; + +angular.module('dgc.tags.definition').service('AttributeDefinition', function Attribute() { + this.getModel = function getJson() { + return { + name: null, + dataTypeName: 'string', + multiplicity: 'optional', + isComposite: false, + isUnique: false, + isIndexable: true, + reverseAttributeName: null + }; + }; +}); http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/4f61fff2/dashboard/public/modules/tags/definition/views/add.html ---------------------------------------------------------------------- diff --git a/dashboard/public/modules/tags/definition/views/add.html b/dashboard/public/modules/tags/definition/views/add.html new file mode 100755 index 0000000..7f4f82a --- /dev/null +++ b/dashboard/public/modules/tags/definition/views/add.html @@ -0,0 +1,134 @@ +<!-- + ~ 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 class="container"> + <div class="appForm" data-ng-controller="DefinitionTagsController"> + <h4>Tag Definition</h4> + + <form data-name="tagForm" class="form-horizontal" novalidate role="form"> + <fieldset data-ng-disabled="saving"> + + <div class="form-group hide"> + <label for="category" class="col-sm-2 control-label">Category</label> + + <div class="col-sm-10"> + <select class="form-control" id="category" name="category" data-ng-model="category" data-ng-change="categoryChange()" required> + <option value="{{key}}" data-ng-repeat="(key, value) in categoryList" ng-selected="{{key===category}}">{{key}}</option> + </select> + </div> + </div> + <div class="form-group" data-ng-class="{'has-error': tagForm.typeName.$invalid && tagForm.typeName.$dirty}"> + <label for="typeName" class="col-sm-2 control-label">Tag Name</label> + + <div class="col-sm-10"> + <input type="text" class="form-control" name="typeName" id="typeName" placeholder="Tag Name" data-ng-model="tagModel.typeName" required/> + </div> + </div> + <ng-form name="attributeForm"> + <div class="form-group" data-ng-class="{'has-error': attributeForm.name.$invalid && attributeForm.name.$dirty}" + data-ng-repeat-start="attribute in tagModel.attributeDefinitions"> + <label for="attributeId_{{$index}}" class="col-sm-2 control-label">Attribute name</label> + + <div class="col-sm-10"> + <!-- <div class="input-group"> --> + <input type="text" class="form-control" name="name" id="attributeId_{{$index}}" placeholder="Attribute name" data-ng-model="attribute.name" + required/> + <!-- <i class="input-group-addon fa fa-2x" data-ng-class="{'fa-angle-double-down':!attribute.$$show, 'fa-angle-double-up':attribute.$$show}" + data-ng-click="attribute.$$show=!attribute.$$show"></i> --> + <!-- </div> --> + </div> + </div> + <div class="form-group" data-ng-class="{'has-error': attributeForm.name.$invalid && attributeForm.name.$dirty}" data-ng-show="attribute.$$show"> + <label for="attributeDatatype_{{$index}}" class="col-sm-2 control-label">Data Type Name</label> + + <div class="col-sm-10"> + <input type="text" class="form-control" name="name" id="attributeDatatype_{{$index}}" placeholder="dataTypeName" + data-ng-model="attribute.dataTypeName"/> + </div> + </div> + <div class="form-group" data-ng-class="{'has-error': attributeForm.name.$invalid && attributeForm.name.$dirty}" data-ng-show="attribute.$$show"> + <label for="attributeMultiplicity_{{$index}}" class="col-sm-2 control-label">Multiplicity</label> + + <div class="col-sm-10"> + <input type="text" class="form-control" name="name" id="attributeMultiplicity_{{$index}}" placeholder="multiplicity" + data-ng-model="attribute.multiplicity"/> + </div> + </div> + + <div class="form-group" data-ng-class="{'has-error': attributeForm.name.$invalid && attributeForm.name.$dirty}" data-ng-show="attribute.$$show"> + <label for="attributeIscomposite_{{$index}}" class="col-sm-2 control-label">isComposite</label> + + <div class="col-sm-10"> + <span class ="btnToggle"> + <a class="btn-sm " ng-class="{true: 'btn-primary'}[attribute.isComposite]" ng-click="attribute.isComposite = true">true </a> + <a class="btn-sm " ng-class="{false: 'btn-danger'}[attribute.isComposite]" ng-click="attribute.isComposite = false"> false </a> + + </span> + </div> + </div> + <div class="form-group" data-ng-class="{'has-error': attributeForm.name.$invalid && attributeForm.name.$dirty}" data-ng-show="attribute.$$show"> + <label for="attributeIsunique_{{$index}}" class="col-sm-2 control-label">isUnique</label> + + <div class="col-sm-10"> + <span class ="btnToggle"> + <a class="btn-sm " ng-class="{true: 'btn-primary'}[attribute.isUnique]" ng-click="attribute.isUnique = true">true </a> + <a class="btn-sm " ng-class="{false: 'btn-danger'}[attribute.isUnique]" ng-click="attribute.isUnique = false"> false </a> + + </span> + </div> + </div> + <div class="form-group" data-ng-class="{'has-error': attributeForm.name.$invalid && attributeForm.name.$dirty}" data-ng-show="attribute.$$show"> + <label for="attributeIndexable_{{$index}}" class="col-sm-2 control-label">isIndexable</label> + + <div class="col-sm-10"> + <span class ="btnToggle"> + <a class="btn-sm " ng-class="{true: 'btn-primary'}[attribute.isIndexable]" ng-click="attribute.isIndexable = true">true </a> + <a class="btn-sm " ng-class="{false: 'btn-danger'}[attribute.isIndexable]" ng-click="attribute.isIndexable = false"> false </a> + + </span> + </div> + </div> + + + <div class="form-group" data-ng-class="{'has-error': attributeForm.name.$invalid && attributeForm.name.$dirty}" data-ng-show="attribute.$$show" + data-ng-repeat-end> + <label for="attributeReverseName_{{$index}}" class="col-sm-2 control-label">reverseAttributeName</label> + + <div class="col-sm-10"> + <input type="text" class="form-control" name="reverseName" id="attributeReverseName_{{$index}}" placeholder="reverseAttributeName" + data-ng-model="attribute.reverseAttributeName"/> + </div> + </div> + </ng-form> + <div class="form-group text-right"> + <div class="col-sm-offset-2 col-sm-10"> + + <button data-ng-click="addAttribute()" class="btn btn-default">Add Attribute</button> + </div> + </div> + <div class="form-group"> + <div class="col-sm-offset-2 col-sm-10"> + <button type="submit" data-ng-click="save(tagForm)" data-ng-disabled="tagForm.$invalid" class="btn btn-default">Save</button> + </div> + </div> + </fieldset> + </form> + <div class="row" data-ng-show="savedTag"> + <pre>{{savedTag | json}}</pre> + </div> + </div> +</div> \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/4f61fff2/dashboard/public/modules/tags/instance/createTagController.js ---------------------------------------------------------------------- diff --git a/dashboard/public/modules/tags/instance/createTagController.js b/dashboard/public/modules/tags/instance/createTagController.js new file mode 100644 index 0000000..e6df24c --- /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'); + }; + } +]); http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/4f61fff2/dashboard/public/modules/tags/instance/instanceTagsController.js ---------------------------------------------------------------------- diff --git a/dashboard/public/modules/tags/instance/instanceTagsController.js b/dashboard/public/modules/tags/instance/instanceTagsController.js new file mode 100644 index 0000000..663a8d0 --- /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); + } +]); http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/4f61fff2/dashboard/public/modules/tags/instance/instanceTagsModule.js ---------------------------------------------------------------------- diff --git a/dashboard/public/modules/tags/instance/instanceTagsModule.js b/dashboard/public/modules/tags/instance/instanceTagsModule.js new file mode 100644 index 0000000..5f7083d --- /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', []); http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/4f61fff2/dashboard/public/modules/tags/instance/views/createTag.html ---------------------------------------------------------------------- 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 0000000..f4db1ce --- /dev/null +++ b/dashboard/public/modules/tags/instance/views/createTag.html @@ -0,0 +1,42 @@ +<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> http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/4f61fff2/dashboard/public/modules/tags/instance/views/tags.html ---------------------------------------------------------------------- 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 0000000..33904b0 --- /dev/null +++ b/dashboard/public/modules/tags/instance/views/tags.html @@ -0,0 +1,28 @@ +<!-- + ~ 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 http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/4f61fff2/dashboard/public/modules/tags/tagAttributeDefinition.js ---------------------------------------------------------------------- diff --git a/dashboard/public/modules/tags/tagAttributeDefinition.js b/dashboard/public/modules/tags/tagAttributeDefinition.js deleted file mode 100644 index 6b57bd1..0000000 --- a/dashboard/public/modules/tags/tagAttributeDefinition.js +++ /dev/null @@ -1,33 +0,0 @@ -/* - * 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').service('AttributeDefinition', function Attribute() { - this.getModel = function getJson() { - return { - name: null, - dataTypeName: 'string', - multiplicity: 'optional', - isComposite: false, - isUnique: false, - isIndexable: true, - reverseAttributeName: null - }; - }; -}); http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/4f61fff2/dashboard/public/modules/tags/tagClasses.js ---------------------------------------------------------------------- diff --git a/dashboard/public/modules/tags/tagClasses.js b/dashboard/public/modules/tags/tagClasses.js index 81ad77c..416acaa 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) http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/4f61fff2/dashboard/public/modules/tags/tagsController.js ---------------------------------------------------------------------- diff --git a/dashboard/public/modules/tags/tagsController.js b/dashboard/public/modules/tags/tagsController.js deleted file mode 100755 index e548287..0000000 --- a/dashboard/public/modules/tags/tagsController.js +++ /dev/null @@ -1,63 +0,0 @@ -/* - * 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').controller('TagsController', ['$scope', '$resource', '$state', '$stateParams', 'lodash', 'AttributeDefinition', 'TagClasses', 'TagsResource', 'NotificationService', - function($scope, $resource, $state, $stateParams, _, AttributeDefinition, Categories, TagsResource, NotificationService) { - $scope.categoryList = Categories; - $scope.category = 'TRAIT'; - $scope.tagModel = { - typeName: null, - attributeDefinitions: [] - }; - - $scope.addAttribute = function AddAttribute() { - $scope.tagModel.attributeDefinitions.push(AttributeDefinition.getModel()); - }; - - $scope.categoryChange = function CategorySwitched() { - $scope.categoryInst = Categories[$scope.category].clearTags(); - }; - - $scope.save = function saveTag(form) { - $scope.savedTag = null; - if (form.$valid) { - $scope.categoryInst = Categories[$scope.category]; - $scope.categoryInst.clearTags().addTag($scope.tagModel); - - NotificationService.reset(); - $scope.saving = true; - - TagsResource.save($scope.categoryInst.toJson()).$promise - .then(function TagCreateSuccess() { - NotificationService.info('"' + $scope.tagModel.typeName + '" has been created', false); - return TagsResource.get({ - id: $scope.tagModel.typeName - }).$promise; - }).then(function TagFound(res) { - $scope.savedTag = JSON.parse(res.definition); - }).catch(function TagCreateFailed(error) { - NotificationService.error(error.data.error, false); - }).finally(function() { - $scope.saving = false; - }); - } - }; - } -]); http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/4f61fff2/dashboard/public/modules/tags/tagsRoutes.js ---------------------------------------------------------------------- diff --git a/dashboard/public/modules/tags/tagsRoutes.js b/dashboard/public/modules/tags/tagsRoutes.js index a15c3ba..5d768a5 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('^'); + }); + }] }); } ]); http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/4f61fff2/dashboard/public/modules/tags/views/add.html ---------------------------------------------------------------------- diff --git a/dashboard/public/modules/tags/views/add.html b/dashboard/public/modules/tags/views/add.html deleted file mode 100755 index 05ddd89..0000000 --- a/dashboard/public/modules/tags/views/add.html +++ /dev/null @@ -1,134 +0,0 @@ -<!-- - ~ 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 class="container"> - <div class="appForm" data-ng-controller="TagsController"> - <h4>Tag Definition</h4> - - <form data-name="tagForm" class="form-horizontal" novalidate role="form"> - <fieldset data-ng-disabled="saving"> - - <div class="form-group hide"> - <label for="category" class="col-sm-2 control-label">Category</label> - - <div class="col-sm-10"> - <select class="form-control" id="category" name="category" data-ng-model="category" data-ng-change="categoryChange()" required> - <option value="{{key}}" data-ng-repeat="(key, value) in categoryList" ng-selected="{{key===category}}">{{key}}</option> - </select> - </div> - </div> - <div class="form-group" data-ng-class="{'has-error': tagForm.typeName.$invalid && tagForm.typeName.$dirty}"> - <label for="typeName" class="col-sm-2 control-label">Tag Name</label> - - <div class="col-sm-10"> - <input type="text" class="form-control" name="typeName" id="typeName" placeholder="Tag Name" data-ng-model="tagModel.typeName" required/> - </div> - </div> - <ng-form name="attributeForm"> - <div class="form-group" data-ng-class="{'has-error': attributeForm.name.$invalid && attributeForm.name.$dirty}" - data-ng-repeat-start="attribute in tagModel.attributeDefinitions"> - <label for="attributeId_{{$index}}" class="col-sm-2 control-label">Attribute name</label> - - <div class="col-sm-10"> - <!-- <div class="input-group"> --> - <input type="text" class="form-control" name="name" id="attributeId_{{$index}}" placeholder="Attribute name" data-ng-model="attribute.name" - required/> - <!-- <i class="input-group-addon fa fa-2x" data-ng-class="{'fa-angle-double-down':!attribute.$$show, 'fa-angle-double-up':attribute.$$show}" - data-ng-click="attribute.$$show=!attribute.$$show"></i> --> - <!-- </div> --> - </div> - </div> - <div class="form-group" data-ng-class="{'has-error': attributeForm.name.$invalid && attributeForm.name.$dirty}" data-ng-show="attribute.$$show"> - <label for="attributeDatatype_{{$index}}" class="col-sm-2 control-label">Data Type Name</label> - - <div class="col-sm-10"> - <input type="text" class="form-control" name="name" id="attributeDatatype_{{$index}}" placeholder="dataTypeName" - data-ng-model="attribute.dataTypeName"/> - </div> - </div> - <div class="form-group" data-ng-class="{'has-error': attributeForm.name.$invalid && attributeForm.name.$dirty}" data-ng-show="attribute.$$show"> - <label for="attributeMultiplicity_{{$index}}" class="col-sm-2 control-label">Multiplicity</label> - - <div class="col-sm-10"> - <input type="text" class="form-control" name="name" id="attributeMultiplicity_{{$index}}" placeholder="multiplicity" - data-ng-model="attribute.multiplicity"/> - </div> - </div> - - <div class="form-group" data-ng-class="{'has-error': attributeForm.name.$invalid && attributeForm.name.$dirty}" data-ng-show="attribute.$$show"> - <label for="attributeIscomposite_{{$index}}" class="col-sm-2 control-label">isComposite</label> - - <div class="col-sm-10"> - <span class ="btnToggle"> - <a class="btn-sm " ng-class="{true: 'btn-primary'}[attribute.isComposite]" ng-click="attribute.isComposite = true">true </a> - <a class="btn-sm " ng-class="{false: 'btn-danger'}[attribute.isComposite]" ng-click="attribute.isComposite = false"> false </a> - - </span> - </div> - </div> - <div class="form-group" data-ng-class="{'has-error': attributeForm.name.$invalid && attributeForm.name.$dirty}" data-ng-show="attribute.$$show"> - <label for="attributeIsunique_{{$index}}" class="col-sm-2 control-label">isUnique</label> - - <div class="col-sm-10"> - <span class ="btnToggle"> - <a class="btn-sm " ng-class="{true: 'btn-primary'}[attribute.isUnique]" ng-click="attribute.isUnique = true">true </a> - <a class="btn-sm " ng-class="{false: 'btn-danger'}[attribute.isUnique]" ng-click="attribute.isUnique = false"> false </a> - - </span> - </div> - </div> - <div class="form-group" data-ng-class="{'has-error': attributeForm.name.$invalid && attributeForm.name.$dirty}" data-ng-show="attribute.$$show"> - <label for="attributeIndexable_{{$index}}" class="col-sm-2 control-label">isIndexable</label> - - <div class="col-sm-10"> - <span class ="btnToggle"> - <a class="btn-sm " ng-class="{true: 'btn-primary'}[attribute.isIndexable]" ng-click="attribute.isIndexable = true">true </a> - <a class="btn-sm " ng-class="{false: 'btn-danger'}[attribute.isIndexable]" ng-click="attribute.isIndexable = false"> false </a> - - </span> - </div> - </div> - - - <div class="form-group" data-ng-class="{'has-error': attributeForm.name.$invalid && attributeForm.name.$dirty}" data-ng-show="attribute.$$show" - data-ng-repeat-end> - <label for="attributeReverseName_{{$index}}" class="col-sm-2 control-label">reverseAttributeName</label> - - <div class="col-sm-10"> - <input type="text" class="form-control" name="reverseName" id="attributeReverseName_{{$index}}" placeholder="reverseAttributeName" - data-ng-model="attribute.reverseAttributeName"/> - </div> - </div> - </ng-form> - <div class="form-group text-right"> - <div class="col-sm-offset-2 col-sm-10"> - - <button data-ng-click="addAttribute()" class="btn btn-default">Add Attribute</button> - </div> - </div> - <div class="form-group"> - <div class="col-sm-offset-2 col-sm-10"> - <button type="submit" data-ng-click="save(tagForm)" data-ng-disabled="tagForm.$invalid" class="btn btn-default">Save</button> - </div> - </div> - </fieldset> - </form> - <div class="row" data-ng-show="savedTag"> - <pre>{{savedTag | json}}</pre> - </div> - </div> -</div> \ No newline at end of file
