The open and composable observability and data visualization platform. Visualize metrics, logs, and traces from multiple sources like Prometheus, Loki, Elasticsearch, InfluxDB, Postgres and many more.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
grafana/public/app/features/panel/panel_header.ts

120 lines
2.8 KiB

import { coreModule } from 'app/core/core';
const template = `
<span class="panel-title">
<span class="icon-gf panel-alert-icon"></span>
<span class="panel-title-text">{{ctrl.panel.title | interpolateTemplateVars:this}}</span>
<span class="panel-menu-container dropdown">
<span class="fa fa-caret-down panel-menu-toggle" data-toggle="dropdown"></span>
<ul class="dropdown-menu dropdown-menu--menu panel-menu" role="menu">
</ul>
</span>
8 years ago
<span class="panel-time-info" ng-if="ctrl.timeInfo"><i class="fa fa-clock-o"></i> {{ctrl.timeInfo}}</span>
</span>`;
8 years ago
function renderMenuItem(item, ctrl) {
let html = '';
let listItemClass = '';
8 years ago
if (item.divider) {
return '<li class="divider"></li>';
}
8 years ago
if (item.submenu) {
listItemClass = 'dropdown-submenu';
8 years ago
}
html += `<li class="${listItemClass}"><a `;
if (item.click) {
html += ` ng-click="${item.click}"`;
}
if (item.href) {
html += ` href="${item.href}"`;
}
8 years ago
html += `><i class="${item.icon}"></i>`;
html += `<span class="dropdown-item-text" aria-label="${item.text} panel menu item">${item.text}</span>`;
8 years ago
if (item.shortcut) {
html += `<span class="dropdown-menu-item-shortcut">${item.shortcut}</span>`;
}
html += `</a>`;
if (item.submenu) {
html += '<ul class="dropdown-menu dropdown-menu--menu panel-menu">';
for (const subitem of item.submenu) {
8 years ago
html += renderMenuItem(subitem, ctrl);
}
html += '</ul>';
8 years ago
}
html += `</li>`;
return html;
}
function createMenuTemplate(ctrl) {
let html = '';
8 years ago
for (const item of ctrl.getMenu()) {
8 years ago
html += renderMenuItem(item, ctrl);
}
return html;
}
/** @ngInject */
8 years ago
function panelHeader($compile) {
return {
restrict: 'E',
template: template,
link: (scope, elem, attrs) => {
const menuElem = elem.find('.panel-menu');
8 years ago
let menuScope;
let isDragged;
8 years ago
elem.click(evt => {
const targetClass = evt.target.className;
8 years ago
// remove existing scope
if (menuScope) {
menuScope.$destroy();
}
menuScope = scope.$new();
const menuHtml = createMenuTemplate(scope.ctrl);
8 years ago
menuElem.html(menuHtml);
$compile(menuElem)(menuScope);
if (targetClass.indexOf('panel-title-text') >= 0 || targetClass.indexOf('panel-title') >= 0) {
togglePanelMenu(evt);
}
});
function togglePanelMenu(e) {
if (!isDragged) {
e.stopPropagation();
elem.find('[data-toggle=dropdown]').dropdown('toggle');
}
}
let mouseX, mouseY;
elem.mousedown(e => {
mouseX = e.pageX;
mouseY = e.pageY;
});
elem.mouseup(e => {
if (mouseX === e.pageX && mouseY === e.pageY) {
isDragged = false;
} else {
isDragged = true;
}
});
},
};
}
coreModule.directive('panelHeader', panelHeader);