mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Dashboard and nav links are near completion now, #1944
This commit is contained in:
parent
4b4f398e83
commit
0bde1bb857
@ -107,7 +107,7 @@
|
||||
</div>
|
||||
|
||||
<div ng-if="editor.index == 2">
|
||||
<dash-links-editor dashboard="dashboard"></dash-links-editor>
|
||||
<dash-links-editor></dash-links-editor>
|
||||
</div>
|
||||
|
||||
<div ng-repeat="pulldown in dashboard.nav" ng-controller="SubmenuCtrl" ng-show="editor.index == 3+$index">
|
||||
|
@ -9,7 +9,8 @@ function (angular, _, require, config) {
|
||||
|
||||
var module = angular.module('grafana.controllers');
|
||||
|
||||
module.controller('ShareModalCtrl', function($scope, $rootScope, $location, $timeout, timeSrv, $element, templateSrv) {
|
||||
module.controller('ShareModalCtrl', function($scope, $rootScope, $location, $timeout, timeSrv, $element, templateSrv, linkSrv) {
|
||||
|
||||
$scope.options = { forCurrent: true, includeTemplateVars: true, theme: 'current' };
|
||||
$scope.editor = { index: 0 };
|
||||
|
||||
@ -47,14 +48,7 @@ function (angular, _, require, config) {
|
||||
params.to = range.to;
|
||||
|
||||
if ($scope.options.includeTemplateVars) {
|
||||
_.each(templateSrv.variables, function(variable) {
|
||||
params['var-' + variable.name] = variable.current.text;
|
||||
});
|
||||
}
|
||||
else {
|
||||
_.each(templateSrv.variables, function(variable) {
|
||||
delete params['var-' + variable.name];
|
||||
});
|
||||
templateSrv.fillVariableValuesForUrl(params);
|
||||
}
|
||||
|
||||
if (!$scope.options.forCurrent) {
|
||||
@ -74,19 +68,7 @@ function (angular, _, require, config) {
|
||||
delete params.fullscreen;
|
||||
}
|
||||
|
||||
var paramsArray = [];
|
||||
_.each(params, function(value, key) {
|
||||
if (value === null) { return; }
|
||||
if (value === true) {
|
||||
paramsArray.push(key);
|
||||
} else {
|
||||
key += '=' + encodeURIComponent(value);
|
||||
paramsArray.push(key);
|
||||
}
|
||||
});
|
||||
|
||||
var queryParams = "?" + paramsArray.join('&');
|
||||
$scope.shareUrl = baseUrl + queryParams;
|
||||
$scope.shareUrl = linkSrv.addParamsToUrl(baseUrl, params);
|
||||
|
||||
var soloUrl = $scope.shareUrl;
|
||||
soloUrl = soloUrl.replace('/dashboard/db/', '/dashboard/solo/db/');
|
||||
|
@ -9,7 +9,7 @@
|
||||
<i ng-click="moveLink($index, 1)" ng-hide="$last" class="pointer fa fa-fw fa-arrow-down"></i>
|
||||
</li>
|
||||
<li class="tight-form-item last">
|
||||
<i class="fa fa-remove pointer" ng-click="deleteLink(link)"></i>
|
||||
<i class="fa fa-remove pointer" ng-click="deleteLink($index)"></i>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
@ -36,8 +36,6 @@
|
||||
<li ng-show="link.type === 'dashboards' && link.asDropdown">
|
||||
<input type="text" ng-model="link.title" class="input-medium tight-form-input" ng-model-onblur ng-change="updated()">
|
||||
</li>
|
||||
|
||||
|
||||
<li class="tight-form-item" ng-show="link.type === 'link'" style="width: 51px">Url</li>
|
||||
<li ng-show="link.type === 'link'">
|
||||
<input type="text" ng-model="link.url" class="input-xlarge tight-form-input" style="width: 302px;" ng-model-onblur ng-change="updated()">
|
||||
@ -68,24 +66,22 @@
|
||||
</ul>
|
||||
<div class="clearfix"></div>
|
||||
</div>
|
||||
<div class="tight-form">
|
||||
<ul class="tight-form-list">
|
||||
<li class="tight-form-item" style="width: 20px">
|
||||
<i class="fa fa-fw fa-unlink invisible"></i>
|
||||
</li>
|
||||
<li class="tight-form-item">
|
||||
<editor-checkbox text="Keep current time range" model="link.keepTime" change="updated()"></editor-checkbox>
|
||||
</li>
|
||||
<li class="tight-form-item">
|
||||
<editor-checkbox text="Add current variable values" model="link.includeVars" change="updated()"></editor-checkbox>
|
||||
</li>
|
||||
</ul>
|
||||
<div class="clearfix"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- <div class="tight-form"> -->
|
||||
<!-- <ul class="tight-form-list" role="menu"> -->
|
||||
<!-- <li class="tight-form-item"> -->
|
||||
<!-- <i class="fa fa-remove invisible"></i> -->
|
||||
<!-- </li> -->
|
||||
<!-- <li class="tight-form-item" style="width: 80px;"> -->
|
||||
<!-- Params -->
|
||||
<!-- <tip>Use var-variableName=value to pass templating variables.</tip> -->
|
||||
<!-- </li> -->
|
||||
<!-- <li> -->
|
||||
<!-- <input type="text" ng-model="link.params" class="input-xxlarge tight-form-input"> -->
|
||||
<!-- </li> -->
|
||||
<!-- </ul> -->
|
||||
<!-- <div class="clearfix"></div> -->
|
||||
<!-- </div> -->
|
||||
|
||||
<div class="editor-row">
|
||||
<br>
|
||||
<button class="btn btn-inverse" ng-click="addLink()"><i class="fa fa-plus"></i> Add link</button>
|
||||
|
@ -19,9 +19,6 @@ function (angular, _) {
|
||||
|
||||
module.directive('dashLinksEditor', function() {
|
||||
return {
|
||||
scope: {
|
||||
dashboard: "="
|
||||
},
|
||||
restrict: 'E',
|
||||
controller: 'DashLinkEditorCtrl',
|
||||
templateUrl: 'app/features/dashlinks/editor.html',
|
||||
@ -76,6 +73,11 @@ function (angular, _) {
|
||||
icon.attr('class', 'fa fa-fw ' + scope.link.icon);
|
||||
anchor.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();
|
||||
scope.$on('refresh', update);
|
||||
}
|
||||
@ -96,12 +98,14 @@ function (angular, _) {
|
||||
return $q.when([{
|
||||
title: linkDef.title,
|
||||
tag: linkDef.tag,
|
||||
keepTime: linkDef.keepTime,
|
||||
includeVars: linkDef.includeVars,
|
||||
icon: "fa fa-bars",
|
||||
asDropdown: true
|
||||
}]);
|
||||
}
|
||||
|
||||
return $scope.searchDashboards(linkDef.tag);
|
||||
return $scope.searchDashboards(linkDef);
|
||||
}
|
||||
|
||||
if (linkDef.type === 'link') {
|
||||
@ -111,6 +115,8 @@ function (angular, _) {
|
||||
icon: iconMap[linkDef.icon],
|
||||
tooltip: linkDef.tooltip,
|
||||
target: linkDef.targetBlank ? "_blank" : "",
|
||||
keepTime: linkDef.keepTime,
|
||||
includeVars: linkDef.includeVars,
|
||||
}]);
|
||||
}
|
||||
|
||||
@ -125,12 +131,18 @@ function (angular, _) {
|
||||
});
|
||||
}
|
||||
|
||||
$scope.searchDashboards = function(tag) {
|
||||
return backendSrv.search({tag: tag}).then(function(results) {
|
||||
$scope.searchDashboards = function(link) {
|
||||
return backendSrv.search({tag: link.tag}).then(function(results) {
|
||||
return _.reduce(results.dashboards, function(memo, dash) {
|
||||
// do not add current dashboard
|
||||
if (dash.id !== currentDashId) {
|
||||
memo.push({ title: dash.title, url: 'dashboard/db/'+ dash.slug, icon: 'fa fa-th-large', addTime: true });
|
||||
memo.push({
|
||||
title: dash.title,
|
||||
url: 'dashboard/db/'+ dash.slug,
|
||||
icon: 'fa fa-th-large',
|
||||
keepTime: link.keepTime,
|
||||
includeVars: link.includeVars
|
||||
});
|
||||
}
|
||||
return memo;
|
||||
}, []);
|
||||
@ -138,7 +150,7 @@ function (angular, _) {
|
||||
};
|
||||
|
||||
$scope.fillDropdown = function(link) {
|
||||
$scope.searchDashboards(link.tag).then(function(results) {
|
||||
$scope.searchDashboards(link).then(function(results) {
|
||||
_.each(results, function(hit) {
|
||||
hit.url = linkSrv.getLinkUrl(hit);
|
||||
});
|
||||
@ -154,8 +166,11 @@ function (angular, _) {
|
||||
|
||||
$scope.iconMap = iconMap;
|
||||
$scope.dashboard.links = $scope.dashboard.links || [];
|
||||
|
||||
$scope.addLink = function() {
|
||||
$scope.dashboard.links.push({ type: 'dashboards', icon: 'external link' });
|
||||
$scope.updateSubmenuVisibility();
|
||||
$scope.updated();
|
||||
};
|
||||
|
||||
$scope.moveLink = function(index, dir) {
|
||||
@ -167,8 +182,10 @@ function (angular, _) {
|
||||
$rootScope.appEvent('dash-links-updated');
|
||||
};
|
||||
|
||||
$scope.deleteLink = function(link) {
|
||||
$scope.dashboard.links = _.without($scope.dashboard.links, link);
|
||||
$scope.deleteLink = function(index) {
|
||||
$scope.dashboard.links.splice(index, 1);
|
||||
$scope.updateSubmenuVisibility();
|
||||
$scope.updated();
|
||||
};
|
||||
|
||||
});
|
||||
|
@ -1,63 +1,55 @@
|
||||
define([
|
||||
'angular',
|
||||
'kbn',
|
||||
'lodash',
|
||||
],
|
||||
function (angular, kbn) {
|
||||
function (angular, kbn, _) {
|
||||
'use strict';
|
||||
|
||||
angular
|
||||
.module('grafana.services')
|
||||
.service('linkSrv', function(templateSrv, timeSrv) {
|
||||
|
||||
// parseUri 1.2.2
|
||||
// (c) Steven Levithan <stevenlevithan.com>
|
||||
// MIT License
|
||||
this.getLinkUrl = function(link) {
|
||||
var url = templateSrv.replace(link.url || '');
|
||||
var params = {};
|
||||
|
||||
function parseUri (str) {
|
||||
var o = parseUri.options,
|
||||
m = o.parser[o.strictMode ? "strict" : "loose"].exec(str),
|
||||
uri = {},
|
||||
i = 14;
|
||||
|
||||
while (i--) {
|
||||
uri[o.key[i]] = m[i] || "";
|
||||
if (link.keepTime) {
|
||||
var range = timeSrv.timeRangeForUrl();
|
||||
params['from'] = range.from;
|
||||
params['to'] = range.to;
|
||||
}
|
||||
|
||||
uri[o.q.name] = {};
|
||||
uri[o.key[12]].replace(o.q.parser, function ($0, $1, $2) {
|
||||
if ($1) {
|
||||
uri[o.q.name][$1] = $2;
|
||||
if (link.includeVars) {
|
||||
templateSrv.fillVariableValuesForUrl(params);
|
||||
}
|
||||
|
||||
return this.addParamsToUrl(url, params);
|
||||
};
|
||||
|
||||
this.addParamsToUrl = function(url, params) {
|
||||
var paramsArray = [];
|
||||
_.each(params, function(value, key) {
|
||||
if (value === null) { return; }
|
||||
if (value === true) {
|
||||
paramsArray.push(key);
|
||||
}
|
||||
else if (_.isArray(value)) {
|
||||
_.each(value, function(instance) {
|
||||
paramsArray.push(key + '=' + encodeURIComponent(instance));
|
||||
});
|
||||
}
|
||||
else {
|
||||
paramsArray.push(key + '=' + encodeURIComponent(value));
|
||||
}
|
||||
});
|
||||
|
||||
return uri;
|
||||
}
|
||||
|
||||
parseUri.options = {
|
||||
strictMode: false,
|
||||
key: ["source","protocol","authority","userInfo","user","password","host",
|
||||
"port","relative","path","directory","file","query","anchor"],
|
||||
q: {
|
||||
name: "queryKey",
|
||||
parser: /(?:^|&)([^&=]*)=?([^&]*)/g
|
||||
},
|
||||
/* jshint ignore:start */
|
||||
parser: {
|
||||
strict: /^(?:([^:\/?#]+):)?(?:\/\/((?:(([^:@]*)(?::([^:@]*))?)?@)?([^:\/?#]*)(?::(\d*))?))?((((?:[^?#\/]*\/)*)([^?#]*))(?:\?([^#]*))?(?:#(.*))?)/,
|
||||
loose: /^(?:(?![^:@]+:[^:@\/]*@)([^:\/?#.]+):)?(?:\/\/)?((?:(([^:@]*)(?::([^:@]*))?)?@)?([^:\/?#]*)(?::(\d*))?)(((\/(?:[^?#](?![^?#\/]*\.[^?#\/.]+(?:[?#]|$)))*\/?)?([^?#\/]*))(?:\?([^#]*))?(?:#(.*))?)/
|
||||
if (paramsArray.length === 0) {
|
||||
return url;
|
||||
}
|
||||
/* jshint ignore:end */
|
||||
};
|
||||
|
||||
this.getLinkUrl = function(link) {
|
||||
var href = templateSrv.replace(link.url || '');
|
||||
if (link.addTime) {
|
||||
var range = timeSrv.timeRangeForUrl();
|
||||
href += (href.indexOf('?') !== -1 ? '&' : '?');
|
||||
href += 'from=' + range.from;
|
||||
href += '&to=' + range.to;
|
||||
}
|
||||
return href;
|
||||
url += (url.indexOf('?') !== -1 ? '&' : '?');
|
||||
return url + paramsArray.join('&');
|
||||
};
|
||||
|
||||
this.getAnchorInfo = function(link) {
|
||||
|
@ -76,7 +76,7 @@ function (angular, _) {
|
||||
};
|
||||
|
||||
this.replace = function(target, scopedVars) {
|
||||
if (!target) { return; }
|
||||
if (!target) { return target; }
|
||||
|
||||
var value;
|
||||
this._regex.lastIndex = 0;
|
||||
@ -95,7 +95,7 @@ function (angular, _) {
|
||||
};
|
||||
|
||||
this.replaceWithText = function(target, scopedVars) {
|
||||
if (!target) { return; }
|
||||
if (!target) { return target; }
|
||||
|
||||
var value;
|
||||
var text;
|
||||
@ -115,6 +115,12 @@ function (angular, _) {
|
||||
});
|
||||
};
|
||||
|
||||
this.fillVariableValuesForUrl = function(params) {
|
||||
_.each(this.variables, function(variable) {
|
||||
params['var-' + variable.name] = variable.current.value;
|
||||
});
|
||||
};
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
|
@ -94,4 +94,5 @@
|
||||
}
|
||||
|
||||
.dash-nav-link {
|
||||
color: @textColor;
|
||||
}
|
||||
|
@ -131,6 +131,7 @@ define([
|
||||
return _.template(text, this.data, this.templateSettings);
|
||||
};
|
||||
this.init = function() {};
|
||||
this.fillVariableValuesForUrl = function() {};
|
||||
this.updateTemplateData = function() { };
|
||||
this.variableExists = function() { return false; };
|
||||
this.highlightVariablesAsHtml = function(str) { return str; };
|
||||
|
@ -1,6 +1,7 @@
|
||||
define([
|
||||
'helpers',
|
||||
'features/dashboard/shareModalCtrl'
|
||||
'features/dashboard/shareModalCtrl',
|
||||
'features/panellinks/linkSrv',
|
||||
], function(helpers) {
|
||||
'use strict';
|
||||
|
||||
@ -14,8 +15,10 @@ define([
|
||||
setTime({ from: 'now-1h', to: 'now' });
|
||||
|
||||
beforeEach(module('grafana.controllers'));
|
||||
beforeEach(module('grafana.services'));
|
||||
|
||||
beforeEach(ctx.providePhase());
|
||||
|
||||
beforeEach(ctx.createControllerPhase('ShareModalCtrl'));
|
||||
|
||||
describe('shareUrl with current time range and panel', function() {
|
||||
@ -63,8 +66,11 @@ define([
|
||||
ctx.$location.path('/test');
|
||||
ctx.scope.options.includeTemplateVars = true;
|
||||
|
||||
ctx.templateSrv.variables = [{ name: 'app', current: {text: 'mupp' }}, {name: 'server', current: {text: 'srv-01'}}];
|
||||
setTime({ from: 'now-1h', to: 'now' });
|
||||
ctx.templateSrv.fillVariableValuesForUrl = function(params) {
|
||||
params['var-app'] = 'mupp';
|
||||
params['var-server'] = 'srv-01';
|
||||
};
|
||||
|
||||
ctx.scope.buildUrl();
|
||||
expect(ctx.scope.shareUrl).to.be('http://server/#/test?from=now-1h&to=now&var-app=mupp&var-server=srv-01');
|
||||
|
Loading…
Reference in New Issue
Block a user