Просмотр исходного кода

Merge branch 'updated-list-views' of https://github.com/nchristus/grafana into nchristus-updated-list-views

Torkel Ödegaard 10 лет назад
Родитель
Сommit
736d58e35f

+ 3 - 0
public/app/core/routes/all.js

@@ -131,6 +131,9 @@ define([
         templateUrl: 'app/partials/reset_password.html',
         templateUrl: 'app/partials/reset_password.html',
         controller : 'ResetPasswordCtrl',
         controller : 'ResetPasswordCtrl',
       })
       })
+      .when('/global-alerts', {
+        templateUrl: 'app/features/dashboard/partials/globalAlerts.html',
+      })
       .otherwise({
       .otherwise({
         templateUrl: 'app/partials/error.html',
         templateUrl: 'app/partials/error.html',
         controller: 'ErrorCtrl'
         controller: 'ErrorCtrl'

+ 26 - 24
public/app/features/admin/partials/orgs.html

@@ -4,33 +4,35 @@
 	</ul>
 	</ul>
 </topnav>
 </topnav>
 
 
-<div class="page-container">
-	<div class="page">
+<div class="page-container" style="background: transparent; border: 0;">
+	<div class="page-wide">
 		<h2>
 		<h2>
 			Organizations
 			Organizations
 		</h2>
 		</h2>
-
-		<table class="grafana-options-table">
-			<tr>
-				<th style="text-align:left">Id</th>
-				<th>Name</th>
-				<th></th>
-			</tr>
-			<tr ng-repeat="org in orgs">
-        <td>{{org.id}}</td>
-				<td>{{org.name}}</td>
-				<td style="width: 1%">
-					<a href="admin/orgs/edit/{{org.id}}" class="btn btn-inverse btn-small">
-						<i class="fa fa-edit"></i>
-						Edit
-					</a>
-					&nbsp;&nbsp;
-					<a ng-click="deleteOrg(org)" class="btn btn-danger btn-small">
-						<i class="fa fa-remove"></i>
-					</a>
-				</td>
-			</tr>
+    <table class="filter-table form-inline">
+			<thead>
+				<tr>
+					<th>Id</th>
+					<th>Name</th>
+          <th></th>
+				</tr>
+			</thead>
+			<tbody>
+				<tr ng-repeat="org in orgs">
+          <td>{{org.id}}</td>
+					<td>{{org.name}}</td>
+					<td class="text-right">
+						<a href="admin/orgs/edit/{{org.id}}" class="btn btn-inverse btn-small">
+							<i class="fa fa-edit"></i>
+							Edit
+						</a>
+						&nbsp;&nbsp;
+						<a ng-click="deleteOrg(org)" class="btn btn-danger btn-small">
+							<i class="fa fa-remove"></i>
+						</a>
+					</td>
+				</tr>
+			</tbody>
 		</table>
 		</table>
-
 	</div>
 	</div>
 </div>
 </div>

+ 32 - 28
public/app/features/admin/partials/users.html

@@ -5,38 +5,42 @@
 	</ul>
 	</ul>
 </topnav>
 </topnav>
 
 
-<div class="page-container">
-	<div class="page">
+<div class="page-container" style="background: transparent; border: 0;">
+	<div class="page-wide">
 		<h2>
 		<h2>
 			Users
 			Users
 		</h2>
 		</h2>
 
 
-		<table class="grafana-options-table">
-			<tr>
-				<th style="text-align:left">Id</th>
-				<th>Name</th>
-				<th>Login</th>
-				<th>Email</th>
-				<th style="white-space: nowrap">Grafana Admin</th>
-				<th></th>
-			</tr>
-			<tr ng-repeat="user in users">
-				<td>{{user.id}}</td>
-				<td>{{user.name}}</td>
-				<td>{{user.login}}</td>
-				<td>{{user.email}}</td>
-				<td>{{user.isAdmin}}</td>
-				<td style="width: 1%">
-					<a href="admin/users/edit/{{user.id}}" class="btn btn-inverse btn-small">
-						<i class="fa fa-edit"></i>
-						Edit
-					</a>
-					&nbsp;&nbsp;
-					<a ng-click="deleteUser(user)" class="btn btn-danger btn-small">
-						<i class="fa fa-remove"></i>
-					</a>
-				</td>
-			</tr>
+    <table class="filter-table form-inline">
+			<thead>
+				<tr>
+					<th>Id</th>
+					<th>Name</th>
+					<th>Login</th>
+					<th>Email</th>
+					<th style="white-space: nowrap">Grafana Admin</th>
+					<th></th>
+				</tr>
+			</thead>
+			<tbody>
+				<tr ng-repeat="user in users">
+					<td>{{user.id}}</td>
+					<td>{{user.name}}</td>
+					<td>{{user.login}}</td>
+					<td>{{user.email}}</td>
+					<td>{{user.isAdmin}}</td>
+					<td class="text-right">
+						<a href="admin/users/edit/{{user.id}}" class="btn btn-inverse btn-small">
+							<i class="fa fa-edit"></i>
+							Edit
+						</a>
+						&nbsp;&nbsp;
+						<a ng-click="deleteUser(user)" class="btn btn-danger btn-small">
+							<i class="fa fa-remove"></i>
+						</a>
+					</td>
+				</tr>
+			</tbody>
 		</table>
 		</table>
 	</div>
 	</div>
 </div>
 </div>

+ 282 - 0
public/app/features/dashboard/partials/globalAlerts.html

@@ -0,0 +1,282 @@
+<topnav title="Alerting" subnav="false">
+  <ul class="nav">
+    <li class="active" ><a href="global-alerts">Global Alerts</a></li>
+  </ul>
+</topnav>
+
+<div class="page-container" style="background: transparent; border: 0;">
+  <div class="page-wide">
+    <h2>Global alerts</h2>
+
+    <div class="filter-controls-filters">
+      <div class="tight-form last">
+        <ul class="tight-form-list">
+          <li class="tight-form-item">Filters:</li>
+          <li class="tight-form-item">Alert State</li>
+          <li><!-- <value-select-dropdown></value-select-dropdown> --></li>
+          <li class="tight-form-item">Dashboards</li>
+          <li><!-- <value-select-dropdown></value-select-dropdown> --></li>
+          <li class="tight-form-item">
+            <a class="pointer">
+              <i class="fa fa-pencil"></i>
+            </a>
+          </li>
+        </ul>
+        <div class="clearfix"></div>
+      </div>
+    </div>
+    <ul class="filter-controls-actions">
+      <li>
+        <div class="dropdown">
+          <button class="btn btn-inverse dropdown-toggle" data-toggle="dropdown">
+            <input class="cr1" id="state-enabled" type="checkbox">
+            <label for="state-enabled" class="cr1"></label> <span class="caret"></span>
+          </button>
+          <ul class="dropdown-menu" role="menu">
+            <li><a>All</a></li>
+          </ul>
+        </div>
+      </li>
+      <li>
+        <div class="dropdown">
+          <button class="btn btn-inverse dropdown-toggle" data-toggle="dropdown">
+            Bulk Actions &nbsp; <span class="caret"></span>
+          </button>
+          <ul class="dropdown-menu" role="menu">
+            <li><a>Update notifications</a></li>
+          </ul>
+        </div>
+      </li>
+      <li>
+        <button class="btn btn-inverse" data-toggle="dropdown">
+          <i class="fa fa-fw fa-th-large"></i> New Dashboard from selected
+        </button>
+      </li>
+      <li>
+        <span class="filter-controls-actions-selected">2 selected, showing 6 of 6 total</span>
+      </li>
+    </ul>
+    <ul class="filter-list">
+      <li>
+        <ul class="filter-list-card">
+          <li class="filter-list-card-select">
+            <input class="cr1" id="alert1" type="checkbox">
+            <label for="alert1" class="cr1"></label>
+          </li>
+          <li>
+            <div class="filter-list-card-controls">
+              <div class="filter-list-card-links">
+                <span class="filter-list-card-link"><i class="fa fa-fw fa-th-large"></i>: <a href="">OpSec Super Sekret</a></span>
+                <span class="filter-list-card-link">Panel: <a href="">Prod CPU Data Writes</a></span>
+              </div>
+              <div class="filter-list-card-config">
+                <a href="#"><i class="fa fa-cog"></i></a>
+              </div>
+              <div class="filter-list-card-expand" ng-click="alert1.expanded = !alert1.expanded">
+                <i class="fa fa-angle-right" ng-show="!alert1.expanded"></i>
+                <i class="fa fa-angle-down" ng-show="alert1.expanded"></i>
+              </div>
+            </div>
+            <span class="filter-list-card-title">Prod CPU Data Writes</span>
+            <span class="filter-list-card-status">
+              <span class="filter-list-card-state online">Online</span> for 19 hours
+            </span>
+          </li>
+        </ul>
+        <div class="filter-list-card-details" ng-show="alert1.expanded">
+          <h5 class="filter-list-card-details-heading">Alert query <a>configure alerting</a></h5>
+          <div class="tight-form last">
+            <ul class="tight-form-list">
+              <li class="tight-form-item" style="min-width: 15px; text-align: center">A</li>
+              <li class="tight-form-item">apps</li>
+              <li class="tight-form-item"><i class="fa fa-asterisk"><i></i></i></li>
+              <li class="tight-form-item">fakesite</li>
+              <li class="tight-form-item">counters</li>
+              <li class="tight-form-item">requests</li>
+              <li class="tight-form-item">count</li>
+              <li class="tight-form-item">scaleToSeconds(1)</li>
+              <li class="tight-form-item">aliasByNode(2)</li>
+            </ul>
+            <div class="clearfix"></div>
+          </div>
+        </div>
+      </li>
+      <li>
+        <ul class="filter-list-card">
+          <li class="filter-list-card-select">
+            <input class="cr1" id="alert2" type="checkbox" checked>
+            <label for="alert2" class="cr1"></label>
+          </li>
+          <li>
+            <div class="filter-list-card-controls">
+              <div class="filter-list-card-links">
+                <span class="filter-list-card-link"><i class="fa fa-fw fa-th-large"></i>: <a href="">OpSec Insanely Super Duper Sekret</a></span>
+                <span class="filter-list-card-link">Panel: <a href="">client side full page load</a></span>
+              </div>
+              <div class="filter-list-card-config">
+                <a href="#"><i class="fa fa-cog"></i></a>
+              </div>
+              <div class="filter-list-card-expand" ng-click="alert2.expanded = !alert2.expanded">
+                <i class="fa fa-angle-right" ng-show="!alert2.expanded"></i>
+                <i class="fa fa-angle-down" ng-show="alert2.expanded"></i>
+              </div>
+            </div>
+            <span class="filter-list-card-title">Prod DB Reads</span>
+            <span class="filter-list-card-status">
+              <span class="filter-list-card-state warn">Warn</span> for 1 hour
+            </span>
+          </li>
+        </ul>
+        <div class="filter-list-card-details" ng-show="alert2.expanded">
+          <h5 class="filter-list-card-details-heading">Alert query <a>configure alerting</a></h5>
+          <div class="tight-form last">
+            <ul class="tight-form-list">
+              <li class="tight-form-item" style="min-width: 15px; text-align: center">A</li>
+              <li class="tight-form-item">apps</li>
+              <li class="tight-form-item"><i class="fa fa-asterisk"><i></i></i></li>
+              <li class="tight-form-item">fakesite</li>
+              <li class="tight-form-item">counters</li>
+              <li class="tight-form-item">requests</li>
+              <li class="tight-form-item">count</li>
+              <li class="tight-form-item">scaleToSeconds(1)</li>
+              <li class="tight-form-item">aliasByNode(2)</li>
+            </ul>
+            <div class="clearfix"></div>
+          </div>
+        </div>
+      </li>
+      <li>
+        <ul class="filter-list-card">
+          <li class="filter-list-card-select">
+            <input class="cr1" id="alert3" type="checkbox" checked>
+            <label for="alert3" class="cr1"></label>
+          </li>
+          <li>
+            <div class="filter-list-card-controls">
+              <div class="filter-list-card-links">
+                <span class="filter-list-card-link"><i class="fa fa-fw fa-th-large"></i>: <a href="">OpSec Mildly Sekret</a></span>
+                <span class="filter-list-card-link">Panel: <a href="">Memory/CPU</a></span>
+              </div>
+              <div class="filter-list-card-config">
+                <a href="#"><i class="fa fa-cog"></i></a>
+              </div>
+              <div class="filter-list-card-expand" ng-click="alert3.expanded = !alert3.expanded">
+                <i class="fa fa-angle-right" ng-show="!alert3.expanded"></i>
+                <i class="fa fa-angle-down" ng-show="alert3.expanded"></i>
+              </div>
+            </div>
+            <span class="filter-list-card-title">Prod CPU Data Writes</span>
+            <span class="filter-list-card-status">
+              <span class="filter-list-card-state critical">Online</span> for 10 minutes
+            </span>
+          </li>
+        </ul>
+        <div class="filter-list-card-details" ng-show="alert3.expanded">
+          <h5 class="filter-list-card-details-heading">Alert query <a>configure alerting</a></h5>
+          <div class="tight-form last">
+            <ul class="tight-form-list">
+              <li class="tight-form-item" style="min-width: 15px; text-align: center">A</li>
+              <li class="tight-form-item">apps</li>
+              <li class="tight-form-item"><i class="fa fa-asterisk"><i></i></i></li>
+              <li class="tight-form-item">fakesite</li>
+              <li class="tight-form-item">counters</li>
+              <li class="tight-form-item">requests</li>
+              <li class="tight-form-item">count</li>
+              <li class="tight-form-item">scaleToSeconds(1)</li>
+              <li class="tight-form-item">aliasByNode(2)</li>
+            </ul>
+            <div class="clearfix"></div>
+          </div>
+        </div>
+      </li>
+      <li>
+        <ul class="filter-list-card">
+          <li class="filter-list-card-select">
+            <input class="cr1" id="alert4" type="checkbox">
+            <label for="alert4" class="cr1"></label>
+          </li>
+          <li>
+            <div class="filter-list-card-controls">
+              <div class="filter-list-card-links">
+                <span class="filter-list-card-link"><i class="fa fa-fw fa-th-large"></i>: <a href="">OpSec Super Sekret</a></span>
+                <span class="filter-list-card-link">Panel: <a href="">Stacked lines</a></span>
+              </div>
+              <div class="filter-list-card-config">
+                <a href="#"><i class="fa fa-cog"></i></a>
+              </div>
+              <div class="filter-list-card-expand" ng-click="alert4.expanded = !alert4.expanded">
+                <i class="fa fa-angle-right" ng-show="!alert4.expanded"></i>
+                <i class="fa fa-angle-down" ng-show="alert4.expanded"></i>
+              </div>
+            </div>
+            <span class="filter-list-card-title">Critical Thing</span>
+            <span class="filter-list-card-status">
+              <span class="filter-list-card-state online">Online</span> for 5 weeks
+            </span>
+          </li>
+        </ul>
+        <div class="filter-list-card-details" ng-show="alert4.expanded">
+          <h5 class="filter-list-card-details-heading">Alert query <a>configure alerting</a></h5>
+          <div class="tight-form last">
+            <ul class="tight-form-list">
+              <li class="tight-form-item" style="min-width: 15px; text-align: center">A</li>
+              <li class="tight-form-item">apps</li>
+              <li class="tight-form-item"><i class="fa fa-asterisk"><i></i></i></li>
+              <li class="tight-form-item">fakesite</li>
+              <li class="tight-form-item">counters</li>
+              <li class="tight-form-item">requests</li>
+              <li class="tight-form-item">count</li>
+              <li class="tight-form-item">scaleToSeconds(1)</li>
+              <li class="tight-form-item">aliasByNode(2)</li>
+            </ul>
+            <div class="clearfix"></div>
+          </div>
+        </div>
+      </li>
+      <li>
+        <ul class="filter-list-card">
+          <li class="filter-list-card-select">
+            <input class="cr1" id="alert5" type="checkbox">
+            <label for="alert5" class="cr1"></label>
+          </li>
+          <li>
+            <div class="filter-list-card-controls">
+              <div class="filter-list-card-links">
+                <span class="filter-list-card-link"><i class="fa fa-fw fa-th-large"></i>: <a href="">OpSec Public</a></span>
+                <span class="filter-list-card-link">Panel: <a href="">More Critical Thing</a></span>
+              </div>
+              <div class="filter-list-card-config">
+                <a href="#"><i class="fa fa-cog"></i></a>
+              </div>
+              <div class="filter-list-card-expand" ng-click="alert5.expanded = !alert5.expanded">
+                <i class="fa fa-angle-right" ng-show="!alert5.expanded"></i>
+                <i class="fa fa-angle-down" ng-show="alert5.expanded"></i>
+              </div>
+            </div>
+            <span class="filter-list-card-title">More Critical Thing</span>
+            <span class="filter-list-card-status">
+              <span class="filter-list-card-state online">Online</span> for 2 months
+            </span>
+          </li>
+        </ul>
+        <div class="filter-list-card-details" ng-show="alert5.expanded">
+          <h5 class="filter-list-card-details-heading">Alert query <a>configure alerting</a></h5>
+          <div class="tight-form last">
+            <ul class="tight-form-list">
+              <li class="tight-form-item" style="min-width: 15px; text-align: center">A</li>
+              <li class="tight-form-item">apps</li>
+              <li class="tight-form-item"><i class="fa fa-asterisk"><i></i></i></li>
+              <li class="tight-form-item">fakesite</li>
+              <li class="tight-form-item">counters</li>
+              <li class="tight-form-item">requests</li>
+              <li class="tight-form-item">count</li>
+              <li class="tight-form-item">scaleToSeconds(1)</li>
+              <li class="tight-form-item">aliasByNode(2)</li>
+            </ul>
+            <div class="clearfix"></div>
+          </div>
+        </div>
+      </li>
+    </ul>
+  </div>
+</div>

+ 85 - 35
public/app/features/org/partials/datasources.html

@@ -5,47 +5,97 @@
 	</ul>
 	</ul>
 </topnav>
 </topnav>
 
 
-<div class="page-container">
-	<div class="page">
+<div class="page-container" style="background: transparent; border: 0;">
+	<div class="page-wide">
 		<h2>Data sources</h2>
 		<h2>Data sources</h2>
 
 
+    <!--
+		<div class="filter-controls-filters">
+      <div class="tight-form last">
+        <ul class="tight-form-list">
+          <li class="tight-form-item">Filters:</li>
+          <li class="tight-form-item">Name</li>
+          <li><value-select-dropdown></value-select-dropdown></li>
+          <li class="tight-form-item">URL</li>
+          <li><value-select-dropdown></value-select-dropdown></li>
+          <li class="tight-form-item">
+            <a class="pointer">
+              <i class="fa fa-pencil"></i>
+            </a>
+          </li>
+        </ul>
+        <div class="clearfix"></div>
+      </div>
+    </div>
+
+    <ul class="filter-controls-actions">
+      <li>
+        <div class="dropdown">
+          <button class="btn btn-inverse dropdown-toggle" data-toggle="dropdown">
+            <input class="cr1" id="state-enabled" type="checkbox">
+            <label for="state-enabled" class="cr1"></label> <span class="caret"></span>
+          </button>
+          <ul class="dropdown-menu" role="menu">
+            <li><a>All</a></li>
+          </ul>
+        </div>
+      </li>
+      <li>
+        <div class="dropdown">
+          <button class="btn btn-inverse dropdown-toggle" data-toggle="dropdown">
+            Bulk Actions &nbsp; <span class="caret"></span>
+          </button>
+          <ul class="dropdown-menu" role="menu">
+            <li><a>Update notifications</a></li>
+          </ul>
+        </div>
+      </li>
+      <li>
+        <span class="filter-controls-actions-selected">0 selected, showing 2 of 2 total</span>
+      </li>
+    </ul>
+    -->
+
 		<div ng-if="datasources.length === 0">
 		<div ng-if="datasources.length === 0">
 			<em>No datasources defined</em>
 			<em>No datasources defined</em>
 		</div>
 		</div>
 
 
-		<table class="grafana-options-table" ng-if="datasources.length > 0">
-			<tr>
-				<td><strong>Name</strong></td>
-				<td><strong>Url</strong></td>
-				<td></td>
-				<td></td>
-				<td></td>
-			</tr>
-			<tr ng-repeat="ds in datasources">
-				<td style="width:1%">
-					<i class="fa fa-database"></i> &nbsp;
-					{{ds.name}}
-				</td>
-				<td style="width:90%">
-					{{ds.url}}
-				</td>
-				<td style="width:2%" class="text-center">
-					<span ng-if="ds.isDefault">
-						<span class="label label-info">default</span>
-					</span>
-				</td>
-				<td style="width: 1%">
-					<a href="datasources/edit/{{ds.id}}" class="btn btn-inverse btn-mini">
-						<i class="fa fa-edit"></i>
-						Edit
-					</a>
-				</td>
-				<td style="width: 1%">
-					<a ng-click="remove(ds)" class="btn btn-danger btn-mini">
-						<i class="fa fa-remove"></i>
-					</a>
-				</td>
-			</tr>
+		<table class="filter-table" ng-if="datasources.length > 0">
+			<thead>
+				<tr>
+					<th><strong>Name</strong></th>
+					<th><strong>Url</strong></th>
+					<th style="width: 60px;"></th>
+					<th style="width: 65px;"></th>
+					<th style="width: 34px;"></th>
+				</tr>
+			</thead>
+			<tbody>
+				<tr ng-repeat="ds in datasources">
+					<td>
+						<i class="fa fa-database"></i> &nbsp; {{ds.name}}
+					</td>
+					<td>
+						<span class="ellipsis">{{ds.url}}</span>
+					</td>
+					<td class="text-center">
+						<span ng-if="ds.isDefault">
+							<span class="label label-info">default</span>
+						</span>
+					</td>
+					<td class="text-right">
+						<a href="datasources/edit/{{ds.id}}" class="btn btn-inverse btn-mini">
+							<i class="fa fa-edit"></i>
+							Edit
+						</a>
+					</td>
+					<td class="text-right">
+						<a ng-click="remove(ds)" class="btn btn-danger btn-mini">
+							<i class="fa fa-remove"></i>
+						</a>
+					</td>
+				</tr>
+			</tbody>
 		</table>
 		</table>
 
 
 	</div>
 	</div>

+ 21 - 18
public/app/features/org/partials/orgApiKeys.html

@@ -4,9 +4,8 @@
 	</ul>
 	</ul>
 </topnav>
 </topnav>
 
 
-<div class="page-container">
-	<div class="page">
-
+<div class="page-container" style="background: transparent; border: 0;">
+	<div class="page-wide">
 		<h2>
 		<h2>
 			API Keys
 			API Keys
 		</h2>
 		</h2>
@@ -32,21 +31,25 @@
 			</ul>
 			</ul>
 		</form>
 		</form>
 
 
-		<table class="grafana-options-table" style="width: 250px">
-			<tr>
-				<th style="text-align: left">Name</th>
-				<th style="text-align: left">Role</th>
-				<th></th>
-			</tr>
-			<tr ng-repeat="t in tokens">
-				<td>{{t.name}}</td>
-				<td>{{t.role}}</td>
-				<td style="width: 1%">
-					<a ng-click="removeToken(t.id)" class="btn btn-danger btn-mini">
-						<i class="fa fa-remove"></i>
-					</a>
-				</td>
-			</tr>
+		<table class="filter-table">
+			<thead>
+				<tr>
+					<th>Name</th>
+					<th>Role</th>
+					<th style="width: 34px;"></th>
+				</tr>
+			</thead>
+			<tbody>
+				<tr ng-repeat="t in tokens">
+					<td>{{t.name}}</td>
+					<td>{{t.role}}</td>
+					<td>
+						<a ng-click="removeToken(t.id)" class="btn btn-danger btn-mini">
+							<i class="fa fa-remove"></i>
+						</a>
+					</td>
+				</tr>
+			</tbody>
 		</table>
 		</table>
 	</div>
 	</div>
 
 

+ 54 - 39
public/app/features/org/partials/orgUsers.html

@@ -4,8 +4,8 @@
 	</ul>
 	</ul>
 </topnav>
 </topnav>
 
 
-<div class="page-container">
-	<div class="page">
+<div class="page-container" style="background: transparent; border: 0;">
+	<div class="page-wide">
 
 
 		<h2>Organization users</h2>
 		<h2>Organization users</h2>
 
 
@@ -18,21 +18,23 @@
 
 
 		<tabset>
 		<tabset>
 			<tab heading="Users ({{users.length}})">
 			<tab heading="Users ({{users.length}})">
-				<table class="grafana-options-table form-inline">
-					<tr>
-						<th>Login</th>
-						<th>Email</th>
-						<th>Role</th>
-						<th></th>
-					</tr>
+				<table class="filter-table form-inline">
+					<thead>
+						<tr>
+							<th>Login</th>
+							<th>Email</th>
+							<th>Role</th>
+							<th style="width: 34px;"></th>
+						</tr>
+					</thead>
 					<tr ng-repeat="user in users">
 					<tr ng-repeat="user in users">
 						<td>{{user.login}}</td>
 						<td>{{user.login}}</td>
-						<td>{{user.email}}</td>
+						<td><span class="ellipsis">{{user.email}}</span></td>
 						<td>
 						<td>
 							<select type="text" ng-model="user.role" class="input-medium" ng-options="f for f in ['Viewer', 'Editor', 'Read Only Editor', 'Admin']" ng-change="updateOrgUser(user)">
 							<select type="text" ng-model="user.role" class="input-medium" ng-options="f for f in ['Viewer', 'Editor', 'Read Only Editor', 'Admin']" ng-change="updateOrgUser(user)">
 							</select>
 							</select>
 						</td>
 						</td>
-						<td style="width: 1%">
+						<td>
 							<a ng-click="removeUser(user)" class="btn btn-danger btn-mini">
 							<a ng-click="removeUser(user)" class="btn btn-danger btn-mini">
 								<i class="fa fa-remove"></i>
 								<i class="fa fa-remove"></i>
 							</a>
 							</a>
@@ -41,36 +43,49 @@
 				</table>
 				</table>
 			</tab>
 			</tab>
 			<tab heading="Pending Invitations ({{pendingInvites.length}})">
 			<tab heading="Pending Invitations ({{pendingInvites.length}})">
-				<div class="grafana-list-item" ng-repeat="invite in pendingInvites" ng-click="invite.expanded = !invite.expanded">
-					{{invite.email}}
-					<span ng-show="invite.name" style="padding-left: 20px"> {{invite.name}}</span>
-					<span class="pull-right">
-						<button class="btn btn-inverse btn-mini " data-clipboard-text="{{invite.url}}" clipboard-button ng-click="copyInviteToClipboard($event)">
-							<i class="fa fa-clipboard"></i> Copy Invite
-						</button>
-						&nbsp;
-						<a class="pointer">
-							<i ng-show="!invite.expanded" class="fa fa-caret-right"></i>
-							<i ng-show="invite.expanded" class="fa fa-caret-down"></i>
-						</a>
-					</span>
-					<div ng-show="invite.expanded">
-						<a href="{{invite.url}}">{{invite.url}}</a><br>
-						<button class="btn btn-inverse btn-mini">
-							<i class="fa fa-envelope-o"></i> Resend invite
-						</button>
-						&nbsp;
-						<button class="btn btn-inverse btn-mini" ng-click="revokeInvite(invite, $event)">
-							<i class="fa fa-remove" style="color: red"></i> Revoke invite
-						</button>
-						<span style="padding-left: 15px">
-							Invited: <em> {{invite.createdOn | date: 'shortDate'}} by {{invite.invitedBy}} </em>
-						</span>
-					<div>
-				</div>
+				<table class="filter-table form-inline">
+					<thead>
+						<tr>
+							<th>Email</th>
+							<th>Name</th>
+							<th></th>
+						</tr>
+					</thead>
+					<tbody ng-repeat="invite in pendingInvites">
+						<tr ng-click="invite.expanded = !invite.expanded" ng-class="{'expanded': invite.expanded}">
+							<td>{{invite.email}}</td>
+							<td ng-show="invite.name">{{invite.name}}</td>
+							<td class="text-right">
+								<button class="btn btn-inverse btn-mini " data-clipboard-text="{{invite.url}}" clipboard-button ng-click="copyInviteToClipboard($event)">
+									<i class="fa fa-clipboard"></i> Copy Invite
+								</button>
+								&nbsp;
+								<a class="pointer">
+									<i ng-show="!invite.expanded" class="fa fa-caret-right"></i>
+									<i ng-show="invite.expanded" class="fa fa-caret-down"></i>
+								</a>
+							</td>
+						</tr>
+						<tr ng-show="invite.expanded">
+							<td></td>
+							<td colspan="3">
+								<a href="{{invite.url}}">{{invite.url}}</a><br><br>
+								<button class="btn btn-inverse btn-mini">
+									<i class="fa fa-envelope-o"></i> Resend invite
+								</button>
+								&nbsp;
+								<button class="btn btn-inverse btn-mini" ng-click="revokeInvite(invite, $event)">
+									<i class="fa fa-remove" style="color: red"></i> Revoke invite
+								</button>
+								<span style="padding-left: 15px">
+									Invited: <em> {{invite.createdOn | date: 'shortDate'}} by {{invite.invitedBy}} </em>
+								</span>
+							</td>
+						</tr>
+					</tbody>
+				</table>
 			</tab>
 			</tab>
 		</tabset>
 		</tabset>
-
 	</div>
 	</div>
 </div>
 </div>
 
 

+ 5 - 0
public/app/features/panel/partials/panel.html

@@ -35,6 +35,11 @@
 			<button class="gf-box-header-close-btn" ng-click="exitFullscreen();">
 			<button class="gf-box-header-close-btn" ng-click="exitFullscreen();">
 				Back to dashboard
 				Back to dashboard
 			</button>
 			</button>
+
+			<div class="gf-box-header-save-btn">
+				There are unsaved changes.
+				<button class="btn btn-success btn-small"><i class="fa fa-save"></i> Save</button>
+			</div>
 		</div>
 		</div>
 
 
 		<div class="gf-box-body">
 		<div class="gf-box-body">

+ 24 - 15
public/app/features/profile/partials/profile.html

@@ -5,8 +5,8 @@
 	</ul>
 	</ul>
 </topnav>
 </topnav>
 
 
-<div class="page-container">
-	<div class="page">
+<div class="page-container" style="background: transparent; border: 0;">
+	<div class="page-wide">
 
 
 		<h2>Profile</h2>
 		<h2>Profile</h2>
 
 
@@ -62,19 +62,28 @@
 
 
 		<h3>Organizations</h3>
 		<h3>Organizations</h3>
 
 
-		<table class="grafana-options-table">
-			<tr ng-repeat="org in orgs">
-				<td style="width: 98%"><strong>Name: </strong> {{org.name}}</td>
-				<td><strong>Role: </strong> {{org.role}}</td>
-				<td class="nobg max-width-btns">
-					<span class="btn btn-primary btn-mini" ng-show="org.orgId === contextSrv.user.orgId">
-						Current
-					</span>
-					<a ng-click="setUsingOrg(org)" class="btn btn-inverse btn-mini" ng-show="org.orgId !== contextSrv.user.orgId">
-						Select
-					</a>
-				</td>
-			</tr>
+		<table class="filter-table form-inline">
+			<thead>
+				<tr>
+					<th>Name</th>
+					<th>Role</th>
+					<th></th>
+				</tr>
+			</thead>
+			<tbody>
+				<tr ng-repeat="org in orgs">
+					<td>{{org.name}}</td>
+					<td>{{org.role}}</td>
+					<td class="text-right">
+						<span class="btn btn-primary btn-mini" ng-show="org.orgId === contextSrv.user.orgId">
+							Current
+						</span>
+						<a ng-click="setUsingOrg(org)" class="btn btn-inverse btn-mini" ng-show="org.orgId !== contextSrv.user.orgId">
+							Select
+						</a>
+					</td>
+				</tr>
+			</tbody>
 		</table>
 		</table>
 
 
 	</div>
 	</div>

+ 220 - 0
public/app/panels/graph/alerting.html

@@ -0,0 +1,220 @@
+<div class="editor-row" style="margin-bottom: 20px;">
+  <span style="float: right; font-size: 12px;"><i>Last updated by Grafana October 4, 2015 12:15:04 by $username</i></span>
+  <div class="section">
+    <h5>General Alerting Options</h5>
+    <div class="tight-form last">
+      <ul class="tight-form-list">
+        <li class="tight-form-item">
+          Alert Title
+        </li>
+        <li>
+          <input type="text" class="input-xlarge tight-form-input"></input>
+        </li>
+        <li class="tight-form-item">
+          Alerting Backend
+        </li>
+        <li>
+          <select class="input-medium tight-form-input">
+            <option>Grafana Alerting</option>
+          </select>
+        </li>
+        <li class="tight-form-item last">
+          <label class="checkbox-label" for="alerting-enabled">Enabled</label>
+          <input class="cr1" id="alerting-enabled" type="checkbox">
+          <label for="alerting-enabled" class="cr1"></label>
+        </li>
+      </ul>
+      <div class="clearfix"></div>
+    </div>
+  </div>
+</div>
+<div class="editor-row" style="margin-bottom: 20px;">
+  <h5>Choose your query:</h5>
+  <p>Select an exising query to alert on:</p>
+  <div class="tight-form">
+    <ul class="tight-form-list">
+      <li class="tight-form-item"><input type="radio" class="radio input-small" name="query" style="margin: 0 4px 4px;" /></li>
+      <li class="tight-form-item">None</li>
+    </ul>
+    <div class="clearfix"></div>
+  </div>
+  <div class="tight-form">
+    <ul class="tight-form-list">
+      <li class="tight-form-item"><input type="radio" class="radio input-small" name="query" style="margin: 0 4px 4px;" /></li>
+      <li class="tight-form-item" style="min-width: 15px; text-align: center">A</li>
+      <li class="tight-form-item">apps</li>
+      <li class="tight-form-item"><i class="fa fa-asterisk"><i></i></i></li>
+      <li class="tight-form-item">fakesite</li>
+      <li class="tight-form-item">counters</li>
+      <li class="tight-form-item">requests</li>
+      <li class="tight-form-item">count</li>
+      <li class="tight-form-item">scaleToSeconds(1)</li>
+      <li class="tight-form-item last">aliasByNode(2)</li>
+      <li><div class="copy-query" bs-tooltip="'Copy to custom query'" data-placement="top"></div></li>
+    </ul>
+    <div class="clearfix"></div>
+  </div>
+  <div class="tight-form">
+    <ul class="tight-form-list">
+      <li class="tight-form-item"><input type="radio" class="radio input-small" name="query" style="margin: 0 4px 4px;" /></li>
+      <li class="tight-form-item" style="min-width: 15px; text-align: center">B</li>
+      <li class="tight-form-item last"><span class="query-keyword">Metric:</span> us-west-2 AWS/EC2 CPUUtilization <span class="query-keyword">Stats:</span> Minimum Maximum <span class="query-keyword">Dimensions</span> InstanceIS <span class="query-segment-operator">=</span> i-b0e8a447 <span class="query-keyword">Alias</span> {{stat}} <span class="query-keyword">Period</span> 60</li>
+      <li><div class="copy-query" bs-tooltip="'Copy to custom query'" data-placement="top"></div></li>
+    </ul>
+    <div class="clearfix"></div>
+  </div>
+  <div class="tight-form">
+    <ul class="tight-form-list">
+      <li class="tight-form-item"><input type="radio" class="radio input-small" name="query" style="margin: 0 4px 4px;" /></li>
+      <li class="tight-form-item" style="min-width: 15px; text-align: center">C</li>
+      <li class="tight-form-item last"><span class="query-keyword">Query:</span> avg(counters_logins) by(server) <span class="query-keyword">Legend Format:</span> {{app}} - {{server}} <span class="query-keyword">Step:</span> 1s <span class="query-keyword">Resolution:</span> 1/2</li>
+      <li><div class="copy-query" bs-tooltip="'Copy to custom query'" data-placement="top"></div></li>
+    </ul>
+    <div class="clearfix"></div>
+  </div>
+  <div class="tight-form">
+    <ul class="tight-form-list">
+      <li class="tight-form-item"><input type="radio" class="radio input-small" name="query" style="margin: 0 4px 4px;" /></li>
+      <li class="tight-form-item" style="min-width: 15px; text-align: center">D</li>
+      <li class="tight-form-item last"><span class="query-keyword">SELECT</span> mean(value) <span class="query-keyword">FROM</span> logins.count <span class="query-keyword">WHERE</span> hostname <span class="query-segment-operator">=</span> /$Hostname$/ <span class="query-keyword">GROUP BY</span> time($internal) hostname</li>
+      <li><div class="copy-query" bs-tooltip="'Copy to custom query'" data-placement="top"></div></li>
+    </ul>
+    <div class="clearfix"></div>
+  </div>
+  <div class="tight-form last">
+    <ul class="tight-form-list">
+      <li class="tight-form-item"><input type="radio" class="radio input-small" name="query" style="margin: 0 4px 4px;" checked /></li>
+      <li class="tight-form-item" style="min-width: 15px; text-align: center">E</li>
+      <li class="tight-form-item last"><span class="query-keyword">Metric:</span> apps.backend.backend_01.counters.requests.count <span class="query-keyword">Alias:</span> Bristow <span class="query-keyword">Aggregator:</span> Sum <span class="query-keyword">Downsample:</span> 1m <span class="query-keyword">Aggregator</span> Sum <span class="query-keyword">Tags</span> host = test</li>
+      <li><div class="copy-query" bs-tooltip="'Copy to custom query'" data-placement="top"></div></li>
+    </ul>
+    <div class="clearfix"></div>
+  </div>
+</div>
+<div class="editor-row" style="margin-bottom: 20px;">
+  <p>Or write a new custom alerting query:</p>
+  <div class="section">
+    <div class="tight-form last">
+      <ul class="tight-form-list">
+        <li class="tight-form-item"><input type="radio" class="radio input-small" name="query" style="margin: 0 4px 4px;" /></li>
+        <li class="tight-form-item">
+          <a class="pointer">
+            <i class="fa fa-pencil"></i>
+          </a>
+        </li>
+        <li class="tight-form-item">
+          select metric
+        </li>
+        <li>
+          <a class="tight-form-item tight-form-func last dropdown-toggle"><i class="fa fa-plus"></i></a>
+        </li>
+      </ul>
+      <div class="clearfix"></div>
+    </div>
+  </div>
+</div>
+<div class="editor-row" style="margin-bottom: 10px;">
+  <div class="section">
+    <h5>Define Your States</h5>
+    <div class="tight-form last">
+      <ul class="tight-form-list">
+        <li class="tight-form-item">
+          by
+        </li>
+        <li>
+          <select class="input-medium tight-form-input">
+            <option>Averaging</option>
+          </select>
+        </li>
+        <li class="tight-form-item">
+          the values in the query over the last
+        </li>
+        <li>
+          <input type="text" class="input-mini tight-form-input last"></input>
+        </li>
+      </ul>
+      <div class="clearfix"></div>
+    </div>
+  </div>
+</div>
+<div class="editor-row" style="margin-bottom: 20px;">
+  <div class="section">
+    <div class="tight-form">
+      <ul class="tight-form-list">
+        <li class="tight-form-item" style="width: 100px;">
+          <span class="alert-state alert-state-warning">Warn</span>
+        </li>
+        <li>
+          <input type="text" class="input-mini tight-form-input" value=">" style="text-align: center;"></input>
+        </li>
+        <li>
+          <input type="text" class="input-mini tight-form-input" value="#B" style="text-align: center;"></input>
+        </li>
+        <li class="tight-form-item">
+          .notify
+        </li>
+        <li class="alert-notify-emails">
+          <bootstrap-tagsinput tagclass="label label-tag label-tag-email"></bootstrap-tagsinput>
+        </li>
+        <li class="tight-form-item last">
+          <label class="checkbox-label" for="state-enabled">Enabled</label>
+          <input class="cr1" id="state-enabled" type="checkbox">
+          <label for="state-enabled" class="cr1"></label>
+        </li>
+      </ul>
+      <div class="clearfix"></div>
+    </div>
+    <div class="tight-form last">
+      <ul class="tight-form-list">
+        <li class="tight-form-item" style="width: 100px;">
+          <span class="alert-state alert-state-critical">Critical</span>
+        </li>
+        <li>
+          <input type="text" class="input-mini tight-form-input"></input>
+        </li>
+        <li>
+          <input type="text" class="input-mini tight-form-input"></input>
+        </li>
+        <li class="tight-form-item">
+          .notify
+        </li>
+        <li class="alert-notify-emails">
+          <bootstrap-tagsinput tagclass="label label-tag label-tag-email"></bootstrap-tagsinput>
+        </li>
+        <li class="tight-form-item last">
+          <label class="checkbox-label" for="state-enabled2">Enabled</label>
+          <input class="cr1" id="state-enabled2" type="checkbox">
+          <label for="state-enabled2" class="cr1"></label>
+        </li>
+      </ul>
+      <div class="clearfix"></div>
+    </div>
+  </div>
+</div>
+<div class="editor-row">
+  <div class="section">
+    <h5>What to Say <span style="float: right; font-size: 12px; font-weight: normal;"><a href="#">Variables</a> | <a href="#">Preview</a></span></h5>
+    <div class="tight-form">
+      <ul class="tight-form-list">
+        <li class="tight-form-item" style="width: 100px;">
+          Summary
+        </li>
+        <li>
+          <input type="text" class="input-xxlarge tight-form-input last"></input>
+        </li>
+      </ul>
+      <div class="clearfix"></div>
+    </div>
+    <div class="tight-form last">
+      <ul class="tight-form-list">
+        <li class="tight-form-item" style="width: 100px;">
+          Description
+        </li>
+        <li>
+          <textarea class="tight-form-textarea input-xxlarge last"></textarea>
+        </li>
+      </ul>
+      <div class="clearfix"></div>
+    </div>
+  </div>
+</div>

+ 1 - 0
public/app/panels/graph/module.js

@@ -33,6 +33,7 @@ function (angular, _, moment, kbn, TimeSeries, PanelMeta) {
     $scope.panelMeta.addEditorTab('Axes & Grid', 'app/panels/graph/axisEditor.html');
     $scope.panelMeta.addEditorTab('Axes & Grid', 'app/panels/graph/axisEditor.html');
     $scope.panelMeta.addEditorTab('Display Styles', 'app/panels/graph/styleEditor.html');
     $scope.panelMeta.addEditorTab('Display Styles', 'app/panels/graph/styleEditor.html');
     $scope.panelMeta.addEditorTab('Time range', 'app/features/panel/partials/panelTime.html');
     $scope.panelMeta.addEditorTab('Time range', 'app/features/panel/partials/panelTime.html');
+    $scope.panelMeta.addEditorTab('Alerting', 'app/panels/graph/alerting.html');
 
 
     $scope.panelMeta.addExtendedMenuItem('Export CSV', '', 'exportCsv()');
     $scope.panelMeta.addExtendedMenuItem('Export CSV', '', 'exportCsv()');
     $scope.panelMeta.addExtendedMenuItem('Toggle legend', '', 'toggleLegend()');
     $scope.panelMeta.addExtendedMenuItem('Toggle legend', '', 'toggleLegend()');

BIN
public/img/CopyQuery.png


+ 15 - 0
public/img/critical.svg

@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 19.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<svg version="1.1" baseProfile="tiny" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
+	 x="0px" y="0px" width="70px" height="70px" viewBox="15 -15 70 70" xml:space="preserve">
+<g>
+	<path fill="#EC2128" d="M55.2-7l-0.1,0.4 M78.9-6.1c-3.9-3.9-9.1-6.1-14.6-6.1c-2.7,0-5.4,0.5-7.9,1.6L55.2-7l1.1-3.5l3.4,1.1
+		l-0.2,0.6c1.5-0.4,3.1-0.6,4.7-0.6c4.8,0,9.4,1.9,12.8,5.3s5.3,7.9,5.3,12.8s-1.9,9.4-5.3,12.8l-27,27l-27-27
+		c-3.4-3.4-5.3-7.9-5.3-12.8S19.6-0.8,23-4.2s7.9-5.3,12.8-5.3c2,0,4,0.3,5.8,1l0.3-1.5l3.5,0.7l0.1-0.4c-3-1.6-6.3-2.4-9.7-2.4
+		c-5.6-0.1-10.8,2.1-14.7,6S15,3,15,8.6s2.2,10.7,6.1,14.7L50,52.2l28.9-28.9c3.9-3.9,6.1-9.1,6.1-14.7S82.8-2.2,78.9-6.1z"/>
+	<path fill="#EC2128" d="M51.3,5.3l6.5-1l-11.2,27l-0.1,0.2l1.9-19.7l-7.3,0.5v-0.2l4.3-21.4L41.9-10l-0.3,1.5l-1.1,5.3
+		c-1.5-0.6-3.1-0.9-4.8-0.9c-3.4,0-6.6,1.3-9,3.7S23,5.2,23,8.6s1.3,6.6,3.7,9L50,40.8l23.2-23.2c2.4-2.4,3.7-5.6,3.7-9
+		s-1.3-6.6-3.7-9c-2.4-2.4-5.6-3.7-9-3.7c-2.5,0-4.8,0.7-6.8,2l2.2-6.8l0.2-0.6l-3.4-1.1L55.2-7l-0.1,0.4
+		C55.1-6.6,51.3,5.3,51.3,5.3z"/>
+</g>
+</svg>

BIN
public/img/envelope.png


+ 12 - 0
public/img/online.svg

@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 19.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<svg version="1.1" baseProfile="tiny" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
+	 x="0px" y="0px" width="70px" height="70px" viewBox="15 -15 70 70" xml:space="preserve">
+<path fill="#01A64F" d="M50,52.2l-28.9-29C17.2,19.3,15,14.1,15,8.6s2.2-10.8,6.1-14.7s9.1-6.1,14.6-6.1c5.4,0,10.4,2,14.3,5.7
+	c3.9-3.7,8.9-5.7,14.3-5.7c5.5,0,10.7,2.2,14.6,6.1S85,3,85,8.6s-2.2,10.7-6.1,14.7L50,52.2z M35.7-9.5c-4.8,0-9.4,1.9-12.8,5.3
+	s-5.3,7.9-5.3,12.8s2,9.3,5.4,12.7l27,27l27-27c3.4-3.4,5.3-7.9,5.3-12.8S80.4-0.9,77-4.3c-3.4-3.4-7.9-5.3-12.8-5.3
+	c-4.8,0-9.4,1.9-12.8,5.3L50-2.7l-1.5-1.5C45.1-7.6,40.6-9.5,35.7-9.5z"/>
+<path fill="#01A64F" d="M73.2-0.4c-2.4-2.4-5.6-3.7-9-3.7c-3.4,0-6.6,1.3-9,3.7l-1.5,1.5L51.9,3L50,4.9L48.1,3l-1.9-1.9l-1.5-1.5
+	c-2.4-2.4-5.6-3.7-9-3.7c-3.4,0-6.6,1.3-9,3.7S23,5.2,23,8.6s1.3,6.6,3.7,9L50,40.8l23.2-23.2c2.4-2.4,3.7-5.6,3.7-9
+	S75.6,2,73.2-0.4z"/>
+</svg>

+ 16 - 0
public/img/warn-tiny.svg

@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 19.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<svg version="1.1" baseProfile="tiny" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
+	 x="0px" y="0px" width="78px" height="71.9px" viewBox="19 -15.9 78 71.9" xml:space="preserve">
+<g>
+	<path fill="#FEC254" d="M21.9,7.3c0-0.5,0-1,0.1-1.5l-3,3c0.3,5.3,2.4,10.2,6,14.1l2.1-2.1C23.8,17,21.9,12.3,21.9,7.3z
+		 M28.41,26.338l2.12-2.12l10.04,10.04l-2.12,2.12L28.41,26.338z M42.1-12.9c5,0,9.7,1.8,13.4,5.2l2.2-2.2c-3.9-3.6-8.8-5.6-14.1-6
+		l-3,3H42.1z M41.905,39.846l2.12-2.12l10.042,10.04l-2.12,2.12L41.905,39.846z M88.2,21.5L58,51.7l-0.5-0.5l-2.1,2.1l2.6,2.6
+		l32.3-32.3c3.2-3.2,5.3-7.2,6.3-11.5l-5.2,5.2C90.5,18.9,89.5,20.3,88.2,21.5L88.2,21.5z M94.1,7.3v0.5L97,4.9
+		C96.5-0.2,94.2-5,90.6-8.8l-2.1,2.1C92.1-2.9,94.1,2,94.1,7.3z M25.7-9.1C22.8-6.2,20.8-2.8,19.8,1l16-16C32-14,28.6-12,25.7-9.1z
+		 M74-12.9c3.8,0,7.5,1.1,10.7,3.1l2.2-2.2c-3.8-2.5-8.3-3.9-12.9-3.9c-1.2,0-2.4,0.1-3.6,0.3L66-11.3C68.5-12.3,71.2-12.9,74-12.9z
+		 M64-2.7L62.3-1l-2.1,2.1L58,3.2l-2.1-2.1L54.8,0l-20,20l10,10L80.2-5.4c-1.9-1-4-1.5-6.2-1.5C70.2-6.9,66.6-5.4,64-2.7z M32.1-2.7
+		C29.4,0,28,3.5,28,7.3c0,3.4,1.3,6.6,3.4,9.2L51.3-3.4c-2.6-2.2-5.8-3.5-9.2-3.5C38.3-6.9,34.8-5.4,32.1-2.7z M84,17.3
+		c2.7-2.7,4.1-6.2,4.1-10c0-3.7-1.4-7.1-3.9-9.7L48.3,33.5l9.7,9.7C58,43.2,84,17.3,84,17.3z"/>
+</g>
+</svg>

+ 22 - 0
public/img/warn.svg

@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 19.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<svg version="1.1" baseProfile="tiny" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
+	 x="0px" y="0px" width="70px" height="70px" viewBox="15 -15 70 70" xml:space="preserve">
+<g>
+	<path fill="#F79520" d="M41.39,43.607l1.908-1.91l3.677,3.678l-1.91,1.91L41.39,43.607z M21.635,23.795l1.91-1.91l3.677,3.678
+		l-1.91,1.91L21.635,23.795z M47.8-4.9l1.9-1.9c-1.3-1.2-2.8-2.2-4.3-3l-2,2C45-7,46.4-6.1,47.8-4.9z M35.7-9.5c2,0,4,0.3,5.8,1
+		l2.1-2.1c-1.9-0.8-3.8-1.3-5.9-1.5l-2.6,2.6H35.7z M17.7,8.6V8l-2.6,2.6c0.2,2,0.7,4,1.5,5.9l2.1-2.1C18,12.6,17.7,10.6,17.7,8.6z
+		 M23-4.2c2.6-2.6,5.8-4.3,9.4-5l3-3c-3.7,0.1-7.2,1.1-10.3,3L18-2.1C16.1,1,15.1,4.5,15,8.2l3-3C18.7,1.7,20.4-1.6,23-4.2z
+		 M19.4,16.2l-2,2c0.8,1.5,1.8,3,3,4.3l1.9-1.9C21.1,19.3,20.1,17.8,19.4,16.2z M36.433,38.6l1.91-1.908l3.676,3.677l-1.91,1.908
+		L36.433,38.6z M82.4,8.6c0,0.5,0,0.9-0.1,1.4L85,7.3c-0.1-2.1-0.6-4.1-1.3-6l-2.1,2.1C82.1,5,82.4,6.8,82.4,8.6z M85,9.8L81.8,13
+		c-0.8,3.1-2.4,6-4.7,8.3L50,48.4l-1.8-1.8l-1.9,1.9l3.7,3.7l29.9-29.9C83,18.8,84.7,14.4,85,9.8z M26.59,28.8l1.91-1.908
+		l3.677,3.677l-1.91,1.908L26.59,28.8z M31.477,33.737l1.91-1.91l3.676,3.677l-1.91,1.91L31.477,33.737z M70.9-8.2l2-2
+		c-1.8-0.8-3.7-1.4-5.7-1.7l-2.5,2.5C66.9-9.4,69-9,70.9-8.2z M50-2.7l1.5-1.5c2.9-2.9,6.6-4.7,10.6-5.2l2.8-2.8h-0.6
+		c-3,0-5.8,0.6-8.5,1.8l-6.7,6.7L50-2.7z M76.9-4.4l1.9-1.9c-1.3-1.2-2.7-2.3-4.2-3.2l-2,2C74.2-6.6,75.6-5.6,76.9-4.4z M80.9,1.5
+		l2-2c-0.8-1.6-1.7-3.1-2.9-4.4L78.1-3C79.3-1.7,80.2-0.1,80.9,1.5z M26.8-0.4c-2.4,2.4-3.7,5.6-3.7,9c0,0.5,0,0.9,0.1,1.3l14-14
+		c-0.4,0-0.9-0.1-1.3-0.1C32.4-4.1,29.2-2.8,26.8-0.4z M23.5,12c0.5,1.7,1.4,3.4,2.6,4.8L44-1.1c-1.4-1.2-3-2.1-4.8-2.6L23.5,12z
+		 M73.3,17.6c2.4-2.4,3.7-5.6,3.7-9V8L47.1,37.9l2.9,2.9C50,40.8,73.3,17.6,73.3,17.6z M37.2,28l3.7,3.7L73.1-0.5
+		c-1.3-1.3-2.9-2.2-4.5-2.8L37.2,28z M57.4-2L32.3,23.1l3.7,3.7L66.6-3.8C65.9-3.9,65.1-4,64.3-4C61.8-4.1,59.4-3.4,57.4-2z
+		 M42.1,32.9l3.7,3.7L76.6,5.8c-0.4-1.8-1.2-3.5-2.4-5L42.1,32.9z M46.2,1.1l-0.9-0.9l-18,17.9l3.7,3.7l17.9-18L48.1,3"/>
+</g>
+</svg>

+ 42 - 0
public/less/alerting.less

@@ -0,0 +1,42 @@
+.copy-query {
+  display: block;
+  width: 30px;
+  height: 36px;
+  margin: 0;
+  padding: 0;
+  border: 0;
+  background: transparent url(/img/CopyQuery.png) 50% 50% no-repeat;
+  cursor: pointer;
+}
+
+.alert-state {
+  display: inline-block;
+  padding-left: 30px;
+  background: 0 50% no-repeat;
+  background-size: 20px auto;
+}
+
+.alert-state-online {
+  background-image: url('/img/online.svg');
+}
+
+.alert-state-warning {
+  background-image: url('/img/warn-tiny.svg');
+}
+
+.alert-state-critical {
+  background-image: url('/img/critical.svg');
+}
+
+.alert-notify-emails {
+  width: 400px;
+  border-right: 1px solid @black;
+}
+
+.alert-notify-emails .bootstrap-tagsinput {
+  width: 394px; // offset for 8px left padding and border width
+}
+
+.alert-notify-emails .bootstrap-tagsinput input {
+  border: 0;
+}

+ 37 - 0
public/less/filter-controls.less

@@ -0,0 +1,37 @@
+// ==========================================================================
+// FILTER CONTROLS
+// ==========================================================================
+
+
+
+// Filters
+// --------------------------------------------------------------------------
+
+.filter-controls-filters {
+  display: inline-block;
+  margin-bottom: 40px;
+}
+
+.tab-pane > .filter-controls-filters {
+  margin-top: 20px;
+}
+
+
+
+// Actions
+// --------------------------------------------------------------------------
+
+.filter-controls-actions {
+  margin: 0 0 10px;
+  padding: 0;
+  list-style: none;
+}
+
+.filter-controls-actions > li {
+  display: inline-block;
+  margin-right: 10px;
+}
+
+.filter-controls-actions-selected {
+  text-transform: uppercase;
+}

+ 136 - 0
public/less/filter-list.less

@@ -0,0 +1,136 @@
+// ==========================================================================
+// FILTER LIST
+// ==========================================================================
+
+
+
+// List
+// --------------------------------------------------------------------------
+
+.filter-list {
+  margin: 0;
+  padding: 0;
+  list-style: none;
+}
+
+.filter-list > li {
+  padding: 10px;
+  margin-bottom: 2px;
+  background: @grafanaPanelBackground;
+
+  &:last-child {
+    margin: 0;
+  }
+}
+
+
+
+// Card
+// --------------------------------------------------------------------------
+
+.filter-list-card {
+  display: table;
+  width: 100%;
+  margin: 0;
+  padding: 0;
+  list-style: none;
+}
+
+.filter-list-card > li {
+  display: table-cell;
+  vertical-align: top;
+}
+
+.filter-list-card-select {
+  width: 23px;
+  padding-right: 5px;
+}
+
+.filter-list-card-title {
+  display: block;
+  font-size: 16px;
+  font-weight: normal;
+}
+
+.filter-list-card-status {
+  color: #777;
+  font-size: 12px;
+}
+
+.filter-list-card-state {
+  display: inline-block;
+  padding: 5px 0 0 28px;
+  background: 0 bottom no-repeat;
+  background-size: 24px auto;
+  font-size: 14px;
+  text-transform: uppercase;
+
+  &.online {
+    background-image: url('/img/online.svg');
+    color: @online;
+  }
+
+  &.warn {
+    background-image: url('/img/warn-tiny.svg');
+    color: @warn;
+  }
+
+  &.critical {
+    background-image: url('/img/critical.svg');
+    color: @critical;
+  }
+}
+
+.filter-list-card-controls {
+  float: right;
+}
+
+.filter-list-card-links,
+.filter-list-card-config,
+.filter-list-card-expand {
+  display: inline-block;
+  vertical-align: middle;
+}
+
+.filter-list-card-link {
+  display: block;
+  color: #777;
+  text-align: right;
+
+  > a {
+    color: #777;
+  }
+}
+
+.filter-list-card-config {
+  padding: 8px 8px 8px 16px;
+  color: #777;
+  font-size: 25px;
+
+  > a {
+    color: #777;
+  }
+}
+
+.filter-list-card-expand {
+  width: 20px;
+  padding: 8px 0 8px 8px;
+  color: #aaa;
+  font-size: 30px;
+  text-align: center;
+  cursor: pointer;
+}
+
+.filter-list-card-details {
+  padding: 20px 0 0 30px;
+}
+
+.filter-list-card-details-heading {
+  font-weight: normal;
+
+  > a {
+    float: right;
+    color: @blue;
+    font-size: 12px;
+  }
+}

+ 57 - 0
public/less/filter-table.less

@@ -0,0 +1,57 @@
+// ==========================================================================
+// FILTER TABLE
+// ==========================================================================
+
+
+
+// Table
+// --------------------------------------------------------------------------
+
+.filter-table * {
+  box-sizing: border-box;
+}
+
+.filter-table {
+  width: 100%;
+  border-collapse: collapse;
+  // table-layout: fixed;
+}
+
+.filter-table tr {
+  background: @grafanaPanelBackground;
+  border-bottom: 2px solid @bodyBackground;
+}
+
+.filter-table th {
+  width: auto;
+  padding: 10px 15px 10px 0;
+  text-align: left;
+
+  &:first-child {
+    padding-left: 15px;
+  }
+}
+
+.filter-table td {
+  padding: 15px 15px 15px 0;
+
+  &:first-child {
+    padding-left: 15px;
+  }
+}
+
+.filter-table .ellipsis {
+  display: block;
+  width: 100%;
+  white-space: nowrap;
+  overflow: hidden;
+  text-overflow: ellipsis;
+}
+
+.filter-table .expanded {
+  border-color: @grafanaPanelBackground;
+}
+
+.filter-table .expanded > td {
+  padding-bottom: 0;
+}

+ 11 - 0
public/less/gfbox.less

@@ -25,6 +25,13 @@
   }
   }
 }
 }
 
 
+.gf-box-header-save-btn {
+  padding: 7px 0;
+  float: right;
+  color: @grayLight;
+  font-style: italic;
+}
+
 .gf-box-body {
 .gf-box-body {
   padding: 20px;
   padding: 20px;
   min-height: 150px;
   min-height: 150px;
@@ -73,6 +80,10 @@
   max-width: 653px;
   max-width: 653px;
 }
 }
 
 
+.page-wide {
+  max-width: 1000px;
+}
+
 .admin-page {
 .admin-page {
   max-width: 800px;
   max-width: 800px;
   margin-left: 10px;
   margin-left: 10px;

+ 4 - 0
public/less/grafana.less

@@ -20,6 +20,10 @@
 @import "fonts.less";
 @import "fonts.less";
 @import "tabs.less";
 @import "tabs.less";
 @import "timepicker.less";
 @import "timepicker.less";
+@import "alerting.less";
+@import "filter-controls.less";
+@import "filter-list.less";
+@import "filter-table.less";
 
 
 .row-control-inner {
 .row-control-inner {
   padding:0px;
   padding:0px;

+ 9 - 0
public/less/overrides.less

@@ -560,6 +560,15 @@ div.flot-text {
   background-color: darken(@purple, 10%);
   background-color: darken(@purple, 10%);
 }
 }
 
 
+.label-tag-email {
+  padding-left: 25px;
+  background: @black url(/img/envelope.png) 5px 50% no-repeat !important;
+  border-color: @black !important;
+  font-size: 12px;
+  font-weight: normal;
+  border-radius: 5px;
+}
+
 
 
 // inspector
 // inspector
 .inspector-request-table {
 .inspector-request-table {

+ 6 - 0
public/less/tightform.less

@@ -161,6 +161,12 @@ input[type=checkbox].tight-form-checkbox {
   margin: 0;
   margin: 0;
 }
 }
 
 
+.tight-form-textarea {
+  height: 200px;
+  margin: 0;
+  box-sizing: border-box;
+}
+
 select.tight-form-input {
 select.tight-form-input {
   border: none;
   border: none;
   border-right: 1px solid @grafanaTargetSegmentBorder;
   border-right: 1px solid @grafanaTargetSegmentBorder;

+ 6 - 0
public/less/variables.dark.less

@@ -25,6 +25,12 @@
 @purple:                #9933CC;
 @purple:                #9933CC;
 @variable:              #32D1DF;
 @variable:              #32D1DF;
 
 
+// Status colors
+// -------------------------
+@online:                #10a345;
+@warn:                  #ffc03c;
+@critical:              #ed2e18;
+
 // grafana Variables
 // grafana Variables
 // -------------------------
 // -------------------------
 @grafanaPanelBackground: 	@grayDarker;
 @grafanaPanelBackground: 	@grayDarker;

+ 6 - 0
public/less/variables.light.less

@@ -31,6 +31,12 @@
 @purple:                #9954BB;
 @purple:                #9954BB;
 @variable:              #2AB2E4;
 @variable:              #2AB2E4;
 
 
+// Status colors
+// -------------------------
+@online:                #10a345;
+@warn:                  #ffc03c;
+@critical:              #ed2e18;
+
 // grafana Variables
 // grafana Variables
 // -------------------------
 // -------------------------
 @grafanaPanelBackground: 	@grayLighter;
 @grafanaPanelBackground: 	@grayLighter;