gethue
Version:
Hue is an Open source SQL Query Editor for Databases/Warehouses
221 lines (200 loc) • 7.81 kB
JavaScript
// Licensed to Cloudera, Inc. under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. Cloudera, Inc. licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
import $ from 'jquery';
import * as ko from 'knockout';
import componentUtils from './componentUtils';
import huePubSub from '../../utils/huePubSub';
import I18n from '../../utils/i18n';
export const NAME = 'hue-job-browser-links';
const TEMPLATE = `
<div class="btn-group pull-right">
<!-- ko if: window.IS_K8S_ONLY -->
<a class="btn btn-flat" style="padding-right: 4px" title="${I18n(
'Query browser'
)}" data-bind="hueLink: '/jobbrowser#!queries', click: function() { huePubSub.publish('show.jobs.panel', {interface: 'queries'}); huePubSub.publish('hide.jobs.panel'); }">
<span>${I18n('Queries')}</span>
</a>
<!-- /ko -->
<!-- ko if: window.HAS_JOB_BROWSER -->
<!-- ko ifnot: window.IS_K8S_ONLY -->
<a class="btn btn-flat" style="padding-right: 4px" title="${I18n(
'Job browser'
)}" data-bind="hueLink: '/jobbrowser#!jobs', click: function() { huePubSub.publish('hide.jobs.panel'); }">
<span>${I18n(window.IS_MULTICLUSTER_ONLY ? 'Queries' : 'Jobs')}</span>
</a>
<!-- /ko -->
<button class="btn btn-flat btn-toggle-jobs-panel" title="${I18n(
'Jobs preview'
)}" data-bind="click: function() { huePubSub.publish('toggle.jobs.panel'); }, style: {'paddingLeft': jobCount() > 0 ? '0': '4px'}">
<span class="jobs-badge" data-bind="visible: jobCount() > 0, text: jobCount"></span>
<i class="fa fa-tasks"></i>
</button>
<!-- /ko -->
</div>
`;
const JB_CHECK_INTERVAL_IN_MILLIS = 30000;
class JobBrowserPanel {
constructor(params) {
const self = this;
const $container = $('body');
const $jobsPanel = $('#jobsPanel');
const $toggle = $('.btn-toggle-jobs-panel');
const reposition = function () {
$jobsPanel.css('top', $toggle.offset().top + $toggle.height() + 15 + 'px');
$jobsPanel.css('left', $container.offset().left + $container.width() - 630 + 'px');
};
huePubSub.subscribe('hide.jobs.panel', () => {
$(window).off('resize', reposition);
$jobsPanel.hide();
});
huePubSub.subscribe('show.jobs.panel', options => {
if (window.IS_K8S_ONLY) {
huePubSub.publish('context.selector.set.cluster', 'impala');
}
huePubSub.publish('hide.history.panel');
$(window).on('resize', reposition);
reposition();
$jobsPanel.show();
huePubSub.publish('mini.jb.navigate', {
section: options && options.interface ? options.interface : 'jobs',
compute: options && options.compute
});
if (options && options.id) {
huePubSub.publish('mini.jb.open.job', options.id);
}
});
huePubSub.subscribe('toggle.jobs.panel', () => {
if ($jobsPanel.is(':visible')) {
huePubSub.publish('hide.jobs.panel');
} else {
huePubSub.publish('show.jobs.panel');
}
});
self.jobCounts = ko.observable({ yarn: 0, schedules: 0, history: 0 });
self.jobCount = ko.pureComputed(() => {
let total = 0;
Object.keys(self.jobCounts()).forEach(value => {
total += self.jobCounts()[value];
});
return total;
});
self.onePageViewModel = params.onePageViewModel;
let lastYarnBrowserRequest = null;
const checkYarnBrowserStatus = function () {
return $.post('/jobbrowser/jobs/', {
format: 'json',
state: 'running',
user: window.LOGGED_USERNAME
})
.done(data => {
if (data != null && data.jobs != null) {
huePubSub.publish('jobbrowser.data', data.jobs);
self.jobCounts()['yarn'] = data.jobs.length;
self.jobCounts.valueHasMutated();
}
})
.fail(response => {
console.warn(response);
});
};
let lastScheduleBrowserRequest = undefined;
const checkScheduleBrowserStatus = function () {
return $.post(
'/scheduler/api/schedule/list',
{
interface: ko.mapping.toJSON('schedules'),
filters: ko.mapping.toJSON([
{ text: 'user:' + window.LOGGED_USERNAME },
{ time: { time_value: 7, time_unit: 'days' } },
{ states: ['running'] },
{ pagination: { page: 1, offset: 1, limit: 1 } }
])
},
data => {
if (data != null && data.total != null) {
huePubSub.publish('jobbrowser.schedule.data', data.apps);
self.jobCounts()['schedules'] = data.total;
self.jobCounts.valueHasMutated();
}
}
);
};
let lastHistoryBrowserRequest = null;
const checkHistoryBrowserStatus = function () {
return $.post('/jobbrowser/api/jobs/history', {
interface: ko.mapping.toJSON('history'),
filters: ko.mapping.toJSON([
{ states: ['running'] },
{ text: 'user:' + window.LOGGED_USERNAME },
{ time: { time_value: 7, time_unit: 'days' } },
{ pagination: { page: 1, offset: 1, limit: 1 } }
])
})
.done(data => {
if (data != null && data.apps != null) {
self.jobCounts()['history'] = data.apps.length;
self.jobCounts.valueHasMutated();
}
})
.fail(response => {
console.warn(response);
});
};
let checkJobBrowserStatusIdx = -1;
const checkJobBrowserStatus = function () {
lastYarnBrowserRequest = checkYarnBrowserStatus();
if (window.ENABLE_QUERY_SCHEDULING) {
lastScheduleBrowserRequest = checkScheduleBrowserStatus();
}
if (window.ENABLE_HISTORY_V2) {
lastHistoryBrowserRequest = checkHistoryBrowserStatus();
}
$.when
.apply($, [lastYarnBrowserRequest, lastScheduleBrowserRequest, lastHistoryBrowserRequest])
.done(() => {
window.clearTimeout(checkJobBrowserStatusIdx);
checkJobBrowserStatusIdx = window.setTimeout(
checkJobBrowserStatus,
JB_CHECK_INTERVAL_IN_MILLIS
);
})
.fail(() => {
window.clearTimeout(checkJobBrowserStatusIdx);
});
};
// Load the mini jobbrowser
$.ajax({
url: '/jobbrowser/apps?is_embeddable=true&is_mini=true',
beforeSend: function (xhr) {
xhr.setRequestHeader('X-Requested-With', 'Hue');
},
dataType: 'html',
success: function (response) {
params.onePageViewModel.processHeaders(response).done(rawHtml => {
$('#mini_jobbrowser').html(rawHtml);
//ko.bindingHandlers.delayedOverflow.init($('#mini_jobbrowser')[0]);
});
}
});
if (!window.IS_K8S_ONLY) {
checkJobBrowserStatusIdx = window.setTimeout(checkJobBrowserStatus, 10);
huePubSub.subscribe('check.job.browser', checkYarnBrowserStatus);
huePubSub.subscribe('check.schedules.browser', checkScheduleBrowserStatus);
huePubSub.subscribe('check.history.browser', checkHistoryBrowserStatus);
}
}
}
componentUtils.registerComponent(NAME, JobBrowserPanel, TEMPLATE);