EVOLUTION-MANAGER
Edit File: DashLinksContainerCtrl.ts
import angular from 'angular'; import _ from 'lodash'; import { iconMap } from './DashLinksEditorCtrl'; import { LinkSrv } from 'app/features/panel/panellinks/link_srv'; import { BackendSrv } from 'app/core/services/backend_srv'; import { DashboardSrv } from '../../services/DashboardSrv'; import { PanelEvents } from '@grafana/data'; import { CoreEvents } from 'app/types'; import { GrafanaRootScope } from 'app/routes/GrafanaCtrl'; export type DashboardLink = { tags: any; target: string; keepTime: any; includeVars: any }; function dashLinksContainer() { return { scope: { links: '=', dashboard: '=', }, restrict: 'E', controller: 'DashLinksContainerCtrl', template: '<dash-link ng-repeat="link in generatedLinks" link="link"></dash-link>', link: () => {}, }; } /** @ngInject */ function dashLink($compile: any, $sanitize: any, linkSrv: LinkSrv) { return { restrict: 'E', link: (scope: any, elem: JQuery) => { const link = scope.link; const dashboard = scope.dashboard; let template = '<div class="gf-form">' + '<a class="pointer gf-form-label" data-placement="bottom"' + (link.asDropdown ? ' ng-click="fillDropdown(link)" data-toggle="dropdown"' : '') + '>' + '<i></i> <span></span></a>'; if (link.asDropdown) { template += '<ul class="dropdown-menu" role="menu">' + '<li ng-repeat="dash in link.searchHits">' + '<a href="{{dash.url}}" target="{{dash.target}}">{{dash.title}}</a>' + '</li>' + '</ul>'; } template += '</div>'; elem.html(template); $compile(elem.contents())(scope); function update() { const linkInfo = linkSrv.getAnchorInfo(link); const anchor = elem.find('a'); const span = elem.find('span'); span.text(linkInfo.title); if (!link.asDropdown) { anchor.attr('href', linkInfo.href); sanitizeAnchor(); } anchor.attr('data-placement', 'bottom'); // tooltip anchor.tooltip({ title: $sanitize(scope.link.tooltip), html: true, container: 'body', }); } function sanitizeAnchor() { const anchor = elem.find('a'); const anchorSanitized = $sanitize(anchor.parent().html()); anchor.parent().html(anchorSanitized); } elem.find('i').attr('class', 'fa fa-fw ' + scope.link.icon); elem.find('a').attr('target', scope.link.target); // fix for menus on the far right if (link.asDropdown && scope.$last) { elem.find('.dropdown-menu').addClass('pull-right'); } update(); dashboard.events.on(PanelEvents.refresh, update, scope); }, }; } export class DashLinksContainerCtrl { /** @ngInject */ constructor( $scope: any, $rootScope: GrafanaRootScope, backendSrv: BackendSrv, dashboardSrv: DashboardSrv, linkSrv: LinkSrv ) { const currentDashId = dashboardSrv.getCurrent().id; function buildLinks(linkDef: any) { if (linkDef.type === 'dashboards') { if (!linkDef.tags) { console.log('Dashboard link missing tag'); return Promise.resolve([]); } if (linkDef.asDropdown) { return Promise.resolve([ { title: linkDef.title, tags: linkDef.tags, keepTime: linkDef.keepTime, includeVars: linkDef.includeVars, target: linkDef.targetBlank ? '_blank' : '_self', icon: 'fa fa-bars', asDropdown: true, }, ]); } return $scope.searchDashboards(linkDef, 7); } if (linkDef.type === 'link') { return Promise.resolve([ { url: linkDef.url, title: linkDef.title, // @ts-ignore icon: iconMap[linkDef.icon], tooltip: linkDef.tooltip, target: linkDef.targetBlank ? '_blank' : '_self', keepTime: linkDef.keepTime, includeVars: linkDef.includeVars, }, ]); } return Promise.resolve([]); } function updateDashLinks() { const promises = _.map($scope.links, buildLinks); Promise.all(promises).then(results => { $scope.generatedLinks = _.flatten(results); }); } $scope.searchDashboards = (link: DashboardLink, limit: any) => { return backendSrv.search({ tag: link.tags, limit: limit }).then(results => { return _.reduce( results, (memo, dash) => { // do not add current dashboard if (dash.id !== currentDashId) { memo.push({ title: dash.title, url: dash.url, target: link.target === '_self' ? '' : link.target, icon: 'fa fa-th-large', keepTime: link.keepTime, includeVars: link.includeVars, }); } return memo; }, [] ); }); }; $scope.fillDropdown = (link: { searchHits: any }) => { $scope.searchDashboards(link, 100).then((results: any) => { _.each(results, hit => { hit.url = linkSrv.getLinkUrl(hit); }); link.searchHits = results; }); }; updateDashLinks(); $rootScope.onAppEvent(CoreEvents.dashLinksUpdated, updateDashLinks, $scope); } } angular.module('grafana.directives').directive('dashLinksContainer', dashLinksContainer); angular.module('grafana.directives').directive('dashLink', dashLink); angular.module('grafana.directives').controller('DashLinksContainerCtrl', DashLinksContainerCtrl);