Commit 607b273b by Torkel Ödegaard

Merge branch 'master' into kariosdb

parents 618d4f0a ce99e7b2
......@@ -6,7 +6,7 @@ init_cmds = [
watch_all = true
watch_dirs = [
"$WORKDIR/pkg",
"$WORKDIR/src/views",
"$WORKDIR/public/views",
"$WORKDIR/conf",
]
watch_exts = [".go", ".ini"]
......
......@@ -13,8 +13,6 @@ docs/changed-files
docs/changed-files
# locally required config files
web.config
config.js
src/css/*.min.css
# Editor junk
......
language: node_js
node_js:
- "0.10"
git:
depth: 1
before_script:
- npm install -g grunt-cli
after_script:
- npm run coveralls
......@@ -5,7 +5,7 @@ module.exports = function (grunt) {
var config = {
pkg: grunt.file.readJSON('package.json'),
baseDir: '.',
srcDir: 'src',
srcDir: 'public',
destDir: 'dist',
tempDir: 'tmp',
arch: grunt.option('arch') || 'x86_64',
......
[Grafana](http://grafana.org) [![Build Status](https://api.travis-ci.org/grafana/grafana.svg)](https://travis-ci.org/grafana/grafana) [![Coverage Status](https://coveralls.io/repos/grafana/grafana/badge.png)](https://coveralls.io/r/grafana/grafana) [![Gitter](https://badges.gitter.im/Join Chat.svg)](https://gitter.im/grafana/grafana?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
[Grafana](http://grafana.org) [![Circle CI](https://circleci.com/gh/grafana/grafana.svg?style=svg)](https://circleci.com/gh/grafana/grafana) [![Coverage Status](https://coveralls.io/repos/grafana/grafana/badge.png)](https://coveralls.io/r/grafana/grafana) [![Gitter](https://badges.gitter.im/Join Chat.svg)](https://gitter.im/grafana/grafana?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
================
[Website](http://grafana.org) |
[Twitter](https://twitter.com/grafana) |
......@@ -10,70 +10,12 @@ Graphite, InfluxDB & OpenTSDB.
![](http://grafana.org/assets/img/start_page_bg.png)
# Grafana 2.0 Alpha branch [![Circle CI](https://circleci.com/gh/grafana/grafana.svg?style=svg)](https://circleci.com/gh/grafana/grafana)
Grafana 2.0 comes with a backend written in Go. It is not ready for production use yet as there is still a lot of small
issues to fix and polish missing. But feedback on what is done and bug reports would be greatly appreciated.
## Try it out with docker
```
docker run -i -p 3000:3000 grafana/grafana:develop
```
The default admin user is admin/admin.
## building and running
```
go get github.com/grafana/grafana
```
The above will give an error saying there is no go code. That is because the new backend parts are in the develop branch.
Building
```
cd $GOPATH/src/github.com/grafana/grafana
git checkout -t origin/develop
go run build.go setup (only needed once to install godep)
godep restore (will pull down all golang lib dependecies in your current GOPATH)
go build .
```
To build less to css for the frontend you will need a recent version of of node (v0.12.0),
npm (v2.5.0) and grunt (v0.4.5). Run the following:
```
npm install
npm install -g grunt-cli
grunt
```
To rebuild on source change (requires that you executed godep restore)
```
go get github.com/Unknwon/bra
bra run
```
Running
```
./bin/grafana web
```
Open grafana in your browser (default http://localhost:3000) and login with admin user (default user/pass = admin/admin).
### Config
Create a grafana.custom.ini in the conf directory to override default configuration options.
You only need to add the options you want to override. Config files are applied in the order of:
1. grafana.ini
2. grafana.dev.ini (if found)
3. grafana.custom.ini
### Docs
There is no docs for the configuration and new UI views, or the account / user model yet. But a quick note
is that Grafana 2.0 has a multi tenant account & user model where Dashboards, data sources, api keys, etc are
tied to an account and not to a specific user. Users are coupled to accounts via an account user role (Admin, Editor, Viewer).
The default configuration is set to a single account mode to make this user & account model easier to handle in a single account setup.
User sign ups are automatically added to a main account with the Editor role (this can be overriden in the config file). The default
grafana admin user that is created on first startup also creates the main account.
## Grafana 2.0
The develop branch has now been merged with master. For 1.9 users this is a big change as Grafana is no longer
a standalone frontend only web application. Grafana 2.0 comes with a backend.
- [Install instructions](http://docs.grafana.org/v2.0/installation/)
- [Migrating from 1.x to 2.x](http://docs.grafana.org/v2.0/installation/migrating_to2/)
- [What's New in Grafana 2.0](http://docs.grafana.org/v2.0/guides/whats-new-in-v2/)
## Features
### Graphite Target Editor
......@@ -81,33 +23,32 @@ grafana admin user that is created on first startup also creates the main accoun
- Feature rich query composer
- Quickly add and edit functions & parameters
- Templated queries
- [See it in action](http://grafana.org/docs/features/graphite)
- [See it in action](http://docs.grafana.org/datasources/graphite/)
### Graphing
- Fast rendering, even over large timespans
- Click and drag to zoom
- Multiple Y-axis
- Multiple Y-axis, logarithmic scales
- Bars, Lines, Points
- Smart Y-axis formating
- Series toggles & color selector
- Legend values, and formatting options
- Grid thresholds, axis labels
- [Annotations](http://grafana.org/docs/features/annotations)
- [Annotations](http://docs.grafana.org/reference/annotations/)
- Any panel can be rendered to PNG (server side using phantomjs)
### Dashboards
- Create, edit, save & search dashboards
- Change column spans and row heights
- Drag and drop panels to rearrange
- Use InfluxDB or Elasticsearch as dashboard storage
- Import & export dashboard (json file)
- Import dashboard from Graphite
- Templating
- [Scripted dashboards](http://grafana.org/docs/features/scripted_dashboards)
- [Dashboard playlists](http://grafana.org/docs/features/playlist)
- [Time range controls](http://grafana.org/docs/features/time_range)
- [Templating](http://docs.grafana.org/reference/templating/)
- [Scripted dashboards](http://docs.grafana.org/reference/scripting/)
- [Dashboard playlists](http://docs.grafana.org/reference/playlist/)
- [Time range controls](http://docs.grafana.org/reference/timerange/)
- [Share snapshots publicly](http://docs.grafana.org/v2.0/reference/sharing/)
### InfluxDB
- Use InfluxDB as a metric data source, annotation source, and for dashboard storage
- Use InfluxDB as a metric data source, annotation source
- Query editor with series and column typeahead, easy group by and function selection
### OpenTSDB
......@@ -115,31 +56,77 @@ grafana admin user that is created on first startup also creates the main accoun
- Query editor with metric name typeahead and tag filtering
## Requirements
There are no dependencies, Grafana is a client side application that runs in your browser. It only needs a time series store where it can fetch metrics. If you use InfluxDB Grafana can use it to store dashboards. If you use Graphite or OpenTSDB you can use Elasticsearch to store dashboards or just use json files stored on disk.
There are no dependencies except an external time series data store. For dashboards and user accounts Grafana can use an embedded
database (sqlite3) or you can use an external SQL data base like MySQL or Postgres.
## Installation
Head to [grafana.org](http://grafana.org) and [download](http://grafana.org/download/)
Head to [grafana.org](http://docs.grafana.org/installation/) and [download](http://grafana.org/download/)
the latest release.
Then follow the [quick setup & config guide](http://grafana.org/docs/). If you have any problems please
read the [troubleshooting guide](http://grafana.org/docs/troubleshooting).
If you have any problems please read the [troubleshooting guide](http://docs.grafana.org/installation/troubleshooting/).
## Documentation & Support
Be sure to read the [getting started guide](http://grafana.org/docs/features/intro) and the other
feature guides.
Be sure to read the [getting started guide](http://docs.grafana.org/guides/gettingstarted/) and the other feature guides.
## Run from master
Grafana uses Node.js and Grunt for asset management (css & javascript), unit test runner and javascript syntax verification.
- clone repository
- install nodejs
- npm install (in project root)
- npm install -g grunt-cli
- grunt (grunt default task that will generate css files)
- grunt build (creates optimized & minified release)
- grunt release (same as grunt build but will also create tar & zip package)
- grunt test (executes jshint and unit tests)
## Contribute
If you want to build a package your self, or contribute. Here is a guide for how to do that. You can always find
the latest master builds [here](http://grafana.org/download/builds)
### Dependencies
- Go 1.4
- NodeJS
### Get Code
```
go get github.com/grafana/grafana
```
### Building the backend
```
cd $GOPATH/src/github.com/grafana/grafana
go run build.go setup (only needed once to install godep)
godep restore (will pull down all golang lib dependecies in your current GOPATH)
go build .
```
### Building frontend assets
To build less to css for the frontend you will need a recent version of of node (v0.12.0),
npm (v2.5.0) and grunt (v0.4.5). Run the following:
```
npm install
npm install -g grunt-cli
grunt
```
### Recompile backend on source change
To rebuild on source change (requires that you executed godep restore)
```
go get github.com/Unknwon/bra
bra run
```
### Running
```
./grafana web
```
Open grafana in your browser (default http://localhost:3000) and login with admin user (default user/pass = admin/admin).
### Dev config
Create a custom.ini in the conf directory to override default configuration options.
You only need to add the options you want to override. Config files are applied in the order of:
1. grafana.ini
2. dev.ini (if found)
3. custom.ini
## Create a pull requests
Before or after your create a pull requests, sign the [contributor license aggrement](/docs/contributing/cla.html).## Contribute
If you have any idea for an improvement or found a bug do not hesitate to open an issue.
And if you have time clone this repo and submit a pull request and help me make Grafana
the kickass metrics & devops dashboard we all dream about!
......
app_name = Grafana
app_mode = production
# Report anonymous usage counters to stats.grafana.org (https).
# No ip addresses are being tracked, only simple counters to track
# running instances, dashboard and error counts. It is very helpful to us.
# Change this option to false to disable reporting.
reporting-enabled = true
[server]
; protocol (http or https)
protocol = http
......@@ -21,11 +15,21 @@ root_url = %(protocol)s://%(domain)s:%(http_port)s/
router_logging = false
; the path relative to the binary where the static (html/js/css) files are placed
static_root_path = public
; enable gzip
enable_gzip = false
; if https protocol
; https certs & key file
cert_file =
cert_key =
[analytics]
# Server reporting, sends usage counters to stats.grafana.org (https).
# No ip addresses are being tracked, only simple counters to track
# running instances, dashboard and error counts. It is very helpful to us.
# Change this option to false to disable reporting.
reporting_enabled = true
; Google Analytics universal tracking code, only enabled if you specify an id here
google_analytics_ua_id =
[database]
; Either "mysql", "postgres" or "sqlite3", it's your choice
type = sqlite3
......
......@@ -2,7 +2,6 @@ app_mode = development
[server]
router_logging = false
static_root_path = src
[log]
level = Trace
......
......@@ -5,12 +5,6 @@
app_mode = production
# Report anonymous usage counters to stats.grafana.org (https).
# No ip addresses are being tracked, only simple counters to track
# running instances, dashboard and error counts. It is very helpful to us.
# Change this option to false to disable reporting.
reporting-enabled = true
[server]
; protocol (http or https)
protocol = http
......@@ -27,6 +21,15 @@ router_logging = false
static_root_path = public
enable_gzip = false
[analytics]
# Server reporting, sends usage counters to stats.grafana.org (https).
# No ip addresses are being tracked, only simple counters to track
# running instances, dashboard and error counts. It is very helpful to us.
# Change this option to false to disable reporting.
reporting_enabled = true
; Google Analytics universal tracking code, only enabled if you specify an id here
google_analytics_ua_id =
[database]
; Either "mysql", "postgres" or "sqlite3", it's your choice
type = sqlite3
......
......@@ -6,42 +6,53 @@ page_keywords: grafana, installation, migration, documentation
# Migrating from v1.x to v2.x
Grafana 2.x is pretty different from v1.x in that Grafana 2.x has its own backend and its own
database to store dashboards and users in.
Grafana 2.0 represents a major update to Grafana. It brings new capabilities, many of which are enabled by its new backend server and integrated database.
The new backend lays a solid foundation that we hope to build on over the coming months. For the 2.0 release, it enables authentication as well as server-side sharing and rendering.
We've attempted to provide a smooth migration path for V1.9 users to migrate to Grafana 2.0.
## Adding Data sources
Data sources in Grafana v2.0 are no longer configured via the `config.js` file. That config file is no more.
You add data sources via UI or via the [HTTP API](../reference/http_api.md). Go the `Data Sources` view via the side menu.
The side menu can be toggled via the Grafana icon in the top header (to the right).
The config.js file has been deprecated. Data sources are now managed via the UI or [HTTP API](../reference/http_api.md). Manage your organizations data sources by clicking on the `Data Sources` menu on the side menu (which can be toggled via the Grafana icon in the upper left of your browser).
## Importing dashboards
From here, you can add any Graphite, InfluxDB, elasticsearch, and OpenTSDB datasources that you were using with Grafana 1.x. Grafana 2.0 can be configured to communicate with your datasource using a backend mode which can eliminate many CORS-related issues, as well as provide more secure authentication to your datasources.
### From Elasticsearch
Start by going to the `Data Sources` view and add your elasticsearch datasource. Specify the elasticsearch
index name where your Grafana v1.x dashboards are stored, default is `grafana-dash`.
## Importing your existing dashboards
![](/img/v2/datasource_edit_elastic.jpg)
Grafana 2.0 now has integrated dashboard storage engine that can be configured to use an internal sqlite database, MySQL, or Postgres. This eliminates the need to use Elasticsearch for dashboard storage for Graphite users. Grafana 2.0 does not support storing dashboards in InfluxDB.
You can seamlessly import your existing dashboards.
### From InfluxDB
### dashboards from Elasticsearch
Start by going to the `Data Sources` view (via the side menu), and make sure your elasticsearch datasource is added. Specify the elasticsearch index name where your existing Grafana v1.x dashboards are stored (default is `grafana-dash`).
![](/img/v2/datasource_edit_elastic.jpg)
Start by going to the `Data Sources` view and add your influxdb datasource. Specify the database
name where your Grafana v1.x dashboards are stored, default is `grafana`.
### dashboards from InfluxDB
Start by going to the `Data Sources` view (via the side menu), and make sure your InfluxDB datasource is added. Specify the database name where your Grafana v1.x dashboards are stored, default is `grafana`.
### Go to Import dashboards view
Go to the `Dashboards` view and click on the dashboards search dropdown. At the bottom of the search dropdown
you find the `Import` button.
Go to the `Dashboards` view and click on the dashboards search dropdown. Click the `Import` button at the bottom of the search dropdown.
![](/img/v2/dashboard_import.jpg)
### Import view
In the Import view you find the section `Migrate dashboards`. Pick the datasource you added (Elasticsearch or InfluxDB)
In the Import view you find the section `Migrate dashboards`. Pick the datasource you added (from elasticsearch or InfluxDB),
and click the `Import` button.
![](/img/v2/migrate_dashboards.jpg)
Your dashboards should be automatically imported into the Grafana 2.0 backend.
Dashboards will no longer be stored in your previous elasticsearch or InfluxDB databases.
### Invite your team
Explain users and orgs.
### Enjoy the new features
......@@ -14,19 +14,15 @@ dev environment.
- Go 1.4
- NodeJS
## Get Code
```
go get github.com/grafana/grafana
```
The above will give an error saying there is no go code. That is because the new backend parts are in the develop branch.
## Building the backend
```
cd $GOPATH/src/github.com/grafana/grafana
git checkout -t origin/develop
go run build.go setup (only needed once to install godep)
godep restore (will pull down all golang lib dependecies in your current GOPATH)
go build .
......@@ -52,7 +48,7 @@ bra run
## Running
```
./bin/grafana web
./grafana web
```
Open grafana in your browser (default http://localhost:3000) and login with admin user (default user/pass = admin/admin).
......
......@@ -10,38 +10,31 @@ page_keywords: grafana, annotations, guide, documentation
Annotations provide a way to mark points on the graph with rich events. When you hover over an annotation
you can get title, tags, and text information for the event.
To enable annotations open dashboard settings and the controls tab.
Under feature toggles you will find the checkbox for annotations.
To add an annotation query click dashboard settings icon in top menu and select `Annotations` from the
dropdown. This will open the `Annotations` edit view. Click the `Add` tab to add a new annotation query.
When enabled they will appear in the sub menu controls area.
![](/img/v1/annotations_submenu1.png)
### Graphite annotations
Click the cog wheel to open the dialog where you can add & edit annotations.
![](/img/v1/annotations_dialog1.png)
Graphite supports two ways to query annotations.
## Datasources
Grafana supports many data sources for annotation.
- A regular metric query, use the `Graphite target expression` text input for this
- Graphite events query, use the `Graphite event tags` text input, especify an tag or wildcard (leave empty should also work)
- Graphite metrics
- Graphite events
- InfluxDB query
- Elasticsearch query
## Elasticsearch annoations
![](/img/v2/annotations_es.png)
Grafana can query any Elasticsearch index for annotation events. The index name can be the name of an alias or an index wildcard pattern.
You can leave the search query blank or specify a lucene query.
If your elasticsearch document has a timestamp field other than `@timestamp` you will need to specify that. As well
as the name for the fields that should be used for the annotation title, tags and text. Tags and text are optional.
> **Note** The annotation timestamp field in elasticsearch need to be in UTC format.
## InfluxDB Annotations
![](/img/influxdb/influxdb_annotation.png)
![](/img/v2/annotations_influxdb.png)
For InfluxDB you need to enter a query like in the above screenshot. You need to have the ```where $timeFilter``` part.
If you only select one column you will not need to enter anything in the column mapping fields.
If you have multiple columns you need to specify which column should be treated as title, tags and text column.
## Elasticsearch Annotations
![](/img/v1/elasticsearch_annotations_edit.png)
You can use the same data source as you specified in config.js for storing grafana dashboards or you can specify another one.
The annotation definition contains an index name that will override the index name specified in config.js. The index name can
be the name of an alias or an index wildcard pattern. You can leave the search query blank or specify a lucene query.
If your elasticsearch document has a timestamp field other than ```@timestamp``` you will need to specify that. As well
as the name for the fields that should be used for the annotation title, tags and text. Tags and text are optional.
**The annotation timestamp field in elasticsearch need to be in UTC format**
......@@ -6,4 +6,10 @@ page_keywords: grafana, singlestat, panel, documentation
# Singlestat Panel
![](/img/v1/singlestat_panel2.png)
The singlestat panel allows you to show the one main summery stat of a single series (like max, min, avg, sum). It also
provides thresholds to color that singlestat metric or the panel background.
## Options
- TODO
......@@ -4,7 +4,7 @@
"company": "Coding Instinct AB"
},
"name": "grafana",
"version": "2.0.0-prebeta2",
"version": "2.0.0-prebeta3",
"repository": {
"type": "git",
"url": "http://github.com/torkelo/grafana.git"
......
......@@ -65,7 +65,11 @@ func GetDashboardSnapshot(c *middleware.Context) {
dto := dtos.Dashboard{
Model: snapshot.Dashboard,
Meta: dtos.DashboardMeta{IsSnapshot: true},
Meta: dtos.DashboardMeta{
IsSnapshot: true,
Created: snapshot.Created,
Expires: snapshot.Expires,
},
}
metrics.M_Api_Dashboard_Snapshot_Get.Inc(1)
......
......@@ -4,6 +4,7 @@ import (
"crypto/md5"
"fmt"
"strings"
"time"
m "github.com/grafana/grafana/pkg/models"
)
......@@ -27,10 +28,12 @@ type CurrentUser struct {
}
type DashboardMeta struct {
IsStarred bool `json:"isStarred"`
IsHome bool `json:"isHome"`
IsSnapshot bool `json:"isSnapshot"`
Slug string `json:"slug"`
IsStarred bool `json:"isStarred"`
IsHome bool `json:"isHome"`
IsSnapshot bool `json:"isSnapshot"`
Slug string `json:"slug"`
Expires time.Time `json:"expires"`
Created time.Time `json:"created"`
}
type Dashboard struct {
......
......@@ -33,6 +33,10 @@ func setIndexViewData(c *middleware.Context) error {
c.Data["AppUrl"] = setting.AppUrl
c.Data["AppSubUrl"] = setting.AppSubUrl
if setting.GoogleAnalyticsId != "" {
c.Data["GoogleAnalyticsId"] = setting.GoogleAnalyticsId
}
return nil
}
......
......@@ -10,7 +10,7 @@ import (
func TestPluginScans(t *testing.T) {
Convey("When scaning for plugins", t, func() {
path, _ := filepath.Abs("../../src/app/plugins")
path, _ := filepath.Abs("../../public/app/plugins")
err := scan(path)
So(err, ShouldBeNil)
......
......@@ -97,7 +97,8 @@ var (
configFiles []string
ReportingEnabled bool
ReportingEnabled bool
GoogleAnalyticsId string
)
func init() {
......@@ -235,7 +236,9 @@ func NewConfigContext(config string) {
ImagesDir = "data/png"
PhantomDir = "vendor/phantomjs"
ReportingEnabled = Cfg.Section("").Key("reporting-enabled").MustBool(true)
analytics := Cfg.Section("analytics")
ReportingEnabled = analytics.Key("reporting_enabled").MustBool(true)
GoogleAnalyticsId = analytics.Key("google_analytics_ua_id").String()
readSessionConfig()
}
......
......@@ -158,11 +158,6 @@ function($, _, moment) {
return info.sec * info.count;
};
// This should go away, moment.js can do this
kbn.time_ago = function(string) {
return new Date(new Date().getTime() - (kbn.interval_to_ms(string)));
};
/* This is a simplified version of elasticsearch's date parser */
kbn.parseDate = function(text) {
if(_.isDate(text)) {
......
......@@ -25,7 +25,7 @@ function (angular) {
'<i class="fa fa-bars"></i>' +
'</a>' +
'<span class="icon-circle top-nav-icon"">' +
'<span class="icon-circle top-nav-icon">' +
'<i ng-class="icon"></i>' +
'</span>' +
......
define([
'./dashboardCtrl',
'./dashboardNavCtrl',
'./snapshotTopNavCtrl',
'./saveDashboardAsCtrl',
'./playlistCtrl',
'./rowCtrl',
......
......@@ -21,6 +21,7 @@ function (angular, $, config) {
$timeout) {
$scope.editor = { index: 0 };
$scope.topNavPartial = 'app/features/dashboard/partials/dashboardTopNav.html';
$scope.panels = config.panels;
var resizeEventTimeout;
......@@ -58,7 +59,7 @@ function (angular, $, config) {
});
};
$scope.initDashboardMeta = function(meta, dashboard) {
$scope.initDashboardMeta = function(meta) {
meta.canShare = true;
meta.canSave = true;
meta.canEdit = true;
......@@ -75,11 +76,8 @@ function (angular, $, config) {
meta.canEdit = false;
}
if (dashboard.snapshot) {
meta.canEdit = false;
meta.canSave = false;
meta.canStar = false;
meta.canShare = false;
if (meta.isSnapshot) {
$scope.topNavPartial = 'app/features/dashboard/partials/snapshotTopNav.html';
}
$scope.dashboardMeta = meta;
......
define([
'angular',
'lodash',
'moment',
'config',
'store',
'filesaver'
],
function (angular, _, moment) {
function (angular, _) {
'use strict';
var module = angular.module('grafana.controllers');
module.controller('DashboardNavCtrl', function($scope, $rootScope, alertSrv, $location, playlistSrv, backendSrv, timeSrv, $timeout) {
module.controller('DashboardNavCtrl', function($scope, $rootScope, alertSrv, $location, playlistSrv, backendSrv, $timeout) {
$scope.init = function() {
$scope.onAppEvent('save-dashboard', $scope.saveDashboard);
$scope.onAppEvent('delete-dashboard', $scope.deleteDashboard);
$scope.onAppEvent('zoom-out', function() {
$scope.zoom(2);
});
};
$scope.openEditView = function(editview) {
......@@ -136,27 +131,6 @@ function (angular, _, moment) {
window.saveAs(blob, $scope.dashboard.title + '-' + new Date().getTime());
};
$scope.zoom = function(factor) {
var range = timeSrv.timeRange();
var timespan = (range.to.valueOf() - range.from.valueOf());
var center = range.to.valueOf() - timespan/2;
var to = (center + (timespan*factor)/2);
var from = (center - (timespan*factor)/2);
if(to > Date.now() && range.to <= Date.now()) {
var offset = to - Date.now();
from = from - offset;
to = Date.now();
}
timeSrv.setTime({
from: moment.utc(from).toDate(),
to: moment.utc(to).toDate(),
});
};
$scope.snapshot = function() {
$scope.dashboard.snapshot = true;
$rootScope.$broadcast('refresh');
......
......@@ -47,8 +47,12 @@
<div class="gf-box-body share-snapshot ng-cloak" ng-cloak ng-if="editor.index === 1" ng-controller="ShareSnapshotCtrl">
<div class="share-snapshot-header" ng-if="step === 1">
<div style="margin: 10px 0">
<i ng-if="loading" class="fa fa-spinner fa-spin"></i>
<i ng-if="!loading" class="gf-icon gf-icon-snap-multi"></i>
</div>
<div class="share-snapshot-header" ng-if="step === 1">
<p class="share-snapshot-info-text">
A snapshot is an instant way to share an interactive dashboard publicly.
When created, we <strong>strip sensitive data</strong> like queries (metric, template and annotation) and panel links,
......@@ -86,7 +90,7 @@
</div>
</div>
<div class="gf-form" ng-if="step === 2" style="margin-top: 55px">
<div class="gf-form" ng-if="step === 2" style="margin-top: 40px">
<div class="gf-form-row">
<a href="{{snapshotUrl}}" class="large share-snapshot-link" target="_blank">
<i class="fa fa-external-link-square"></i>
......
<div class="navbar navbar-static-top" ng-controller='SnapshotTopNavCtrl' ng-init="init()">
<div class="navbar-inner">
<div class="container-fluid">
<div class="top-nav">
<a class="pointer top-nav-menu-btn" ng-if="!contextSrv.sidemenu" ng-click="contextSrv.toggleSideMenu()">
<img class="logo-icon" src="img/fav32.png"></img>
<i class="fa fa-bars"></i>
</a>
<div class="top-nav-snapshot-title">
<a class="pointer" bs-tooltip="titleTooltip" data-placement="bottom">
<i class="gf-icon gf-icon-snap-multi"></i>
<span class="dashboard-title">
{{dashboard.title}}
<em class="small">&nbsp;&nbsp;(snapshot)</em>
</span>
</a>
</div>
</div>
<ul class="nav pull-right">
<li ng-repeat="pulldown in dashboard.nav" ng-controller="PulldownCtrl" ng-show="pulldown.enable">
<grafana-simple-panel type="pulldown.type" ng-cloak>
</grafana-simple-panel>
</li>
</ul>
</div>
</div>
</div>
define([
'angular',
'moment',
],
function (angular, moment) {
'use strict';
var module = angular.module('grafana.controllers');
module.controller('SnapshotTopNavCtrl', function($scope) {
$scope.init = function() {
var meta = $scope.dashboardMeta;
$scope.titleTooltip = 'Created: &nbsp;' + moment(meta.created).calendar();
if (meta.expires) {
$scope.titleTooltip += '<br>Expires: &nbsp;' + moment(meta.expires).fromNow() + '<br>';
}
};
});
});
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
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