Repository: incubator-atlas Updated Branches: refs/heads/master 27a39063d -> 0fad1ed2c
ATLAS-211 UI: UI Facelift (anilsg 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/0fad1ed2 Tree: http://git-wip-us.apache.org/repos/asf/incubator-atlas/tree/0fad1ed2 Diff: http://git-wip-us.apache.org/repos/asf/incubator-atlas/diff/0fad1ed2 Branch: refs/heads/master Commit: 0fad1ed2c88679a1e5afc95feb5c719508ba4b80 Parents: 27a3906 Author: Suma Shivaprasad <[email protected]> Authored: Fri Nov 6 14:37:41 2015 +0530 Committer: Suma Shivaprasad <[email protected]> Committed: Fri Nov 6 14:37:41 2015 +0530 ---------------------------------------------------------------------- dashboard/public/css/common.css | 245 ++++++++++++++++++- dashboard/public/css/details.css | 45 ++++ dashboard/public/css/lineage.css | 10 + dashboard/public/css/tags.css | 69 +++++- dashboard/public/img/addTag.png | Bin 0 -> 724 bytes dashboard/public/img/logo-green.png | Bin 0 -> 7271 bytes dashboard/public/index.html | 31 +-- .../public/modules/details/detailsController.js | 16 +- .../public/modules/details/detailsResource.js | 4 + .../public/modules/details/views/details.html | 52 +++- .../public/modules/details/views/schema.html | 4 +- dashboard/public/modules/home/views/header.html | 18 +- .../modules/lineage/views/lineage_io.html | 2 +- .../modules/navigation/views/navigation.html | 4 +- .../public/modules/search/searchController.js | 63 +++-- dashboard/public/modules/search/searchRoutes.js | 18 ++ .../public/modules/search/views/search.html | 140 +++++++---- .../tags/definition/definitionTagsController.js | 9 +- .../modules/tags/definition/views/add.html | 233 +++++++++--------- .../tags/instance/createTagController.js | 2 +- .../tags/instance/instanceTagsController.js | 36 ++- .../modules/tags/instance/views/createTag.html | 6 +- .../modules/tags/instance/views/tags.html | 17 +- release-log.txt | 1 + 24 files changed, 784 insertions(+), 241 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/0fad1ed2/dashboard/public/css/common.css ---------------------------------------------------------------------- diff --git a/dashboard/public/css/common.css b/dashboard/public/css/common.css index dbb0a5e..7f55c0c 100644 --- a/dashboard/public/css/common.css +++ b/dashboard/public/css/common.css @@ -25,7 +25,19 @@ div.separator { padding-top: 10px; padding-bottom: 10px; } - +.breadcrumb{ + padding: 8px !important; + margin-bottom: 10px !important; + border-radius: 0 !important; + background-color: #f5f5f5 !important; + border: 1px solid #e3e3e3; +} +.pointer{ + cursor: pointer; +} +.alert{ + border-radius: 0 !important; +} span.separator { display: block; position: absolute; @@ -44,6 +56,9 @@ hr.separator { margin-bottom: 0px !important; } +.popover{ + max-width: none !important; +} .pointer { cursor: pointer; } @@ -57,22 +72,67 @@ hr.separator { color: #999999; padding-left: 14px; } - +.mB20{ + margin-bottom: 20px; +} +.padding0{ + padding: 0 !important; +} +.paddingR0{ + padding-right: 0 !important; +} /* Header background */ header.navbar-top { - background-color: #fafafa; - border-bottom: solid 4px #5cbb5a; - margin-bottom: 0px; + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#555555), to(#333333)); + background-image: -webkit-linear-gradient(top, #555555, #333333); + background-image: -o-linear-gradient(top, #555555, #333333); + background-image: linear-gradient(to bottom, #555555, #333333); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr=#555555, endColorstr=#333333); + -webkit-box-shadow: inset 0 0 0 rgba(0, 0, 0, 0.1), 0 1px 10px rgba(0, 0, 0, 0.1); + -moz-box-shadow: inset 0 0 0 rgba(0, 0, 0, 0.1), 0 1px 10px rgba(0, 0, 0, 0.1); + box-shadow: inset 0 0 0 rgba(0, 0, 0, 0.1), 0 1px 10px rgba(0, 0, 0, 0.1); + max-height: 40px; + min-height: 40px; } -header .container { - padding: 12px; + +header a.mainLogo{ + color: #ffffff; + font-size: 16px; + line-height: 40px; + padding: 2px 5px 0 15px; + text-shadow: 0 1px 0 #555555; +} +header a.mainLogo:hover,header a.mainLogo:focus{ + text-decoration: none; } +header ul.menuBar li a{ + line-height: 10px; + color: #c3c3c3; +} +header ul.menuBar li a>i { + margin-right: 3px; + font-size: 12px; +} +header ul.menuBar li a:hover{ + color: #fff; + background: transparent; +} +header ul.menuBar li a:focus{ + background: transparent; +} +header ul.menuBar li.active a{ + color: #333333; + background-color: #ffffff; + -webkit-box-shadow: inset 0 3px 8px rgba(0, 0, 0, 0.125); + -moz-box-shadow: inset 0 3px 8px rgba(0, 0, 0, 0.125); + box-shadow: inset 0 3px 8px rgba(0, 0, 0, 0.125); +} /* Footer */ footer.navbar-bottom { background-color: #fafafa; - border-top: solid 4px #5cbb5a; + border-top: solid 4px #444; } footer.navbar-bottom p { @@ -85,9 +145,118 @@ footer.navbar-bottom img { margin-top: -21px; } -.searchresults { - border: 1px solid #ddd; - padding: 10px; +/*======================================================================================= +Search Bar design +=======================================================================================*/ +.mainSearch input{ + height: 50px; + border-radius: 0px; + border: 1px solid #e3e3e3; + color: #414141; + border-top-right-radius: 0px; + border-bottom-right-radius: 0px; + box-shadow: none; +} +.mainSearch .input-group-btn button{ + border-radius: 0; + border-radius: 0; + padding: 14px 20px; +} + +/*======================================================================================= +Tags on Home Page design +=======================================================================================*/ +.mainTags{ + min-height: 20px; + margin-bottom: 20px; + background-color: #f5f5f5; + border: 1px solid #e3e3e3; + -webkit-border-radius: 0px; + -moz-border-radius: 0px; + border-radius: 0px; +} +.mainTags a{ + background: transparent; + border: none; + padding:5px 10px; + text-shadow: 0 1px 0 rgba(255, 255, 255, 0.5); + color: #0088cc !important; + border-radius: 0 !important; +} +.mainTags a:hover{ + color: #005580 !important; + background: #eeeeee !important; +} +.mainTags h4{ + padding:0 10px; +} +.mainTags i{ + font-size: 12px; + margin-right: 3px; +} +.mainTags .list-group-item.limitSize{ + overflow: hidden; + text-overflow: ellipsis; + -o-text-overflow: ellipsis; + white-space: nowrap; + text-transform: capitalize;y +} + +/*======================================================================================= +Search Bar design +=======================================================================================*/ +.mainSearch input{ + height: 50px; + border-radius: 2px; + border: 1px solid #e3e3e3; + color: #414141; + border-top-right-radius: 0px; + border-bottom-right-radius: 0px; + box-shadow: none; +} +.mainSearch .input-group-btn button{ + border-top-left-radius: 0; + border-bottom-left-radius: 0; + padding: 14px 20px; +} +.breakword{ + word-wrap: break-word; +} +/*======================================================================================= +Tags on Home Page design +=======================================================================================*/ +.mainTags{ + min-height: 20px; + margin-bottom: 20px; + background-color: #f5f5f5; + border: 1px solid #e3e3e3; + -webkit-border-radius: 0px; + -moz-border-radius: 0px; + border-radius: 0px; +} +.mainTags a{ + background: transparent; + border: none; + padding:5px 10px; + text-shadow: 0 1px 0 rgba(255, 255, 255, 0.5); + color: #0088cc !important; + border-radius: 0 !important; +} +.mainTags a:hover{ + color: #005580 !important; + background: #eeeeee !important; +} +.mainTags h4{ + padding:0 10px; +} +.mainTags i{ + font-size: 12px; + margin-right: 3px; +} + +.pdLft15px +{ + padding-left: 15px; } .mt10px { @@ -98,6 +267,10 @@ footer.navbar-bottom img { margin-top: 20px; } +/*.searchresults { + border: 1px solid #ddd; + padding: 10px; +} .searchresults:first-child { border-top-right-radius: 4px; border-top-left-radius: 4px; @@ -119,7 +292,7 @@ footer.navbar-bottom img { height: auto; min-height: 0; padding: 5px 5px 5px 0; -} +}*/ .search-spinner { text-align: center; } @@ -133,3 +306,51 @@ footer.navbar-bottom img { border: 1px solid #CCCCCC; padding: 5px; } + +.wordBreak { + word-break: break-word; +} + +.tabsearchanchor { + max-width: 100px; + display: list-item; + overflow: hidden; + text-overflow: ellipsis; + -o-text-overflow: ellipsis; + white-space: nowrap; + text-transform: capitalize; + float: left; + + background: lightblue !important; + color: black !important; + margin: 4px !important; + padding-left: 7px !important; + padding-right: 7px !important; +} + +.tabsearchResult { + max-width: 500px; + display: list-item; + overflow: hidden; + text-overflow: ellipsis; + -o-text-overflow: ellipsis; + white-space: nowrap; + text-transform: capitalize; +} +.searchResultCount { + max-width: 500px; + display: list-item; + overflow: hidden; + text-overflow: ellipsis; + -o-text-overflow: ellipsis; + text-transform: capitalize; +} + +.maxwidth125px { + max-width: 125px !important; +} + +.anchorAbsolute { + position: absolute; + right: 4px; +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/0fad1ed2/dashboard/public/css/details.css ---------------------------------------------------------------------- diff --git a/dashboard/public/css/details.css b/dashboard/public/css/details.css index 6c62bcf..f3100cc 100644 --- a/dashboard/public/css/details.css +++ b/dashboard/public/css/details.css @@ -19,3 +19,48 @@ .tab-content .table-bordered { border-top: none; } + +.detailsPage .nav-tabs>li.active>a, +.detailsPage .nav-tabs>li.active>a:focus, +.detailsPage .nav-tabs>li.active>a:hover, +.detailsPage .nav-tabs>li>a:hover { + border-radius: 0; +} +.detailsPage .nav-tabs>li.active>a, +.detailsPage .nav-tabs>li.active>a:focus{ + border-radius: 0; + background: #F8F8F8; +} + +.detailsPage .nav-tabs>li>a { + margin-right: 0px; + +} + +.detailsPage .table>thead:first-child>tr:first-child>th { + border-bottom-width: 1px; +} +.detailsPage .table td{ + padding-left: 15px; +} +.detailsPage .table tr:nth-child(even) td{ + padding-left: 15px; + background: #f9f9f9; +} +.detailsPage .table tr td:first-child{ + font-weight: bold; +} +.detailsPage .table th{ + padding-left: 15px; + background: #f8f8f8; +} +.detailsPage .lineage{ + position: absolute; + width: 100%; + margin-top: 10px; + text-align: center; + z-index: -1; +} +.detailsPage .black{ + color: #555; +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/0fad1ed2/dashboard/public/css/lineage.css ---------------------------------------------------------------------- diff --git a/dashboard/public/css/lineage.css b/dashboard/public/css/lineage.css index fddc0b0..d700e34 100644 --- a/dashboard/public/css/lineage.css +++ b/dashboard/public/css/lineage.css @@ -74,6 +74,16 @@ div.lineage { border-top: none;*/ } +.lineage-viz button{ + margin: 5px; + border-radius: 2px +} /*.images {*/ /*background-image: url("../img/process.png");*/ /*}â*/ + + +.alignLineage{ + text-align: center; + margin-top: 100px; +} http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/0fad1ed2/dashboard/public/css/tags.css ---------------------------------------------------------------------- diff --git a/dashboard/public/css/tags.css b/dashboard/public/css/tags.css index 21aa89d..3078d3d 100644 --- a/dashboard/public/css/tags.css +++ b/dashboard/public/css/tags.css @@ -17,7 +17,56 @@ */ .add-tag { - text-decoration: underline; + margin-top: -7px; +} +.inputs input{ + height: 50px; + border-radius: 0px; + border: 1px solid #e3e3e3; + color: #414141; + box-shadow: none; +} +.inputs .control-label{ + padding: 15px; + padding-top: 15px !important; +} +.inputs button.addAttr, .inputs button.saveAttr{ + height: 40px; + border-radius: 4px; + border: 1px solid #FFFFFF; + color: #fff; + text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); + font-weight: bold; +} +.inputs button.addAttr{ + background-color: #ff8e00; +} +.inputs pre{ + border: 0; + border-top: 1px solid #ddd; + border-radius: 0; + margin-bottom: 0; + background-color: #dff0d8; + border-color: #d6e9c6; +} +.inputs button.remove{ + position: absolute; + right: 28px; + bottom: 12px; + color: #FFFFFF; + border: 0; + border-radius: 4px; + background-color: #a94442; +} +.appForm .panel{ + border-radius: 0 !important; +} +.appForm .panel-footer{ + margin-bottom: 0; +} + +.appForm .panel-body{ + padding-bottom: 0; } .input-spacing{ @@ -46,6 +95,22 @@ display: inline; line-height: 30px; border:none; - padding: 0px; + padding: 2px; background-color: inherit; + padding-right: 20px !important; +} +.addTag{ + text-align: center; +} +.addTag img{ + cursor: pointer; +} +.searchResults td{ + border: 0; +} +.tagalign{ + margin-top: 14px; +} +.tagsAdded{ + display: inline; } \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/0fad1ed2/dashboard/public/img/addTag.png ---------------------------------------------------------------------- diff --git a/dashboard/public/img/addTag.png b/dashboard/public/img/addTag.png new file mode 100644 index 0000000..5b012d5 Binary files /dev/null and b/dashboard/public/img/addTag.png differ http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/0fad1ed2/dashboard/public/img/logo-green.png ---------------------------------------------------------------------- diff --git a/dashboard/public/img/logo-green.png b/dashboard/public/img/logo-green.png new file mode 100644 index 0000000..fc3f234 Binary files /dev/null and b/dashboard/public/img/logo-green.png differ http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/0fad1ed2/dashboard/public/index.html ---------------------------------------------------------------------- diff --git a/dashboard/public/index.html b/dashboard/public/index.html index 64c8f58..d9b09f9 100644 --- a/dashboard/public/index.html +++ b/dashboard/public/index.html @@ -27,7 +27,7 @@ <meta http-equiv="Content-type" content="text/html;charset=UTF-8"> - <link href="/img/favicon.ico" rel="shortcut icon" type="image/x-icon"> + <link href="img/favicon.ico" rel="shortcut icon" type="image/x-icon"> <link rel="stylesheet" href="/lib/font-awesome/css/font-awesome.min.css"> <link rel="stylesheet" href="/css/sticky-footer-navbar.css"> @@ -35,10 +35,11 @@ <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="/lib/bootstrap/dist/css/bootstrap.css"> + <link rel="stylesheet" href="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/css/bootstrap.min.css"> </head> +<link href="img/favicon.ico" rel="shortcut icon" type="image/x-icon"> <body> <header class="navbar navbar-static-top navbar-top" data-role="navigation"> <div class="container" data-ng-include="'/modules/home/views/header.html'"></div> @@ -49,24 +50,24 @@ </div> <footer class="footer navbar-bottom"> <div class="container"> - <!--<p align="right">Powered by<img src="modules/home/img/logo-green.png"></p>--> + <p align="right">Powered by<img src="../img/logo-green.png"></p> </div> </footer> -<script src="/lib/jquery/dist/jquery.js"></script> -<script src="/lib/angular/angular.js"></script> -<script src="/lib/bootstrap/dist/js/bootstrap.js"></script> -<script src="/lib/angular-bootstrap/ui-bootstrap-tpls.js"></script> -<script src="/lib/angular-cookies/angular-cookies.js"></script> -<script src="/lib/angular-resource/angular-resource.js"></script> -<script src="/lib/angular-route/angular-route.js"></script> -<script src="/lib/angular-sanitize/angular-sanitize.js"></script> -<script src="/lib/angular-ui-router/release/angular-ui-router.js"></script> -<script src="/lib/angular-ui-utils/ui-utils.js"></script> -<script src="/lib/lodash/lodash.js"></script> +<script src="lib/jquery/dist/jquery.js"></script> +<script src="lib/angular/angular.js"></script> +<script src="lib/bootstrap/dist/js/bootstrap.js"></script> +<script src="lib/angular-bootstrap/ui-bootstrap-tpls.js"></script> +<script src="lib/angular-cookies/angular-cookies.js"></script> +<script src="lib/angular-resource/angular-resource.js"></script> +<script src="lib/angular-route/angular-route.js"></script> +<script src="lib/angular-sanitize/angular-sanitize.js"></script> +<script src="lib/angular-ui-router/release/angular-ui-router.js"></script> +<script src="lib/angular-ui-utils/ui-utils.js"></script> +<script src="lib/lodash/lodash.js"></script> <script src="/lib/d3/d3.js"></script> <script src="/lib/d3-tip/index.js"></script> -<script src="/js/app.min.js"></script> +<script src="js/app.min.js"></script> </body> </html> \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/0fad1ed2/dashboard/public/modules/details/detailsController.js ---------------------------------------------------------------------- diff --git a/dashboard/public/modules/details/detailsController.js b/dashboard/public/modules/details/detailsController.js index 538d262..ddd2a11 100644 --- a/dashboard/public/modules/details/detailsController.js +++ b/dashboard/public/modules/details/detailsController.js @@ -17,8 +17,8 @@ */ 'use strict'; -angular.module('dgc.details').controller('DetailsController', ['$window', '$scope', '$stateParams', 'DetailsResource', - function($window, $scope, $stateParams, DetailsResource) { +angular.module('dgc.details').controller('DetailsController', ['$window', '$scope', '$state', '$stateParams', 'DetailsResource', + function($window, $scope, $state, $stateParams, DetailsResource) { $scope.tableName = false; $scope.isTable = false; @@ -27,15 +27,17 @@ angular.module('dgc.details').controller('DetailsController', ['$window', '$scop id: $stateParams.id }, function(data) { $scope.details = data; + console.log(data); $scope.schemas = data; $scope.tableName = data.values.name; - $scope.isTable = data.typeName === 'Table'; + $scope.isTable = (typeof data.typeName != 'undefined' && data.typeName.toLowerCase().indexOf('table') != -1) ? true : false; $scope.onActivate('io'); }); $scope.isNumber = angular.isNumber; - + $scope.isObject = angular.isObject; $scope.isString = angular.isString; + $scope.isArray = angular.isArray; $scope.onActivate = function tabActivate(tabname) { $scope.$broadcast('render-lineage', { type: tabname, @@ -43,6 +45,12 @@ angular.module('dgc.details').controller('DetailsController', ['$window', '$scop }); }; + $scope.goDetails = function(id){ + $state.go("details", { + id: id + }); + }; + $scope.goBack = function() { $window.history.back(); }; http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/0fad1ed2/dashboard/public/modules/details/detailsResource.js ---------------------------------------------------------------------- diff --git a/dashboard/public/modules/details/detailsResource.js b/dashboard/public/modules/details/detailsResource.js index a765595..0c28edd 100644 --- a/dashboard/public/modules/details/detailsResource.js +++ b/dashboard/public/modules/details/detailsResource.js @@ -32,6 +32,10 @@ angular.module('dgc.details').factory('DetailsResource', ['$resource', function( saveTag: { method: 'POST', url: '/api/atlas/entity/:id/traits' + }, + detachTag : { + method: 'DELETE', + url: '/api/atlas/entity/:id/traits/:tagName' } }); http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/0fad1ed2/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 f53f94d..c05e222 100644 --- a/dashboard/public/modules/details/views/details.html +++ b/dashboard/public/modules/details/views/details.html @@ -16,14 +16,18 @@ ~ limitations under the License. --> -<div class="row" data-ng-controller="DetailsController"> - <ul class="breadcrumb"> - <li><button class="btn btn-link" data-ng-click="goBack()">Back To Result</button> </li> - </ul> - <div role="tabpanel" class="col-lg-12"> - <h2>Name: {{details.values.name}}</h2> - <h4>Description: {{details.values.description}}</h4> - <h4>Lineage: <ng-include data-table-type="io" src="'/modules/lineage/views/lineage_io.html'"/></h4> +<div class="row detailsPage" data-ng-controller="DetailsController"> + <div class="col-lg-12 padding0"> + <ul class="breadcrumb"> + <li><button class="btn btn-link" data-ng-click="goBack()"><i class="fa fa-arrow-left"></i> Back To Result</button> </li> + </ul> + </div> + <div role="tabpanel" class="col-lg-12 padding0"> + <div class="mB20"> + <h4><b>Name:</b> <span class="black">{{details.values.name}}</span></h2> + <h4><b>Description:</b> <span class="black">{{details.values.description}}</span></h4> + <h4 data-ng-show="isTable" data-disable="!tableName" data-select="onActivate('io')"><span class="lineage">Lineage</span> <ng-include data-table-type="io" src="'/modules/lineage/views/lineage_io.html'"/></h4> + </div> <tabset> <tab heading="Details"> <table class="table table-bordered"> @@ -35,9 +39,37 @@ </thead> <tbody> <tr data-ng-repeat="(key,value) in details.values" ng-if="value && !(key==='columns') && !(key==='name') && !(key==='description')"> + <td>{{key}}</td> - <td data-ng-if="!isString(value) && !isNumber(value)" data-ng-include="'/modules/details/views/attribute.html'"></td> - <td data-ng-if="isString(value) || isNumber(value)">{{value | date:'medium'}}</td> + + <td data-ng-if="isObject(value) && isString(value.id)" class="pointer"> + <a data-ui-sref="details({id:value.id})">{{ value.id }}</a> + </td> + + <td data-ng-if="isObject(value) && isObject(value.id) && isString(value.id.id)" class="pointer"><a data-ui-sref="details({id:value.id.id})">{{ value.id.id }}</a></td> + + <td data-ng-if="isArray(value)"> + <div class="row" data-ng-repeat="(key1, value1) in value" ng-if="value1"> + <div data-ng-if="isObject(value1)" data-ng-repeat="(key2, value2) in value1" > + <a data-ng-if="isString(value2) && key2 == 'id'" class="pointer pdLft15px" data-ui-sref="details({id:value2})">{{ value2 }}</a> + </div> + </div> + </td> + + <td data-ng-if="!isArray(value) && isObject(value[0]) && isString(value[0].id) && key=='inputTables'" data-ng-click="goDetails(value[0].id)" class="pointer"> + + <div class="row" data-ng-repeat="(key1, value1) in value[0]" ng-if="value1"> + <div class="col-md-6" data-ng-if="!isString(value1)" data-ng-repeat="(key2, value2) in value1 track by $index"></div> + <div data-ng-if="isString(value2)" data-ng-repeat="(key3, value3) in value2"> {{key3}}: {{value3}}</div> + <div class="col-md-6" data-ng-if="isString(value1)"> {{key1}} : {{value1 | date:'medium'}} UTC</div> + </div> + + </td> + + <td data-ng-if="isNumber(value)">{{value * 1000 | date:'yyyy-MM-dd HH:mm:ss'}} UTC</td> + + <td data-ng-if="isString(value)">{{value}}</td> + </tr> </tbody> </table> http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/0fad1ed2/dashboard/public/modules/details/views/schema.html ---------------------------------------------------------------------- diff --git a/dashboard/public/modules/details/views/schema.html b/dashboard/public/modules/details/views/schema.html index 311191c..8426473 100644 --- a/dashboard/public/modules/details/views/schema.html +++ b/dashboard/public/modules/details/views/schema.html @@ -23,8 +23,8 @@ <th>DataType</th> </tr> </thead> - <tbody ng-repeat="colm in details.values.columns"> - <tr> + <tbody> + <tr ng-repeat="colm in details.values.columns"> <td> {{colm.values.name}}</td> <td>{{colm.values.comment}}</td> <td> {{colm.values.dataType}}</td> http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/0fad1ed2/dashboard/public/modules/home/views/header.html ---------------------------------------------------------------------- diff --git a/dashboard/public/modules/home/views/header.html b/dashboard/public/modules/home/views/header.html index 538321d..0d64257 100644 --- a/dashboard/public/modules/home/views/header.html +++ b/dashboard/public/modules/home/views/header.html @@ -24,15 +24,25 @@ <span class="icon-bar"></span> <span class="icon-bar"></span> </button> - <a data-ui-sref="search({ query: '' })" data-ui-sref-active="active"><img src="../img/ApacheAtlasLogo.png" /></a> + <a data-ui-sref="search({ query: '' })" data-ui-sref-active="active" class="mainLogo"> + <!-- <img src="../img/ApacheAtlasLogo.png" /> --> + Apache <b>Atlas</b> + </a> </div> <nav class="collapse navbar-collapse" data-collapse="isCollapsed" data-role="navigation"> - <ul class="navbar-nav nav" data-ng-if="isLoggedIn()"> + <ul class="navbar-nav nav pull-right menuBar" data-ng-if="isLoggedIn()"> + <li data-ui-sref-active="active"> + <a data-ui-sref="search({ query: '' })" class="menulink">Search</a> + </li> <li data-ng-repeat="item in menu" data-ui-sref-active="active"> <a data-ui-sref="{{item.state}}">{{item.title}}</a> </li> + <li data-ui-sref-active="active"> + <a ng-if="!username" class="menulink" href="https://cwiki.apache.org/confluence/display/ATLAS/Atlas+Home" target="_blank">Help</a> + </li> + <li data-ui-sref-active="active"> + <a ng-if="!username" class="menulink" href="javascript:void(0)" ng-click="ShowAbout()">About</a> + </li> </ul> - <a ng-if="!username" class="pull-right menulink" href="https://cwiki.apache.org/confluence/display/ATLAS/Atlas+Home" target="_blank">Help</a> - <a ng-if="!username" class="pull-right menulink" href="javascript:void(0)" ng-click="ShowAbout()">About</a> </nav> </div> \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/0fad1ed2/dashboard/public/modules/lineage/views/lineage_io.html ---------------------------------------------------------------------- diff --git a/dashboard/public/modules/lineage/views/lineage_io.html b/dashboard/public/modules/lineage/views/lineage_io.html index 377f273..58f8f19 100644 --- a/dashboard/public/modules/lineage/views/lineage_io.html +++ b/dashboard/public/modules/lineage/views/lineage_io.html @@ -21,7 +21,7 @@ Reset </button> <div class="graph"> - <h4 data-ng-if="!requested && !lineageData">No lineage data found</h4> + <h4 data-ng-if="!requested && !lineageData" class="alignLineage">No lineage data found</h4> <i data-ng-if="requested" class="fa fa-spinner fa-spin fa-5x"></i> <svg > <g/> http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/0fad1ed2/dashboard/public/modules/navigation/views/navigation.html ---------------------------------------------------------------------- diff --git a/dashboard/public/modules/navigation/views/navigation.html b/dashboard/public/modules/navigation/views/navigation.html index 1c94671..af19294 100644 --- a/dashboard/public/modules/navigation/views/navigation.html +++ b/dashboard/public/modules/navigation/views/navigation.html @@ -16,9 +16,9 @@ ~ limitations under the License. --> -<div data-ng-controller="NavigationController"> +<div data-ng-controller="NavigationController" class="mainTags"> <h4>Tags</h4> <div class="list-group"> - <a ng-repeat="nav in leftnav" ui-sref="search({ query: nav })" class="list-group-item">{{nav}} </a> + <a ng-repeat="nav in leftnav" ui-sref="search({ query: nav })" class="list-group-item limitSize" title="{{nav}}"><i class="fa fa-tag"></i> {{nav}} </a> </div> </div> \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/0fad1ed2/dashboard/public/modules/search/searchController.js ---------------------------------------------------------------------- diff --git a/dashboard/public/modules/search/searchController.js b/dashboard/public/modules/search/searchController.js index 46bc823..2a134d6 100644 --- a/dashboard/public/modules/search/searchController.js +++ b/dashboard/public/modules/search/searchController.js @@ -18,8 +18,8 @@ 'use strict'; -angular.module('dgc.search').controller('SearchController', ['$scope', '$location', '$http', '$state', '$stateParams', 'lodash', 'SearchResource', 'NotificationService', - function($scope, $location, $http, $state, $stateParams, _, SearchResource, NotificationService) { +angular.module('dgc.search').controller('SearchController', ['$scope', '$location', '$http', '$state', '$stateParams', 'lodash', 'SearchResource', 'DetailsResource', 'NotificationService', + function($scope, $location, $http, $state, $stateParams, _, SearchResource, DetailsResource, NotificationService) { $scope.results = []; $scope.resultCount = 0; @@ -28,6 +28,7 @@ angular.module('dgc.search').controller('SearchController', ['$scope', '$locatio $scope.itemsPerPage = 10; $scope.filteredResults = []; $scope.resultRows = []; + $scope.resultType = ''; $scope.setPage = function(pageNo) { $scope.currentPage = pageNo; }; @@ -36,10 +37,9 @@ angular.module('dgc.search').controller('SearchController', ['$scope', '$locatio NotificationService.reset(); $scope.limit = 4; $scope.searchMessage = 'load-gif'; - $scope.$parent.query = query; SearchResource.search({ - query: query + query: encodeURIComponent(query) }, function searchSuccess(response) { $scope.resultCount = response.count; $scope.results = response.results; @@ -47,9 +47,9 @@ angular.module('dgc.search').controller('SearchController', ['$scope', '$locatio $scope.totalItems = $scope.resultCount; $scope.transformedResults = {}; $scope.dataTransitioned = false; - if (response.results.dataType && response.results.dataType.typeName.indexOf('__') === 0) { + if (response.dataType && response.dataType.typeName.indexOf('__') === 0) { $scope.dataTransitioned = true; - var attrDef = response.results.dataType.attributeDefinitions; + var attrDef = response.dataType.attributeDefinitions; angular.forEach(attrDef, function(value) { if (value.dataTypeName === '__IdType') { $scope.searchKey = value.name; @@ -59,15 +59,20 @@ angular.module('dgc.search').controller('SearchController', ['$scope', '$locatio } else { $scope.transformedResults = $scope.resultRows; } - if ($scope.results) + if ($scope.results) { + if (response.dataType) { + $scope.resultType = response.dataType.typeName; + } $scope.searchMessage = $scope.resultCount + ' results matching your search query ' + $scope.query + ' were found'; - else + } else { $scope.searchMessage = '0 results matching your search query ' + $scope.query + ' were found'; + } $scope.$watch('currentPage + itemsPerPage', function() { var begin = (($scope.currentPage - 1) * $scope.itemsPerPage), end = begin + $scope.itemsPerPage; if ($scope.transformedResults) $scope.filteredResults = $scope.transformedResults.slice(begin, end); + console.log($scope.filteredResults); $scope.pageCount = function() { return Math.ceil($scope.resultCount / $scope.itemsPerPage); }; @@ -79,11 +84,6 @@ angular.module('dgc.search').controller('SearchController', ['$scope', '$locatio $scope.searchMessage = '0 results matching your search query ' + $scope.query + ' were found'; NotificationService.error('Error occurred during executing search query, error status code = ' + err.status + ', status text = ' + err.statusText, false); }); - $state.go('search', { - query: query - }, { - location: 'replace' - }); }; $scope.filterResults = function() { @@ -96,6 +96,33 @@ angular.module('dgc.search').controller('SearchController', ['$scope', '$locatio $scope.doToggle = function($event, el) { this.isCollapsed = !el; }; + $scope.openAddTagHome = function(traitId) { + $state.go('addTagHome', { + id: traitId + }); + }; + $scope.isTag = function(typename) { + + if ( typename.indexOf( "__tempQueryResultStruct" ) > -1 ) { + return true; + } else { + return false; + } + }; + $scope.getResourceDataHome = function(event, id) { + DetailsResource.get({ + id: id + }, function(data) { + if ($scope.filteredResults !== null && Object.keys($scope.filteredResults).length > 0) { + angular.forEach($scope.filteredResults, function(obj, trait) { + if ( obj.$id$.id.indexOf( id ) > -1 ) { + $scope.filteredResults[trait].$traits$ = data.traits; + } + }); + } + }); + }; + $scope.$on('refreshResourceData', $scope.getResourceDataHome); $scope.filterSearchResults = function(items) { var res = {}; var count = 0; @@ -110,10 +137,18 @@ angular.module('dgc.search').controller('SearchController', ['$scope', '$locatio return res; }; $scope.searchQuery = $location.search(); - $scope.query = ($location.search()).query; + if ($location.search().query) + $scope.query = decodeURIComponent($location.search().query); if ($scope.query) { $scope.search($scope.query); } + $scope.goSearch = function(query) { + $state.go('search', { + query: encodeURIComponent(query) + }, { + location: 'replace' + }); + }; } ]); http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/0fad1ed2/dashboard/public/modules/search/searchRoutes.js ---------------------------------------------------------------------- diff --git a/dashboard/public/modules/search/searchRoutes.js b/dashboard/public/modules/search/searchRoutes.js index abfe322..c9bf1c0 100644 --- a/dashboard/public/modules/search/searchRoutes.js +++ b/dashboard/public/modules/search/searchRoutes.js @@ -26,5 +26,23 @@ angular.module('dgc.search').config(['$stateProvider', templateUrl: '/modules/search/views/search.html', controller: 'SearchController' }); + $stateProvider.state('addTagHome', { + parent: 'search', + params: { id:null}, + 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/0fad1ed2/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 d5bc6c6..e355644 100644 --- a/dashboard/public/modules/search/views/search.html +++ b/dashboard/public/modules/search/views/search.html @@ -15,53 +15,109 @@ ~ See the License for the specific language governing permissions and ~ limitations under the License. --> +<div class="row"> + <div class="col-lg-2 padding0" data-ng-include="'/modules/navigation/views/navigation.html'"></div> -<div class="row mt20px"> - <form class="col-lg-offset-3 col-lg-9" name="form" novalidate> - <div class="input-group"> - <input type="text" class="form-control" placeholder="Search" data-ng-model="query" required/> - <span class="input-group-btn"> - <button class="btn btn-success" type="submit" data-ng-disabled="form.$invalid" ui-sref="search({ query: query })"> - <i class="glyphicon glyphicon-search white "></i> - </button> - </span> - </div> - <div> - <small class="small-txt">Search: Table, DB, Column</small> - </div> - </form> -</div> -<div class="row mt10px"> - <div class="col-lg-3" data-ng-include="'/modules/navigation/views/navigation.html'"></div> - <div class="col-lg-9"> - <div ng-switch on="searchMessage"> - <div ng-switch-when="load-gif" class="search-spinner"><img src="../img/spinner.gif" align="middle" /></div> - <div ng-switch-default><h4 ng-show="searchMessage">{{searchMessage}}</h4></div> + <div class="col-lg-10 paddingR0"> + <div class="row mainSearch"> + <form class="col-lg-12" name="form" novalidate> + <div class="input-group"> + <input type="text" class="form-control" placeholder="Search: Table, DB, Column" data-ng-model="query" required/> + <span class="input-group-btn"> + <button class="btn btn-success" type="submit" data-ng-disabled="form.$invalid" ng-click="goSearch(query)"> + <i class="glyphicon glyphicon-search white "></i> + </button> + </span> + </div> + </form> </div> - <ul class="list-unstyled" ng-show='resultCount > 0'> - <li ng-repeat="result in filteredResults" class="searchresults"> - <h4><a data-ui-sref="details({id:result['$id$'].id || result.guid})">{{result.name || result.guid}}</a></h4> + <div class="col-lg-12 padding0 searchresults"> + <div ng-switch on="searchMessage"> + <div ng-switch-when="load-gif" class="search-spinner"><img src="../img/spinner.gif" align="middle" /></div> + <div ng-switch-default><h4 ng-show="searchMessage" title="{{searchMessage}}" class="searchResultCount">{{searchMessage}}</h4></div> + </div> + <div class="panel panel-default" ng-show='resultCount > 0'> + <table class="table table-bordered datatable" > + <thead> + <tr ng-if="!isTag(resultType)"> + <th>Name</th> + <th>Description</th> + <th>Owner</th> + <th>Tags</th> + <th>Tools</th> + </tr> + <tr ng-if="isTag(resultType)"> + <th>Name</th> + <th>Type</th> + </tr> + </thead> - <p>{{result.description}}</p> - <span ng-repeat="(key, value) in filterSearchResults(result)"> - <span ng-show="$index <= 3 "><b>{{key}}: </b>{{value}} {{(($index+1 === limit) || $last ) ? '' : ', '}}</span> - </span> + <tbody> + <tr ng-if="!isTag(resultType)" ng-repeat="result in filteredResults"> + <td> + <a data-ui-sref="details({id:result['$id$'].id || result.guid})">{{result.name || result.guid}}</a> + </td> - <div collapse="isCollapsed"> - <span ng-repeat="(key, value) in filterSearchResults(result)"> - <span ng-show="$index > 3"><b>{{key}}: </b>{{value}}{{$last ? '' : ', '}}</span> - </span> - </div> - <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> + <td> + {{result.description}} + </td> + + <td> + <span ng-repeat="(key, value) in filterSearchResults(result)"> + <span ng-if="key =='owner'">{{value}}</span> + </span> + </td> + + <td> + <div ng-show="!dataTransitioned" class="wordBreak"><a class="tabsearchanchor" ng-repeat="(key, value) in result['$traits$']" data-ui-sref="search({query: key})" title="{{key}}">{{key}}<span> </span></a></div> + </td> + <td class="addTag"><img ng-src="img/addTag.png" tooltip="Add Tag" ng-click="openAddTagHome(result['$id$'].id || result.guid)"></td> + </tr> + <tr ng-if="isTag(resultType)" ng-repeat="result in filteredResults"> + <td> + <a data-ui-sref="details({id:result.guid})">{{result.guid}}</a> + </td> + + <td> + {{result.typeName}} + </td> + </tr> + </tbody> + </table> + </div> + + <!-- <ul class="list-unstyled" ng-show='resultCount > 0'> + </tr> + </tbody> + </table> + </div> + + <!-- <ul class="list-unstyled" ng-show='resultCount > 0'> + <li ng-repeat="result in filteredResults" class="searchresults"> + <h4><a data-ui-sref="details({id:result['$id$'].id || result.guid})">{{result.name || result.guid}}</a></h4> + + <p>{{result.description}}</p> + <span ng-repeat="(key, value) in filterSearchResults(result)"> + <span ng-show="$index <= 3 "><b>{{key}}: </b>{{value}} {{(($index+1 === limit) || $last ) ? '' : ', '}}</span> + </span> + + <div collapse="isCollapsed"> + <span ng-repeat="(key, value) in filterSearchResults(result)"> + <span ng-show="$index > 3"><b>{{key}}: </b>{{value}}{{$last ? '' : ', '}}</span> + </span> + </div> + <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}}<span ng-show="!{{$last}}">,</span> </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> --> - </li> - </ul> - <div class="pull-right" ng-show='resultCount > 0'> - <pagination total-items="totalItems" items-per-page="itemsPerPage" ng-model="currentPage" ng-change="pageChanged()"></pagination> - <p> + <div class="pull-right" ng-show='resultCount > 0'> + <pagination total-items="totalItems" items-per-page="itemsPerPage" ng-model="currentPage" ng-change="pageChanged()"></pagination> + <p> + </div> </div> </div> -</div> +</div> \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/0fad1ed2/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 index 099695d..a3e7ce6 100755 --- a/dashboard/public/modules/tags/definition/definitionTagsController.js +++ b/dashboard/public/modules/tags/definition/definitionTagsController.js @@ -31,6 +31,10 @@ angular.module('dgc.tags.definition').controller('DefinitionTagsController', ['$ $scope.tagModel.attributeDefinitions.push(AttributeDefinition.getModel()); }; + $scope.removeAttribute = function(index){ + $scope.tagModel.attributeDefinitions.splice(index,1); + }; + $scope.categoryChange = function CategorySwitched() { $scope.categoryInst = Categories[$scope.category].clearTags(); }; @@ -47,11 +51,6 @@ angular.module('dgc.tags.definition').controller('DefinitionTagsController', ['$ 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() { http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/0fad1ed2/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 index 7f4f82a..dcdd27d 100755 --- a/dashboard/public/modules/tags/definition/views/add.html +++ b/dashboard/public/modules/tags/definition/views/add.html @@ -15,120 +15,125 @@ ~ 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 class="row"> + <div class="appForm col-lg-12" data-ng-controller="DefinitionTagsController"> + <div class="panel panel-default"> + <div class="panel-heading"><h4>Tag Definition</h4></div> + <div class="panel-body inputs"> + <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/> + <button class="remove" ng-click="removeAttribute($index)"><i class="fa fa-times"></i></button> + <!-- <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 addAttr"><i class="fa fa-plus"></i> Add Attribute</button> + </div> + </div> + <div class="form-group panel-footer"> + <div class="col-sm-12 text-right padding0"> + <button type="submit" data-ng-click="save(tagForm)" data-ng-disabled="tagForm.$invalid" class="btn btn-primary saveAttr">Save</button> + </div> + </div> + </fieldset> + </form> + + <!-- <div class="row" data-ng-show="savedTag"> + <pre>{{savedTag | json}}</pre> + </div> --> </div> </div> + </div> </div> \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/0fad1ed2/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 index e6df24c..7cfc392 100644 --- a/dashboard/public/modules/tags/instance/createTagController.js +++ b/dashboard/public/modules/tags/instance/createTagController.js @@ -55,7 +55,7 @@ angular.module('dgc.tags.instance').controller('CreateTagController', ['$scope', DetailsResource.saveTag({ id: $stateParams.id }, requestObject).$promise.then(function() { - $rootScope.$broadcast('refreshResourceData'); + $rootScope.$broadcast('refreshResourceData', $stateParams.id); NotificationService.info('Tag "' + $scope.selectedType + '" has been added to entity', true); $modalInstance.close(true); }).catch(function(err) { http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/0fad1ed2/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 index 663a8d0..81b8299 100644 --- a/dashboard/public/modules/tags/instance/instanceTagsController.js +++ b/dashboard/public/modules/tags/instance/instanceTagsController.js @@ -26,7 +26,21 @@ angular.module('dgc.tags.instance').controller('InstanceTagController', ['$scope DetailsResource.get({ id: $stateParams.id }, function(data) { - $scope.traitsList = data.traitNames; + + angular.forEach(data.traits, function(obj, trait) { + var pair_arr = []; + if (obj.values !== null && Object.keys(obj.values).length > 0) { + angular.forEach(obj.values, function(value, key) { + var pair = key+":"+value; + pair_arr.push(pair); + }); + data.traits[trait].values = pair_arr.join(" | "); + } else { + data.traits[trait].values = 'NA'; + } + }); + + $scope.traitsList = data.traits; }); } $scope.openAddTag = function() { @@ -34,6 +48,26 @@ angular.module('dgc.tags.instance').controller('InstanceTagController', ['$scope id: $scope.id }); }; + + $scope.detachTag = function($event, name) { + var r = confirm("Please confirm delete."); + if (r == true) { + DetailsResource.detachTag({ + id: $stateParams.id, + tagName: name + }, function(data) { + console.log("Detached Tag"); + console.log(data); + + if (data.requestId != undefined && data.GUID == $stateParams.id && data.traitName == name) { + var curent = $event.currentTarget; + curent.parentElement.remove(); + $(".popover").remove(); + } + }); + } + }; + getResourceData(); $scope.$on('refreshResourceData', getResourceData); } http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/0fad1ed2/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 index c67ed38..c5ab5b3 100644 --- a/dashboard/public/modules/tags/instance/views/createTag.html +++ b/dashboard/public/modules/tags/instance/views/createTag.html @@ -20,7 +20,7 @@ </div> <div class="modal-body"> <div class="form-group"> - <div align="center" class="error col-sm-12" ng-if="isError"> + <div align="center" class="error col-sm-12 tabsearchResult pointer" title="{{error}}" ng-if="isError"> {{error}} </div> </div> @@ -39,9 +39,9 @@ <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" + <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> + <option ng-repeat="data in typesList " ng-value="{{data}}" title="{{data}}">{{data}}</option> </select> </div> </div> http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/0fad1ed2/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 index 33904b0..40eccd5 100644 --- a/dashboard/public/modules/tags/instance/views/tags.html +++ b/dashboard/public/modules/tags/instance/views/tags.html @@ -16,13 +16,12 @@ ~ 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 class="container tag-list wordBreak"> + <h4 class="tagsAdded">Tags</h4> + <a ng-click="openAddTag()" href="" class="add-tag btn btn-primary pull-right">Add tag</a> + <ul class="tagalign"> + <li ng-repeat="trait in traitsList" class="list-group-item pointer tabsearchanchor maxwidth125px" popover="{{trait.values}}" popover-title="{{trait.typeName}} Values" popover-trigger="mouseenter" > + {{trait.typeName}} <a href="" class="anchorAbsolute" ng-click="detachTag($event, trait.typeName)"> <i class="fa fa-times"></i> </a> </li> + </ul> + </div> </div> \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/0fad1ed2/release-log.txt ---------------------------------------------------------------------- diff --git a/release-log.txt b/release-log.txt index 1d7fbc5..6e94f95 100644 --- a/release-log.txt +++ b/release-log.txt @@ -10,6 +10,7 @@ ATLAS-54 Rename configs in hive hook (shwethags) ATLAS-3 Mixed Index creation fails with Date types (sumasai via shwethags) ALL CHANGES: +ATLAS-211 UI: UI Facelift(anilsg via sumasai) ATLAS-257 import_hive.sh fails when run under cygwin(dkantor via sumasai) ATLAS-255 Add log level setting for titan in atlas-log4j.xml(ayubkhan via sumasai) ATLAS-246 QuickStart uses integer data type for dates, which causes data loss (dkantor via sumasai)
