Commit cb83c237 by Torkel Ödegaard

Merge branch 'master' of github.com:grafana/grafana

Conflicts:
	public/sass/_grafana.scss
parents 145c14ed 773a13dc
///<reference path="../../../headers/common.d.ts" />
import _ from 'lodash';
import $ from 'jquery';
import coreModule from '../../core_module';
import Drop from 'tether-drop';
export function popoverDirective() {
return {
restrict: 'E',
transclude: true,
link: function(scope, elem, attrs, ctrl, transclude) {
var inputElem = elem.prev();
if (inputElem.length === 0) {
console.log('Failed to find input element for popover');
return;
}
var offset = attrs.offset || '0 -10px';
transclude(function(clone, newScope) {
var content = document.createElement("div");
_.each(clone, (node) => {
content.appendChild(node);
});
var drop = new Drop({
target: inputElem[0],
content: content,
position: 'right middle',
classes: 'drop-help',
openOn: 'click',
tetherOptions: {
offset: offset
}
});
// inputElem.on('focus.popover', function() {
// drop.open();
// });
//
// inputElem.on('blur.popover', function() {
// close();
// });
scope.$on('$destroy', function() {
drop.destroy();
});
});
}
};
}
coreModule.directive('gfPopover', popoverDirective);
<ul class="sidemenu"> <ul class="sidemenu">
<li class="sidemenu-org-section" ng-if="ctrl.isSignedIn" class="dropdown"> <li class="sidemenu-org-section" ng-if="ctrl.isSignedIn" class="dropdown">
<div class="sidemenu-org"> <a class="sidemenu-org" href="profile">
<div class="sidemenu-org-avatar"> <div class="sidemenu-org-avatar">
<img ng-if="ctrl.user.gravatarUrl" ng-src="{{ctrl.user.gravatarUrl}}"> <img ng-if="ctrl.user.gravatarUrl" ng-src="{{ctrl.user.gravatarUrl}}">
<span class="sidemenu-org-avatar--missing"> <span class="sidemenu-org-avatar--missing">
...@@ -12,7 +12,7 @@ ...@@ -12,7 +12,7 @@
<span class="sidemenu-org-user sidemenu-item-text">{{ctrl.user.name}}</span> <span class="sidemenu-org-user sidemenu-item-text">{{ctrl.user.name}}</span>
<span class="sidemenu-org-name sidemenu-item-text">{{ctrl.user.orgName}}</span> <span class="sidemenu-org-name sidemenu-item-text">{{ctrl.user.orgName}}</span>
</div> </div>
</div> </a>
<i class="fa fa-caret-right"></i> <i class="fa fa-caret-right"></i>
<ul class="dropdown-menu" role="menu"> <ul class="dropdown-menu" role="menu">
<li ng-repeat="menuItem in ctrl.orgMenu" ng-class="menuItem.cssClass"> <li ng-repeat="menuItem in ctrl.orgMenu" ng-class="menuItem.cssClass">
......
...@@ -24,6 +24,7 @@ import './partials'; ...@@ -24,6 +24,7 @@ import './partials';
import {grafanaAppDirective} from './components/grafana_app'; import {grafanaAppDirective} from './components/grafana_app';
import {sideMenuDirective} from './components/sidemenu/sidemenu'; import {sideMenuDirective} from './components/sidemenu/sidemenu';
import {searchDirective} from './components/search/search'; import {searchDirective} from './components/search/search';
import {popoverDirective} from './components/popover/popover';
import {navbarDirective} from './components/navbar/navbar'; import {navbarDirective} from './components/navbar/navbar';
import {arrayJoin} from './directives/array_join'; import {arrayJoin} from './directives/array_join';
import 'app/core/controllers/all'; import 'app/core/controllers/all';
...@@ -32,4 +33,12 @@ import 'app/core/routes/routes'; ...@@ -32,4 +33,12 @@ import 'app/core/routes/routes';
import './filters/filters'; import './filters/filters';
import coreModule from './core_module'; import coreModule from './core_module';
export {arrayJoin, coreModule, grafanaAppDirective, sideMenuDirective, navbarDirective, searchDirective}; export {
arrayJoin,
coreModule,
grafanaAppDirective,
sideMenuDirective,
navbarDirective,
searchDirective,
popoverDirective
};
...@@ -39,7 +39,7 @@ function (angular, coreModule, kbn) { ...@@ -39,7 +39,7 @@ function (angular, coreModule, kbn) {
var tip = attrs.tip ? (' <tip>' + attrs.tip + '</tip>') : ''; var tip = attrs.tip ? (' <tip>' + attrs.tip + '</tip>') : '';
var showIf = attrs.showIf ? (' ng-show="' + attrs.showIf + '" ') : ''; var showIf = attrs.showIf ? (' ng-show="' + attrs.showIf + '" ') : '';
var template = '<div class="editor-option text-center"' + showIf + '>' + var template = '<div class="editor-option gf-form-checkbox text-center"' + showIf + '>' +
' <label for="' + attrs.model + '" class="small">' + ' <label for="' + attrs.model + '" class="small">' +
attrs.text + tip + '</label>' + attrs.text + tip + '</label>' +
'<input class="cr1" id="' + attrs.model + '" type="checkbox" ' + '<input class="cr1" id="' + attrs.model + '" type="checkbox" ' +
......
...@@ -34,8 +34,6 @@ ...@@ -34,8 +34,6 @@
</button> </button>
</div> </div>
<div class="gf-box-body"> <div class="gf-box-body">
<div class="editor-row row" ng-if="mode === 'list'"> <div class="editor-row row" ng-if="mode === 'list'">
<div class="span6"> <div class="span6">
<div ng-if="annotations.length === 0"> <div ng-if="annotations.length === 0">
...@@ -66,28 +64,34 @@ ...@@ -66,28 +64,34 @@
</div> </div>
</div> </div>
<div ng-if="mode === 'edit' || mode === 'new'"> <div class="annotations-basic-settings" ng-if="mode === 'edit' || mode === 'new'">
<div class="editor-row"> <div class="gf-form-group">
<div class="editor-option"> <div class="gf-form-inline">
<label class="small">Name</label> <div class="gf-form gf-size-max-xxl">
<input type="text" class="input-medium" ng-model='currentAnnotation.name' placeholder="name"></input> <span class="gf-form-label width-10">Name</span>
</div> <input type="text" class="gf-form-input" ng-model='currentAnnotation.name' placeholder="name"></input>
<div class="editor-option"> </div>
<label class="small">Datasource</label> <div class="gf-form">
<select ng-model="currentAnnotation.datasource" ng-options="f.name as f.name for f in datasources" ng-change="datasourceChanged()"></select> <span class="gf-form-label max-width-10">Datasource</span>
</div> <select class="gf-form-input gf-size-auto" ng-model="currentAnnotation.datasource" ng-options="f.name as f.name for f in datasources" ng-change="datasourceChanged()"></select>
<div class="editor-option text-center"> </div>
<label class="small">Icon color</label>
<spectrum-picker ng-model="currentAnnotation.iconColor"></spectrum-picker>
</div> </div>
<div class="editor-option"> <div class="gf-form-inline last-row">
<label class="small">Icon size</label> <div class="gf-form gf-size-max-xl">
<select class="input-mini" ng-model="currentAnnotation.iconSize" ng-options="f for f in [7,8,9,10,13,15,17,20,25,30]"></select> <span class="gf-form-label width-10">Icon size</span>
</div> <select class="gf-form-input gf-size-md" ng-model="currentAnnotation.iconSize" ng-options="f for f in [7,8,9,10,13,15,17,20,25,30]"></select>
<editor-opt-bool text="Grid line" model="currentAnnotation.showLine"></editor-opt-bool> </div>
<div class="editor-option text-center"> <div class="gf-form max-width-10">
<label class="small">Line color</label> <spectrum-picker ng-model="currentAnnotation.iconColor"></spectrum-picker>
<spectrum-picker ng-model="currentAnnotation.lineColor"></spectrum-picker> <span class="checkbox-label">Icon color</span>
</div>
<div class="gf-form max-width-10">
<editor-checkbox text="Grid line" model="currentAnnotation.showLine"></editor-checkbox>
</div>
<div class="gf-form max-width-10">
<spectrum-picker ng-model="currentAnnotation.lineColor"></spectrum-picker>
<span class="checkbox-label">Line color</span>
</div>
</div> </div>
</div> </div>
...@@ -96,11 +100,12 @@ ...@@ -96,11 +100,12 @@
</plugin-component> </plugin-component>
</rebuild-on-change> </rebuild-on-change>
<br> <div class="gf-form">
<button ng-show="mode === 'new'" type="button" class="btn btn-success" ng-click="add()">Add</button> <div class="gf-form-button-row">
<button ng-show="mode === 'edit'" type="button" class="btn btn-success pull-left" ng-click="update();">Update</button> <button ng-show="mode === 'new'" type="button" class="btn gf-form-button btn-success" ng-click="add()">Add</button>
<br> <button ng-show="mode === 'edit'" type="button" class="btn btn-success pull-left" ng-click="update();">Update</button>
<br> </div>
</div>
</div> </div>
</div> </div>
</div> </div>
...@@ -15,6 +15,13 @@ ...@@ -15,6 +15,13 @@
<div class="gf-form"> <div class="gf-form">
<span class="gf-form-label width-7">Name</span> <span class="gf-form-label width-7">Name</span>
<input class="gf-form-input max-width-21" type="text" ng-model="current.name" placeholder="My data source name" required> <input class="gf-form-input max-width-21" type="text" ng-model="current.name" placeholder="My data source name" required>
<gf-popover offset="0px -85px">
The name is used when you select the data source in panels.
The <code>Default</code> data source is preselected in new
new panels.
</gf-popover>
<editor-checkbox text="Default" model="current.isDefault"></editor-checkbox> <editor-checkbox text="Default" model="current.isDefault"></editor-checkbox>
</div> </div>
...@@ -24,6 +31,7 @@ ...@@ -24,6 +31,7 @@
<select class="gf-form-input gf-size-auto" ng-model="current.type" ng-options="k as v.name for (k, v) in types" ng-change="typeChanged()"></select> <select class="gf-form-input gf-size-auto" ng-model="current.type" ng-options="k as v.name for (k, v) in types" ng-change="typeChanged()"></select>
</div> </div>
</div> </div>
</div> </div>
<rebuild-on-change property="datasourceMeta.id"> <rebuild-on-change property="datasourceMeta.id">
......
...@@ -6,6 +6,18 @@ ...@@ -6,6 +6,18 @@
<div class="gf-form"> <div class="gf-form">
<span class="gf-form-label width-7">Url</span> <span class="gf-form-label width-7">Url</span>
<input class="gf-form-input max-width-21" type="text" ng-model='current.url' placeholder="http://my.server.com:8080" ng-pattern="/^(ftp|http|https):\/\/(\w+:{0,1}\w*@)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%@!\-\/]))?$/" required></input> <input class="gf-form-input max-width-21" type="text" ng-model='current.url' placeholder="http://my.server.com:8080" ng-pattern="/^(ftp|http|https):\/\/(\w+:{0,1}\w*@)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%@!\-\/]))?$/" required></input>
<gf-popover>
<p>Specify a complete HTTP url (http://your_server:8080)</p>
<span ng-show="current.access === 'direct'">
Your access method is <code>Direct</code>, this means the url
needs to be accessable from the browser.
</span>
<span ng-show="current.access === 'proxy'">
Your access method is currently <code>Proxy</code>, this means the url
needs to be accessable from the grafana backend.
</span>
</gf-popover>
</div> </div>
<div class="gf-form"> <div class="gf-form">
......
...@@ -7,6 +7,8 @@ ...@@ -7,6 +7,8 @@
<h1 ng-show="!ctrl.isNew()">Edit Playlist</h1> <h1 ng-show="!ctrl.isNew()">Edit Playlist</h1>
</div> </div>
<p class="playlist-description">A playlist rotates through a pre-selected list of Dashboards. A Playlist can be a great way to build situational awareness, or just show off your metrics to your team or visitors.</p>
<div class="gf-form-group"> <div class="gf-form-group">
<div class="gf-form"> <div class="gf-form">
<span class="gf-form-label width-7">Name</span> <span class="gf-form-label width-7">Name</span>
...@@ -19,24 +21,28 @@ ...@@ -19,24 +21,28 @@
</div> </div>
<div class="gf-form-group"> <div class="gf-form-group">
<div class="max-width-28"> <h3 class="page-headering">Dashboards</h3>
<h5 class="page-headering">Add dashboards</h5>
<div style="">
<playlist-search class="playlist-search-container" search-started="ctrl.searchStarted(promise)"></playlist-search>
</div>
</div>
</div> </div>
<div class="row"> <div class="row">
<div class="col-md-6"> <div class="col-md-6">
<h5>Search results ({{ctrl.filteredDashboards.length + ctrl.filteredTags.length}})</h5>
<div class="playlist-search-containerwrapper">
<div class="max-width-32">
<h5 class="page-headering playlist-column-header">Available</h5>
<div style="">
<playlist-search class="playlist-search-container" search-started="ctrl.searchStarted(promise)"></playlist-search>
</div>
</div>
</div>
<div ng-if="ctrl.filteredDashboards.length > 0"> <div ng-if="ctrl.filteredDashboards.length > 0">
<table class="grafana-options-table"> <table class="grafana-options-table playlist-available-list">
<tr ng-repeat="playlistItem in ctrl.filteredDashboards"> <tr ng-repeat="playlistItem in ctrl.filteredDashboards">
<td style="white-space: nowrap;"> <td>
{{playlistItem.title}} <i class="icon-gf icon-gf-dashboard"></i>&nbsp;&nbsp;{{playlistItem.title}}
</td> </td>
<td style="text-align: center"> <td class="add-dashboard">
<button class="btn btn-inverse btn-mini pull-right" ng-click="ctrl.addPlaylistItem(playlistItem)"> <button class="btn btn-inverse btn-mini pull-right" ng-click="ctrl.addPlaylistItem(playlistItem)">
<i class="fa fa-plus"></i> <i class="fa fa-plus"></i>
Add to playlist Add to playlist
...@@ -46,7 +52,7 @@ ...@@ -46,7 +52,7 @@
</table> </table>
</div> </div>
<div class="playlist-search-results-container" ng-if="ctrl.filteredTags.length > 0;"> <div class="playlist-search-results-container" ng-if="ctrl.filteredTags.length > 0;">
<div ng-repeat="tag in ctrl.filteredTags" class="pointer" style="width: 180px; float: left;" <div ng-repeat="tag in ctrl.filteredTags" class="pointer tag-result-container"
ng-click="ctrl.addTagPlaylistItem(tag, $event)"> ng-click="ctrl.addTagPlaylistItem(tag, $event)">
<a class="search-result-tag label label-tag" tag-color-from-name="tag.term"> <a class="search-result-tag label label-tag" tag-color-from-name="tag.term">
<i class="fa fa-tag"></i> <i class="fa fa-tag"></i>
...@@ -57,20 +63,20 @@ ...@@ -57,20 +63,20 @@
</div> </div>
<div class="col-md-6"> <div class="col-md-6">
<h5>Added dashboards</h5> <h5 class="page headering playlist-column-header">Selected</h5>
<table class="grafana-options-table"> <table class="grafana-options-table playlist-available-list">
<tr ng-repeat="playlistItem in ctrl.playlistItems"> <tr ng-repeat="playlistItem in ctrl.playlistItems">
<td style="white-space: nowrap;" ng-if="playlistItem.type === 'dashboard_by_id'"> <td ng-if="playlistItem.type === 'dashboard_by_id'">
{{playlistItem.title}} <i class="icon-gf icon-gf-dashboard"></i>&nbsp;&nbsp;{{playlistItem.title}}
</td> </td>
<td style="white-space: nowrap;" ng-if="playlistItem.type === 'dashboard_by_tag'"> <td ng-if="playlistItem.type === 'dashboard_by_tag'">
<a class="search-result-tag label label-tag" tag-color-from-name="playlistItem.title"> <a class="search-result-tag label label-tag" tag-color-from-name="playlistItem.title">
<i class="fa fa-tag"></i> <i class="fa fa-tag"></i>
<span>{{playlistItem.title}}</span> <span>{{playlistItem.title}}</span>
</a> </a>
</td> </td>
<td style="text-align: right"> <td class="selected-playlistitem-settings">
<button class="btn btn-inverse btn-mini" ng-hide="$first" ng-click="ctrl.movePlaylistItemUp(playlistItem)"> <button class="btn btn-inverse btn-mini" ng-hide="$first" ng-click="ctrl.movePlaylistItemUp(playlistItem)">
<i class="fa fa-arrow-up"></i> <i class="fa fa-arrow-up"></i>
</button> </button>
...@@ -89,7 +95,10 @@ ...@@ -89,7 +95,10 @@
<div class="clearfix"></div> <div class="clearfix"></div>
<div class="gf-form-button-row"> <div class="gf-form-button-row">
<a class="btn btn-success" <a class="btn btn-success " ng-show="ctrl.isNew()"
ng-disabled="ctrl.playlistEditForm.$invalid || ctrl.isPlaylistEmpty()"
ng-click="ctrl.savePlaylist(ctrl.playlist, ctrl.playlistItems)"><i class="fa fa-plus"></i>&nbsp;Add</a>
<a class="btn btn-success" ng-show="!ctrl.isNew()"
ng-disabled="ctrl.playlistEditForm.$invalid || ctrl.isPlaylistEmpty()" ng-disabled="ctrl.playlistEditForm.$invalid || ctrl.isPlaylistEmpty()"
ng-click="ctrl.savePlaylist(ctrl.playlist, ctrl.playlistItems)">Save</a> ng-click="ctrl.savePlaylist(ctrl.playlist, ctrl.playlistItems)">Save</a>
<a class="btn-text" ng-click="ctrl.backToList()">Cancel</a> <a class="btn-text" ng-click="ctrl.backToList()">Cancel</a>
......
...@@ -11,7 +11,7 @@ export class PlaylistEditCtrl { ...@@ -11,7 +11,7 @@ export class PlaylistEditCtrl {
searchQuery: string = ''; searchQuery: string = '';
loading: boolean = false; loading: boolean = false;
playlist: any = { playlist: any = {
interval: '10m', interval: '5m',
}; };
playlistItems: any = []; playlistItems: any = [];
dashboardresult: any = []; dashboardresult: any = [];
......
...@@ -39,4 +39,12 @@ declare module 'app/core/store' { ...@@ -39,4 +39,12 @@ declare module 'app/core/store' {
export default store; export default store;
} }
declare module 'tether' {
var config: any;
export default config;
}
declare module 'tether-drop' {
var config: any;
export default config;
}
<div class="editor-row"> <div class="gf-form-group">
<div class="section" ng-if="ctrl.annotation.index"> <div class="gf-form" ng-if="ctrl.annotation.index">
<h5>Index name</h5> <span class="gf-form-label width-14">Index name</span>
<div class="editor-option"> <input type="text" class="gf-form-input max-width-20" ng-model='ctrl.annotation.index' placeholder="events-*"></input>
<input type="text" class="span4" ng-model='ctrl.annotation.index' placeholder="events-*"></input>
</div>
</div> </div>
<div class="section"> <div class="gf-form">
<h5>Search query (lucene) <tip>Use [[filterName]] in query to replace part of the query with a filter value</tip></h5> <span class="gf-form-label width-14">Search query (lucene) <tip>Use [[filterName]] in query to replace part of the query with a filter value</tip></span>
<div class="editor-option"> <input type="text" class="gf-form-input max-width-20" ng-model='ctrl.annotation.query' placeholder="tags:deploy"></input>
<input type="text" class="span6" ng-model='ctrl.annotation.query' placeholder="tags:deploy"></input>
</div>
</div> </div>
</div> </div>
<div class="editor-row"> <div class="gf-form-group">
<div class="section"> <h6>Field mappings</h6>
<h5>Field mappings</h5> <div class="gf-form-inline">
<div class="editor-option"> <div class="gf-form">
<label class="small">Time</label> <span class="gf-form-label width-10">Time</span>
<input type="text" class="input-small" ng-model='ctrl.annotation.timeField' placeholder="@timestamp"></input> <input type="text" class="gf-form-input max-width-16" ng-model='ctrl.annotation.timeField' placeholder="@timestamp"></input>
</div> </div>
<div class="editor-option"> <div class="gf-form">
<label class="small">Title</label> <span class="gf-form-label width-10">Title</span>
<input type="text" class="input-small" ng-model='ctrl.annotation.titleField' placeholder="desc"></input> <input type="text" class="gf-form-input max-width-16" ng-model='ctrl.annotation.titleField' placeholder="desc"></input>
</div> </div>
</div>
<div class="editor-option"> <div class="gf-form-inline">
<label class="small">Tags</label> <div class="gf-form">
<input type="text" class="input-small" ng-model='ctrl.annotation.tagsField' placeholder="tags"></input> <span class="gf-form-label width-10">Tags</span>
<input type="text" class="gf-form-input max-width-16" ng-model='ctrl.annotation.tagsField' placeholder="tags"></input>
</div> </div>
<div class="editor-option"> <div class="gf-form">
<label class="small">Text</label> <span class="gf-form-label width-10">Text</span>
<input type="text" class="input-small" ng-model='ctrl.annotation.textField' placeholder=""></input> <input type="text" class="gf-form-input max-width-16" ng-model='ctrl.annotation.textField' placeholder=""></input>
</div> </div>
</div> </div>
</div> </div>
\ No newline at end of file
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
<div class="gf-form-group"> <div class="gf-form-group">
<div class="gf-form-inline"> <div class="gf-form-inline">
<div class="gf-form max-width-19"> <div class="gf-form max-width-25">
<span class="gf-form-label width-9">Index name</span> <span class="gf-form-label width-9">Index name</span>
<input class="gf-form-input" type="text" ng-model='ctrl.current.database' placeholder="" required></input> <input class="gf-form-input" type="text" ng-model='ctrl.current.database' placeholder="" required></input>
</div> </div>
...@@ -16,7 +16,7 @@ ...@@ -16,7 +16,7 @@
</div> </div>
</div> </div>
<div class="gf-form max-width-28"> <div class="gf-form max-width-25">
<span class="gf-form-label width-9">Time field name</span> <span class="gf-form-label width-9">Time field name</span>
<input class="gf-form-input" type="text" ng-model='ctrl.current.jsonData.timeField' placeholder="" required ng-init=""></input> <input class="gf-form-input" type="text" ng-model='ctrl.current.jsonData.timeField' placeholder="" required ng-init=""></input>
</div> </div>
......
<div class="editor-row"> <div class="gf-form-group">
<div class="editor-option"> <div class="gf-form">
<label class="small">Graphite target expression</label> <span class="gf-form-label width-14">Graphite target expression</span>
<input type="text" class="span10" ng-model='ctrl.annotation.target' placeholder=""></input> <input type="text" class="gf-form-input max-width-20" ng-model='ctrl.annotation.target' placeholder=""></input>
</div> </div>
</div> <div class="gf-form">
<span class="gf-form-label width-14">Graphite event tags</span>
<div class="editor-row"> <input type="text" class="gf-form-input max-width-20" ng-model='ctrl.annotation.tags' placeholder=""></input>
<div class="editor-option"> </div>
<label class="small">Graphite event tags</label> </div>
<input type="text" ng-model='ctrl.annotation.tags' placeholder=""></input> \ No newline at end of file
</div>
</div>
<div class="editor-row"> <div class="gf-form-group">
<div class="section"> <div class="gf-form-inline">
<h5>InfluxDB Query <tip>Example: select text from events where $timeFilter</tip></h5> <div class="gf-form">
<div class="editor-option"> <span class="gf-form-label width-14">InfluxDB Query <tip>Example: select text from events where $timeFilter</tip></span class="gf-form-label">
<input type="text" class="span10" ng-model='ctrl.annotation.query' placeholder="select text from events where $timeFilter"></input> <input type="text" class="gf-form-input" ng-model='ctrl.annotation.query' placeholder="select text from events where $timeFilter"></input>
</div> </div>
</div> </div>
</div> </div>
<div class="gf-form-group">
<div class="editor-row"> <h6>Column mappings <tip>If your influxdb query returns more than one column you need to specify the column names below. An annotation event is composed of a title, tags, and an additional text field.</tip></h6>
<div class="section"> <div class="gf-form-inline">
<h5>Column mappings <tip>If your influxdb query returns more than one column you need to specify the column names below. An annotation event is composed of a title, tags, and an additional text field.</tip></h5> <div class="gf-form">
<div class="editor-option"> <span class="gf-form-label width-10">Title</span>
<label class="small">Title</label> <input type="text" class="gf-form-input" ng-model='ctrl.annotation.titleColumn' placeholder=""></input>
<input type="text" class="input-small" ng-model='ctrl.annotation.titleColumn' placeholder=""></input>
</div> </div>
<div class="editor-option"> <div class="gf-form">
<label class="small">Tags</label> <span class="gf-form-label width-10">Tags</span>
<input type="text" class="input-small" ng-model='ctrl.annotation.tagsColumn' placeholder=""></input> <input type="text" class="gf-form-input" ng-model='ctrl.annotation.tagsColumn' placeholder=""></input>
</div> </div>
<div class="editor-option"> <div class="gf-form">
<label class="small">Text</label> <span class="gf-form-label width-10">Text</span>
<input type="text" class="input-small" ng-model='ctrl.annotation.textColumn' placeholder=""></input> <input type="text" class="gf-form-input" ng-model='ctrl.annotation.textColumn' placeholder=""></input>
</div> </div>
</div> </div>
</div> </div>
<div class="editor-row"> <div class="gf-form-group">
<div class="section"> <div class="gf-form-inline">
<h5>Search expression</h5> <div class="gf-form">
<div class="editor-option"> <span class="gf-form-label width-10">Search expression</span>
<input type="text" class="span6" ng-model='ctrl.annotation.expr' placeholder="ALERTS"></input> <input type="text" class="gf-form-input max-width-16" ng-model='ctrl.annotation.expr' placeholder="ALERTS"></input>
</div> </div>
</div> </div>
</div> </div>
<div class="gf-form-group">
<div class="editor-row"> <h6>Field formats</h6>
<div class="section"> <div class="gf-form-inline">
<h5>Field formats</h5> <div class="gf-form">
<div class="editor-option"> <span class="gf-form-label width-10">Title</span>
<label class="small">Title</label> <input type="text" class="gf-form-input" ng-model='ctrl.annotation.titleFormat' placeholder="alertname"></input>
<input type="text" class="input-small" ng-model='ctrl.annotation.titleFormat' placeholder="alertname"></input>
</div> </div>
<div class="editor-option"> <div class="gf-form">
<label class="small">Tags</label> <span class="gf-form-label width-10">Tags</span>
<input type="text" class="input-small" ng-model='ctrl.annotation.tagKeys' placeholder="label1,label2"></input> <input type="text" class="gf-form-input" ng-model='ctrl.annotation.tagKeys' placeholder="label1,label2"></input>
</div> </div>
</div>
<div class="editor-option"> <div class="gf-form-inline">
<label class="small">Text</label> <div class="gf-form">
<input type="text" class="input-small" ng-model='ctrl.annotation.textFormat' placeholder="instance"></input> <span class="gf-form-label width-10">Text</span>
<input type="text" class="gf-form-input" ng-model='ctrl.annotation.textFormat' placeholder="instance"></input>
</div> </div>
</div> </div>
</div> </div>
...@@ -3,6 +3,7 @@ System.config({ ...@@ -3,6 +3,7 @@ System.config({
baseURL: 'public', baseURL: 'public',
paths: { paths: {
'tether': 'vendor/npm/tether/dist/js/tether.js', 'tether': 'vendor/npm/tether/dist/js/tether.js',
'tether-drop': 'vendor/npm/tether-drop/dist/js/drop.js',
'moment': 'vendor/moment.js', 'moment': 'vendor/moment.js',
"jquery": "vendor/jquery/dist/jquery.js", "jquery": "vendor/jquery/dist/jquery.js",
'lodash-src': 'vendor/lodash.js', 'lodash-src': 'vendor/lodash.js',
......
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
@import "mixins/grid-framework"; @import "mixins/grid-framework";
@import "mixins/hover"; @import "mixins/hover";
@import "mixins/forms"; @import "mixins/forms";
@import "mixins/drop_element";
// BASE // BASE
@import "base/normalize"; @import "base/normalize";
...@@ -63,6 +64,7 @@ ...@@ -63,6 +64,7 @@
@import "components/footer"; @import "components/footer";
@import "components/infobox"; @import "components/infobox";
@import "components/shortcuts"; @import "components/shortcuts";
@import "components/drop";
@import "components/query_editor"; @import "components/query_editor";
// PAGES // PAGES
...@@ -74,4 +76,5 @@ ...@@ -74,4 +76,5 @@
@import "pages/signup"; @import "pages/signup";
@import "pages/styleguide"; @import "pages/styleguide";
@import "old_responsive"; @import "old_responsive";
...@@ -246,5 +246,9 @@ $popoverTitleBackground: $popoverBackground; ...@@ -246,5 +246,9 @@ $popoverTitleBackground: $popoverBackground;
$popoverArrowOuterWidth: $popoverArrowWidth + 1; $popoverArrowOuterWidth: $popoverArrowWidth + 1;
$popoverArrowOuterColor: rgba(0,0,0,.25); $popoverArrowOuterColor: rgba(0,0,0,.25);
// popover
$popover-help-bg: $btn-secondary-bg;
$popover-help-color: $text-color;
// images // images
$checkboxImageUrl: '../img/checkbox.png'; $checkboxImageUrl: '../img/checkbox.png';
...@@ -174,7 +174,7 @@ $dropdownBorder: $tight-form-border; ...@@ -174,7 +174,7 @@ $dropdownBorder: $tight-form-border;
$dropdownDividerTop: $gray-6; $dropdownDividerTop: $gray-6;
$dropdownDividerBottom: $white; $dropdownDividerBottom: $white;
$dropdownDivider: $dropdownDividerTop; $dropdownDivider: $dropdownDividerTop;
$dropdownTitle: $dark-5; $dropdownTitle: $gray-3;
$dropdownLinkColor: $dark-3; $dropdownLinkColor: $dark-3;
$dropdownLinkColorHover: $link-color; $dropdownLinkColorHover: $link-color;
...@@ -273,5 +273,9 @@ $popoverTitleBackground: $white; ...@@ -273,5 +273,9 @@ $popoverTitleBackground: $white;
$popoverArrowOuterWidth: $popoverArrowWidth + 1; $popoverArrowOuterWidth: $popoverArrowWidth + 1;
$popoverArrowOuterColor: rgba(0,0,0,.25); $popoverArrowOuterColor: rgba(0,0,0,.25);
// popover
$popover-help-bg: $blue-dark;
$popover-help-color: $gray-6;
// images // images
$checkboxImageUrl: '../img/checkbox_white.png'; $checkboxImageUrl: '../img/checkbox_white.png';
...@@ -285,3 +285,9 @@ div.flot-text { ...@@ -285,3 +285,9 @@ div.flot-text {
padding: 1.2rem .5rem .4rem .5rem; padding: 1.2rem .5rem .4rem .5rem;
} }
} }
.annotations-basic-settings {
.last-row {
margin-bottom: 20px;
}
}
$popover-arrow-size: 1rem;
$color: inherit;
$backgroundColor: $btn-secondary-bg;
$color: $text-color;
$useDropShadow: false;
$attachmentOffset: $popover-arrow-size;
$easing: cubic-bezier(0, 0, 0.265, 1.55);
.drop-element {
position: absolute;
display: none;
&.drop-open {
display: block;
}
&.drop-open.drop-popover.drop-out-of-bounds,
&.drop-open-transitionend.drop-popover.drop-out-of-bounds {
display: none;
}
}
.drop-element, .drop-element * {
box-sizing: border-box;
}
@include drop-theme("help", $popover-help-bg, $popover-help-color);
@include drop-animation-scale("drop", "help", $attachmentOffset: $attachmentOffset, $easing: $easing);
...@@ -124,5 +124,5 @@ ...@@ -124,5 +124,5 @@
bottom: -$popoverArrowWidth; bottom: -$popoverArrowWidth;
} }
} }
} }
@mixin drop-theme($themeName, $theme-bg, $theme-color) {
.drop-element.drop-#{$themeName} {
max-width: 100%;
max-height: 100%;
.drop-content {
border-radius: $border-radius-lg;
position: relative;
font-family: inherit;
background: $theme-bg;
color: $theme-color;
padding: 1em;
font-size: $font-size-sm;
max-width: 20rem;
&:before {
content: "";
display: block;
position: absolute;
width: 0;
height: 0;
border-color: transparent;
border-width: $popover-arrow-size;
border-style: solid;
pointer-events: null;
}
}
// Centers and middles
&.drop-element-attached-bottom.drop-element-attached-center .drop-content {
margin-bottom: $popover-arrow-size;
&:before {
top: 100%;
left: 50%;
margin-left: - $popover-arrow-size;
border-top-color: $theme-bg;
}
}
&.drop-element-attached-top.drop-element-attached-center .drop-content {
margin-top: $popover-arrow-size;
&:before {
bottom: 100%;
left: 50%;
margin-left: - $popover-arrow-size;
border-bottom-color: $theme-bg;
}
}
&.drop-element-attached-right.drop-element-attached-middle .drop-content {
margin-right: $popover-arrow-size;
&:before {
left: 100%;
top: 50%;
margin-top: - $popover-arrow-size;
border-left-color: $theme-bg;
}
}
&.drop-element-attached-left.drop-element-attached-middle .drop-content {
margin-left: $popover-arrow-size;
&:before {
right: 100%;
top: 50%;
margin-top: - $popover-arrow-size;
border-right-color: $theme-bg;
}
}
// Target middle/center, element corner
&.drop-element-attached-left.drop-target-attached-center .drop-content {
left: - $popover-arrow-size * 2;
}
&.drop-element-attached-right.drop-target-attached-center .drop-content {
left: $popover-arrow-size * 2;
}
&.drop-element-attached-top.drop-element-attached-left.drop-target-attached-middle .drop-content {
margin-top: $popover-arrow-size;
&:before {
bottom: 100%;
left: $popover-arrow-size;
border-bottom-color: $theme-bg;
}
}
&.drop-element-attached-top.drop-element-attached-right.drop-target-attached-middle .drop-content {
margin-top: $popover-arrow-size;
&:before {
bottom: 100%;
right: $popover-arrow-size;
border-bottom-color: $theme-bg;
}
}
&.drop-element-attached-bottom.drop-element-attached-left.drop-target-attached-middle .drop-content {
margin-bottom: $popover-arrow-size;
&:before {
top: 100%;
left: $popover-arrow-size;
border-top-color: $theme-bg;
}
}
&.drop-element-attached-bottom.drop-element-attached-right.drop-target-attached-middle .drop-content {
margin-bottom: $popover-arrow-size;
&:before {
top: 100%;
right: $popover-arrow-size;
border-top-color: $theme-bg;
}
}
// Top and bottom corners
&.drop-element-attached-top.drop-element-attached-left.drop-target-attached-bottom .drop-content {
margin-top: $popover-arrow-size;
&:before {
bottom: 100%;
left: $popover-arrow-size;
border-bottom-color: $theme-bg;
}
}
&.drop-element-attached-top.drop-element-attached-right.drop-target-attached-bottom .drop-content {
margin-top: $popover-arrow-size;
&:before {
bottom: 100%;
right: $popover-arrow-size;
border-bottom-color: $theme-bg;
}
}
&.drop-element-attached-bottom.drop-element-attached-left.drop-target-attached-top .drop-content {
margin-bottom: $popover-arrow-size;
&:before {
top: 100%;
left: $popover-arrow-size;
border-top-color: $theme-bg;
}
}
&.drop-element-attached-bottom.drop-element-attached-right.drop-target-attached-top .drop-content {
margin-bottom: $popover-arrow-size;
&:before {
top: 100%;
right: $popover-arrow-size;
border-top-color: $theme-bg;
}
}
// Side corners
&.drop-element-attached-top.drop-element-attached-right.drop-target-attached-left .drop-content {
margin-right: $popover-arrow-size;
&:before {
top: $popover-arrow-size;
left: 100%;
border-left-color: $theme-bg;
}
}
&.drop-element-attached-top.drop-element-attached-left.drop-target-attached-right .drop-content {
margin-left: $popover-arrow-size;
&:before {
top: $popover-arrow-size;
right: 100%;
border-right-color: $theme-bg;
}
}
&.drop-element-attached-bottom.drop-element-attached-right.drop-target-attached-left .drop-content {
margin-right: $popover-arrow-size;
&:before {
bottom: $popover-arrow-size;
left: 100%;
border-left-color: $theme-bg;
}
}
&.drop-element-attached-bottom.drop-element-attached-left.drop-target-attached-right .drop-content {
margin-left: $popover-arrow-size;
&:before {
bottom: $popover-arrow-size;
right: 100%;
border-right-color: $theme-bg;
}
}
}
}
@mixin drop-animation-scale($themePrefix: "drop", $themeName: "default", $attachmentOffset: 0, $easing: "linear") {
.#{$themePrefix}-element.#{$themePrefix}-#{$themeName} {
transform: translateZ(0);
transition: opacity 100ms;
opacity: 0;
.#{$themePrefix}-content {
transition: transform 0.2s $easing;
transform: scale(0) translateZ(0);
}
&.#{$themePrefix}-open {
display: none;
}
&.#{$themePrefix}-open-transitionend {
display: block;
}
&.#{$themePrefix}-after-open {
transition: none;
opacity: 1;
.#{$themePrefix}-content {
transform: scale(1) translateZ(0);
}
}
// Centers and middles
&.#{$themePrefix}-element-attached-bottom.#{$themePrefix}-element-attached-center .#{$themePrefix}-content {
transform-origin: 50% calc(100% + #{$attachmentOffset});
}
&.#{$themePrefix}-element-attached-top.#{$themePrefix}-element-attached-center .#{$themePrefix}-content {
transform-origin: 50% (-$attachmentOffset);
}
&.#{$themePrefix}-element-attached-right.#{$themePrefix}-element-attached-middle .#{$themePrefix}-content {
transform-origin: calc(100% + #{$attachmentOffset}) 50%;
}
&.#{$themePrefix}-element-attached-left.#{$themePrefix}-element-attached-middle .#{$themePrefix}-content {
transform-origin: -($attachmentOffset 50%);
}
// Top and bottom corners
&.#{$themePrefix}-element-attached-top.#{$themePrefix}-element-attached-left.#{$themePrefix}-target-attached-bottom .#{$themePrefix}-content {
transform-origin: 0 (-$attachmentOffset);
}
&.#{$themePrefix}-element-attached-top.#{$themePrefix}-element-attached-right.#{$themePrefix}-target-attached-bottom .#{$themePrefix}-content {
transform-origin: 100% (-$attachmentOffset);
}
&.#{$themePrefix}-element-attached-bottom.#{$themePrefix}-element-attached-left.#{$themePrefix}-target-attached-top .#{$themePrefix}-content {
transform-origin: 0 calc(100% + #{$attachmentOffset});
}
&.#{$themePrefix}-element-attached-bottom.#{$themePrefix}-element-attached-right.#{$themePrefix}-target-attached-top .#{$themePrefix}-content {
transform-origin: 100% calc(100% + #{$attachmentOffset});
}
// Side corners
&.#{$themePrefix}-element-attached-top.#{$themePrefix}-element-attached-right.#{$themePrefix}-target-attached-left .#{$themePrefix}-content {
transform-origin: calc(100% + #{$attachmentOffset}) 0;
}
&.#{$themePrefix}-element-attached-top.#{$themePrefix}-element-attached-left.#{$themePrefix}-target-attached-right .#{$themePrefix}-content {
transform-origin: (-$attachmentOffset) 0;
}
&.#{$themePrefix}-element-attached-bottom.#{$themePrefix}-element-attached-right.#{$themePrefix}-target-attached-left .#{$themePrefix}-content {
transform-origin: calc(100% + #{$attachmentOffset}) 100%;
}
&.#{$themePrefix}-element-attached-bottom.#{$themePrefix}-element-attached-left.#{$themePrefix}-target-attached-right .#{$themePrefix}-content {
transform-origin: (-$attachmentOffset) 100%;
}
}
}
.playlist-description {
width: 555px;
margin-bottom: 20px;
}
.playlist-search-container { .playlist-search-container {
z-index: 1000; z-index: 1000;
position: relative; position: relative;
...@@ -18,6 +23,10 @@ ...@@ -18,6 +23,10 @@
right: 11px; right: 11px;
} }
.playlist-search-containerwrapper {
margin-bottom: 15px;
}
.playlist-search-field-wrapper { .playlist-search-field-wrapper {
input { input {
width: 100%; width: 100%;
...@@ -90,3 +99,29 @@ ...@@ -90,3 +99,29 @@
padding-left: 20px; padding-left: 20px;
} }
} }
.playlist-available-list {
td {
line-height: 2rem;
white-space: nowrap;
}
.add-dashboard {
text-align: center;
}
}
.playlist-column-header {
border-bottom: thin solid $gray-1;
padding-bottom: 10px;
margin-bottom: 15px;
}
.selected-playlistitem-settings {
text-align: right;
}
.tag-result-container {
width: 160px;
float: left;
}
\ No newline at end of file
...@@ -10,6 +10,8 @@ ...@@ -10,6 +10,8 @@
baseURL: '/base/', baseURL: '/base/',
defaultJSExtensions: true, defaultJSExtensions: true,
paths: { paths: {
'tether': 'vendor/npm/tether/dist/js/tether.js',
'tether-drop': 'vendor/npm/tether-drop/dist/js/drop.js',
'moment': 'vendor/moment.js', 'moment': 'vendor/moment.js',
"jquery": "vendor/jquery/dist/jquery.js", "jquery": "vendor/jquery/dist/jquery.js",
'lodash-src': 'vendor/lodash.js', 'lodash-src': 'vendor/lodash.js',
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment