|
|
@@ -199,44 +199,7 @@ ${ hueIcons.symbols() }
|
|
|
</div>
|
|
|
<!-- /ko -->
|
|
|
|
|
|
- <div class="search-container-top">
|
|
|
- <input placeholder="${ _('Search data and saved documents...') }" type="text"
|
|
|
- data-bind="autocomplete: {
|
|
|
- source: searchAutocompleteSource,
|
|
|
- itemTemplate: 'top-search-autocomp-item',
|
|
|
- noMatchTemplate: 'top-search-autocomp-no-match',
|
|
|
- classPrefix: 'nav-',
|
|
|
- showOnFocus: true,
|
|
|
- closeOnEnter: false,
|
|
|
- onSelect: mainSearchSelect,
|
|
|
- reopenPattern: /.*:$/
|
|
|
- },
|
|
|
- hasFocus: searchHasFocus,
|
|
|
- clearable: { value: searchInput, onClear: function () { searchActive(false); huePubSub.publish('autocomplete.close'); } },
|
|
|
- textInput: searchInput,
|
|
|
- valueUpdate: 'afterkeydown'">
|
|
|
- </div>
|
|
|
-
|
|
|
- <script type="text/html" id="top-search-autocomp-item">
|
|
|
- <a href="javascript:void(0);">
|
|
|
- <div class="nav-autocomplete-item-link">
|
|
|
- <div class="nav-search-result-icon"><i class="fa fa-fw" data-bind="css: icon"></i></div>
|
|
|
- <div class="nav-search-result-text">
|
|
|
- <div class="nav-search-result-header" data-bind="html: label, style: { 'padding-top': description ? 0 : '9px' }"></div>
|
|
|
- <!-- ko if: description -->
|
|
|
- <div class="nav-search-result-description" data-bind="html: description"></div>
|
|
|
- <!-- /ko -->
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- </a>
|
|
|
- </script>
|
|
|
-
|
|
|
- <script type="text/html" id="top-search-autocomp-no-match">
|
|
|
- <div class="nav-autocomplete-item-link" style="height: 30px;">
|
|
|
- <div class="nav-autocomplete-empty">${ _('No match found') }</div>
|
|
|
- </div>
|
|
|
- </script>
|
|
|
-
|
|
|
+ <div class="search-container-top" data-bind="component: 'hue-global-search'"></div>
|
|
|
</div>
|
|
|
|
|
|
<div class="top-nav-right">
|
|
|
@@ -1202,25 +1165,6 @@ ${ smart_unicode(login_modal(request).content) | n,unicode }
|
|
|
|
|
|
var topNavViewModel = (function (onePageViewModel) {
|
|
|
|
|
|
- // TODO: Extract to common module (shared with nav search autocomplete)
|
|
|
- var SEARCH_FACET_ICON = 'fa-tags';
|
|
|
- var SEARCH_TYPE_ICONS = {
|
|
|
- 'DATABASE': 'fa-database',
|
|
|
- 'TABLE': 'fa-table',
|
|
|
- 'VIEW': 'fa-eye',
|
|
|
- 'FIELD': 'fa-columns',
|
|
|
- 'PARTITION': 'fa-th',
|
|
|
- 'SOURCE': 'fa-server',
|
|
|
- 'OPERATION': 'fa-cogs',
|
|
|
- 'OPERATION_EXECUTION': 'fa-cog',
|
|
|
- 'DIRECTORY': 'fa-folder-o',
|
|
|
- 'FILE': 'fa-file-o',
|
|
|
- 'SUB_OPERATION': 'fa-code-fork',
|
|
|
- 'COLLECTION': 'fa-search',
|
|
|
- 'HBASE': 'fa-th-large',
|
|
|
- 'HUE': 'fa-file-o'
|
|
|
- };
|
|
|
-
|
|
|
function TopNavViewModel (onePageViewModel) {
|
|
|
var self = this;
|
|
|
self.onePageViewModel = onePageViewModel;
|
|
|
@@ -1233,11 +1177,6 @@ ${ smart_unicode(login_modal(request).content) | n,unicode }
|
|
|
self.leftNavVisible(false);
|
|
|
});
|
|
|
|
|
|
- self.apiHelper = ApiHelper.getInstance();
|
|
|
- self.searchActive = ko.observable(false);
|
|
|
- self.searchHasFocus = ko.observable(false);
|
|
|
- self.searchInput = ko.observable();
|
|
|
-
|
|
|
self.mainQuickCreateAction = ko.observable();
|
|
|
self.quickCreateActions = ko.observableArray();
|
|
|
|
|
|
@@ -1361,93 +1300,8 @@ ${ smart_unicode(login_modal(request).content) | n,unicode }
|
|
|
}
|
|
|
};
|
|
|
self.cluster = new ClusterPanelViewModel();
|
|
|
-
|
|
|
- self.searchAutocompleteSource = function (request, callback) {
|
|
|
- // TODO: Extract complete contents to common module (shared with nav search autocomplete)
|
|
|
- var facetMatch = request.term.match(/([a-z]+):\s*(\S+)?$/i);
|
|
|
- var isFacet = facetMatch !== null;
|
|
|
- var partialMatch = isFacet ? null : request.term.match(/\S+$/);
|
|
|
- var partial = isFacet && facetMatch[2] ? facetMatch[2] : (partialMatch ? partialMatch[0] : '');
|
|
|
- var beforePartial = request.term.substring(0, request.term.length - partial.length);
|
|
|
-
|
|
|
- self.apiHelper.globalSearchAutocomplete({
|
|
|
- query: request.term,
|
|
|
- successCallback: function (data) {
|
|
|
- var values = [];
|
|
|
- var facetPartialRe = new RegExp(partial.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&"), 'i'); // Protect for 'tags:*axe'
|
|
|
-
|
|
|
- if (typeof data.resultsHuedocuments !== 'undefined') {
|
|
|
- data.resultsHuedocuments.forEach(function (result) {
|
|
|
- values.push({ data: { label: result.hue_name, icon: SEARCH_TYPE_ICONS[result.type], description: result.hue_description, link: result.link }, value: beforePartial + result.originalName });
|
|
|
- });
|
|
|
- }
|
|
|
- if (values.length > 0) {
|
|
|
- values.push({ divider: true });
|
|
|
- }
|
|
|
-
|
|
|
- if (isFacet && typeof data.facets !== 'undefined') { // Is typed facet, e.g. type: type:bla
|
|
|
- var facetInQuery = facetMatch[1];
|
|
|
- if (typeof data.facets[facetInQuery] !== 'undefined') {
|
|
|
- $.map(data.facets[facetInQuery], function (count, value) {
|
|
|
- if (facetPartialRe.test(value)) {
|
|
|
- values.push({ data: { label: facetInQuery + ':' + value, icon: SEARCH_FACET_ICON, description: count }, value: beforePartial + value})
|
|
|
- }
|
|
|
- });
|
|
|
- }
|
|
|
- } else {
|
|
|
- if (typeof data.facets !== 'undefined') {
|
|
|
- Object.keys(data.facets).forEach(function (facet) {
|
|
|
- if (facetPartialRe.test(facet)) {
|
|
|
- if (Object.keys(data.facets[facet]).length > 0) {
|
|
|
- values.push({ data: { label: facet + ':', icon: SEARCH_FACET_ICON, description: $.map(data.facets[facet], function (key, value) { return value + ' (' + key + ')'; }).join(', ') }, value: beforePartial + facet + ':'});
|
|
|
- } else { // Potential facet from the list
|
|
|
- values.push({ data: { label: facet + ':', icon: SEARCH_FACET_ICON, description: '' }, value: beforePartial + facet + ':'});
|
|
|
- }
|
|
|
- } else if (partial.length > 0) {
|
|
|
- Object.keys(data.facets[facet]).forEach(function (facetValue) {
|
|
|
- if (facetValue.indexOf(partial) !== -1) {
|
|
|
- values.push({ data: { label: facet + ':' + facetValue, icon: SEARCH_FACET_ICON, description: facetValue }, value: beforePartial + facet + ':' + facetValue });
|
|
|
- }
|
|
|
- });
|
|
|
- }
|
|
|
- });
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- if (values.length > 0) {
|
|
|
- values.push({ divider: true });
|
|
|
- }
|
|
|
- if (typeof data.results !== 'undefined') {
|
|
|
- data.results.forEach(function (result) {
|
|
|
- values.push({ data: { label: result.hue_name, icon: SEARCH_TYPE_ICONS[result.type], description: result.hue_description }, value: beforePartial + result.originalName });
|
|
|
- });
|
|
|
- }
|
|
|
-
|
|
|
- if (values.length > 0 && values[values.length - 1].divider) {
|
|
|
- values.pop();
|
|
|
- }
|
|
|
- if (values.length === 0) {
|
|
|
- values.push({ noMatch: true });
|
|
|
- }
|
|
|
- callback(values);
|
|
|
- },
|
|
|
- silenceErrors: true,
|
|
|
- errorCallback: function () {
|
|
|
- callback([]);
|
|
|
- }
|
|
|
- });
|
|
|
- };
|
|
|
}
|
|
|
|
|
|
- TopNavViewModel.prototype.mainSearchSelect = function (entry) {
|
|
|
- if (entry.data && entry.data.link) {
|
|
|
- huePubSub.publish('open.link', entry.data.link);
|
|
|
- } else if (!/:\s*$/.test(entry.value)) {
|
|
|
- huePubSub.publish('assist.show.sql');
|
|
|
- huePubSub.publish('assist.db.search', entry.value);
|
|
|
- }
|
|
|
- };
|
|
|
-
|
|
|
var topNavViewModel = new TopNavViewModel(onePageViewModel);
|
|
|
ko.applyBindings(topNavViewModel, $('.top-nav')[0]);
|
|
|
|
|
|
@@ -1628,38 +1482,38 @@ ${ smart_unicode(login_modal(request).content) | n,unicode }
|
|
|
});
|
|
|
|
|
|
tour.addStep('welcome', {
|
|
|
- text: '<b>${ _ko('Welcome to Hue 4!') }</b><br><br>${ _ko('We want to introduce you to the new interface. It takes less than a minute. Ready? ') }',
|
|
|
+ text: '<b>${ _ko('Welcome to Hue 4!') }</b><br><br>${ _ko('We want to introduce you to the new interface. It takes less than a minute. Ready? ') }'
|
|
|
});
|
|
|
|
|
|
tour.addStep('topnav', {
|
|
|
text: '${ _ko('A new nav bar and big blue button!') }<br><br>${ _ko('Open Hue to your favorite app, select other apps from the blue button, do global search, and view notification panels at right.') }',
|
|
|
- attachTo: '.navbar-default bottom',
|
|
|
+ attachTo: '.navbar-default bottom'
|
|
|
});
|
|
|
|
|
|
%if user.is_superuser:
|
|
|
tour.addStep('admin', {
|
|
|
text: '${ _ko('As a superuser, you can check system configuration from the username drop down and install sample data and jobs for your users.') }',
|
|
|
- attachTo: '.top-nav-right .dropdown bottom',
|
|
|
+ attachTo: '.top-nav-right .dropdown bottom'
|
|
|
});
|
|
|
%endif
|
|
|
|
|
|
tour.addStep('leftpanel', {
|
|
|
text: '${ _ko('Discover data sources with the improved data assist panel. Remember to right-click for more!') }',
|
|
|
- attachTo: '.left-panel right',
|
|
|
+ attachTo: '.left-panel right'
|
|
|
});
|
|
|
|
|
|
tour.addStep('pagecontent', {
|
|
|
text: '${ _ko('This is the main attraction, where your selected app runs.') }<br>${ _ko('Hover on the app name to star it as your favorite application.') }',
|
|
|
- attachTo: '.page-content center',
|
|
|
+ attachTo: '.page-content center'
|
|
|
});
|
|
|
|
|
|
tour.addStep('rightpanel', {
|
|
|
text: '${ _ko('Some apps have a right panel with additional information to assist you in your data discovery.') }',
|
|
|
- attachTo: '.right-panel left',
|
|
|
+ attachTo: '.right-panel left'
|
|
|
});
|
|
|
|
|
|
tour.addStep('bye', {
|
|
|
- text: '${ _ko('This ends the tour. To see it again, click Welcome Tour from the username drop down.') }<br><br>${ _ko('And now go ') }<b>${ _ko('Query, Explore, Repeat') }</b>!',
|
|
|
+ text: '${ _ko('This ends the tour. To see it again, click Welcome Tour from the username drop down.') }<br><br>${ _ko('And now go ') }<b>${ _ko('Query, Explore, Repeat') }</b>!'
|
|
|
});
|
|
|
|
|
|
var closeTourOnEsc = function (e) {
|