mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
ux: merge branch navbarv2, new navbar with dashboard search available on all pages, closes #6475
This commit is contained in:
parent
1bdf82dca3
commit
e9d5e037e8
@ -105,10 +105,14 @@ export function grafanaAppDirective(playlistSrv, contextSrv) {
|
||||
if (pageClass) {
|
||||
body.removeClass(pageClass);
|
||||
}
|
||||
pageClass = data.$$route.pageClass;
|
||||
if (pageClass) {
|
||||
body.addClass(pageClass);
|
||||
|
||||
if (data.$$route) {
|
||||
pageClass = data.$$route.pageClass;
|
||||
if (pageClass) {
|
||||
body.addClass(pageClass);
|
||||
}
|
||||
}
|
||||
|
||||
$("#tooltip, .tooltip").remove();
|
||||
|
||||
// check for kiosk url param
|
||||
@ -194,6 +198,15 @@ export function grafanaAppDirective(playlistSrv, contextSrv) {
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// hide menus
|
||||
var openMenus = body.find('.navbar-page-btn--open');
|
||||
if (openMenus.length > 0) {
|
||||
if (target.parents('.navbar-page-btn--open').length === 0) {
|
||||
openMenus.removeClass('navbar-page-btn--open');
|
||||
}
|
||||
}
|
||||
|
||||
// hide sidemenu
|
||||
if (!ignoreSideMenuHide && !contextSrv.pinned && body.find('.sidemenu').length > 0) {
|
||||
if (target.parents('.sidemenu').length === 0) {
|
||||
|
@ -1,7 +1,7 @@
|
||||
<div class="modal-body">
|
||||
<div class="modal-header">
|
||||
<h2 class="modal-header-title">
|
||||
<i class="fa fa-keyboard"></i>
|
||||
<i class="fa fa-keyboard-o"></i>
|
||||
<span class="p-l-1">Shortcuts</span>
|
||||
</h2>
|
||||
|
||||
@ -20,7 +20,7 @@
|
||||
|
||||
<div class="modal-content help-modal">
|
||||
|
||||
<p class="small" style="position: absolute; top: 48px; right: 10px">
|
||||
<p class="small" style="position: absolute; top: 13px; right: 44px">
|
||||
<span class="shortcut-table-key">mod</span> =
|
||||
<span class="muted">CTRL on windows or linux and CMD key on Mac</span>
|
||||
</p>
|
||||
|
@ -8,11 +8,36 @@
|
||||
<i class="fa fa-chevron-left"></i>
|
||||
</a>
|
||||
|
||||
<a href="{{ctrl.titleUrl}}" class="navbar-page-btn" ng-show="ctrl.title">
|
||||
<i class="{{ctrl.icon}}" ng-show="ctrl.icon"></i>
|
||||
<img ng-src="{{ctrl.iconUrl}}" ng-show="ctrl.iconUrl"></i>
|
||||
{{ctrl.title}}
|
||||
<a class="navbar-page-btn" ng-click="ctrl.showSearch()">
|
||||
<i class="fa fa-search"></i>
|
||||
</a>
|
||||
|
||||
<div ng-transclude></div>
|
||||
<div ng-if="::!ctrl.hasMenu">
|
||||
<a href="{{::ctrl.section.url}}" class="navbar-page-btn">
|
||||
<i class="{{::ctrl.section.icon}}" ng-show="::ctrl.section.icon"></i>
|
||||
<img ng-src="{{::ctrl.section.iconUrl}}" ng-show="::ctrl.section.iconUrl"></i>
|
||||
{{::ctrl.section.title}}
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div class="dropdown navbar-section-wrapper" ng-if="::ctrl.hasMenu">
|
||||
<a href="{{::ctrl.section.url}}" class="navbar-page-btn" data-toggle="dropdown">
|
||||
<i class="{{::ctrl.section.icon}}" ng-show="::ctrl.section.icon"></i>
|
||||
<img ng-src="{{::ctrl.section.iconUrl}}" ng-show="::ctrl.section.iconUrl"></i>
|
||||
{{::ctrl.section.title}}
|
||||
<i class="fa fa-caret-down"></i>
|
||||
</a>
|
||||
<ul class="dropdown-menu dropdown-menu--navbar">
|
||||
<li ng-repeat="navItem in ::ctrl.model.menu" ng-class="{active: navItem.active}">
|
||||
<a class="pointer" ng-href="{{::navItem.url}}" ng-click="ctrl.navItemClicked(navItem, $event)">
|
||||
<i class="{{::navItem.icon}}" ng-show="::navItem.icon"></i>
|
||||
{{::navItem.title}}
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div ng-transclude></div>
|
||||
</div>
|
||||
|
||||
<dashboard-search></dashboard-search>
|
||||
|
@ -4,10 +4,28 @@ import config from 'app/core/config';
|
||||
import _ from 'lodash';
|
||||
import $ from 'jquery';
|
||||
import coreModule from '../../core_module';
|
||||
import {NavModel, NavModelItem} from '../../nav_model_srv';
|
||||
|
||||
export class NavbarCtrl {
|
||||
model: NavModel;
|
||||
section: NavModelItem;
|
||||
hasMenu: boolean;
|
||||
|
||||
/** @ngInject */
|
||||
constructor(private $scope, private contextSrv) {
|
||||
constructor(private $scope, private $rootScope, private contextSrv) {
|
||||
this.section = this.model.section;
|
||||
this.hasMenu = this.model.menu.length > 0;
|
||||
}
|
||||
|
||||
showSearch() {
|
||||
this.$rootScope.appEvent('show-dash-search');
|
||||
}
|
||||
|
||||
navItemClicked(navItem, evt) {
|
||||
if (navItem.clickHandler) {
|
||||
navItem.clickHandler();
|
||||
evt.preventDefault();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -20,12 +38,9 @@ export function navbarDirective() {
|
||||
transclude: true,
|
||||
controllerAs: 'ctrl',
|
||||
scope: {
|
||||
title: "@",
|
||||
titleUrl: "@",
|
||||
iconUrl: "@",
|
||||
model: "=",
|
||||
},
|
||||
link: function(scope, elem, attrs, ctrl) {
|
||||
ctrl.icon = attrs.icon;
|
||||
link: function(scope, elem) {
|
||||
elem.addClass('navbar');
|
||||
}
|
||||
};
|
||||
|
@ -1,9 +1,22 @@
|
||||
|
||||
<div class="search-backdrop" ng-if="ctrl.isOpen"></div>
|
||||
|
||||
<div class="search-container" ng-if="ctrl.isOpen">
|
||||
|
||||
<div class="search-field-wrapper">
|
||||
<span style="position: relative;">
|
||||
<input type="text" placeholder="Find dashboards by name" give-focus="ctrl.giveSearchFocus" tabindex="1"
|
||||
ng-keydown="ctrl.keyDown($event)" ng-model="ctrl.query.query" ng-model-options="{ debounce: 500 }" spellcheck='false' ng-change="ctrl.search()" />
|
||||
</span>
|
||||
<div class="search-field-icon">
|
||||
<i class="fa fa-search"></i>
|
||||
</div>
|
||||
|
||||
<input type="text" placeholder="Find dashboards by name" give-focus="ctrl.giveSearchFocus" tabindex="1"
|
||||
ng-keydown="ctrl.keyDown($event)"
|
||||
ng-model="ctrl.query.query"
|
||||
ng-model-options="{ debounce: 500 }"
|
||||
spellcheck='false'
|
||||
ng-change="ctrl.search()"
|
||||
ng-blur="ctrl.searchInputBlur()"
|
||||
/>
|
||||
|
||||
<div class="search-switches">
|
||||
<i class="fa fa-filter"></i>
|
||||
<a class="pointer" href="javascript:void 0;" ng-click="ctrl.showStarred()" tabindex="2">
|
||||
@ -24,54 +37,55 @@
|
||||
</span>
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div class="search-field-spacer"></div>
|
||||
</div>
|
||||
|
||||
<div class="search-results-container" ng-if="ctrl.tagsMode">
|
||||
<div ng-repeat="tag in ctrl.results" class="pointer" style="width: 180px; float: left;"
|
||||
ng-class="{'selected': $index === ctrl.selectedIndex }"
|
||||
ng-click="ctrl.filterByTag(tag.term, $event)">
|
||||
<a class="search-result-tag label label-tag" tag-color-from-name="tag.term">
|
||||
<i class="fa fa-tag"></i>
|
||||
<span>{{tag.term}} ({{tag.count}})</span>
|
||||
<div class="search-dropdown" ng-class="{'search-dropdown--fade-in': ctrl.openCompleted}">
|
||||
<div class="search-results-container" ng-if="ctrl.tagsMode">
|
||||
<div ng-repeat="tag in ctrl.results" class="pointer" style="width: 180px; float: left;"
|
||||
ng-class="{'selected': $index === ctrl.selectedIndex }"
|
||||
ng-click="ctrl.filterByTag(tag.term, $event)">
|
||||
<a class="search-result-tag label label-tag" tag-color-from-name="tag.term">
|
||||
<i class="fa fa-tag"></i>
|
||||
<span>{{tag.term}} ({{tag.count}})</span>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="search-results-container" ng-if="!ctrl.tagsMode">
|
||||
<h6 ng-hide="ctrl.results.length">No dashboards matching your query were found.</h6>
|
||||
|
||||
<a class="search-item pointer search-item-{{row.type}}" bindonce ng-repeat="row in ctrl.results"
|
||||
ng-class="{'selected': $index == ctrl.selectedIndex}" ng-href="{{row.url}}">
|
||||
|
||||
<span class="search-result-tags">
|
||||
<span ng-click="ctrl.filterByTag(tag, $event)" ng-repeat="tag in row.tags" tag-color-from-name="tag" class="label label-tag">
|
||||
{{tag}}
|
||||
</span>
|
||||
<i class="fa" ng-class="{'fa-star': row.isStarred, 'fa-star-o': !row.isStarred}"></i>
|
||||
</span>
|
||||
|
||||
<span class="search-result-link">
|
||||
<i class="fa search-result-icon"></i>
|
||||
<span bo-text="row.title"></span>
|
||||
</span>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div class="search-button-row">
|
||||
<a class="btn btn-secondary" href="dashboard/new" ng-show="ctrl.contextSrv.isEditor" ng-click="ctrl.isOpen = false;">
|
||||
<i class="fa fa-plus"></i> New Dashboard
|
||||
</a>
|
||||
|
||||
<a class="btn btn-inverse" href="dashboard/new/?editview=import" ng-show="ctrl.contextSrv.isEditor" ng-click="ctrl.isOpen = false;">
|
||||
<i class="fa fa-upload"></i> Import Dashboard
|
||||
</a>
|
||||
|
||||
<a class="search-button-row-explore-link" target="_blank" href="https://grafana.com/dashboards?utm_source=grafana_search">
|
||||
Find <img src="public/img/icn-dashboard-tiny.svg" width="14" /> dashboards on Grafana.com
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="search-results-container" ng-if="!ctrl.tagsMode">
|
||||
<h6 ng-hide="ctrl.results.length">No dashboards matching your query were found.</h6>
|
||||
|
||||
<a class="search-item pointer search-item-{{row.type}}" bindonce ng-repeat="row in ctrl.results"
|
||||
ng-class="{'selected': $index == ctrl.selectedIndex}" ng-href="{{row.url}}">
|
||||
|
||||
<span class="search-result-tags">
|
||||
<span ng-click="ctrl.filterByTag(tag, $event)" ng-repeat="tag in row.tags" tag-color-from-name="tag" class="label label-tag">
|
||||
{{tag}}
|
||||
</span>
|
||||
<i class="fa" ng-class="{'fa-star': row.isStarred, 'fa-star-o': !row.isStarred}"></i>
|
||||
</span>
|
||||
|
||||
<span class="search-result-link">
|
||||
<i class="fa search-result-icon"></i>
|
||||
<span bo-text="row.title"></span>
|
||||
</span>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div class="search-button-row">
|
||||
<a class="btn btn-inverse pull-left" href="dashboard/new" ng-show="ctrl.contextSrv.isEditor" ng-click="ctrl.isOpen = false;">
|
||||
<i class="fa fa-plus"></i>
|
||||
Create New
|
||||
</a>
|
||||
|
||||
<a class="btn btn-inverse pull-left" href="dashboard/new/?editview=import" ng-show="ctrl.contextSrv.isEditor" ng-click="ctrl.isOpen = false;">
|
||||
<i class="fa fa-upload"></i>
|
||||
Import
|
||||
</a>
|
||||
|
||||
<a class="pull-right search-button-row-explore-link" target="_blank" href="https://grafana.com/dashboards?utm_source=grafana_search">
|
||||
Find <img src="public/img/icn-dashboard-tiny.svg" width="14" /> dashboards on Grafana.com
|
||||
</a>
|
||||
|
||||
<div class="clearfix"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
@ -18,6 +18,8 @@ export class SearchCtrl {
|
||||
showImport: boolean;
|
||||
dismiss: any;
|
||||
ignoreClose: any;
|
||||
// triggers fade animation class
|
||||
openCompleted: boolean;
|
||||
|
||||
/** @ngInject */
|
||||
constructor(private $scope, private $location, private $timeout, private backendSrv, private contextSrv, private $rootScope) {
|
||||
@ -27,6 +29,7 @@ export class SearchCtrl {
|
||||
|
||||
closeSearch() {
|
||||
this.isOpen = this.ignoreClose;
|
||||
this.openCompleted = false;
|
||||
}
|
||||
|
||||
openSearch(evt, payload) {
|
||||
@ -56,6 +59,7 @@ export class SearchCtrl {
|
||||
}
|
||||
|
||||
this.$timeout(() => {
|
||||
this.openCompleted = true;
|
||||
this.ignoreClose = false;
|
||||
this.giveSearchFocus = this.giveSearchFocus + 1;
|
||||
this.search();
|
||||
@ -169,6 +173,7 @@ export function searchDirective() {
|
||||
controller: SearchCtrl,
|
||||
bindToController: true,
|
||||
controllerAs: 'ctrl',
|
||||
scope: {},
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -5,7 +5,9 @@ define([
|
||||
function (angular, coreModule) {
|
||||
'use strict';
|
||||
|
||||
coreModule.default.controller('ErrorCtrl', function($scope, contextSrv) {
|
||||
coreModule.default.controller('ErrorCtrl', function($scope, contextSrv, navModelSrv) {
|
||||
|
||||
$scope.navModel = navModelSrv.getNotFoundNav();
|
||||
|
||||
var showSideMenu = contextSrv.sidemenu;
|
||||
contextSrv.sidemenu = false;
|
||||
|
@ -44,6 +44,7 @@ import {assignModelProperties} from './utils/model_utils';
|
||||
import {contextSrv} from './services/context_srv';
|
||||
import {KeybindingSrv} from './services/keybindingSrv';
|
||||
import {helpModal} from './components/help/help';
|
||||
import {NavModelSrv, NavModel} from './nav_model_srv';
|
||||
|
||||
|
||||
export {
|
||||
@ -68,4 +69,6 @@ export {
|
||||
contextSrv,
|
||||
KeybindingSrv,
|
||||
helpModal,
|
||||
NavModelSrv,
|
||||
NavModel,
|
||||
};
|
||||
|
209
public/app/core/nav_model_srv.ts
Normal file
209
public/app/core/nav_model_srv.ts
Normal file
@ -0,0 +1,209 @@
|
||||
///<reference path="../headers/common.d.ts" />
|
||||
|
||||
import coreModule from 'app/core/core_module';
|
||||
|
||||
export interface NavModelItem {
|
||||
title: string;
|
||||
url: string;
|
||||
icon?: string;
|
||||
iconUrl?: string;
|
||||
}
|
||||
|
||||
export interface NavModel {
|
||||
section: NavModelItem;
|
||||
menu: NavModelItem[];
|
||||
}
|
||||
|
||||
export class NavModelSrv {
|
||||
|
||||
|
||||
/** @ngInject */
|
||||
constructor(private contextSrv) {
|
||||
}
|
||||
|
||||
getAlertingNav(subPage) {
|
||||
return {
|
||||
section: {
|
||||
title: 'Alerting',
|
||||
url: 'plugins',
|
||||
icon: 'icon-gf icon-gf-alert'
|
||||
},
|
||||
menu: [
|
||||
{title: 'Alert List', active: subPage === 0, url: 'alerting/list', icon: 'fa fa-list-ul'},
|
||||
{title: 'Notification channels', active: subPage === 1, url: 'alerting/notifications', icon: 'fa fa-bell-o'},
|
||||
]
|
||||
};
|
||||
}
|
||||
|
||||
getDatasourceNav(subPage) {
|
||||
return {
|
||||
section: {
|
||||
title: 'Data Sources',
|
||||
url: 'datasources',
|
||||
icon: 'icon-gf icon-gf-datasources'
|
||||
},
|
||||
menu: [
|
||||
{title: 'List view', active: subPage === 0, url: '/datasources', icon: 'fa fa-list-ul'},
|
||||
{title: 'Add data source', active: subPage === 1, url: '/datasources/new', icon: 'fa fa-plus'},
|
||||
]
|
||||
};
|
||||
}
|
||||
|
||||
getPlaylistsNav(subPage) {
|
||||
return {
|
||||
section: {
|
||||
title: 'Playlists',
|
||||
url: 'playlists',
|
||||
icon: 'fa fa-fw fa-film'
|
||||
},
|
||||
menu: [
|
||||
{title: 'List view', active: subPage === 0, url: '/playlists', icon: 'fa fa-list-ul'},
|
||||
{title: 'Add Playlist', active: subPage === 1, url: '/playlists/create', icon: 'fa fa-plus'},
|
||||
]
|
||||
};
|
||||
}
|
||||
|
||||
getProfileNav() {
|
||||
return {
|
||||
section: {
|
||||
title: 'User Profile',
|
||||
url: 'profile',
|
||||
icon: 'fa fa-fw fa-user'
|
||||
},
|
||||
menu: []
|
||||
};
|
||||
}
|
||||
|
||||
getNotFoundNav() {
|
||||
return {
|
||||
section: {
|
||||
title: 'Page',
|
||||
url: '',
|
||||
icon: 'fa fa-fw fa-warning'
|
||||
},
|
||||
menu: []
|
||||
};
|
||||
}
|
||||
|
||||
getOrgNav(subPage) {
|
||||
return {
|
||||
section: {
|
||||
title: 'Organization',
|
||||
url: 'org',
|
||||
icon: 'icon-gf icon-gf-users'
|
||||
},
|
||||
menu: [
|
||||
{title: 'Preferences', active: subPage === 0, url: '/org', icon: 'fa fa-fw fa-cog'},
|
||||
{title: 'Org Users', active: subPage === 1, url: '/org/users', icon: 'fa fa-fw fa-users'},
|
||||
{title: 'API Keys', active: subPage === 2, url: '/org/apikeys', icon: 'fa fa-fw fa-key'},
|
||||
]
|
||||
};
|
||||
}
|
||||
|
||||
getAdminNav(subPage) {
|
||||
return {
|
||||
section: {
|
||||
title: 'Admin',
|
||||
url: 'admin',
|
||||
icon: 'fa fa-fw fa-cogs'
|
||||
},
|
||||
menu: [
|
||||
{title: 'Users', active: subPage === 0, url: '/admin/users', icon: 'fa fa-fw fa-user'},
|
||||
{title: 'Orgs', active: subPage === 1, url: '/admin/orgs', icon: 'fa fa-fw fa-users'},
|
||||
{title: 'Server Settings', active: subPage === 2, url: '/admin/settings', icon: 'fa fa-fw fa-cogs'},
|
||||
{title: 'Server Stats', active: subPage === 2, url: '/admin/stats', icon: 'fa fa-fw fa-line-chart'},
|
||||
{title: 'Style Guide', active: subPage === 2, url: '/styleguide', icon: 'fa fa-fw fa-key'},
|
||||
]
|
||||
};
|
||||
}
|
||||
|
||||
getPluginsNav() {
|
||||
return {
|
||||
section: {
|
||||
title: 'Plugins',
|
||||
url: 'plugins',
|
||||
icon: 'icon-gf icon-gf-apps'
|
||||
},
|
||||
menu: []
|
||||
};
|
||||
}
|
||||
|
||||
getDashboardNav(dashboard, dashNavCtrl) {
|
||||
// special handling for snapshots
|
||||
if (dashboard.meta.isSnapshot) {
|
||||
return {
|
||||
section: {
|
||||
title: dashboard.title,
|
||||
icon: 'icon-gf icon-gf-snapshot'
|
||||
},
|
||||
menu: [
|
||||
{
|
||||
title: 'Go to original dashboard',
|
||||
icon: 'fa fa-fw fa-external-link',
|
||||
url: dashboard.snapshot.originalUrl,
|
||||
}
|
||||
]
|
||||
};
|
||||
}
|
||||
|
||||
var menu = [];
|
||||
|
||||
if (dashboard.meta.canEdit) {
|
||||
menu.push({
|
||||
title: 'Settings',
|
||||
icon: 'fa fa-fw fa-cog',
|
||||
clickHandler: () => dashNavCtrl.openEditView('settings')
|
||||
});
|
||||
|
||||
menu.push({
|
||||
title: 'Templating',
|
||||
icon: 'fa fa-fw fa-code',
|
||||
clickHandler: () => dashNavCtrl.openEditView('templating')
|
||||
});
|
||||
|
||||
menu.push({
|
||||
title: 'Annotations',
|
||||
icon: 'fa fa-fw fa-bolt',
|
||||
clickHandler: () => dashNavCtrl.openEditView('annotations')
|
||||
});
|
||||
|
||||
menu.push({
|
||||
title: 'View JSON',
|
||||
icon: 'fa fa-fw fa-eye',
|
||||
clickHandler: () => dashNavCtrl.viewJson()
|
||||
});
|
||||
}
|
||||
|
||||
if (this.contextSrv.isEditor && !dashboard.editable) {
|
||||
menu.push({
|
||||
title: 'Make Editable',
|
||||
icon: 'fa fa-fw fa-edit',
|
||||
clickHandler: () => dashNavCtrl.makeEditable()
|
||||
});
|
||||
}
|
||||
|
||||
menu.push({
|
||||
title: 'Shortcuts',
|
||||
icon: 'fa fa-fw fa-keyboard-o',
|
||||
clickHandler: () => dashNavCtrl.showHelpModal()
|
||||
});
|
||||
|
||||
if (this.contextSrv.isEditor) {
|
||||
menu.push({
|
||||
title: 'Save As ...',
|
||||
icon: 'fa fa-fw fa-save',
|
||||
clickHandler: () => dashNavCtrl.saveDashboardAs()
|
||||
});
|
||||
}
|
||||
|
||||
return {
|
||||
section: {
|
||||
title: dashboard.title,
|
||||
icon: 'icon-gf icon-gf-dashboard'
|
||||
},
|
||||
menu: menu
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
coreModule.service('navModelSrv', NavModelSrv);
|
@ -103,11 +103,13 @@ function setupAngularRoutes($routeProvider, $locationProvider) {
|
||||
.when('/admin', {
|
||||
templateUrl: 'public/app/features/admin/partials/admin_home.html',
|
||||
controller : 'AdminHomeCtrl',
|
||||
controllerAs: 'ctrl',
|
||||
resolve: loadAdminBundle,
|
||||
})
|
||||
.when('/admin/settings', {
|
||||
templateUrl: 'public/app/features/admin/partials/settings.html',
|
||||
controller : 'AdminSettingsCtrl',
|
||||
controllerAs: 'ctrl',
|
||||
resolve: loadAdminBundle,
|
||||
})
|
||||
.when('/admin/users', {
|
||||
@ -129,11 +131,13 @@ function setupAngularRoutes($routeProvider, $locationProvider) {
|
||||
.when('/admin/orgs', {
|
||||
templateUrl: 'public/app/features/admin/partials/orgs.html',
|
||||
controller : 'AdminListOrgsCtrl',
|
||||
controllerAs: 'ctrl',
|
||||
resolve: loadAdminBundle,
|
||||
})
|
||||
.when('/admin/orgs/edit/:id', {
|
||||
templateUrl: 'public/app/features/admin/partials/edit_org.html',
|
||||
controller : 'AdminEditOrgCtrl',
|
||||
controllerAs: 'ctrl',
|
||||
resolve: loadAdminBundle,
|
||||
})
|
||||
.when('/admin/stats', {
|
||||
|
@ -113,10 +113,6 @@ export class KeybindingSrv {
|
||||
scope.appEvent('shift-time-forward');
|
||||
});
|
||||
|
||||
this.bind('mod+i', () => {
|
||||
scope.appEvent('quick-snapshot');
|
||||
});
|
||||
|
||||
// edit panel
|
||||
this.bind('e', () => {
|
||||
if (dashboard.meta.focusPanelId && dashboard.meta.canEdit) {
|
||||
@ -225,7 +221,7 @@ export class KeybindingSrv {
|
||||
}
|
||||
|
||||
scope.appEvent('hide-dash-editor');
|
||||
scope.exitFullscreen();
|
||||
scope.appEvent('panel-change-view', {fullscreen: false, edit: false});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -6,9 +6,11 @@ import './adminEditUserCtrl';
|
||||
import coreModule from 'app/core/core_module';
|
||||
|
||||
class AdminSettingsCtrl {
|
||||
navModel: any;
|
||||
|
||||
/** @ngInject **/
|
||||
constructor($scope, backendSrv) {
|
||||
constructor($scope, backendSrv, navModelSrv) {
|
||||
this.navModel = navModelSrv.getAdminNav();
|
||||
|
||||
backendSrv.get('/api/admin/settings').then(function(settings) {
|
||||
$scope.settings = settings;
|
||||
@ -18,16 +20,22 @@ class AdminSettingsCtrl {
|
||||
}
|
||||
|
||||
class AdminHomeCtrl {
|
||||
navModel: any;
|
||||
|
||||
/** @ngInject **/
|
||||
constructor() {
|
||||
constructor(navModelSrv) {
|
||||
this.navModel = navModelSrv.getAdminNav();
|
||||
}
|
||||
}
|
||||
|
||||
export class AdminStatsCtrl {
|
||||
stats: any;
|
||||
navModel: any;
|
||||
|
||||
/** @ngInject */
|
||||
constructor(backendSrv: any) {
|
||||
constructor(backendSrv: any, navModelSrv) {
|
||||
this.navModel = navModelSrv.getAdminNav();
|
||||
|
||||
backendSrv.get('/api/admin/stats').then(stats => {
|
||||
this.stats = stats;
|
||||
});
|
||||
|
@ -6,9 +6,11 @@ function (angular) {
|
||||
|
||||
var module = angular.module('grafana.controllers');
|
||||
|
||||
module.controller('AdminEditOrgCtrl', function($scope, $routeParams, backendSrv, $location) {
|
||||
module.controller('AdminEditOrgCtrl', function($scope, $routeParams, backendSrv, $location, navModelSrv) {
|
||||
|
||||
$scope.init = function() {
|
||||
$scope.navModel = navModelSrv.getAdminNav();
|
||||
|
||||
if ($routeParams.id) {
|
||||
$scope.getOrg($routeParams.id);
|
||||
$scope.getOrgUsers($routeParams.id);
|
||||
|
@ -7,10 +7,11 @@ function (angular, _) {
|
||||
|
||||
var module = angular.module('grafana.controllers');
|
||||
|
||||
module.controller('AdminEditUserCtrl', function($scope, $routeParams, backendSrv, $location) {
|
||||
module.controller('AdminEditUserCtrl', function($scope, $routeParams, backendSrv, $location, navModelSrv) {
|
||||
$scope.user = {};
|
||||
$scope.newOrg = { name: '', role: 'Editor' };
|
||||
$scope.permissions = {};
|
||||
$scope.navModel = navModelSrv.getAdminNav();
|
||||
|
||||
$scope.init = function() {
|
||||
if ($routeParams.id) {
|
||||
|
@ -6,9 +6,10 @@ function (angular) {
|
||||
|
||||
var module = angular.module('grafana.controllers');
|
||||
|
||||
module.controller('AdminListOrgsCtrl', function($scope, backendSrv) {
|
||||
module.controller('AdminListOrgsCtrl', function($scope, backendSrv, navModelSrv) {
|
||||
|
||||
$scope.init = function() {
|
||||
$scope.navModel = navModelSrv.getAdminNav();
|
||||
$scope.getOrgs();
|
||||
};
|
||||
|
||||
|
@ -8,9 +8,11 @@ export default class AdminListUsersCtrl {
|
||||
totalPages: number;
|
||||
showPaging = false;
|
||||
query: any;
|
||||
navModel: any;
|
||||
|
||||
/** @ngInject */
|
||||
constructor(private $scope, private backendSrv) {
|
||||
constructor(private $scope, private backendSrv, private navModelSrv) {
|
||||
this.navModel = navModelSrv.getAdminNav();
|
||||
this.query = '';
|
||||
this.getUsers();
|
||||
}
|
||||
|
@ -1,5 +1,4 @@
|
||||
<navbar icon="fa fa-fw fa-cogs" title="Admin" title-url="admin">
|
||||
</navbar>
|
||||
<navbar model="ctrl.navModel"></navbar>
|
||||
|
||||
<div class="page-container">
|
||||
<div class="page-header">
|
||||
|
@ -1,9 +1,4 @@
|
||||
<navbar icon="fa fa-fw fa-cogs" title="Admin" title-url="admin">
|
||||
<a href="admin/orgs" class="navbar-page-btn">
|
||||
<i class="icon-gf icon-gf-users"></i>
|
||||
Orgs
|
||||
</a>
|
||||
</navbar>
|
||||
<navbar model="navModel"></navbar>
|
||||
|
||||
<div class="page-container">
|
||||
<div class="page-header">
|
||||
|
@ -1,9 +1,4 @@
|
||||
<navbar icon="fa fa-fw fa-cogs" title="Admin" title-url="admin">
|
||||
<a href="admin/users" class="navbar-page-btn">
|
||||
<i class="icon-gf icon-gf-users"></i>
|
||||
Users
|
||||
</a>
|
||||
</navbar>
|
||||
<navbar model="navModel"></navbar>
|
||||
|
||||
<div class="page-container">
|
||||
<div class="page-header">
|
||||
|
@ -1,9 +1,4 @@
|
||||
<navbar icon="fa fa-fw fa-cogs" title="Admin" title-url="admin">
|
||||
<a href="admin/users" class="navbar-page-btn">
|
||||
<i class="icon-gf icon-gf-users"></i>
|
||||
Users
|
||||
</a>
|
||||
</navbar>
|
||||
<navbar model="navModel"></navbar>
|
||||
|
||||
<div class="page-container">
|
||||
<div class="page-header">
|
||||
|
@ -1,9 +1,4 @@
|
||||
<navbar icon="fa fa-fw fa-cogs" title="Admin" title-url="admin">
|
||||
<a href="admin/orgs" class="navbar-page-btn">
|
||||
<i class="icon-gf icon-gf-users"></i>
|
||||
Orgs
|
||||
</a>
|
||||
</navbar>
|
||||
<navbar model="navModel"></navbar>
|
||||
|
||||
<div class="page-container">
|
||||
<div class="page-header">
|
||||
|
@ -1,5 +1,4 @@
|
||||
<navbar icon="fa fa-fw fa-cogs" title="Admin" title-url="admin">
|
||||
</navbar>
|
||||
<navbar model="ctrl.navModel"></navbar>
|
||||
|
||||
<div class="page-container">
|
||||
<div class="page-header">
|
||||
|
@ -1,5 +1,4 @@
|
||||
<navbar icon="fa fa-fw fa-cogs" title="Admin" title-url="admin">
|
||||
</navbar>
|
||||
<navbar model="ctrl.navModel"></navbar>
|
||||
|
||||
<div class="page-container">
|
||||
<div class="page-header">
|
||||
|
@ -1,9 +1,4 @@
|
||||
<navbar icon="fa fa-fw fa-cogs" title="Admin" title-url="admin">
|
||||
<a href="admin/users" class="navbar-page-btn">
|
||||
<i class="icon-gf icon-gf-users"></i>
|
||||
Users
|
||||
</a>
|
||||
</navbar>
|
||||
<navbar model="ctrl.navModel"></navbar>
|
||||
|
||||
<div class="page-container">
|
||||
<div class="page-header">
|
||||
@ -14,12 +9,14 @@
|
||||
Add new user
|
||||
</a>
|
||||
</div>
|
||||
<div class="search-field-wrapper pull-right width-18">
|
||||
|
||||
<div class="gf-form pull-right gf-form-group">
|
||||
<label class="gf-form-label">Search</label>
|
||||
<span style="position: relative;">
|
||||
<input type="text" placeholder="Find user by name/login/email" tabindex="1" give-focus="true"
|
||||
ng-model="ctrl.query" ng-model-options="{ debounce: 500 }" spellcheck='false' ng-change="ctrl.getUsers()" />
|
||||
<input class="gf-form-input width-15" type="text" placeholder="Find user by name/login/email" tabindex="1" give-focus="true" ng-model="ctrl.query" ng-model-options="{ debounce: 500 }" spellcheck='false' ng-change="ctrl.getUsers()" />
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div class="admin-list-table">
|
||||
<table class="filter-table form-inline">
|
||||
<thead>
|
||||
|
@ -2,13 +2,12 @@
|
||||
|
||||
import angular from 'angular';
|
||||
import _ from 'lodash';
|
||||
import coreModule from '../../core/core_module';
|
||||
import appEvents from '../../core/app_events';
|
||||
import moment from 'moment';
|
||||
|
||||
import {coreModule, appEvents} from 'app/core/core';
|
||||
import alertDef from './alert_def';
|
||||
|
||||
export class AlertListCtrl {
|
||||
|
||||
alerts: any;
|
||||
stateFilters = [
|
||||
{text: 'All', value: null},
|
||||
@ -17,13 +16,15 @@ export class AlertListCtrl {
|
||||
{text: 'No Data', value: 'no_data'},
|
||||
{text: 'Paused', value: 'paused'},
|
||||
];
|
||||
|
||||
filters = {
|
||||
state: 'ALL'
|
||||
};
|
||||
navModel: any;
|
||||
|
||||
/** @ngInject */
|
||||
constructor(private backendSrv, private $location, private $scope) {
|
||||
constructor(private backendSrv, private $location, private $scope, navModelSrv) {
|
||||
this.navModel = navModelSrv.getAlertingNav(0);
|
||||
|
||||
var params = $location.search();
|
||||
this.filters.state = params.state || null;
|
||||
this.loadAlerts();
|
||||
|
@ -7,6 +7,7 @@ import {appEvents, coreModule} from 'app/core/core';
|
||||
|
||||
export class AlertNotificationEditCtrl {
|
||||
theForm: any;
|
||||
navModel: any;
|
||||
testSeverity = "critical";
|
||||
notifiers: any;
|
||||
notifierTemplateId: string;
|
||||
@ -23,7 +24,9 @@ export class AlertNotificationEditCtrl {
|
||||
};
|
||||
|
||||
/** @ngInject */
|
||||
constructor(private $routeParams, private backendSrv, private $location, private $templateCache) {
|
||||
constructor(private $routeParams, private backendSrv, private $location, private $templateCache, navModelSrv) {
|
||||
this.navModel = navModelSrv.getAlertingNav();
|
||||
|
||||
this.backendSrv.get(`/api/alert-notifiers`).then(notifiers => {
|
||||
this.notifiers = notifiers;
|
||||
|
||||
|
@ -2,16 +2,19 @@
|
||||
|
||||
import angular from 'angular';
|
||||
import _ from 'lodash';
|
||||
import coreModule from '../../core/core_module';
|
||||
import config from 'app/core/config';
|
||||
|
||||
export class AlertNotificationsListCtrl {
|
||||
import {coreModule} from 'app/core/core';
|
||||
|
||||
|
||||
export class AlertNotificationsListCtrl {
|
||||
notifications: any;
|
||||
navModel: any;
|
||||
|
||||
/** @ngInject */
|
||||
constructor(private backendSrv, private $scope) {
|
||||
constructor(private backendSrv, private $scope, navModelSrv) {
|
||||
this.loadNotifications();
|
||||
this.navModel = navModelSrv.getAlertingNav(1);
|
||||
}
|
||||
|
||||
loadNotifications() {
|
||||
|
@ -1,5 +1,4 @@
|
||||
<navbar icon="icon-gf icon-gf-alert" title="Alerting" title-url="alerting">
|
||||
</navbar>
|
||||
<navbar model="ctrl.navModel"></navbar>
|
||||
|
||||
<div class="page-container" >
|
||||
<div class="page-header">
|
||||
|
@ -1,9 +1,4 @@
|
||||
<navbar icon="icon-gf icon-gf-alert" title="Alerting" title-url="alerting">
|
||||
<a href="alerting/notifications" class="navbar-page-btn">
|
||||
<i class="fa fa-fw fa-rss"></i>
|
||||
Notification channels
|
||||
</a>
|
||||
</navbar>
|
||||
<navbar model="ctrl.navModel"></navbar>
|
||||
|
||||
<div class="page-container">
|
||||
<div class="page-header">
|
||||
|
@ -1,5 +1,4 @@
|
||||
<navbar icon="icon-gf icon-gf-alert" title="Alerting" title-url="alerting">
|
||||
</navbar>
|
||||
<navbar model="ctrl.navModel"></navbar>
|
||||
|
||||
<div class="page-container" >
|
||||
<div class="page-header">
|
||||
|
@ -1,93 +1,62 @@
|
||||
<navbar>
|
||||
<navbar model="ctrl.navModel">
|
||||
|
||||
<a class="pointer navbar-page-btn" ng-if="::!dashboardMeta.isSnapshot" ng-click="openSearch()">
|
||||
<i class="icon-gf icon-gf-dashboard"></i>
|
||||
<span>{{dashboard.title}}</span>
|
||||
<i class="fa fa-caret-down"></i>
|
||||
</a>
|
||||
|
||||
<a class="pointer navbar-page-btn" ng-if="::dashboardMeta.isSnapshot" bs-tooltip="titleTooltip" data-placement="bottom" ng-click="openSearch()">
|
||||
<i class="icon-gf icon-gf-snapshot"></i>
|
||||
<span>
|
||||
{{dashboard.title}}
|
||||
<em class="small"> (snapshot)</em>
|
||||
</span>
|
||||
</a>
|
||||
|
||||
<ul class="nav dash-playlist-actions" ng-if="playlistSrv">
|
||||
<ul class="nav dash-playlist-actions" ng-if="ctrl.playlistSrv.isPlaying">
|
||||
<li>
|
||||
<a ng-click="playlistSrv.prev()"><i class="fa fa-step-backward"></i></a>
|
||||
<a ng-click="ctrl.playlistSrv.prev()"><i class="fa fa-step-backward"></i></a>
|
||||
</li>
|
||||
<li>
|
||||
<a ng-click="playlistSrv.stop()"><i class="fa fa-stop"></i></a>
|
||||
<a ng-click="ctrl.playlistSrv.stop()"><i class="fa fa-stop"></i></a>
|
||||
</li>
|
||||
<li>
|
||||
<a ng-click="playlistSrv.next()"><i class="fa fa-step-forward"></i></a>
|
||||
<a ng-click="ctrl.playlistSrv.next()"><i class="fa fa-step-forward"></i></a>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<ul class="nav pull-left dashnav-action-icons">
|
||||
<li ng-show="::dashboardMeta.canStar">
|
||||
<a class="pointer" ng-click="starDashboard()">
|
||||
<i class="fa" ng-class="{'fa-star-o': !dashboardMeta.isStarred, 'fa-star': dashboardMeta.isStarred}" style="color: orange;"></i>
|
||||
<li ng-show="::ctrl.dashboard.meta.canStar">
|
||||
<a class="pointer" ng-click="ctrl.starDashboard()">
|
||||
<i class="fa" ng-class="{'fa-star-o': !ctrl.dashboard.meta.isStarred, 'fa-star': ctrl.dashboard.meta.isStarred}" style="color: orange;"></i>
|
||||
</a>
|
||||
</li>
|
||||
<li ng-show="::dashboardMeta.canShare" class="dropdown">
|
||||
<a class="pointer" ng-click="hideTooltip($event)" bs-tooltip="'Share dashboard'" data-placement="bottom" data-toggle="dropdown"><i class="fa fa-share-square-o"></i></a>
|
||||
<li ng-show="::ctrl.dashboard.meta.canShare" class="dropdown">
|
||||
<a class="pointer" ng-click="ctrl.hideTooltip($event)" bs-tooltip="'Share dashboard'" data-placement="bottom" data-toggle="dropdown"><i class="fa fa-share-square-o"></i></a>
|
||||
<ul class="dropdown-menu">
|
||||
<li>
|
||||
<a class="pointer" ng-click="shareDashboard(0)">
|
||||
<a class="pointer" ng-click="ctrl.shareDashboard(0)">
|
||||
<i class="fa fa-link"></i> Link to Dashboard
|
||||
<div class="dropdown-desc">Share an internal link to the current dashboard. Some configuration options available.</div>
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a class="pointer" ng-click="shareDashboard(1)">
|
||||
<a class="pointer" ng-click="ctrl.shareDashboard(1)">
|
||||
<i class="icon-gf icon-gf-snapshot"></i>Snapshot
|
||||
<div class="dropdown-desc">Interactive, publically accessible dashboard. Sensitive data is stripped out.</div>
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a class="pointer" ng-click="shareDashboard(2)">
|
||||
<li>
|
||||
<a class="pointer" ng-click="ctrl.shareDashboard(2)">
|
||||
<i class="fa fa-cloud-upload"></i>Export
|
||||
<div class="dropdown-desc">Export the dashboard to a JSON file for others and to share on Grafana.com</div>
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li ng-show="::dashboardMeta.canSave">
|
||||
<a ng-click="saveDashboard()" bs-tooltip="'Save dashboard <br> CTRL+S'" data-placement="bottom"><i class="fa fa-save"></i></a>
|
||||
<li ng-show="::ctrl.dashboard.meta.canSave">
|
||||
<a ng-click="ctrl.saveDashboard()" bs-tooltip="'Save dashboard <br> CTRL+S'" data-placement="bottom"><i class="fa fa-save"></i></a>
|
||||
</li>
|
||||
<li ng-if="dashboard.snapshot.originalUrl">
|
||||
<a ng-href="{{dashboard.snapshot.originalUrl}}" bs-tooltip="'Open original dashboard'" data-placement="bottom"><i class="fa fa-link"></i></a>
|
||||
</li>
|
||||
<li ng-if="::showSettingsMenu" class="dropdown">
|
||||
<a class="pointer" ng-click="hideTooltip($event)" bs-tooltip="'Manage dashboard'" data-placement="bottom" data-toggle="dropdown"><i class="fa fa-cog"></i></a>
|
||||
<ul class="dropdown-menu">
|
||||
<li ng-if="dashboardMeta.canEdit"><a class="pointer" ng-click="openEditView('settings');">Settings</a></li>
|
||||
<li ng-if="dashboardMeta.canEdit"><a class="pointer" ng-click="openEditView('annotations');">Annotations</a></li>
|
||||
<li ng-if="dashboardMeta.canEdit"><a class="pointer" ng-click="openEditView('templating');">Templating</a></li>
|
||||
<li ng-if="dashboardMeta.canEdit"><a class="pointer" ng-click="viewJson();">View JSON</a></li>
|
||||
<li ng-if="contextSrv.isEditor && !dashboard.editable"><a class="pointer" ng-click="makeEditable();">Make Editable</a></li>
|
||||
<li ng-if="contextSrv.isEditor"><a class="pointer" ng-click="saveDashboardAs();">Save As...</a></li>
|
||||
<li class="dropdown-menu-item-with-shortcut">
|
||||
<a class="pointer" ng-click="showHelpModal();">
|
||||
Shortcuts <span class="dropdown-menu-item-shortcut">?</span>
|
||||
</a>
|
||||
</li>
|
||||
<li ng-if="dashboardMeta.canSave"><a class="pointer" ng-click="deleteDashboard();">Delete dashboard</a></li>
|
||||
</ul>
|
||||
<li ng-if="ctrl.dashboard.snapshot.originalUrl">
|
||||
<a ng-href="{{ctrl.dashboard.snapshot.originalUrl}}" bs-tooltip="'Open original dashboard'" data-placement="bottom"><i class="fa fa-link"></i></a>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<ul class="nav pull-right">
|
||||
<li ng-show="dashboard.meta.fullscreen" class="dashnav-back-to-dashboard">
|
||||
<a ng-click="exitFullscreen()">
|
||||
<li ng-show="ctrl.dashboard.meta.fullscreen" class="dashnav-back-to-dashboard">
|
||||
<a ng-click="ctrl.exitFullscreen()">
|
||||
Back to dashboard
|
||||
</a>
|
||||
</li>
|
||||
<li ng-if="dashboard">
|
||||
<gf-time-picker dashboard="dashboard"></gf-time-picker>
|
||||
<li>
|
||||
<gf-time-picker dashboard="ctrl.dashboard"></gf-time-picker>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
|
@ -3,92 +3,98 @@
|
||||
import _ from 'lodash';
|
||||
import moment from 'moment';
|
||||
import angular from 'angular';
|
||||
|
||||
import {appEvents, NavModel} from 'app/core/core';
|
||||
import {DashboardModel} from '../model';
|
||||
import {DashboardExporter} from '../export/exporter';
|
||||
|
||||
export class DashNavCtrl {
|
||||
dashboard: DashboardModel;
|
||||
navModel: NavModel;
|
||||
titleTooltip: string;
|
||||
|
||||
/** @ngInject */
|
||||
constructor($scope, $rootScope, dashboardSrv, $location, playlistSrv, backendSrv, $timeout, datasourceSrv) {
|
||||
constructor(
|
||||
private $scope,
|
||||
private $rootScope,
|
||||
private dashboardSrv,
|
||||
private $location,
|
||||
private playlistSrv,
|
||||
private backendSrv,
|
||||
private $timeout,
|
||||
private datasourceSrv,
|
||||
private navModelSrv) {
|
||||
|
||||
$scope.init = function() {
|
||||
$scope.onAppEvent('save-dashboard', $scope.saveDashboard);
|
||||
$scope.onAppEvent('delete-dashboard', $scope.deleteDashboard);
|
||||
$scope.onAppEvent('quick-snapshot', $scope.quickSnapshot);
|
||||
this.navModel = navModelSrv.getDashboardNav(this.dashboard, this);
|
||||
|
||||
$scope.showSettingsMenu = $scope.dashboardMeta.canEdit || $scope.contextSrv.isEditor;
|
||||
appEvents.on('save-dashboard', this.saveDashboard.bind(this), $scope);
|
||||
appEvents.on('delete-dashboard', this.deleteDashboard.bind(this), $scope);
|
||||
|
||||
if ($scope.dashboardMeta.isSnapshot) {
|
||||
$scope.showSettingsMenu = false;
|
||||
var meta = $scope.dashboardMeta;
|
||||
$scope.titleTooltip = 'Created: ' + moment(meta.created).calendar();
|
||||
if (this.dashboard.meta.isSnapshot) {
|
||||
var meta = this.dashboard.meta;
|
||||
this.titleTooltip = 'Created: ' + moment(meta.created).calendar();
|
||||
if (meta.expires) {
|
||||
$scope.titleTooltip += '<br>Expires: ' + moment(meta.expires).fromNow() + '<br>';
|
||||
this.titleTooltip += '<br>Expires: ' + moment(meta.expires).fromNow() + '<br>';
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
$scope.openEditView = function(editview) {
|
||||
var search = _.extend($location.search(), {editview: editview});
|
||||
$location.search(search);
|
||||
};
|
||||
openEditView(editview) {
|
||||
var search = _.extend(this.$location.search(), {editview: editview});
|
||||
this.$location.search(search);
|
||||
}
|
||||
|
||||
$scope.showHelpModal = function() {
|
||||
$scope.appEvent('show-modal', {templateHtml: '<help-modal></help-modal>'});
|
||||
};
|
||||
showHelpModal() {
|
||||
appEvents.emit('show-modal', {templateHtml: '<help-modal></help-modal>'});
|
||||
}
|
||||
|
||||
$scope.starDashboard = function() {
|
||||
if ($scope.dashboardMeta.isStarred) {
|
||||
backendSrv.delete('/api/user/stars/dashboard/' + $scope.dashboard.id).then(function() {
|
||||
$scope.dashboardMeta.isStarred = false;
|
||||
});
|
||||
} else {
|
||||
backendSrv.post('/api/user/stars/dashboard/' + $scope.dashboard.id).then(function() {
|
||||
$scope.dashboardMeta.isStarred = true;
|
||||
starDashboard() {
|
||||
if (this.dashboard.meta.isStarred) {
|
||||
return this.backendSrv.delete('/api/user/stars/dashboard/' + this.dashboard.id).then(() => {
|
||||
this.dashboard.meta.isStarred = false;
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
$scope.shareDashboard = function(tabIndex) {
|
||||
var modalScope = $scope.$new();
|
||||
this.backendSrv.post('/api/user/stars/dashboard/' + this.dashboard.id).then(() => {
|
||||
this.dashboard.meta.isStarred = true;
|
||||
});
|
||||
}
|
||||
|
||||
shareDashboard(tabIndex) {
|
||||
var modalScope = this.$scope.$new();
|
||||
modalScope.tabIndex = tabIndex;
|
||||
modalScope.dashboard = this.dashboard;
|
||||
|
||||
$scope.appEvent('show-modal', {
|
||||
appEvents.emit('show-modal', {
|
||||
src: 'public/app/features/dashboard/partials/shareModal.html',
|
||||
scope: modalScope
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
$scope.quickSnapshot = function() {
|
||||
$scope.shareDashboard(1);
|
||||
};
|
||||
|
||||
$scope.openSearch = function() {
|
||||
$scope.appEvent('show-dash-search');
|
||||
};
|
||||
|
||||
$scope.hideTooltip = function(evt) {
|
||||
hideTooltip(evt) {
|
||||
angular.element(evt.currentTarget).tooltip('hide');
|
||||
$scope.appEvent('hide-dash-search');
|
||||
};
|
||||
}
|
||||
|
||||
$scope.makeEditable = function() {
|
||||
$scope.dashboard.editable = true;
|
||||
makeEditable() {
|
||||
this.dashboard.editable = true;
|
||||
|
||||
return dashboardSrv.saveDashboard({makeEditable: true, overwrite: false}).then(function() {
|
||||
return this.dashboardSrv.saveDashboard({makeEditable: true, overwrite: false}).then(() => {
|
||||
// force refresh whole page
|
||||
window.location.href = window.location.href;
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
$scope.saveDashboard = function(options) {
|
||||
return dashboardSrv.saveDashboard(options);
|
||||
};
|
||||
exitFullscreen() {
|
||||
this.$rootScope.appEvent('panel-change-view', {fullscreen: false, edit: false});
|
||||
}
|
||||
|
||||
$scope.deleteDashboard = function() {
|
||||
saveDashboard(options) {
|
||||
return this.dashboardSrv.saveDashboard(options);
|
||||
}
|
||||
|
||||
deleteDashboard() {
|
||||
var confirmText = "";
|
||||
var text2 = $scope.dashboard.title;
|
||||
var alerts = $scope.dashboard.rows.reduce((memo, row) => {
|
||||
var text2 = this.dashboard.title;
|
||||
var alerts = this.dashboard.rows.reduce((memo, row) => {
|
||||
memo += row.panels.filter(panel => panel.alert).length;
|
||||
return memo;
|
||||
}, 0);
|
||||
@ -98,60 +104,37 @@ export class DashNavCtrl {
|
||||
text2 = `This dashboad contains ${alerts} alerts. Deleting this dashboad will also delete those alerts`;
|
||||
}
|
||||
|
||||
$scope.appEvent('confirm-modal', {
|
||||
appEvents.emit('confirm-modal', {
|
||||
title: 'Delete',
|
||||
text: 'Do you want to delete this dashboard?',
|
||||
text2: text2,
|
||||
icon: 'fa-trash',
|
||||
confirmText: confirmText,
|
||||
yesText: 'Delete',
|
||||
onConfirm: function() {
|
||||
$scope.dashboardMeta.canSave = false;
|
||||
$scope.deleteDashboardConfirmed();
|
||||
onConfirm: () => {
|
||||
this.dashboard.meta.canSave = false;
|
||||
this.deleteDashboardConfirmed();
|
||||
}
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
$scope.deleteDashboardConfirmed = function() {
|
||||
backendSrv.delete('/api/dashboards/db/' + $scope.dashboardMeta.slug).then(function() {
|
||||
$scope.appEvent('alert-success', ['Dashboard Deleted', $scope.dashboard.title + ' has been deleted']);
|
||||
$location.url('/');
|
||||
deleteDashboardConfirmed() {
|
||||
this.backendSrv.delete('/api/dashboards/db/' + this.dashboard.meta.slug).then(() => {
|
||||
appEvents.emit('alert-success', ['Dashboard Deleted', this.dashboard.title + ' has been deleted']);
|
||||
this.$location.url('/');
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
$scope.saveDashboardAs = function() {
|
||||
return dashboardSrv.saveDashboardAs();
|
||||
};
|
||||
saveDashboardAs() {
|
||||
return this.dashboardSrv.saveDashboardAs();
|
||||
}
|
||||
|
||||
$scope.viewJson = function() {
|
||||
var clone = $scope.dashboard.getSaveModelClone();
|
||||
viewJson() {
|
||||
var clone = this.dashboard.getSaveModelClone();
|
||||
var html = angular.toJson(clone, true);
|
||||
var uri = "data:application/json;charset=utf-8," + encodeURIComponent(html);
|
||||
var newWindow = window.open(uri);
|
||||
};
|
||||
|
||||
$scope.snapshot = function() {
|
||||
$scope.dashboard.snapshot = true;
|
||||
$rootScope.$broadcast('refresh');
|
||||
|
||||
$timeout(function() {
|
||||
$scope.dashboard.snapshot = false;
|
||||
$scope.appEvent('dashboard-snapshot-cleanup');
|
||||
}, 1000);
|
||||
|
||||
};
|
||||
|
||||
$scope.editJson = function() {
|
||||
var clone = $scope.dashboard.getSaveModelClone();
|
||||
$scope.appEvent('show-json-editor', { object: clone });
|
||||
};
|
||||
|
||||
$scope.stopPlaylist = function() {
|
||||
playlistSrv.stop(1);
|
||||
};
|
||||
|
||||
$scope.init();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export function dashNavDirective() {
|
||||
@ -159,7 +142,10 @@ export function dashNavDirective() {
|
||||
restrict: 'E',
|
||||
templateUrl: 'public/app/features/dashboard/dashnav/dashnav.html',
|
||||
controller: DashNavCtrl,
|
||||
bindToController: true,
|
||||
controllerAs: 'ctrl',
|
||||
transclude: true,
|
||||
scope: { dashboard: "=" }
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -20,12 +20,6 @@ function (angular, _, $, config) {
|
||||
self.$scope = $scope;
|
||||
self.dashboard = $scope.dashboard;
|
||||
|
||||
$scope.exitFullscreen = function() {
|
||||
if (self.state.fullscreen) {
|
||||
self.update({ fullscreen: false });
|
||||
}
|
||||
};
|
||||
|
||||
$scope.onAppEvent('$routeUpdate', function() {
|
||||
var urlState = self.getQueryStringState();
|
||||
if (self.needsSync(urlState)) {
|
||||
@ -41,6 +35,9 @@ function (angular, _, $, config) {
|
||||
self.registerPanel(payload.scope);
|
||||
});
|
||||
|
||||
// this marks changes to location during this digest cycle as not to add history item
|
||||
// dont want url changes like adding orgId to add browser history
|
||||
$location.replace();
|
||||
this.update(this.getQueryStringState());
|
||||
this.expandRowForPanel();
|
||||
}
|
||||
|
@ -7,11 +7,12 @@ function (angular, config) {
|
||||
|
||||
var module = angular.module('grafana.controllers');
|
||||
|
||||
module.controller('ChangePasswordCtrl', function($scope, backendSrv, $location) {
|
||||
module.controller('ChangePasswordCtrl', function($scope, backendSrv, $location, navModelSrv) {
|
||||
|
||||
$scope.command = {};
|
||||
$scope.authProxyEnabled = config.authProxyEnabled;
|
||||
$scope.ldapEnabled = config.ldapEnabled;
|
||||
$scope.navModel = navModelSrv.getProfileNav();
|
||||
|
||||
$scope.changePassword = function() {
|
||||
if (!$scope.userForm.$valid) { return; }
|
||||
|
@ -7,8 +7,9 @@ function (angular, config) {
|
||||
|
||||
var module = angular.module('grafana.controllers');
|
||||
|
||||
module.controller('NewOrgCtrl', function($scope, $http, backendSrv) {
|
||||
module.controller('NewOrgCtrl', function($scope, $http, backendSrv, navModelSrv) {
|
||||
|
||||
$scope.navModel = navModelSrv.getOrgNav(0);
|
||||
$scope.newOrg = {name: ''};
|
||||
|
||||
$scope.createOrg = function() {
|
||||
|
@ -6,8 +6,9 @@ function (angular) {
|
||||
|
||||
var module = angular.module('grafana.controllers');
|
||||
|
||||
module.controller('OrgApiKeysCtrl', function($scope, $http, backendSrv) {
|
||||
module.controller('OrgApiKeysCtrl', function($scope, $http, backendSrv, navModelSrv) {
|
||||
|
||||
$scope.navModel = navModelSrv.getOrgNav(0);
|
||||
$scope.roleTypes = ['Viewer', 'Editor', 'Admin'];
|
||||
$scope.token = { role: 'Viewer' };
|
||||
|
||||
|
@ -6,10 +6,11 @@ function (angular) {
|
||||
|
||||
var module = angular.module('grafana.controllers');
|
||||
|
||||
module.controller('OrgDetailsCtrl', function($scope, $http, backendSrv, contextSrv) {
|
||||
module.controller('OrgDetailsCtrl', function($scope, $http, backendSrv, contextSrv, navModelSrv) {
|
||||
|
||||
$scope.init = function() {
|
||||
$scope.getOrgInfo();
|
||||
$scope.navModel = navModelSrv.getOrgNav(0);
|
||||
};
|
||||
|
||||
$scope.getOrgInfo = function() {
|
||||
|
@ -11,13 +11,15 @@ export class OrgUsersCtrl {
|
||||
pendingInvites: any;
|
||||
editor: any;
|
||||
showInviteUI: boolean;
|
||||
navModel: any;
|
||||
|
||||
/** @ngInject */
|
||||
constructor(private $scope, private $http, private backendSrv) {
|
||||
constructor(private $scope, private $http, private backendSrv, navModelSrv) {
|
||||
this.user = {
|
||||
loginOrEmail: '',
|
||||
role: 'Viewer',
|
||||
};
|
||||
this.navModel = navModelSrv.getOrgNav(0);
|
||||
|
||||
this.get();
|
||||
this.editor = { index: 0 };
|
||||
|
@ -1,5 +1,4 @@
|
||||
<navbar icon="icon-gf icon-gf-users" title="Profile" title-url="profile">
|
||||
</navbar>
|
||||
<navbar model="navModel"></navbar>
|
||||
|
||||
<div class="page-container">
|
||||
<div class="page-header">
|
||||
|
@ -1,5 +1,4 @@
|
||||
<navbar title="Organization" icon="icon-gf icon-gf-users">
|
||||
</navbar>
|
||||
<navbar model="navModel"></navbar>
|
||||
|
||||
<div class="page-container" ng-form="playlistEditForm">
|
||||
<div class="page-header">
|
||||
|
@ -1,5 +1,4 @@
|
||||
<navbar icon="icon-gf icon-gf-users" title="Organization" title-url="org">
|
||||
</navbar>
|
||||
<navbar model="navModel"></navbar>
|
||||
|
||||
<div class="page-container">
|
||||
<div class="page-header">
|
||||
|
@ -1,5 +1,4 @@
|
||||
<navbar icon="icon-gf icon-gf-users" title="Organization" title-url="org">
|
||||
</navbar>
|
||||
<navbar model="navModel"></navbar>
|
||||
|
||||
<div class="page-container">
|
||||
<div class="page-header">
|
||||
|
@ -1,5 +1,4 @@
|
||||
<navbar icon="icon-gf icon-gf-users" title="Organization Users" title-url="org/users">
|
||||
</navbar>
|
||||
<navbar model="ctrl.navModel"></navbar>
|
||||
|
||||
<div class="page-container">
|
||||
<div class="page-header">
|
||||
|
@ -1,9 +1,8 @@
|
||||
<navbar icon="icon-gf icon-gf-users" title="Profile" title-url="profile">
|
||||
</navbar>
|
||||
<navbar model="ctrl.navModel"></navbar>
|
||||
|
||||
<div class="page-container">
|
||||
<div class="page-header">
|
||||
<h1>Profile</h1>
|
||||
<h1>User Profile</h1>
|
||||
</div>
|
||||
|
||||
<form name="ctrl.userForm" class="gf-form-group">
|
||||
|
@ -11,11 +11,13 @@ export class ProfileCtrl {
|
||||
userForm: any;
|
||||
showOrgsList = false;
|
||||
readonlyLoginFields = config.disableLoginForm;
|
||||
navModel: any;
|
||||
|
||||
/** @ngInject **/
|
||||
constructor(private backendSrv, private contextSrv, private $location) {
|
||||
constructor(private backendSrv, private contextSrv, private $location, navModelSrv) {
|
||||
this.getUser();
|
||||
this.getUserOrgs();
|
||||
this.navModel = navModelSrv.getProfileNav();
|
||||
}
|
||||
|
||||
getUser() {
|
||||
|
@ -1,5 +1,4 @@
|
||||
<navbar icon="fa fa-fw fa-list" title="Playlists" title-url="playlists">
|
||||
</navbar>
|
||||
<navbar model="ctrl.navModel"></navbar>
|
||||
|
||||
<div class="page-container" ng-form="playlistEditForm">
|
||||
<div class="page-header">
|
||||
|
@ -1,5 +1,4 @@
|
||||
<navbar icon="fa fa-fw fa-list" title="Playlists" title-url="playlists">
|
||||
</navbar>
|
||||
<navbar model="ctrl.navModel"></navbar>
|
||||
|
||||
<div class="page-container">
|
||||
<div class="page-header">
|
||||
|
@ -16,21 +16,30 @@ export class PlaylistEditCtrl {
|
||||
playlistItems: any = [];
|
||||
dashboardresult: any = [];
|
||||
tagresult: any = [];
|
||||
navModel: any;
|
||||
|
||||
/** @ngInject */
|
||||
constructor(private $scope, private playlistSrv, private backendSrv, private $location, private $route) {
|
||||
constructor(
|
||||
private $scope,
|
||||
private playlistSrv,
|
||||
private backendSrv,
|
||||
private $location,
|
||||
private $route,
|
||||
private navModelSrv
|
||||
) {
|
||||
|
||||
this.navModel = navModelSrv.getPlaylistsNav(0);
|
||||
|
||||
if ($route.current.params.id) {
|
||||
var playlistId = $route.current.params.id;
|
||||
|
||||
backendSrv.get('/api/playlists/' + playlistId)
|
||||
.then((result) => {
|
||||
this.playlist = result;
|
||||
});
|
||||
backendSrv.get('/api/playlists/' + playlistId).then(result => {
|
||||
this.playlist = result;
|
||||
});
|
||||
|
||||
backendSrv.get('/api/playlists/' + playlistId + '/items')
|
||||
.then((result) => {
|
||||
this.playlistItems = result;
|
||||
});
|
||||
backendSrv.get('/api/playlists/' + playlistId + '/items').then(result => {
|
||||
this.playlistItems = result;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@ -85,7 +94,7 @@ export class PlaylistEditCtrl {
|
||||
? this.backendSrv.put('/api/playlists/' + playlist.id, playlist)
|
||||
: this.backendSrv.post('/api/playlists', playlist);
|
||||
|
||||
savePromise
|
||||
savePromise
|
||||
.then(() => {
|
||||
this.$scope.appEvent('alert-success', ['Playlist saved', '']);
|
||||
this.$location.path('/playlists');
|
||||
|
@ -11,6 +11,7 @@ class PlaylistSrv {
|
||||
private interval: any;
|
||||
private playlistId: number;
|
||||
private startUrl: string;
|
||||
public isPlaying: boolean;
|
||||
|
||||
/** @ngInject */
|
||||
constructor(private $rootScope: any, private $location: any, private $timeout: any, private backendSrv: any) { }
|
||||
@ -42,7 +43,7 @@ class PlaylistSrv {
|
||||
this.startUrl = window.location.href;
|
||||
this.index = 0;
|
||||
this.playlistId = playlistId;
|
||||
this.$rootScope.playlistSrv = this;
|
||||
this.isPlaying = true;
|
||||
|
||||
this.backendSrv.get(`/api/playlists/${playlistId}`).then(playlist => {
|
||||
this.backendSrv.get(`/api/playlists/${playlistId}/dashboards`).then(dashboards => {
|
||||
@ -55,13 +56,12 @@ class PlaylistSrv {
|
||||
|
||||
stop() {
|
||||
this.index = 0;
|
||||
this.isPlaying = false;
|
||||
this.playlistId = 0;
|
||||
|
||||
if (this.cancelPromise) {
|
||||
this.$timeout.cancel(this.cancelPromise);
|
||||
}
|
||||
|
||||
this.$rootScope.playlistSrv = null;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -6,20 +6,22 @@ import coreModule from '../../core/core_module';
|
||||
|
||||
export class PlaylistsCtrl {
|
||||
playlists: any;
|
||||
navModel: any;
|
||||
|
||||
/** @ngInject */
|
||||
constructor(private $scope, private $location, private backendSrv) {
|
||||
backendSrv.get('/api/playlists')
|
||||
.then((result) => {
|
||||
this.playlists = result;
|
||||
});
|
||||
constructor(private $scope, private $location, private backendSrv, private navModelSrv) {
|
||||
this.navModel = navModelSrv.getPlaylistsNav(0);
|
||||
|
||||
backendSrv.get('/api/playlists').then(result => {
|
||||
this.playlists = result;
|
||||
});
|
||||
}
|
||||
|
||||
removePlaylistConfirmed(playlist) {
|
||||
_.remove(this.playlists, { id: playlist.id });
|
||||
|
||||
this.backendSrv.delete('/api/playlists/' + playlist.id)
|
||||
.then(() => {
|
||||
.then(() => {
|
||||
this.$scope.appEvent('alert-success', ['Playlist deleted', '']);
|
||||
}, () => {
|
||||
this.$scope.appEvent('alert-error', ['Unable to delete playlist', '']);
|
||||
|
@ -5,7 +5,11 @@ import {PlaylistEditCtrl} from '../playlist_edit_ctrl';
|
||||
describe('PlaylistEditCtrl', () => {
|
||||
var ctx: any;
|
||||
beforeEach(() => {
|
||||
ctx = new PlaylistEditCtrl(null, null, null, null, { current: { params: {} } });
|
||||
let navModelSrv = {
|
||||
getPlaylistsNav: page => {},
|
||||
};
|
||||
|
||||
ctx = new PlaylistEditCtrl(null, null, null, null, { current: { params: {} } }, navModelSrv);
|
||||
|
||||
ctx.dashboardresult = [
|
||||
{ id: 2, title: 'dashboard: 2' },
|
||||
|
@ -30,6 +30,7 @@ export class DataSourceEditCtrl {
|
||||
hasDashboards: boolean;
|
||||
editForm: any;
|
||||
gettingStarted: boolean;
|
||||
navModel: any;
|
||||
|
||||
/** @ngInject */
|
||||
constructor(
|
||||
@ -38,141 +39,144 @@ export class DataSourceEditCtrl {
|
||||
private backendSrv,
|
||||
private $routeParams,
|
||||
private $location,
|
||||
private datasourceSrv) {
|
||||
private datasourceSrv,
|
||||
private navModelSrv,
|
||||
) {
|
||||
|
||||
this.isNew = true;
|
||||
this.datasources = [];
|
||||
this.tabIndex = 0;
|
||||
this.navModel = navModelSrv.getDatasourceNav(0);
|
||||
this.isNew = true;
|
||||
this.datasources = [];
|
||||
this.tabIndex = 0;
|
||||
|
||||
this.loadDatasourceTypes().then(() => {
|
||||
if (this.$routeParams.id) {
|
||||
this.getDatasourceById(this.$routeParams.id);
|
||||
} else {
|
||||
this.initNewDatasourceModel();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
initNewDatasourceModel() {
|
||||
this.current = angular.copy(defaults);
|
||||
|
||||
// We are coming from getting started
|
||||
if (this.$location.search().gettingstarted) {
|
||||
this.gettingStarted = true;
|
||||
this.current.isDefault = true;
|
||||
this.loadDatasourceTypes().then(() => {
|
||||
if (this.$routeParams.id) {
|
||||
this.getDatasourceById(this.$routeParams.id);
|
||||
} else {
|
||||
this.initNewDatasourceModel();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
this.typeChanged();
|
||||
initNewDatasourceModel() {
|
||||
this.current = angular.copy(defaults);
|
||||
|
||||
// We are coming from getting started
|
||||
if (this.$location.search().gettingstarted) {
|
||||
this.gettingStarted = true;
|
||||
this.current.isDefault = true;
|
||||
}
|
||||
|
||||
loadDatasourceTypes() {
|
||||
if (datasourceTypes.length > 0) {
|
||||
this.types = datasourceTypes;
|
||||
return this.$q.when(null);
|
||||
this.typeChanged();
|
||||
}
|
||||
|
||||
loadDatasourceTypes() {
|
||||
if (datasourceTypes.length > 0) {
|
||||
this.types = datasourceTypes;
|
||||
return this.$q.when(null);
|
||||
}
|
||||
|
||||
return this.backendSrv.get('/api/plugins', {enabled: 1, type: 'datasource'}).then(plugins => {
|
||||
datasourceTypes = plugins;
|
||||
this.types = plugins;
|
||||
});
|
||||
}
|
||||
|
||||
getDatasourceById(id) {
|
||||
this.backendSrv.get('/api/datasources/' + id).then(ds => {
|
||||
this.isNew = false;
|
||||
this.current = ds;
|
||||
if (datasourceCreated) {
|
||||
datasourceCreated = false;
|
||||
this.testDatasource();
|
||||
}
|
||||
return this.typeChanged();
|
||||
});
|
||||
}
|
||||
|
||||
return this.backendSrv.get('/api/plugins', {enabled: 1, type: 'datasource'}).then(plugins => {
|
||||
datasourceTypes = plugins;
|
||||
this.types = plugins;
|
||||
});
|
||||
}
|
||||
typeChanged() {
|
||||
this.hasDashboards = false;
|
||||
return this.backendSrv.get('/api/plugins/' + this.current.type + '/settings').then(pluginInfo => {
|
||||
this.datasourceMeta = pluginInfo;
|
||||
console.log(this.datasourceMeta) ;
|
||||
this.hasDashboards = _.find(pluginInfo.includes, {type: 'dashboard'});
|
||||
});
|
||||
}
|
||||
|
||||
getDatasourceById(id) {
|
||||
this.backendSrv.get('/api/datasources/' + id).then(ds => {
|
||||
this.isNew = false;
|
||||
this.current = ds;
|
||||
if (datasourceCreated) {
|
||||
datasourceCreated = false;
|
||||
this.testDatasource();
|
||||
}
|
||||
return this.typeChanged();
|
||||
});
|
||||
}
|
||||
updateFrontendSettings() {
|
||||
return this.backendSrv.get('/api/frontend/settings').then(settings => {
|
||||
config.datasources = settings.datasources;
|
||||
config.defaultDatasource = settings.defaultDatasource;
|
||||
this.datasourceSrv.init();
|
||||
});
|
||||
}
|
||||
|
||||
typeChanged() {
|
||||
this.hasDashboards = false;
|
||||
return this.backendSrv.get('/api/plugins/' + this.current.type + '/settings').then(pluginInfo => {
|
||||
this.datasourceMeta = pluginInfo;
|
||||
console.log(this.datasourceMeta) ;
|
||||
this.hasDashboards = _.find(pluginInfo.includes, {type: 'dashboard'});
|
||||
});
|
||||
}
|
||||
testDatasource() {
|
||||
this.testing = { done: false };
|
||||
|
||||
updateFrontendSettings() {
|
||||
return this.backendSrv.get('/api/frontend/settings').then(settings => {
|
||||
config.datasources = settings.datasources;
|
||||
config.defaultDatasource = settings.defaultDatasource;
|
||||
this.datasourceSrv.init();
|
||||
});
|
||||
}
|
||||
|
||||
testDatasource() {
|
||||
this.testing = { done: false };
|
||||
|
||||
this.datasourceSrv.get(this.current.name).then(datasource => {
|
||||
if (!datasource.testDatasource) {
|
||||
delete this.testing;
|
||||
return;
|
||||
}
|
||||
|
||||
return datasource.testDatasource().then(result => {
|
||||
this.testing.message = result.message;
|
||||
this.testing.status = result.status;
|
||||
this.testing.title = result.title;
|
||||
}).catch(err => {
|
||||
if (err.statusText) {
|
||||
this.testing.message = err.statusText;
|
||||
this.testing.title = "HTTP Error";
|
||||
} else {
|
||||
this.testing.message = err.message;
|
||||
this.testing.title = "Unknown error";
|
||||
}
|
||||
});
|
||||
}).finally(() => {
|
||||
if (this.testing) {
|
||||
this.testing.done = true;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
saveChanges() {
|
||||
if (!this.editForm.$valid) {
|
||||
this.datasourceSrv.get(this.current.name).then(datasource => {
|
||||
if (!datasource.testDatasource) {
|
||||
delete this.testing;
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.current.id) {
|
||||
return this.backendSrv.put('/api/datasources/' + this.current.id, this.current).then(() => {
|
||||
this.updateFrontendSettings().then(() => {
|
||||
this.testDatasource();
|
||||
});
|
||||
});
|
||||
} else {
|
||||
return this.backendSrv.post('/api/datasources', this.current).then(result => {
|
||||
this.updateFrontendSettings();
|
||||
|
||||
datasourceCreated = true;
|
||||
this.$location.path('datasources/edit/' + result.id);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
confirmDelete() {
|
||||
this.backendSrv.delete('/api/datasources/' + this.current.id).then(() => {
|
||||
this.$location.path('datasources');
|
||||
});
|
||||
}
|
||||
|
||||
delete(s) {
|
||||
appEvents.emit('confirm-modal', {
|
||||
title: 'Delete',
|
||||
text: 'Are you sure you want to delete this datasource?',
|
||||
yesText: "Delete",
|
||||
icon: "fa-trash",
|
||||
onConfirm: () => {
|
||||
this.confirmDelete();
|
||||
return datasource.testDatasource().then(result => {
|
||||
this.testing.message = result.message;
|
||||
this.testing.status = result.status;
|
||||
this.testing.title = result.title;
|
||||
}).catch(err => {
|
||||
if (err.statusText) {
|
||||
this.testing.message = err.statusText;
|
||||
this.testing.title = "HTTP Error";
|
||||
} else {
|
||||
this.testing.message = err.message;
|
||||
this.testing.title = "Unknown error";
|
||||
}
|
||||
});
|
||||
}).finally(() => {
|
||||
if (this.testing) {
|
||||
this.testing.done = true;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
saveChanges() {
|
||||
if (!this.editForm.$valid) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.current.id) {
|
||||
return this.backendSrv.put('/api/datasources/' + this.current.id, this.current).then(() => {
|
||||
this.updateFrontendSettings().then(() => {
|
||||
this.testDatasource();
|
||||
});
|
||||
});
|
||||
} else {
|
||||
return this.backendSrv.post('/api/datasources', this.current).then(result => {
|
||||
this.updateFrontendSettings();
|
||||
|
||||
datasourceCreated = true;
|
||||
this.$location.path('datasources/edit/' + result.id);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
confirmDelete() {
|
||||
this.backendSrv.delete('/api/datasources/' + this.current.id).then(() => {
|
||||
this.$location.path('datasources');
|
||||
});
|
||||
}
|
||||
|
||||
delete(s) {
|
||||
appEvents.emit('confirm-modal', {
|
||||
title: 'Delete',
|
||||
text: 'Are you sure you want to delete this datasource?',
|
||||
yesText: "Delete",
|
||||
icon: "fa-trash",
|
||||
onConfirm: () => {
|
||||
this.confirmDelete();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
coreModule.controller('DataSourceEditCtrl', DataSourceEditCtrl);
|
||||
|
@ -6,31 +6,41 @@ import coreModule from '../../core/core_module';
|
||||
|
||||
export class DataSourcesCtrl {
|
||||
datasources: any;
|
||||
navModel: any;
|
||||
|
||||
/** @ngInject */
|
||||
constructor(private $scope, private $location, private $http, private backendSrv, private datasourceSrv) {
|
||||
backendSrv.get('/api/datasources')
|
||||
.then((result) => {
|
||||
this.datasources = result;
|
||||
});
|
||||
constructor(
|
||||
private $scope,
|
||||
private $location,
|
||||
private $http,
|
||||
private backendSrv,
|
||||
private datasourceSrv,
|
||||
private navModelSrv
|
||||
) {
|
||||
|
||||
this.navModel = this.navModelSrv.getDatasourceNav(0);
|
||||
|
||||
backendSrv.get('/api/datasources').then(result => {
|
||||
this.datasources = result;
|
||||
});
|
||||
}
|
||||
|
||||
removeDataSourceConfirmed(ds) {
|
||||
|
||||
this.backendSrv.delete('/api/datasources/' + ds.id)
|
||||
.then(() => {
|
||||
this.$scope.appEvent('alert-success', ['Datasource deleted', '']);
|
||||
}, () => {
|
||||
this.$scope.appEvent('alert-error', ['Unable to delete datasource', '']);
|
||||
}).then(() => {
|
||||
.then(() => {
|
||||
this.$scope.appEvent('alert-success', ['Datasource deleted', '']);
|
||||
}, () => {
|
||||
this.$scope.appEvent('alert-error', ['Unable to delete datasource', '']);
|
||||
}).then(() => {
|
||||
this.backendSrv.get('/api/datasources')
|
||||
.then((result) => {
|
||||
this.datasources = result;
|
||||
});
|
||||
.then((result) => {
|
||||
this.datasources = result;
|
||||
});
|
||||
this.backendSrv.get('/api/frontend/settings')
|
||||
.then((settings) => {
|
||||
this.datasourceSrv.init(settings.datasources);
|
||||
});
|
||||
.then((settings) => {
|
||||
this.datasourceSrv.init(settings.datasources);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,4 @@
|
||||
<navbar title="Data Sources" title-url="datasources" icon="icon-gf icon-gf-datasources">
|
||||
</navbar>
|
||||
<navbar model="ctrl.navModel"></navbar>
|
||||
|
||||
<div class="page-container">
|
||||
|
||||
|
@ -1,8 +1,4 @@
|
||||
<navbar
|
||||
title="Data Sources"
|
||||
title-url="datasources"
|
||||
icon="icon-gf icon-gf-datasources">
|
||||
</navbar>
|
||||
<navbar model="ctrl.navModel"></navbar>
|
||||
|
||||
<div class="page-container">
|
||||
<div class="page-header">
|
||||
|
@ -1,5 +1,4 @@
|
||||
<navbar title="Plugins" title-url="plugins" icon="icon-gf icon-gf-apps">
|
||||
</navbar>
|
||||
<navbar model="ctrl.navModel"></navbar>
|
||||
|
||||
<div class="page-container" ng-init="ctrl.init()">
|
||||
<div class="page-header">
|
||||
|
@ -1,5 +1,4 @@
|
||||
<navbar title="Plugins" icon="icon-gf icon-gf-apps" title-url="plugins">
|
||||
</navbar>
|
||||
<navbar model="ctrl.navModel"></navbar>
|
||||
|
||||
<div class="page-container">
|
||||
<div class="page-header">
|
||||
|
@ -1,5 +1,4 @@
|
||||
<navbar icon-url="{{ctrl.appLogoUrl}}" title="{{ctrl.appModel.name}}" title-url="{{ctrl.appModel.defaultNavUrl}}">
|
||||
</navbar>
|
||||
<navbar model="ctrl.navModel" ng-if="ctrl.navModel"></navbar>
|
||||
|
||||
<div class="page-container" >
|
||||
<div ng-if="ctrl.page">
|
||||
|
@ -13,17 +13,22 @@ export class PluginEditCtrl {
|
||||
includedDatasources: any;
|
||||
tabIndex: number;
|
||||
tabs: any;
|
||||
navModel: any;
|
||||
hasDashboards: any;
|
||||
preUpdateHook: () => any;
|
||||
postUpdateHook: () => any;
|
||||
|
||||
/** @ngInject */
|
||||
constructor(private $scope,
|
||||
private $rootScope,
|
||||
private backendSrv,
|
||||
private $routeParams,
|
||||
private $sce,
|
||||
private $http) {
|
||||
constructor(
|
||||
private $scope,
|
||||
private $rootScope,
|
||||
private backendSrv,
|
||||
private $routeParams,
|
||||
private $sce,
|
||||
private $http,
|
||||
private navModelSrv,
|
||||
) {
|
||||
this.navModel = navModelSrv.getPluginsNav();
|
||||
this.model = {};
|
||||
this.pluginId = $routeParams.pluginId;
|
||||
this.tabIndex = 0;
|
||||
@ -31,7 +36,7 @@ export class PluginEditCtrl {
|
||||
|
||||
this.preUpdateHook = () => Promise.resolve();
|
||||
this.postUpdateHook = () => Promise.resolve();
|
||||
}
|
||||
}
|
||||
|
||||
init() {
|
||||
return this.backendSrv.get(`/api/plugins/${this.pluginId}/settings`).then(result => {
|
||||
|
@ -5,10 +5,12 @@ import angular from 'angular';
|
||||
export class PluginListCtrl {
|
||||
plugins: any[];
|
||||
tabIndex: number;
|
||||
navModel: any;
|
||||
|
||||
/** @ngInject */
|
||||
constructor(private backendSrv: any, $location) {
|
||||
constructor(private backendSrv: any, $location, navModelSrv) {
|
||||
this.tabIndex = 0;
|
||||
this.navModel = navModelSrv.getPluginsNav();
|
||||
|
||||
var pluginType = $location.search().type || 'panel';
|
||||
switch (pluginType) {
|
||||
|
@ -2,6 +2,7 @@
|
||||
|
||||
import angular from 'angular';
|
||||
import _ from 'lodash';
|
||||
import {NavModel} from 'app/core/core';
|
||||
|
||||
var pluginInfoCache = {};
|
||||
|
||||
@ -9,7 +10,7 @@ export class AppPageCtrl {
|
||||
page: any;
|
||||
pluginId: any;
|
||||
appModel: any;
|
||||
appLogoUrl: any;
|
||||
navModel: NavModel;
|
||||
|
||||
/** @ngInject */
|
||||
constructor(private backendSrv, private $routeParams: any, private $rootScope) {
|
||||
@ -25,13 +26,53 @@ export class AppPageCtrl {
|
||||
initPage(app) {
|
||||
this.appModel = app;
|
||||
this.page = _.find(app.includes, {slug: this.$routeParams.slug});
|
||||
this.appLogoUrl = app.info.logos.small;
|
||||
|
||||
pluginInfoCache[this.pluginId] = app;
|
||||
|
||||
if (!this.page) {
|
||||
this.$rootScope.appEvent('alert-error', ['App Page Not Found', '']);
|
||||
|
||||
this.navModel = {
|
||||
section: {
|
||||
title: "Page not found",
|
||||
url: app.defaultNavUrl,
|
||||
icon: 'icon-gf icon-gf-sadface',
|
||||
},
|
||||
menu: [],
|
||||
};
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
let menu = [];
|
||||
|
||||
for (let item of app.includes) {
|
||||
if (item.addToNav) {
|
||||
if (item.type === 'dashboard') {
|
||||
menu.push({
|
||||
title: item.name,
|
||||
url: 'dashboard/db/' + item.slug,
|
||||
icon: 'fa fa-fw fa-dot-circle-o',
|
||||
});
|
||||
}
|
||||
if (item.type === 'page') {
|
||||
menu.push({
|
||||
title: item.name,
|
||||
url: `plugins/${app.id}/page/${item.slug}`,
|
||||
icon: 'fa fa-fw fa-dot-circle-o',
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
this.navModel = {
|
||||
section: {
|
||||
title: app.name,
|
||||
url: app.defaultNavUrl,
|
||||
iconUrl: app.info.logos.small,
|
||||
},
|
||||
menu: menu,
|
||||
};
|
||||
}
|
||||
|
||||
loadPluginInfo() {
|
||||
|
@ -1,5 +1,4 @@
|
||||
<navbar icon="icon-gf icon-gf-snapshot" title="Snapshots" title-url="dashboard/snapshots">
|
||||
</navbar>
|
||||
<navbar model="ctrl.navModel"></navbar>
|
||||
|
||||
<div class="page-container">
|
||||
<div class="page-header">
|
||||
|
@ -4,11 +4,20 @@ import angular from 'angular';
|
||||
import _ from 'lodash';
|
||||
|
||||
export class SnapshotsCtrl {
|
||||
|
||||
navModel: any;
|
||||
snapshots: any;
|
||||
|
||||
/** @ngInject */
|
||||
constructor(private $rootScope, private backendSrv) {
|
||||
this.navModel = {
|
||||
section: {
|
||||
title: 'Snapshots',
|
||||
icon: 'icon-gf icon-gf-snapshot',
|
||||
url: 'dashboard/snapshots',
|
||||
},
|
||||
menu: [],
|
||||
};
|
||||
|
||||
this.backendSrv.get('/api/dashboard/snapshots').then(result => {
|
||||
this.snapshots = result;
|
||||
});
|
||||
|
@ -1,5 +1,4 @@
|
||||
<navbar icon="fa fa-fw fa-adjust" title="Style Guide" title-url="styleguide">
|
||||
</navbar>
|
||||
<navbar model="ctrl.navModel"></navbar>
|
||||
|
||||
<div class="page-container">
|
||||
<div class="page-header">
|
||||
|
@ -12,9 +12,11 @@ class StyleGuideCtrl {
|
||||
icons: any = [];
|
||||
page: any;
|
||||
pages = ['colors', 'buttons', 'icons', 'plugins'];
|
||||
navModel: any;
|
||||
|
||||
/** @ngInject **/
|
||||
constructor(private $http, private $routeParams, private $location, private backendSrv) {
|
||||
constructor(private $http, private $routeParams, private $location, private backendSrv, navModelSrv) {
|
||||
this.navModel = navModelSrv.getAdminNav();
|
||||
this.theme = config.bootData.user.lightTheme ? 'light': 'dark';
|
||||
this.page = {};
|
||||
|
||||
|
@ -1,9 +1,8 @@
|
||||
<div dash-class ng-if="dashboard">
|
||||
<dashnav></dashnav>
|
||||
<dashnav dashboard="dashboard"></dashnav>
|
||||
|
||||
<div class="dashboard-container">
|
||||
<div dash-editor-view></div>
|
||||
<dashboard-search></dashboard-search>
|
||||
<div class="clearfix"></div>
|
||||
|
||||
<dashboard-submenu ng-if="dashboard.meta.submenuEnabled" dashboard="dashboard"></dashboard-submenu>
|
||||
|
@ -1,5 +1,4 @@
|
||||
<navbar title="404" icon="fa fa-fw fa-question" title-url="/">
|
||||
</navbar>
|
||||
<navbar model="navModel"></navbar>
|
||||
|
||||
<div class="page-container">
|
||||
|
||||
|
@ -40,14 +40,14 @@
|
||||
|
||||
@include media-breakpoint-down(xs) {
|
||||
.page-dashboard .navbar-page-btn {
|
||||
max-width: 150px;
|
||||
max-width: 250px;
|
||||
}
|
||||
}
|
||||
|
||||
// form styles
|
||||
@include media-breakpoint-up(md) {
|
||||
.page-dashboard .navbar-page-btn {
|
||||
max-width: 180px;
|
||||
max-width: 280px;
|
||||
}
|
||||
.gf-timepicker-nav-btn {
|
||||
max-width: 120px;
|
||||
|
@ -15,13 +15,13 @@
|
||||
}
|
||||
|
||||
.dropdown-desc {
|
||||
position: relative;
|
||||
top: -3px;
|
||||
width: 250px;
|
||||
font-size: 80%;
|
||||
margin-left: 22px;
|
||||
color: $gray-2;
|
||||
white-space: normal;
|
||||
position: relative;
|
||||
top: -3px;
|
||||
width: 250px;
|
||||
font-size: 80%;
|
||||
margin-left: 22px;
|
||||
color: $gray-2;
|
||||
white-space: normal;
|
||||
}
|
||||
|
||||
// Dropdown arrow/caret
|
||||
@ -75,7 +75,7 @@
|
||||
|
||||
// Links within the dropdown menu
|
||||
> li {
|
||||
> a {
|
||||
> a {
|
||||
display: block;
|
||||
padding: 3px 20px 3px 15px;
|
||||
clear: both;
|
||||
|
@ -42,7 +42,6 @@
|
||||
// Hover/focus
|
||||
.navbar .nav > li > a:focus,
|
||||
.navbar .nav > li > a:hover {
|
||||
background-color: $navbarLinkBackgroundHover; // "transparent" is default to differentiate :hover/:focus from .active
|
||||
color: $navbarLinkColorHover;
|
||||
text-decoration: none;
|
||||
}
|
||||
@ -64,10 +63,12 @@
|
||||
border-right: 1px solid $tight-form-border;
|
||||
background-color: $navbarButtonBackground;
|
||||
padding: 0.4rem 1.0rem 0.4rem 1rem;
|
||||
min-height:: $navbarHeight;
|
||||
|
||||
.fa-caret-down {
|
||||
font-size: 70%;
|
||||
}
|
||||
|
||||
.fa-chevron-left{
|
||||
display: none;
|
||||
}
|
||||
@ -95,7 +96,7 @@
|
||||
.icon-gf-grafana_wordmark {
|
||||
font-size: 21px;
|
||||
position: relative;
|
||||
top: 4px;
|
||||
top: 5px;
|
||||
padding-left: 5px;
|
||||
display: none;
|
||||
}
|
||||
@ -108,16 +109,16 @@
|
||||
float: left;
|
||||
display: block;
|
||||
margin: 0;
|
||||
font-size: 1.4em;
|
||||
font-size: 1.4rem;
|
||||
border-right: 1px solid $tight-form-border;
|
||||
color: darken($link-color, 5%);
|
||||
background-color: $navbarButtonBackground;
|
||||
font-size: $font-size-lg;
|
||||
padding: 1rem 1rem 0.7rem 1rem;
|
||||
padding: 1rem 1rem 0.75rem 1rem;
|
||||
min-height:: $navbarHeight;
|
||||
|
||||
&:hover {
|
||||
&:hover, &.active {
|
||||
background: $navbarButtonBackgroundHighlight;
|
||||
color: $link-color;
|
||||
}
|
||||
|
||||
.fa-caret-down {
|
||||
@ -138,9 +139,36 @@
|
||||
}
|
||||
}
|
||||
|
||||
.navbar-page-btn-wrapper {
|
||||
display: inline-block;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.dropdown-menu.dropdown-menu--navbar {
|
||||
top: 100%;
|
||||
min-width: 100%;
|
||||
margin-top: 0px;
|
||||
|
||||
li a {
|
||||
padding: $spacer/2 $spacer;
|
||||
border-left: 2px solid $side-menu-bg;
|
||||
background: $side-menu-bg;
|
||||
|
||||
i {
|
||||
display: inline-block;
|
||||
padding-right: 21px;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
@include left-brand-border-gradient();
|
||||
color: $link-hover-color;
|
||||
background: $input-label-bg;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.sidemenu-pinned {
|
||||
.navbar-brand-btn {
|
||||
background-color: $page-bg;
|
||||
width: $side-menu-width;
|
||||
|
||||
.icon-gf-grafana_wordmark {
|
||||
@ -160,3 +188,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
.navbar-section-wrapper {
|
||||
position: relative;
|
||||
float: left;
|
||||
}
|
||||
|
@ -1,14 +1,20 @@
|
||||
.search-backdrop {
|
||||
position: fixed;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
top: $navbarHeight;
|
||||
z-index: $zindex-modal-backdrop;
|
||||
background-color: $black;
|
||||
@include opacity(70);
|
||||
}
|
||||
|
||||
.search-container {
|
||||
left: 72px;
|
||||
top: 39px;
|
||||
margin: 16px 0 0 2px;
|
||||
z-index: 1000;
|
||||
left: 78px;
|
||||
top: 0;
|
||||
right: 0;
|
||||
z-index: ($zindex-modal-backdrop + 10);
|
||||
position: absolute;
|
||||
width: 700px;
|
||||
box-shadow: $search-shadow;
|
||||
padding: 10px;
|
||||
background-color: $panel-bg;
|
||||
border: $panel-border;
|
||||
|
||||
.label-tag {
|
||||
margin-left: 6px;
|
||||
@ -19,19 +25,48 @@
|
||||
|
||||
// Search
|
||||
.search-field-wrapper {
|
||||
padding-bottom: 10px;
|
||||
width: 100%;
|
||||
display: flex;
|
||||
background-color: $navbarButtonBackground;
|
||||
|
||||
input {
|
||||
width: 100%;
|
||||
padding: 8px 8px;
|
||||
height: 100%;
|
||||
max-width: 653px;
|
||||
//padding: 0.5rem 1.5rem 0.5rem 0;
|
||||
padding: 1rem 1rem 0.75rem 1rem;
|
||||
height: 51px;
|
||||
line-height: 51px;
|
||||
box-sizing: border-box;
|
||||
outline: none;
|
||||
background: $side-menu-bg;
|
||||
background-color: $navbarButtonBackground;
|
||||
flex-grow: 10;
|
||||
}
|
||||
button {
|
||||
margin: 0 4px 0 0;
|
||||
}
|
||||
> span {
|
||||
display: block;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.search-field-spacer {
|
||||
flex-grow: 1;
|
||||
}
|
||||
.search-switches {
|
||||
flex-grow: 1;
|
||||
padding: 1rem 1rem 0.75rem 1rem;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.search-field-icon {
|
||||
font-size: $font-size-lg;
|
||||
padding: 1rem 1rem 0.75rem 1rem;
|
||||
}
|
||||
|
||||
.search-dropdown {
|
||||
display: flex;
|
||||
max-width: 1100px;
|
||||
visibility: none;
|
||||
opacity: 0;
|
||||
|
||||
&--fade-in {
|
||||
visibility: visible;
|
||||
opacity: 1;
|
||||
transition: opacity 0.3s;
|
||||
}
|
||||
}
|
||||
|
||||
@ -40,10 +75,9 @@
|
||||
overflow: auto;
|
||||
display: block;
|
||||
line-height: 28px;
|
||||
|
||||
.search-item:hover, .search-item.selected {
|
||||
background-color: $grafanaListHighlight;
|
||||
}
|
||||
padding: $spacer;
|
||||
background: $panel-bg;
|
||||
flex-grow: 10;
|
||||
|
||||
.selected {
|
||||
.search-result-tag {
|
||||
@ -71,8 +105,10 @@
|
||||
word-wrap: break-word;
|
||||
display: block;
|
||||
padding: 3px 10px;
|
||||
background-color: $grafanaListBackground;
|
||||
white-space: nowrap;
|
||||
background-color: $tight-form-bg;
|
||||
margin-bottom: 4px;
|
||||
@include left-brand-border();
|
||||
|
||||
.search-result-icon::before {
|
||||
content: "\f009";
|
||||
@ -81,6 +117,15 @@
|
||||
&.search-item-dash-home .search-result-icon::before {
|
||||
content: "\f015";
|
||||
}
|
||||
|
||||
&:hover {
|
||||
background-color: $tight-form-func-bg;
|
||||
@include left-brand-border-gradient();
|
||||
}
|
||||
|
||||
&.selected {
|
||||
background-color: $grafanaListBackground;
|
||||
}
|
||||
}
|
||||
|
||||
.search-result-tags {
|
||||
@ -93,17 +138,15 @@
|
||||
}
|
||||
}
|
||||
|
||||
.search-switches {
|
||||
position: absolute;
|
||||
top: 19px;
|
||||
right: 21px;
|
||||
}
|
||||
|
||||
.search-button-row {
|
||||
padding-top: 20px;
|
||||
padding: $spacer*2;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: flex-start;
|
||||
|
||||
button, a {
|
||||
margin-right: 10px;
|
||||
margin-bottom: $spacer;
|
||||
}
|
||||
|
||||
.search-button-row-explore-link {
|
||||
|
@ -9,7 +9,8 @@
|
||||
width: $side-menu-width;
|
||||
background-color: rgba($side-menu-bg,$side-menu-opacity);
|
||||
z-index: 101;
|
||||
transform: translate3d(0, -100%, 0);
|
||||
//transform: translate3d(0, -100%, 0);
|
||||
opacity: 0;
|
||||
visibility: hidden;
|
||||
|
||||
a:focus {
|
||||
@ -20,8 +21,9 @@
|
||||
.sidemenu-open {
|
||||
.sidemenu-wrapper {
|
||||
visibility: visible;
|
||||
transform: translate3d(0, 0, 0);
|
||||
transition: all 0.2s;
|
||||
//transform: translate3d(0, 0, 0);
|
||||
opacity: 1;
|
||||
transition: opacity 0.3s;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -51,7 +51,7 @@
|
||||
.navbar-page-btn {
|
||||
border-color: transparent;
|
||||
background: transparent;
|
||||
transform: translate3d(-50px, 0, 0);
|
||||
transform: translate3d(-95px, 0, 0);
|
||||
transition: all 1.5s ease-in-out 1s;
|
||||
.icon-gf {
|
||||
opacity: 0;
|
||||
|
Loading…
Reference in New Issue
Block a user