Commit cc2d8860 by Shwetha GS

ATLAS-279 UI not displaying results for certain successful select search queries…

ATLAS-279 UI not displaying results for certain successful select search queries (anilsg via shwethags)
parent 4aef164c
...@@ -28,7 +28,7 @@ ...@@ -28,7 +28,7 @@
``` ```
git clone $git-repo-url git clone $git-repo-url
git checkout dal git checkout master
cd dashboard/v2 cd dashboard/v2
npm install npm install
grunt server grunt server
......
...@@ -354,3 +354,15 @@ Tags on Home Page design ...@@ -354,3 +354,15 @@ Tags on Home Page design
position: absolute; position: absolute;
right: 4px; right: 4px;
} }
.addTag{
margin-top: -35px;
}
.tagAlign{
text-align: center;
}
.h160 {
height: 160px !important;
}
\ No newline at end of file
...@@ -17,7 +17,7 @@ ...@@ -17,7 +17,7 @@
*/ */
.add-tag { .add-tag {
margin-top: -7px; margin-top: -50px;
} }
.inputs input{ .inputs input{
height: 50px; height: 50px;
...@@ -114,3 +114,10 @@ ...@@ -114,3 +114,10 @@
.tagsAdded{ .tagsAdded{
display: inline; display: inline;
} }
.noTags {
font-size: 24px;
font-weight: bold;
text-align: center;
}
}
\ No newline at end of file
...@@ -44,9 +44,10 @@ ...@@ -44,9 +44,10 @@
<header class="navbar navbar-static-top navbar-top" data-role="navigation"> <header class="navbar navbar-static-top navbar-top" data-role="navigation">
<div class="container" data-ng-include="'/modules/home/views/header.html'"></div> <div class="container" data-ng-include="'/modules/home/views/header.html'"></div>
</header> </header>
<div class="content"> <div class="content container">
<div data-ng-include="'/modules/notification/views/notifications.html'"></div> <div data-ng-include="'/modules/notification/views/notifications.html'"></div>
<div data-ui-view class="container"></div> <div class="col-lg-2 padding0" data-ng-include="'/modules/navigation/views/navigation.html'" ng-class="leftNav ? 'hide' : ''" ></div>
<div data-ui-view class="ngView"></div>
</div> </div>
<footer class="footer navbar-bottom"> <footer class="footer navbar-bottom">
<div class="container"> <div class="container">
......
...@@ -15,7 +15,6 @@ ...@@ -15,7 +15,6 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
'use strict'; 'use strict';
angular.module('dgc', ['ngCookies', angular.module('dgc', ['ngCookies',
...@@ -81,4 +80,31 @@ angular.module('dgc').factory('lodash', ['$window', ...@@ -81,4 +80,31 @@ angular.module('dgc').factory('lodash', ['$window',
$rootScope.$on('$stateChangeStart', function() { $rootScope.$on('$stateChangeStart', function() {
d3.selectAll('.d3-tip').remove(); d3.selectAll('.d3-tip').remove();
}); });
$rootScope.updateTags = function(added, obj) {
if (added) {
$rootScope.$broadcast('add_Tag', obj);
}
};
$rootScope.loadTraits = function() {
$rootScope.$broadcast('load_Traits');
};
$rootScope.$on('$stateChangeSuccess', function(evt, to, toParams, from) {
if (from.name !== '' && to.name === 'search' && to.name !== from.name && typeof to.parent === 'undefined' && typeof from.parent === 'undefined') {
$rootScope.loadTraits();
} else if (from.name === '' && to.name === 'search') {
$rootScope.loadTraits();
}
if (typeof to.parent === 'undefined') {
if (to.name !== 'search') {
$rootScope.leftNav = true;
} else {
$rootScope.leftNav = false;
}
}
});
}]); }]);
\ No newline at end of file
...@@ -27,11 +27,11 @@ angular.module('dgc.details').controller('DetailsController', ['$window', '$scop ...@@ -27,11 +27,11 @@ angular.module('dgc.details').controller('DetailsController', ['$window', '$scop
id: $stateParams.id id: $stateParams.id
}, function(data) { }, function(data) {
$scope.details = data; $scope.details = data;
console.log(data);
$scope.schemas = data; $scope.schemas = data;
$scope.tableName = data.values.name; $scope.tableName = data.values.name;
$scope.isTable = (typeof data.typeName !== 'undefined' && data.typeName.toLowerCase().indexOf('table') !== -1) ? true : false; $scope.isTable = (typeof data.typeName !== 'undefined' && data.typeName.toLowerCase().indexOf('table') !== -1) ? true : false;
$scope.onActivate('io'); $scope.onActivate('io');
$scope.isTags = (typeof data.traits !== 'undefined' && typeof data.traits === 'object') ? true : false;
}); });
$scope.isNumber = angular.isNumber; $scope.isNumber = angular.isNumber;
...@@ -45,7 +45,7 @@ angular.module('dgc.details').controller('DetailsController', ['$window', '$scop ...@@ -45,7 +45,7 @@ angular.module('dgc.details').controller('DetailsController', ['$window', '$scop
}); });
}; };
$scope.goDetails = function(id){ $scope.goDetails = function(id) {
$state.go("details", { $state.go("details", {
id: id id: id
}); });
......
...@@ -73,12 +73,13 @@ ...@@ -73,12 +73,13 @@
</tr> </tr>
</tbody> </tbody>
</table> </table>
</tab>
<tab data-heading="Schema" data-ng-if="isTable">
<ng-include src="'/modules/details/views/schema.html'"/>
</tab>
<tab data-heading="Tags" data-ng-if="isTags">
<ng-include src="'/modules/tags/instance/views/tags.html'"/> <ng-include src="'/modules/tags/instance/views/tags.html'"/>
</tab> </tab>
<tab data-heading="Schema" data-ng-if="isTable"><ng-include src="'/modules/details/views/schema.html'"/></tab>
<!-- <tab data-heading="Output" data-ng-if="isTable" data-disable="!tableName" data-select="onActivate('outputs')"><ng-include data-table-type="outputs" src="'/modules/lineage/views/lineage.html'"/></tab>
<tab data-heading="Input" data-ng-if="isTable" data-disable="!tableName" data-select="onActivate('inputs')"><ng-include data-table-type="inputs" src="'/modules/lineage/views/lineage.html'"/></tab>
<tab data-heading="Lineage" data-ng-if="isTable" data-disable="!tableName" data-select="onActivate('io')"><ng-include data-table-type="io" src="'/modules/lineage_io/views/lineage_io.html'"/></tab> -->
</tabset> </tabset>
</div> </div>
</div> </div>
...@@ -24,7 +24,7 @@ ...@@ -24,7 +24,7 @@
<span class="icon-bar"></span> <span class="icon-bar"></span>
<span class="icon-bar"></span> <span class="icon-bar"></span>
</button> </button>
<a data-ui-sref="search({ query: '' })" data-ui-sref-active="active" class="mainLogo"> <a data-ui-sref="search()" data-ui-sref-active="active" class="mainLogo">
<!-- <img src="../img/ApacheAtlasLogo.png" /> --> <!-- <img src="../img/ApacheAtlasLogo.png" /> -->
Apache <b>Atlas</b> Apache <b>Atlas</b>
</a> </a>
...@@ -32,7 +32,7 @@ ...@@ -32,7 +32,7 @@
<nav class="collapse navbar-collapse" data-collapse="isCollapsed" data-role="navigation"> <nav class="collapse navbar-collapse" data-collapse="isCollapsed" data-role="navigation">
<ul class="navbar-nav nav pull-right menuBar" data-ng-if="isLoggedIn()"> <ul class="navbar-nav nav pull-right menuBar" data-ng-if="isLoggedIn()">
<li data-ui-sref-active="active"> <li data-ui-sref-active="active">
<a data-ui-sref="search({ query: '' })" class="menulink">Search</a> <a data-ui-sref="search()" class="menulink">Search</a>
</li> </li>
<li data-ng-repeat="item in menu" data-ui-sref-active="active"> <li data-ng-repeat="item in menu" data-ui-sref-active="active">
<a data-ui-sref="{{item.state}}">{{item.title}}</a> <a data-ui-sref="{{item.state}}">{{item.title}}</a>
......
...@@ -19,7 +19,9 @@ ...@@ -19,7 +19,9 @@
angular.module('dgc.lineage').controller('Lineage_ioController', ['$element', '$scope', '$state', '$stateParams', 'lodash', 'LineageResource', 'd3', 'DetailsResource', '$q', angular.module('dgc.lineage').controller('Lineage_ioController', ['$element', '$scope', '$state', '$stateParams', 'lodash', 'LineageResource', 'd3', 'DetailsResource', '$q',
function($element, $scope, $state, $stateParams, _, LineageResource, d3, DetailsResource, $q) { function($element, $scope, $state, $stateParams, _, LineageResource, d3, DetailsResource, $q) {
var guidsList = []; var guidsList = [],
$$ = angular.element;
function inVertObj(edgs) { function inVertObj(edgs) {
var newEdgsObj = {}; var newEdgsObj = {};
...@@ -130,7 +132,6 @@ angular.module('dgc.lineage').controller('Lineage_ioController', ['$element', '$ ...@@ -130,7 +132,6 @@ angular.module('dgc.lineage').controller('Lineage_ioController', ['$element', '$
if (!$scope.lineageData) { if (!$scope.lineageData) {
if ($scope.requested) { if ($scope.requested) {
if ($scope.type === 'io') { if ($scope.type === 'io') {
console.log($scope.type);
getCombinedLineageData(lineageData, true); getCombinedLineageData(lineageData, true);
} else { } else {
getCombinedLineageData(lineageData, true); getCombinedLineageData(lineageData, true);
...@@ -305,7 +306,13 @@ angular.module('dgc.lineage').controller('Lineage_ioController', ['$element', '$ ...@@ -305,7 +306,13 @@ angular.module('dgc.lineage').controller('Lineage_ioController', ['$element', '$
tooltip = d3.tip() tooltip = d3.tip()
.attr('class', 'd3-tip') .attr('class', 'd3-tip')
.html(function(d) { .html(function(d) {
return '<pre class="alert alert-success">' + d.name + '</pre>'; var toolTip = $$("<pre>").attr("class", "alert alert-success")
.append($$("<p>").html('Name :<b>' + d.name + '</b>'));
if (d.tip && d.tip.trim() !== "") {
toolTip.append($$("<p>").html('Query: ' + d.tip));
}
return toolTip.prop("outerHTML");
}); });
// define the baseSvg, attaching a class for styling and the zoomListener // define the baseSvg, attaching a class for styling and the zoomListener
...@@ -597,7 +604,7 @@ angular.module('dgc.lineage').controller('Lineage_ioController', ['$element', '$ ...@@ -597,7 +604,7 @@ angular.module('dgc.lineage').controller('Lineage_ioController', ['$element', '$
}) })
.text(function(d) { .text(function(d) {
var nameDis = (d.name.length > 15) ? d.name.substring(0, 15) + "..." : d.name; var nameDis = (d.name.length > 15) ? d.name.substring(0, 15) + "..." : d.name;
$(this).attr('title', d.name); $$(this).attr('title', d.name);
return nameDis; return nameDis;
}) })
.style("fill-opacity", 0); .style("fill-opacity", 0);
......
...@@ -15,17 +15,19 @@ ...@@ -15,17 +15,19 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
'use strict'; 'use strict';
angular.module('dgc.navigation').controller('NavigationController', ['$scope', 'NavigationResource', angular.module('dgc.navigation').controller('NavigationController', ['$scope', 'NavigationResource',
function($scope, NavigationResource) { function($scope, NavigationResource) {
$scope.leftnav = NavigationResource.get();
$scope.updateVar = function(event) { $scope.updateVar = function(event) {
$scope.$$prevSibling.query = angular.element(event.target).text(); $scope.$$prevSibling.query = angular.element(event.target).text();
}; };
$scope.$on('load_Traits', function() {
$scope.leftnav = NavigationResource.get();
});
} }
]); ]);
\ No newline at end of file
...@@ -16,7 +16,7 @@ ...@@ -16,7 +16,7 @@
~ limitations under the License. ~ limitations under the License.
--> -->
<div data-ng-controller="NavigationController" class="mainTags"> <div data-ng-controller="NavigationController" class="mainTags leftNavigation">
<h4>Tags</h4> <h4>Tags</h4>
<div class="list-group"> <div class="list-group">
<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> <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>
......
...@@ -15,7 +15,6 @@ ...@@ -15,7 +15,6 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
'use strict'; 'use strict';
angular.module('dgc.search').controller('SearchController', ['$scope', '$location', '$http', '$state', '$stateParams', 'lodash', 'SearchResource', 'DetailsResource', 'NotificationService', angular.module('dgc.search').controller('SearchController', ['$scope', '$location', '$http', '$state', '$stateParams', 'lodash', 'SearchResource', 'DetailsResource', 'NotificationService',
...@@ -29,6 +28,12 @@ angular.module('dgc.search').controller('SearchController', ['$scope', '$locatio ...@@ -29,6 +28,12 @@ angular.module('dgc.search').controller('SearchController', ['$scope', '$locatio
$scope.filteredResults = []; $scope.filteredResults = [];
$scope.resultRows = []; $scope.resultRows = [];
$scope.resultType = ''; $scope.resultType = '';
$scope.isObject = angular.isObject;
$scope.isString = angular.isString;
$scope.isArray = angular.isArray;
$scope.isNumber = angular.isNumber;
$scope.mapAttr = ['guid', 'typeName', 'owner', 'description', 'createTime', '$traits$', '$id$', 'comment', 'dataType'];
$scope.setPage = function(pageNo) { $scope.setPage = function(pageNo) {
$scope.currentPage = pageNo; $scope.currentPage = pageNo;
}; };
...@@ -39,40 +44,67 @@ angular.module('dgc.search').controller('SearchController', ['$scope', '$locatio ...@@ -39,40 +44,67 @@ angular.module('dgc.search').controller('SearchController', ['$scope', '$locatio
$scope.searchMessage = 'load-gif'; $scope.searchMessage = 'load-gif';
$scope.$parent.query = query; $scope.$parent.query = query;
SearchResource.search({ SearchResource.search({
query: encodeURIComponent(query) query: query
}, function searchSuccess(response) { }, function searchSuccess(response) {
$scope.resultCount = response.count; $scope.resultCount = response.count;
$scope.results = response.results; $scope.results = response.results;
$scope.resultRows = $scope.results; $scope.resultRows = ($scope.results && $scope.results.rows) ? $scope.results.rows : $scope.results;
$scope.totalItems = $scope.resultCount; $scope.totalItems = $scope.resultCount;
$scope.transformedResults = {}; $scope.transformedResults = {};
$scope.dataTransitioned = false; $scope.dataTransitioned = false;
if (response.dataType && response.dataType.typeName.indexOf('__') === 0) {
if ($scope.results) {
if (response.dataType) {
$scope.resultType = response.dataType.typeName;
} else if (response.results.dataType) {
$scope.resultType = response.results.dataType.typeName;
} else if (typeof response.dataType === 'undefined') {
$scope.resultType = "full text";
}
$scope.searchMessage = $scope.resultCount + ' results matching your search query ' + $scope.query + ' were found';
} else {
$scope.searchMessage = '0 results matching your search query ' + $scope.query + ' were found';
}
if (response.dataType && response.dataType.typeName && response.dataType.typeName.toLowerCase().indexOf('table') === -1) {
$scope.dataTransitioned = true; $scope.dataTransitioned = true;
var attrDef = response.dataType.attributeDefinitions; var attrDef = response.dataType.attributeDefinitions;
if (attrDef.length === 1) {
$scope.searchKey = attrDef[0].name;
} else {
angular.forEach(attrDef, function(value) { angular.forEach(attrDef, function(value) {
if (value.dataTypeName === '__IdType') { if (value.dataTypeName === '__IdType') {
$scope.searchKey = value.name; $scope.searchKey = value.name;
} }
}); });
$scope.transformedResults = $scope.filterResults(); if ($scope.searchKey === undefined || $scope.searchKey === '') {
} else { $scope.searchKey = '';
$scope.transformedResults = $scope.resultRows;
} }
if ($scope.results) {
if (response.dataType) {
$scope.resultType = response.dataType.typeName;
} }
$scope.searchMessage = $scope.resultCount + ' results matching your search query ' + $scope.query + ' were found'; $scope.transformedResults = $scope.filterResults();
} else { $scope.transformedProperties = $scope.filterProperties();
$scope.searchMessage = '0 results matching your search query ' + $scope.query + ' were found';
} else if (typeof response.dataType === 'undefined') {
$scope.dataTransitioned = true;
$scope.searchKey = '';
$scope.transformedResults = $scope.filterResults();
$scope.transformedProperties = $scope.filterProperties();
} else if (response.dataType.typeName && response.dataType.typeName.toLowerCase().indexOf('table') !== -1) {
$scope.searchKey = "Table";
$scope.transformedResults = $scope.resultRows;
} else if (response.results.dataType && response.results.dataType.typeName && response.results.dataType.typeName.toLowerCase().indexOf('table') !== -1) {
$scope.searchKey = "Table";
$scope.transformedResults = $scope.resultRows;
} }
$scope.$watch('currentPage + itemsPerPage', function() { $scope.$watch('currentPage + itemsPerPage', function() {
var begin = (($scope.currentPage - 1) * $scope.itemsPerPage), var begin = (($scope.currentPage - 1) * $scope.itemsPerPage),
end = begin + $scope.itemsPerPage; end = begin + $scope.itemsPerPage;
if ($scope.transformedResults) $scope.filteredResults = $scope.transformedResults.slice(begin, end); if ($scope.transformedResults) {
console.log($scope.filteredResults); $scope.filteredResults = $scope.transformedResults.slice(begin, end);
}
$scope.pageCount = function() { $scope.pageCount = function() {
return Math.ceil($scope.resultCount / $scope.itemsPerPage); return Math.ceil($scope.resultCount / $scope.itemsPerPage);
}; };
...@@ -84,15 +116,73 @@ angular.module('dgc.search').controller('SearchController', ['$scope', '$locatio ...@@ -84,15 +116,73 @@ angular.module('dgc.search').controller('SearchController', ['$scope', '$locatio
$scope.searchMessage = '0 results matching your search query ' + $scope.query + ' were found'; $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); 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() { $scope.filterResults = function() {
var res = []; var res = [];
if ($scope.searchKey !== '') {
angular.forEach($scope.resultRows, function(value) { angular.forEach($scope.resultRows, function(value) {
res.push(value[$scope.searchKey]); res.push(value[$scope.searchKey]);
}); });
} else {
angular.forEach($scope.resultRows, function(value) {
var objVal = {},
curVal = value,
onlyId = false;
if (curVal.name) {
objVal.name = curVal.name;
delete curVal.name;
}
angular.forEach(curVal, function(vl, ky) {
if ($scope.mapAttr.indexOf(ky) !== -1 || ky.indexOf('_col_') !== -1 || ky.toLowerCase().indexOf('name') !== -1) {
if (ky === '$id$') {
objVal.id = curVal[ky].id;
onlyId = true;
} else if (ky === '$traits$') {
objVal[ky] = vl;
objVal.Tools = objVal.id;
onlyId = false;
} else if (ky.indexOf('$') === -1) {
objVal[ky] = vl;
onlyId = false;
}
}
});
if (onlyId) {
objVal.guid = objVal.id;
}
res.push(objVal);
});
}
return res; return res;
}; };
$scope.filterProperties = function() {
var results = $scope.transformedResults,
pro = [];
if (results && results.length > 0) {
var result = results[0];
if (typeof result === 'object') {
angular.forEach(result, function(value, key) {
if (key.indexOf('$typeName$') === -1) {
pro.push(key);
}
});
} else {
pro.push($scope.searchKey);
}
}
return pro;
};
$scope.doToggle = function($event, el) { $scope.doToggle = function($event, el) {
this.isCollapsed = !el; this.isCollapsed = !el;
}; };
...@@ -103,7 +193,7 @@ angular.module('dgc.search').controller('SearchController', ['$scope', '$locatio ...@@ -103,7 +193,7 @@ angular.module('dgc.search').controller('SearchController', ['$scope', '$locatio
}; };
$scope.isTag = function(typename) { $scope.isTag = function(typename) {
if ( typename.indexOf( "__tempQueryResultStruct" ) > -1 ) { if (typename.indexOf("__tempQueryResultStruct") > -1 || $scope.searchKey === '') {
return true; return true;
} else { } else {
return false; return false;
...@@ -115,7 +205,7 @@ angular.module('dgc.search').controller('SearchController', ['$scope', '$locatio ...@@ -115,7 +205,7 @@ angular.module('dgc.search').controller('SearchController', ['$scope', '$locatio
}, function(data) { }, function(data) {
if ($scope.filteredResults !== null && Object.keys($scope.filteredResults).length > 0) { if ($scope.filteredResults !== null && Object.keys($scope.filteredResults).length > 0) {
angular.forEach($scope.filteredResults, function(obj, trait) { angular.forEach($scope.filteredResults, function(obj, trait) {
if ( obj.$id$.id.indexOf( id ) > -1 ) { if ((obj.$id$ && obj.$id$.id.indexOf(id) > -1) || (obj.id && obj.id.indexOf(id) > -1)) {
$scope.filteredResults[trait].$traits$ = data.traits; $scope.filteredResults[trait].$traits$ = data.traits;
} }
}); });
...@@ -137,18 +227,10 @@ angular.module('dgc.search').controller('SearchController', ['$scope', '$locatio ...@@ -137,18 +227,10 @@ angular.module('dgc.search').controller('SearchController', ['$scope', '$locatio
return res; return res;
}; };
$scope.searchQuery = $location.search(); $scope.searchQuery = $location.search();
if ($location.search().query) $scope.query = ($location.search()).query;
$scope.query = decodeURIComponent($location.search().query);
if ($scope.query) { if ($scope.query) {
$scope.search($scope.query); $scope.search($scope.query);
} }
$scope.goSearch = function(query) {
$state.go('search', {
query: encodeURIComponent(query)
}, {
location: 'replace'
});
};
} }
]); ]);
\ No newline at end of file
<!-- <!--
~ Licensed to the Apache Software Foundation (ASF) under one ~ Licensed to the Apache Software Foundation (ASF) under one
~ or more contributor license agreements. See the NOTICE file ~ or more contributor license agreements. See the NOTICE file
...@@ -15,16 +17,14 @@ ...@@ -15,16 +17,14 @@
~ See the License for the specific language governing permissions and ~ See the License for the specific language governing permissions and
~ limitations under the License. ~ limitations under the License.
--> -->
<div class="row"> <div class="col-lg-10 paddingR0">
<div class="col-lg-2 padding0" data-ng-include="'/modules/navigation/views/navigation.html'"></div> <div class="">
<div class="col-lg-10 paddingR0">
<div class="row mainSearch"> <div class="row mainSearch">
<form class="col-lg-12" name="form" novalidate> <form class="col-lg-12" name="form" novalidate>
<div class="input-group"> <div class="input-group">
<input type="text" class="form-control" placeholder="Search: Table, DB, Column" data-ng-model="query" required/> <input type="text" class="form-control" placeholder="Search: Table, DB, Column" data-ng-model="query" required/>
<span class="input-group-btn"> <span class="input-group-btn">
<button class="btn btn-success" type="submit" data-ng-disabled="form.$invalid" ng-click="goSearch(query)"> <button class="btn btn-success" type="submit" data-ng-disabled="form.$invalid" ui-sref="search({ query: query })">
<i class="glyphicon glyphicon-search white "></i> <i class="glyphicon glyphicon-search white "></i>
</button> </button>
</span> </span>
...@@ -34,7 +34,9 @@ ...@@ -34,7 +34,9 @@
<div class="col-lg-12 padding0 searchresults"> <div class="col-lg-12 padding0 searchresults">
<div ng-switch on="searchMessage"> <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-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 ng-switch-default>
<h4 ng-show="searchMessage" title="{{searchMessage}}" class="tabsearchResult">{{searchMessage}}</h4>
</div>
</div> </div>
<div class="panel panel-default" ng-show='resultCount > 0'> <div class="panel panel-default" ng-show='resultCount > 0'>
<table class="table table-bordered datatable" > <table class="table table-bordered datatable" >
...@@ -46,74 +48,55 @@ ...@@ -46,74 +48,55 @@
<th>Tags</th> <th>Tags</th>
<th>Tools</th> <th>Tools</th>
</tr> </tr>
<tr ng-if="isTag(resultType)"> <tr ng-if="isTag(resultType) && transformedProperties != undefined" >
<th>Name</th> <th ng-repeat="prop in transformedProperties" ng-if="prop !== 'id'">
<th>Type</th> {{(prop != '$traits$') ? prop : 'Tags'}}
</th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
<tr ng-if="!isTag(resultType)" ng-repeat="result in filteredResults"> <tr ng-if="!isTag(resultType) && isObject(result)" ng-repeat="result in filteredResults track by $index">
<td> <td>
<a data-ui-sref="details({id:result['$id$'].id || result.guid})">{{result.name || result.guid}}</a> <a data-ui-sref="details({id:result['$id$'].id || result.guid})">{{result.name || result.guid}}</a>
</td> </td>
<td> <td>
{{result.description}} {{result.description}}
</td> </td>
<td> <td>
<span ng-repeat="(key, value) in filterSearchResults(result)"> <span ng-repeat="(key, value) in filterSearchResults(result)">
<span ng-if="key =='owner'">{{value}}</span> <span ng-if="key =='owner'">{{value}}</span>
</span> </span>
</td> </td>
<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> <div id="{{result['$id$'].id}}" 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>
<td class="addTag"><img ng-src="img/addTag.png" tooltip="Add Tag" ng-click="openAddTagHome(result['$id$'].id || result.guid)"></td> <td class="addTag"><img ng-src="img/addTag.png" tooltip="Add Tag" ng-click="openAddTagHome(result['$id$'].id || result.guid)"></td>
</tr> </tr>
<tr ng-if="isTag(resultType)" ng-repeat="result in filteredResults"> <tr ng-if="isTag(resultType)" ng-repeat="result in filteredResults track by $index">
<td> <td data-ng-if="isObject(result) && !isString(result) && res != 'id'" data-ng-repeat="res in transformedProperties track by $index">
<a data-ui-sref="details({id:result.guid})">{{result.guid}}</a>
</td>
<td> <a data-ng-if="res == 'guid'" data-ui-sref="details({id:result[res]})">{{result[res]}}</a>
{{result.typeName}}
</td>
</tr>
</tbody>
</table>
</div>
<!-- <ul class="list-unstyled" ng-show='resultCount > 0'> <span data-ng-if="res != '$traits$' && res != 'Tools' && res != 'guid' && res.toLowerCase().indexOf('name') == -1 && res.toLowerCase().indexOf('time') == -1">{{result[res]}}</span>
</tr>
</tbody>
</table>
</div>
<!-- <ul class="list-unstyled" ng-show='resultCount > 0'> <span data-ng-if="res.toLowerCase().indexOf('time') != -1 && isNumber(result[res])">{{result[res] * 1000 | date:'yyyy-MM-dd HH:mm:ss'}} UTC</span>
<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> <a data-ng-if="res.toLowerCase().indexOf('name') != -1" data-ui-sref="details({id:result['id']|| result['guid']})">{{result[res]}}</a>
<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"> <div data-ng-if="res == '$traits$'" class="wordBreak tags" id="{{result['id']|| result['guid']}}">
<span ng-repeat="(key, value) in filterSearchResults(result)"> <a class="tabsearchanchor" ng-repeat="(key, value) in result[res]" data-ui-sref="search({query: key})" title="{{key}}">{{key}}<span> </span></a>
<span ng-show="$index > 3"><b>{{key}}: </b>{{value}}{{$last ? '' : ', '}}</span>
</span>
</div> </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>
</li>
</ul> -->
<span data-ng-if="res == 'Tools'" class="addTag"> <img ng-src="img/addTag.png" tooltip="Add Tag" ng-click="openAddTagHome(result['id']|| result['guid'])"> </span>
</td>
<td data-ng-if="isString(result) || result == false || result == true">
<a data-ng-if="result.toLowerCase() == 'guid'" data-ui-sref="details({id:result})">{{result}}</a>
<span data-ng-if="result.toLowerCase() != 'guid'">{{result}}</span>
</td>
</tr>
</tbody>
</table>
</div>
<div class="pull-right" ng-show='resultCount > 0'> <div class="pull-right" ng-show='resultCount > 0'>
<pagination total-items="totalItems" items-per-page="itemsPerPage" ng-model="currentPage" ng-change="pageChanged()"></pagination> <pagination total-items="totalItems" items-per-page="itemsPerPage" ng-model="currentPage" ng-change="pageChanged()"></pagination>
<p> <p>
...@@ -121,3 +104,4 @@ ...@@ -121,3 +104,4 @@
</div> </div>
</div> </div>
</div> </div>
...@@ -15,24 +15,25 @@ ...@@ -15,24 +15,25 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
'use strict'; 'use strict';
angular.module('dgc.tags.definition').controller('DefinitionTagsController', ['$scope', '$resource', '$state', '$stateParams', 'lodash', 'AttributeDefinition', 'TagClasses', 'TagsResource', 'NotificationService', angular.module('dgc.tags.definition').controller('DefinitionTagsController', ['$scope', '$resource', '$state', '$stateParams', 'lodash', 'AttributeDefinition', 'TagClasses', 'TagsResource', 'NotificationService', 'NavigationResource',
function($scope, $resource, $state, $stateParams, _, AttributeDefinition, Categories, TagsResource, NotificationService) { function($scope, $resource, $state, $stateParams, _, AttributeDefinition, Categories, TagsResource, NotificationService, NavigationResource) {
$scope.categoryList = Categories; $scope.categoryList = Categories;
$scope.category = 'TRAIT'; $scope.category = 'TRAIT';
$scope.tagModel = { $scope.tagModel = {
typeName: null, typeName: null,
superTypes: [],
attributeDefinitions: [] attributeDefinitions: []
}; };
$scope.typesList = NavigationResource.get();
$scope.addAttribute = function AddAttribute() { $scope.addAttribute = function AddAttribute() {
$scope.tagModel.attributeDefinitions.push(AttributeDefinition.getModel()); $scope.tagModel.attributeDefinitions.push(AttributeDefinition.getModel());
}; };
$scope.removeAttribute = function(index){ $scope.removeAttribute = function(index) {
$scope.tagModel.attributeDefinitions.splice(index,1); $scope.tagModel.attributeDefinitions.splice(index, 1);
}; };
$scope.categoryChange = function CategorySwitched() { $scope.categoryChange = function CategorySwitched() {
...@@ -42,6 +43,7 @@ angular.module('dgc.tags.definition').controller('DefinitionTagsController', ['$ ...@@ -42,6 +43,7 @@ angular.module('dgc.tags.definition').controller('DefinitionTagsController', ['$
$scope.save = function saveTag(form) { $scope.save = function saveTag(form) {
$scope.savedTag = null; $scope.savedTag = null;
if (form.$valid) { if (form.$valid) {
$scope.tagModel.superTypes = $scope.selectedParent;
$scope.categoryInst = Categories[$scope.category]; $scope.categoryInst = Categories[$scope.category];
$scope.categoryInst.clearTags().addTag($scope.tagModel); $scope.categoryInst.clearTags().addTag($scope.tagModel);
......
...@@ -39,6 +39,14 @@ ...@@ -39,6 +39,14 @@
<input type="text" class="form-control" name="typeName" id="typeName" placeholder="Tag Name" data-ng-model="tagModel.typeName" required/> <input type="text" class="form-control" name="typeName" id="typeName" placeholder="Tag Name" data-ng-model="tagModel.typeName" required/>
</div> </div>
</div> </div>
<div class="form-group">
<label class="control-label col-sm-2" for="ParentTag">Parent Tag</label>
<div class="col-sm-4">
<select ng-model="selectedParent" class="form-control h160" id="ParentTag" name="ParentTag" multiple>
<option ng-repeat="data in typesList" title="{{data}}">{{data}}</option>
</select>
</div>
</div>
<ng-form name="attributeForm"> <ng-form name="attributeForm">
<div class="form-group" data-ng-class="{'has-error': attributeForm.name.$invalid && attributeForm.name.$dirty}" <div class="form-group" data-ng-class="{'has-error': attributeForm.name.$invalid && attributeForm.name.$dirty}"
data-ng-repeat-start="attribute in tagModel.attributeDefinitions"> data-ng-repeat-start="attribute in tagModel.attributeDefinitions">
...@@ -55,7 +63,7 @@ ...@@ -55,7 +63,7 @@
</div> </div>
</div> </div>
<div class="form-group" data-ng-class="{'has-error': attributeForm.name.$invalid && attributeForm.name.$dirty}" data-ng-show="attribute.$$show"> <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> <label for="attributeDatatype_{{$index}}" class="col-sm-2 control-label">Data Type </label>
<div class="col-sm-10"> <div class="col-sm-10">
<input type="text" class="form-control" name="name" id="attributeDatatype_{{$index}}" placeholder="dataTypeName" <input type="text" class="form-control" name="name" id="attributeDatatype_{{$index}}" placeholder="dataTypeName"
......
...@@ -15,7 +15,6 @@ ...@@ -15,7 +15,6 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
'use strict'; 'use strict';
angular.module('dgc.tags.instance').controller('CreateTagController', ['$scope', 'DetailsResource', '$modalInstance', 'typesList', 'lodash', 'TagsResource', '$stateParams', '$rootScope', 'TagClasses', 'NotificationService', angular.module('dgc.tags.instance').controller('CreateTagController', ['$scope', 'DetailsResource', '$modalInstance', 'typesList', 'lodash', 'TagsResource', '$stateParams', '$rootScope', 'TagClasses', 'NotificationService',
...@@ -23,29 +22,44 @@ angular.module('dgc.tags.instance').controller('CreateTagController', ['$scope', ...@@ -23,29 +22,44 @@ angular.module('dgc.tags.instance').controller('CreateTagController', ['$scope',
if (typesList) { if (typesList) {
$scope.typesList = typesList; $scope.typesList = typesList;
} }
var $$ = angular.element;
$scope.categoryList = Categories; $scope.categoryList = Categories;
$scope.category = 'TRAIT'; $scope.category = 'TRAIT';
$scope.getAttributeDefinations = function() { $scope.getAttributeDefinations = function() {
$scope.propertiesList = {};
$scope.isRequired = {};
$scope.getAttributeApi($scope.selectedType);
};
$scope.getAttributeApi = function(tagName) {
TagsResource.get({ TagsResource.get({
id: $scope.selectedType id: tagName
}, function(data) { }, function(data) {
var instanceType = Categories[$scope.category].instanceInfo(); var instanceType = Categories[$scope.category].instanceInfo();
if (instanceType) { if (instanceType) {
var traitTypes = angular.fromJson(data.definition)[instanceType][0]; var traitTypes = angular.fromJson(data.definition)[instanceType];
if (traitTypes) {
$scope.propertiesList = {}; for (var t = 0; t < traitTypes.length; t++) {
$scope.isRequired = {}; if (traitTypes[t]) {
_.each(traitTypes.attributeDefinitions, function(value) { for(var indx = 0; indx < traitTypes[t].attributeDefinitions.length; indx++)
$scope.propertiesList[value.name] = ''; {
$scope.isRequired[value.name] = value.isRequired; var attrDefn = traitTypes[t].attributeDefinitions[indx];
}); $scope.propertiesList[attrDefn.name] = '';
$scope.isRequired[attrDefn.name] = attrDefn.isRequired;
} }
} }
if (traitTypes[t].superTypes && traitTypes[t].superTypes.length > 0) {
for (var s = 0; s < traitTypes[t].superTypes.length; s++) {
$scope.getAttributeApi(traitTypes[t].superTypes[s]);
}
}
}
}
}); });
}; };
$scope.ok = function(tagDefinitionform) { $scope.ok = function($event, tagDefinitionform) {
if (tagDefinitionform.$valid) { if (tagDefinitionform.$valid) {
var requestObject = { var requestObject = {
"jsonClass": "org.apache.atlas.typesystem.json.InstanceSerialization$_Struct", "jsonClass": "org.apache.atlas.typesystem.json.InstanceSerialization$_Struct",
...@@ -54,8 +68,14 @@ angular.module('dgc.tags.instance').controller('CreateTagController', ['$scope', ...@@ -54,8 +68,14 @@ angular.module('dgc.tags.instance').controller('CreateTagController', ['$scope',
}; };
DetailsResource.saveTag({ DetailsResource.saveTag({
id: $stateParams.id id: $stateParams.id
}, requestObject).$promise.then(function() { }, requestObject).$promise.then(function(data) {
$rootScope.$broadcast('refreshResourceData', $stateParams.id); if (data.requestId !== undefined && data.GUID === $stateParams.id) {
var tagName = $$("#tagDefinition").val();
$rootScope.updateTags(true, {
added: $scope.selectedType
});
$$("#" + $stateParams.id).append("<a class='tabsearchanchor ng-binding ng-scope' data-ui-sref='search({query: " + tagName + "})' title='" + tagName + "' href='#!/search?query=" + tagName + "'>" + tagName + "<span> </span></a>");
}
NotificationService.info('Tag "' + $scope.selectedType + '" has been added to entity', true); NotificationService.info('Tag "' + $scope.selectedType + '" has been added to entity', true);
$modalInstance.close(true); $modalInstance.close(true);
}).catch(function(err) { }).catch(function(err) {
......
...@@ -15,12 +15,12 @@ ...@@ -15,12 +15,12 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
'use strict'; 'use strict';
angular.module('dgc.tags.instance').controller('InstanceTagController', ['$scope', 'DetailsResource', '$stateParams', '$state', angular.module('dgc.tags.instance').controller('InstanceTagController', ['$scope', 'DetailsResource', '$stateParams', '$state',
function($scope, DetailsResource, $stateParams, $state) { function($scope, DetailsResource, $stateParams, $state) {
$scope.id = $stateParams.id; $scope.id = $stateParams.id;
var $$ = angular.element;
function getResourceData() { function getResourceData() {
DetailsResource.get({ DetailsResource.get({
...@@ -31,7 +31,7 @@ angular.module('dgc.tags.instance').controller('InstanceTagController', ['$scope ...@@ -31,7 +31,7 @@ angular.module('dgc.tags.instance').controller('InstanceTagController', ['$scope
var pair_arr = []; var pair_arr = [];
if (obj.values !== null && Object.keys(obj.values).length > 0) { if (obj.values !== null && Object.keys(obj.values).length > 0) {
angular.forEach(obj.values, function(value, key) { angular.forEach(obj.values, function(value, key) {
var pair = key+":"+value; var pair = key + ":" + value;
pair_arr.push(pair); pair_arr.push(pair);
}); });
data.traits[trait].values = pair_arr.join(" | "); data.traits[trait].values = pair_arr.join(" | ");
...@@ -41,8 +41,24 @@ angular.module('dgc.tags.instance').controller('InstanceTagController', ['$scope ...@@ -41,8 +41,24 @@ angular.module('dgc.tags.instance').controller('InstanceTagController', ['$scope
}); });
$scope.traitsList = data.traits; $scope.traitsList = data.traits;
if ($.isEmptyObject($scope.traitsList)) {
$scope.noTags = true;
}
}); });
} }
$scope.$on('add_Tag', function(evt, obj) {
$scope.traitsList[obj.added] = {
typeName: obj.added
};
if ($.isEmptyObject($scope.traitsList)) {
$scope.noTags = true;
} else {
$scope.noTags = false;
}
});
$scope.openAddTag = function() { $scope.openAddTag = function() {
$state.go('addTag', { $state.go('addTag', {
id: $scope.id id: $scope.id
...@@ -50,22 +66,32 @@ angular.module('dgc.tags.instance').controller('InstanceTagController', ['$scope ...@@ -50,22 +66,32 @@ angular.module('dgc.tags.instance').controller('InstanceTagController', ['$scope
}; };
$scope.detachTag = function($event, name) { $scope.detachTag = function($event, name) {
var r = confirm("Please confirm delete."); $scope.displayName = name;
if (r === true) { $$('#btnDelete').modal().on('click', function(e) {
e.preventDefault();
$$("#myModal").modal();
DetailsResource.detachTag({ DetailsResource.detachTag({
id: $stateParams.id, id: $stateParams.id,
tagName: name tagName: name
}, function(data) { }, function(data) {
console.log("Detached Tag");
console.log(data);
if (data.requestId !== undefined && data.GUID === $stateParams.id && data.traitName === name) { if (data.requestId !== undefined && data.GUID === $stateParams.id && data.traitName === name) {
var curent = $event.currentTarget; $$($event.currentTarget).closest('tr').remove();
curent.parentElement.remove(); delete $scope.traitsList[name];
$(".popover").remove(); if ($.isEmptyObject($scope.traitsList)) {
$scope.noTags = true;
} else {
$scope.noTags = false;
} }
});
} }
});
});
};
$scope.cancel = function() {
$$(".modal-backdrop").remove();
}; };
getResourceData(); getResourceData();
......
...@@ -52,7 +52,7 @@ ...@@ -52,7 +52,7 @@
</div> </div>
</div> </div>
<div class="modal-footer"> <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-success" type="submit" ng-click="ok($event, tagDefinitionform)" ng-disabled="tagDefinitionform.$invalid">Save</button>
<button class="btn btn-warning" type="button" ng-click="cancel()">Cancel</button> <button class="btn btn-warning" type="button" ng-click="cancel()">Cancel</button>
</div> </div>
</form> </form>
......
<!-- <!--
~ Licensed to the Apache Software Foundation (ASF) under one ~ Licensed to the Apache Software Foundation (ASF) under one
~ or more contributor license agreements. See the NOTICE file ~ or more contributor license agreements. See the NOTICE file
...@@ -15,13 +17,47 @@ ...@@ -15,13 +17,47 @@
~ See the License for the specific language governing permissions and ~ See the License for the specific language governing permissions and
~ limitations under the License. ~ limitations under the License.
--> -->
<div data-ng-controller="InstanceTagController"> <div data-ng-controller="InstanceTagController" >
<div class="container tag-list wordBreak"> <div>
<h4 class="tagsAdded">Tags</h4> <a ng-click="openAddTag()" class="add-tag btn btn-primary pull-right">Add Tag</a>
<a ng-click="openAddTag()" href="" class="add-tag btn btn-primary pull-right">Add tag</a> </div>
<ul class="tagalign"> <table class="table table-bordered">
<li ng-repeat="trait in traitsList" class="list-group-item pointer tabsearchanchor maxwidth125px" popover="{{trait.values}}" popover-title="{{trait.typeName}} Values" popover-trigger="mouseenter" > <thead>
{{trait.typeName}} <a href="" class="anchorAbsolute" ng-click="detachTag($event, trait.typeName)"> <i class="fa fa-times"></i> </a> </li> <tr>
</ul> <th>Tag</th>
<th>Tools</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="trait in traitsList" class="pointer" ng-if="!noTags">
<td class="col-lg-11" >
{{trait.typeName}}
</td>
<td class="col-lg-1 tagAlign">
<a href="" class="deleteTag confirm-delete" data-toggle="modal" data-target="#myModal" ><i class="fa fa-trash-o " ng-click="detachTag($event, trait.typeName)"></i></a>
</td>
</tr>
</tbody>
</table>
<!-- Modal -->
<div class="modal fade" id="myModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
<h4 class="modal-title" id="myModalLabel">Are you sure you want to delete ? </h4>
</div>
<div class="modal-body">
<b> Tag : {{displayName}} </b>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal" ng-click="cancel()">Close</button>
<button type="button" id="btnDelete" class="btn btn-primary" data-dismiss="modal">Delete</button>
</div>
</div>
</div>
</div>
<div ng-if="noTags" class="noTags">
No tags to display
</div> </div>
</div> </div>
\ No newline at end of file
...@@ -19,12 +19,12 @@ hive_partition(ClassType) - super types [Referenceable] - attributes [values, ta ...@@ -19,12 +19,12 @@ hive_partition(ClassType) - super types [Referenceable] - attributes [values, ta
hive_process(ClassType) - super types [Process] - attributes [startTime, endTime, userName, operationType, queryText, queryPlan, queryId, queryGraph] hive_process(ClassType) - super types [Process] - attributes [startTime, endTime, userName, operationType, queryText, queryPlan, queryId, queryGraph]
</verbatim> </verbatim>
The entities are created and de-duped using unique qualified name. They provide namespace and can be used for querying/lineage as well. Note that dbName and tableName should be in lower case. clusterName is explained below: The entities are created and de-duped using unique qualified name. They provide namespace and can be used for querying/lineage as well. Note that dbName and tableName should be in lower case. clusterName is explained below.
hive_db - attribute qualifiedName - <dbName>@<clusterName> * hive_db - attribute qualifiedName - <dbName>@<clusterName>
hive_table - attribute name - <dbName>.<tableName>@<clusterName> * hive_table - attribute name - <dbName>.<tableName>@<clusterName>
hive_column - attribute qualifiedName - <dbName>.<tableName>.<columnName>@<clusterName> * hive_column - attribute qualifiedName - <dbName>.<tableName>.<columnName>@<clusterName>
hive_partition - attribute qualifiedName - <dbName>.<tableName>.<partitionValues('-' separated)>@<clusterName> * hive_partition - attribute qualifiedName - <dbName>.<tableName>.<partitionValues('-' separated)>@<clusterName>
hive_process - attribute name - <queryString> - trimmed query string in lower case * hive_process - attribute name - <queryString> - trimmed query string in lower case
---++ Importing Hive Metadata ---++ Importing Hive Metadata
......
...@@ -9,6 +9,7 @@ ATLAS-54 Rename configs in hive hook (shwethags) ...@@ -9,6 +9,7 @@ ATLAS-54 Rename configs in hive hook (shwethags)
ATLAS-3 Mixed Index creation fails with Date types (sumasai via shwethags) ATLAS-3 Mixed Index creation fails with Date types (sumasai via shwethags)
ALL CHANGES: ALL CHANGES:
ATLAS-279 UI not displaying results for certain successful "select" search queries (anilsg via shwethags)
ATLAS-242 The qualified name for hive entities should be backward compatible (shwethags) ATLAS-242 The qualified name for hive entities should be backward compatible (shwethags)
ATLAS-361 Add validation when index backends are switched in ATLAS configuration (sumasai via shwethags) ATLAS-361 Add validation when index backends are switched in ATLAS configuration (sumasai via shwethags)
ATLAS-171 Ability to update type definition(shwethags via sumasai) ATLAS-171 Ability to update type definition(shwethags via sumasai)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment