Browse Source

Merge branch 'master' into plugin-editors

Conflicts:
	public/app/features/panel/panel.ts
	public/app/features/panel/panel_directive.js
	public/app/plugins/datasource/grafana/module.ts
Torkel Ödegaard 10 years ago
parent
commit
30a8a434a1
83 changed files with 257 additions and 414 deletions
  1. 0 1
      pkg/cmd/web.go
  2. 5 5
      pkg/log/console.go
  3. 2 2
      pkg/log/file.go
  4. 28 9
      pkg/log/log.go
  5. 1 1
      pkg/log/syslog.go
  6. 1 1
      public/app/core/components/navbar/navbar.ts
  7. 1 1
      public/app/core/components/search/search.ts
  8. 1 1
      public/app/core/components/sidemenu/sidemenu.ts
  9. 3 3
      public/app/core/directives/dash_edit_link.js
  10. 1 1
      public/app/core/directives/value_select_dropdown.js
  11. 32 32
      public/app/core/routes/all.js
  12. 1 1
      public/app/core/services/alert_srv.js
  13. 1 1
      public/app/features/annotations/editor_ctrl.js
  14. 1 1
      public/app/features/annotations/partials/editor.html
  15. 1 1
      public/app/features/annotations/query_editor.ts
  16. 1 1
      public/app/features/dashboard/dashboardCtrl.js
  17. 11 7
      public/app/features/dashboard/dashnav/dashnav.html
  18. 3 3
      public/app/features/dashboard/dashnav/dashnav.ts
  19. 1 1
      public/app/features/dashboard/keybindings.js
  20. 1 1
      public/app/features/dashboard/partials/import.html
  21. 1 1
      public/app/features/dashboard/submenu/submenu.ts
  22. 3 3
      public/app/features/dashboard/timepicker/timepicker.ts
  23. 1 1
      public/app/features/dashboard/unsavedChangesSrv.js
  24. 1 1
      public/app/features/dashlinks/module.js
  25. 1 1
      public/app/features/datasources/edit_ctrl.js
  26. 1 1
      public/app/features/org/orgApiKeysCtrl.js
  27. 1 1
      public/app/features/org/orgUsersCtrl.js
  28. 0 2
      public/app/features/panel/all.js
  29. 1 1
      public/app/features/panel/metrics_panel_ctrl.ts
  30. 1 1
      public/app/features/panel/panel_ctrl.ts
  31. 1 0
      public/app/features/panel/panel_directive.ts
  32. 5 1
      public/app/features/panel/panel_loader.ts
  33. 4 3
      public/app/features/panel/panel_menu.js
  34. 0 162
      public/app/features/panel/panel_srv.js
  35. 1 1
      public/app/features/panel/query_editor.ts
  36. 1 1
      public/app/features/panellinks/module.js
  37. 3 3
      public/app/features/playlist/playlist_routes.js
  38. 1 1
      public/app/features/playlist/playlist_search.ts
  39. 0 5
      public/app/partials/dashboard.html
  40. 2 1
      public/app/partials/login.html
  41. 3 3
      public/app/plugins/datasource/cloudwatch/module.js
  42. 6 6
      public/app/plugins/datasource/cloudwatch/partials/query.editor.html
  43. 1 1
      public/app/plugins/datasource/cloudwatch/query_ctrl.js
  44. 1 1
      public/app/plugins/datasource/elasticsearch/bucket_agg.js
  45. 2 1
      public/app/plugins/datasource/elasticsearch/edit_view.ts
  46. 1 1
      public/app/plugins/datasource/elasticsearch/metric_agg.js
  47. 3 3
      public/app/plugins/datasource/elasticsearch/module.js
  48. 7 7
      public/app/plugins/datasource/elasticsearch/partials/query.editor.html
  49. 3 3
      public/app/plugins/datasource/elasticsearch/partials/query.options.html
  50. 4 3
      public/app/plugins/datasource/elasticsearch/query_ctrl.js
  51. 1 1
      public/app/plugins/datasource/grafana/module.ts
  52. 4 4
      public/app/plugins/datasource/graphite/module.js
  53. 3 2
      public/app/plugins/datasource/graphite/query_ctrl.js
  54. 10 11
      public/app/plugins/datasource/graphite/specs/query_ctrl_specs.ts
  55. 0 1
      public/app/plugins/datasource/influxdb/datasource.js
  56. 4 4
      public/app/plugins/datasource/influxdb/module.js
  57. 4 4
      public/app/plugins/datasource/influxdb/partials/query.editor.html
  58. 9 8
      public/app/plugins/datasource/influxdb/query_ctrl.js
  59. 1 1
      public/app/plugins/datasource/influxdb/query_part_editor.js
  60. 2 2
      public/app/plugins/datasource/influxdb/specs/query_ctrl_specs.ts
  61. 10 0
      public/app/plugins/datasource/opentsdb/datasource.js
  62. 2 2
      public/app/plugins/datasource/opentsdb/module.js
  63. 5 6
      public/app/plugins/datasource/opentsdb/partials/query.editor.html
  64. 1 0
      public/app/plugins/datasource/opentsdb/queryCtrl.js
  65. 2 2
      public/app/plugins/datasource/prometheus/module.js
  66. 5 6
      public/app/plugins/datasource/prometheus/partials/query.editor.html
  67. 3 1
      public/app/plugins/datasource/prometheus/query_ctrl.js
  68. 1 1
      public/app/plugins/panel/dashlist/module.ts
  69. 1 1
      public/app/plugins/panel/graph/legend.js
  70. 1 1
      public/app/plugins/panel/graph/seriesOverridesCtrl.js
  71. 1 1
      public/app/plugins/panel/singlestat/module.ts
  72. 0 3
      public/app/plugins/panel/singlestat/specs/singlestat-specs.ts
  73. 1 1
      public/app/plugins/panel/table/editor.ts
  74. 1 1
      public/app/plugins/panel/table/module.ts
  75. 1 1
      public/app/plugins/panel/text/module.ts
  76. 1 1
      public/app/plugins/panel/unknown/module.html
  77. 1 1
      public/app/plugins/plugin_api.md
  78. 4 3
      public/dashboards/home.json
  79. 9 6
      public/less/grafana.less
  80. 11 3
      public/less/login.less
  81. 1 1
      public/less/timepicker.less
  82. 0 40
      public/test/specs/panelSrv-specs.js
  83. 1 0
      tasks/options/ngtemplates.js

+ 0 - 1
pkg/cmd/web.go

@@ -36,7 +36,6 @@ func newMacaron() *macaron.Macaron {
 	}
 
 	mapStatic(m, setting.StaticRootPath, "", "public")
-	mapStatic(m, setting.StaticRootPath, "app", "app")
 	mapStatic(m, setting.StaticRootPath, "css", "css")
 	mapStatic(m, setting.StaticRootPath, "img", "img")
 	mapStatic(m, setting.StaticRootPath, "fonts", "fonts")

+ 5 - 5
pkg/log/console.go

@@ -46,8 +46,8 @@ var (
 // ConsoleWriter implements LoggerInterface and writes messages to terminal.
 type ConsoleWriter struct {
 	lg         *log.Logger
-	Level      int  `json:"level"`
-	Formatting bool `json:"formatting"`
+	Level      LogLevel `json:"level"`
+	Formatting bool     `json:"formatting"`
 }
 
 // create ConsoleWriter returning as LoggerInterface.
@@ -63,7 +63,7 @@ func (cw *ConsoleWriter) Init(config string) error {
 	return json.Unmarshal([]byte(config), cw)
 }
 
-func (cw *ConsoleWriter) WriteMsg(msg string, skip, level int) error {
+func (cw *ConsoleWriter) WriteMsg(msg string, skip int, level LogLevel) error {
 	if cw.Level > level {
 		return nil
 	}
@@ -82,11 +82,11 @@ func (_ *ConsoleWriter) Flush() {
 func (_ *ConsoleWriter) Destroy() {
 }
 
-func printConsole(level int, msg string) {
+func printConsole(level LogLevel, msg string) {
 	consoleWriter.WriteMsg(msg, 0, level)
 }
 
-func printfConsole(level int, format string, v ...interface{}) {
+func printfConsole(level LogLevel, format string, v ...interface{}) {
 	consoleWriter.WriteMsg(fmt.Sprintf(format, v...), 0, level)
 }
 

+ 2 - 2
pkg/log/file.go

@@ -41,7 +41,7 @@ type FileLogWriter struct {
 
 	startLock sync.Mutex // Only one log can write to the file
 
-	Level int `json:"level"`
+	Level LogLevel `json:"level"`
 }
 
 // an *os.File writer with locker.
@@ -132,7 +132,7 @@ func (w *FileLogWriter) docheck(size int) {
 }
 
 // write logger message into file.
-func (w *FileLogWriter) WriteMsg(msg string, skip, level int) error {
+func (w *FileLogWriter) WriteMsg(msg string, skip int, level LogLevel) error {
 	if level < w.Level {
 		return nil
 	}

+ 28 - 9
pkg/log/log.go

@@ -99,7 +99,7 @@ func Close() {
 type LogLevel int
 
 const (
-	TRACE = iota
+	TRACE LogLevel = iota
 	DEBUG
 	INFO
 	WARN
@@ -111,7 +111,7 @@ const (
 // LoggerInterface represents behaviors of a logger provider.
 type LoggerInterface interface {
 	Init(config string) error
-	WriteMsg(msg string, skip, level int) error
+	WriteMsg(msg string, skip int, level LogLevel) error
 	Destroy()
 	Flush()
 }
@@ -132,8 +132,9 @@ func Register(name string, log loggerType) {
 }
 
 type logMsg struct {
-	skip, level int
-	msg         string
+	skip  int
+	level LogLevel
+	msg   string
 }
 
 // Logger is default logger in beego application.
@@ -141,7 +142,7 @@ type logMsg struct {
 type Logger struct {
 	adapter string
 	lock    sync.Mutex
-	level   int
+	level   LogLevel
 	msg     chan *logMsg
 	outputs map[string]LoggerInterface
 	quit    chan bool
@@ -188,10 +189,7 @@ func (l *Logger) DelLogger(adapter string) error {
 	return nil
 }
 
-func (l *Logger) writerMsg(skip, level int, msg string) error {
-	if l.level > level {
-		return nil
-	}
+func (l *Logger) writerMsg(skip int, level LogLevel, msg string) error {
 	lm := &logMsg{
 		skip:  skip,
 		level: level,
@@ -266,36 +264,57 @@ func (l *Logger) Close() {
 }
 
 func (l *Logger) Trace(format string, v ...interface{}) {
+	if l.level > TRACE {
+		return
+	}
 	msg := fmt.Sprintf("[T] "+format, v...)
 	l.writerMsg(0, TRACE, msg)
 }
 
 func (l *Logger) Debug(format string, v ...interface{}) {
+	if l.level > DEBUG {
+		return
+	}
 	msg := fmt.Sprintf("[D] "+format, v...)
 	l.writerMsg(0, DEBUG, msg)
 }
 
 func (l *Logger) Info(format string, v ...interface{}) {
+	if l.level > INFO {
+		return
+	}
 	msg := fmt.Sprintf("[I] "+format, v...)
 	l.writerMsg(0, INFO, msg)
 }
 
 func (l *Logger) Warn(format string, v ...interface{}) {
+	if l.level > WARN {
+		return
+	}
 	msg := fmt.Sprintf("[W] "+format, v...)
 	l.writerMsg(0, WARN, msg)
 }
 
 func (l *Logger) Error(skip int, format string, v ...interface{}) {
+	if l.level > ERROR {
+		return
+	}
 	msg := fmt.Sprintf("[E] "+format, v...)
 	l.writerMsg(skip, ERROR, msg)
 }
 
 func (l *Logger) Critical(skip int, format string, v ...interface{}) {
+	if l.level > CRITICAL {
+		return
+	}
 	msg := fmt.Sprintf("[C] "+format, v...)
 	l.writerMsg(skip, CRITICAL, msg)
 }
 
 func (l *Logger) Fatal(skip int, format string, v ...interface{}) {
+	if l.level > FATAL {
+		return
+	}
 	msg := fmt.Sprintf("[F] "+format, v...)
 	l.writerMsg(skip, FATAL, msg)
 	l.Close()

+ 1 - 1
pkg/log/syslog.go

@@ -39,7 +39,7 @@ func (sw *SyslogWriter) Init(config string) error {
 	return nil
 }
 
-func (sw *SyslogWriter) WriteMsg(msg string, skip, level int) error {
+func (sw *SyslogWriter) WriteMsg(msg string, skip int, level LogLevel) error {
 	var err error
 
 	switch level {

+ 1 - 1
public/app/core/components/navbar/navbar.ts

@@ -14,7 +14,7 @@ export class NavbarCtrl {
 export function navbarDirective() {
   return {
     restrict: 'E',
-    templateUrl: 'app/core/components/navbar/navbar.html',
+    templateUrl: 'public/app/core/components/navbar/navbar.html',
     controller: NavbarCtrl,
     bindToController: true,
     controllerAs: 'ctrl',

+ 1 - 1
public/app/core/components/search/search.ts

@@ -137,7 +137,7 @@ export class SearchCtrl {
 export function searchDirective() {
   return {
     restrict: 'E',
-    templateUrl: 'app/core/components/search/search.html',
+    templateUrl: 'public/app/core/components/search/search.html',
     controller: SearchCtrl,
     bindToController: true,
     controllerAs: 'ctrl',

+ 1 - 1
public/app/core/components/sidemenu/sidemenu.ts

@@ -148,7 +148,7 @@ export class SideMenuCtrl {
 export function sideMenuDirective() {
   return {
     restrict: 'E',
-    templateUrl: 'app/core/components/sidemenu/sidemenu.html',
+    templateUrl: 'public/app/core/components/sidemenu/sidemenu.html',
     controller: SideMenuCtrl,
     bindToController: true,
     controllerAs: 'ctrl',

+ 3 - 3
public/app/core/directives/dash_edit_link.js

@@ -6,9 +6,9 @@ function ($, coreModule) {
   'use strict';
 
   var editViewMap = {
-    'settings':    { src: 'app/features/dashboard/partials/settings.html', title: "Settings" },
-    'annotations': { src: 'app/features/annotations/partials/editor.html', title: "Annotations" },
-    'templating':  { src: 'app/features/templating/partials/editor.html', title: "Templating" }
+    'settings':    { src: 'public/app/features/dashboard/partials/settings.html', title: "Settings" },
+    'annotations': { src: 'public/app/features/annotations/partials/editor.html', title: "Annotations" },
+    'templating':  { src: 'public/app/features/templating/partials/editor.html', title: "Templating" }
   };
 
   coreModule.default.directive('dashEditorLink', function($timeout) {

+ 1 - 1
public/app/core/directives/value_select_dropdown.js

@@ -227,7 +227,7 @@ function (angular, _, coreModule) {
   coreModule.default.directive('valueSelectDropdown', function($compile, $window, $timeout, $rootScope) {
     return {
       scope: { variable: "=", onUpdated: "&", getValuesForTag: "&" },
-      templateUrl: 'app/partials/valueSelectDropdown.html',
+      templateUrl: 'public/app/partials/valueSelectDropdown.html',
       controller: 'ValueSelectDropdownCtrl',
       controllerAs: 'vm',
       bindToController: true,

+ 32 - 32
public/app/core/routes/all.js

@@ -14,146 +14,146 @@ define([
 
     $routeProvider
       .when('/', {
-        templateUrl: 'app/partials/dashboard.html',
+        templateUrl: 'public/app/partials/dashboard.html',
         controller : 'LoadDashboardCtrl',
         reloadOnSearch: false,
       })
       .when('/dashboard/:type/:slug', {
-        templateUrl: 'app/partials/dashboard.html',
+        templateUrl: 'public/app/partials/dashboard.html',
         controller : 'LoadDashboardCtrl',
         reloadOnSearch: false,
       })
       .when('/dashboard-solo/:type/:slug', {
-        templateUrl: 'app/features/panel/partials/soloPanel.html',
+        templateUrl: 'public/app/features/panel/partials/soloPanel.html',
         controller : 'SoloPanelCtrl',
       })
       .when('/dashboard-import/:file', {
-        templateUrl: 'app/partials/dashboard.html',
+        templateUrl: 'public/app/partials/dashboard.html',
         controller : 'DashFromImportCtrl',
         reloadOnSearch: false,
       })
       .when('/dashboard/new', {
-        templateUrl: 'app/partials/dashboard.html',
+        templateUrl: 'public/app/partials/dashboard.html',
         controller : 'NewDashboardCtrl',
         reloadOnSearch: false,
       })
       .when('/import/dashboard', {
-        templateUrl: 'app/features/dashboard/partials/import.html',
+        templateUrl: 'public/app/features/dashboard/partials/import.html',
         controller : 'DashboardImportCtrl',
       })
       .when('/datasources', {
-        templateUrl: 'app/features/datasources/partials/list.html',
+        templateUrl: 'public/app/features/datasources/partials/list.html',
         controller : 'DataSourcesCtrl',
         resolve: loadOrgBundle,
       })
       .when('/datasources/edit/:id', {
-        templateUrl: 'app/features/datasources/partials/edit.html',
+        templateUrl: 'public/app/features/datasources/partials/edit.html',
         controller : 'DataSourceEditCtrl',
         resolve: loadOrgBundle,
       })
       .when('/datasources/new', {
-        templateUrl: 'app/features/datasources/partials/edit.html',
+        templateUrl: 'public/app/features/datasources/partials/edit.html',
         controller : 'DataSourceEditCtrl',
         resolve: loadOrgBundle,
       })
       .when('/org', {
-        templateUrl: 'app/features/org/partials/orgDetails.html',
+        templateUrl: 'public/app/features/org/partials/orgDetails.html',
         controller : 'OrgDetailsCtrl',
         resolve: loadOrgBundle,
       })
       .when('/org/new', {
-        templateUrl: 'app/features/org/partials/newOrg.html',
+        templateUrl: 'public/app/features/org/partials/newOrg.html',
         controller : 'NewOrgCtrl',
         resolve: loadOrgBundle,
       })
       .when('/org/users', {
-        templateUrl: 'app/features/org/partials/orgUsers.html',
+        templateUrl: 'public/app/features/org/partials/orgUsers.html',
         controller : 'OrgUsersCtrl',
         resolve: loadOrgBundle,
       })
       .when('/org/apikeys', {
-        templateUrl: 'app/features/org/partials/orgApiKeys.html',
+        templateUrl: 'public/app/features/org/partials/orgApiKeys.html',
         controller : 'OrgApiKeysCtrl',
         resolve: loadOrgBundle,
       })
       .when('/profile', {
-        templateUrl: 'app/features/profile/partials/profile.html',
+        templateUrl: 'public/app/features/profile/partials/profile.html',
         controller : 'ProfileCtrl',
       })
       .when('/profile/password', {
-        templateUrl: 'app/features/profile/partials/password.html',
+        templateUrl: 'public/app/features/profile/partials/password.html',
         controller : 'ChangePasswordCtrl',
       })
       .when('/profile/select-org', {
-        templateUrl: 'app/features/profile/partials/select_org.html',
+        templateUrl: 'public/app/features/profile/partials/select_org.html',
         controller : 'SelectOrgCtrl',
       })
       .when('/admin/settings', {
-        templateUrl: 'app/features/admin/partials/settings.html',
+        templateUrl: 'public/app/features/admin/partials/settings.html',
         controller : 'AdminSettingsCtrl',
       })
       .when('/admin/users', {
-        templateUrl: 'app/features/admin/partials/users.html',
+        templateUrl: 'public/app/features/admin/partials/users.html',
         controller : 'AdminListUsersCtrl',
       })
       .when('/admin/users/create', {
-        templateUrl: 'app/features/admin/partials/new_user.html',
+        templateUrl: 'public/app/features/admin/partials/new_user.html',
         controller : 'AdminEditUserCtrl',
       })
       .when('/admin/users/edit/:id', {
-        templateUrl: 'app/features/admin/partials/edit_user.html',
+        templateUrl: 'public/app/features/admin/partials/edit_user.html',
         controller : 'AdminEditUserCtrl',
       })
       .when('/admin/orgs', {
-        templateUrl: 'app/features/admin/partials/orgs.html',
+        templateUrl: 'public/app/features/admin/partials/orgs.html',
         controller : 'AdminListOrgsCtrl',
       })
       .when('/admin/orgs/edit/:id', {
-        templateUrl: 'app/features/admin/partials/edit_org.html',
+        templateUrl: 'public/app/features/admin/partials/edit_org.html',
         controller : 'AdminEditOrgCtrl',
       })
       .when('/admin/stats', {
-        templateUrl: 'app/features/admin/partials/stats.html',
+        templateUrl: 'public/app/features/admin/partials/stats.html',
         controller : 'AdminStatsCtrl',
         controllerAs: 'ctrl',
       })
       .when('/login', {
-        templateUrl: 'app/partials/login.html',
+        templateUrl: 'public/app/partials/login.html',
         controller : 'LoginCtrl',
       })
       .when('/invite/:code', {
-        templateUrl: 'app/partials/signup_invited.html',
+        templateUrl: 'public/app/partials/signup_invited.html',
         controller : 'InvitedCtrl',
       })
       .when('/signup', {
-        templateUrl: 'app/partials/signup_step2.html',
+        templateUrl: 'public/app/partials/signup_step2.html',
         controller : 'SignUpCtrl',
       })
       .when('/user/password/send-reset-email', {
-        templateUrl: 'app/partials/reset_password.html',
+        templateUrl: 'public/app/partials/reset_password.html',
         controller : 'ResetPasswordCtrl',
       })
       .when('/user/password/reset', {
-        templateUrl: 'app/partials/reset_password.html',
+        templateUrl: 'public/app/partials/reset_password.html',
         controller : 'ResetPasswordCtrl',
       })
       .when('/apps', {
-        templateUrl: 'app/features/apps/partials/list.html',
+        templateUrl: 'public/app/features/apps/partials/list.html',
         controller: 'AppListCtrl',
         controllerAs: 'ctrl',
         resolve: loadAppsBundle,
       })
       .when('/apps/edit/:appId', {
-        templateUrl: 'app/features/apps/partials/edit.html',
+        templateUrl: 'public/app/features/apps/partials/edit.html',
         controller: 'AppEditCtrl',
         controllerAs: 'ctrl',
         resolve: loadAppsBundle,
       })
       .when('/global-alerts', {
-        templateUrl: 'app/features/dashboard/partials/globalAlerts.html',
+        templateUrl: 'public/app/features/dashboard/partials/globalAlerts.html',
       })
       .otherwise({
-        templateUrl: 'app/partials/error.html',
+        templateUrl: 'public/app/partials/error.html',
         controller: 'ErrorCtrl'
       });
   });

+ 1 - 1
public/app/core/services/alert_srv.js

@@ -72,7 +72,7 @@ function (angular, _, coreModule) {
       scope.noText = payload.noText || "Cancel";
 
       var confirmModal = $modal({
-        template: './app/partials/confirm_modal.html',
+        template: 'public/app/partials/confirm_modal.html',
         persist: false,
         modalClass: 'modal-no-header confirm-modal',
         show: false,

+ 1 - 1
public/app/features/annotations/editor_ctrl.js

@@ -31,7 +31,7 @@ function (angular, _, $) {
     };
 
     $scope.datasourceChanged = function() {
-      datasourceSrv.get($scope.currentAnnotation.datasource).then(function(ds) {
+      return datasourceSrv.get($scope.currentAnnotation.datasource).then(function(ds) {
         $scope.currentDatasource = ds;
         $scope.currentAnnotation.datasource = ds.name;
       });

+ 1 - 1
public/app/features/annotations/partials/editor.html

@@ -33,9 +33,9 @@
 			<i class="fa fa-remove"></i>
 		</button>
 	</div>
-
 	<div class="gf-box-body">
 
+
 		<div class="editor-row row" ng-if="mode === 'list'">
 			<div class="span6">
 				<div ng-if="annotations.length === 0">

+ 1 - 1
public/app/features/annotations/query_editor.ts

@@ -9,7 +9,7 @@ function annotationsQueryEditor(dynamicDirectiveSrv) {
       annotation: "=",
       datasource: "="
     },
-    watchPath: "datasource.type",
+    watchPath: "annotation.datasource",
     directive: scope => {
       return System.import(scope.datasource.meta.module).then(function(dsModule) {
         return {

+ 1 - 1
public/app/features/dashboard/dashboardCtrl.js

@@ -102,7 +102,7 @@ function (angular, $, config, moment) {
       var editScope = $rootScope.$new();
       editScope.object = options.object;
       editScope.updateHandler = options.updateHandler;
-      $scope.appEvent('show-dash-editor', { src: 'app/partials/edit_json.html', scope: editScope });
+      $scope.appEvent('show-dash-editor', { src: 'public/app/partials/edit_json.html', scope: editScope });
     };
 
     $scope.onDrop = function(panelId, row, dropTarget) {

+ 11 - 7
public/app/features/dashboard/dashnav/dashnav.html

@@ -27,13 +27,17 @@
 	<li ng-show="dashboardMeta.canShare" class="dropdown">
 		<a class="pointer" ng-click="hideTooltip($event)" bs-tooltip="'Share dashboard'" data-placement="bottom" data-toggle="dropdown"><i class="fa fa-share-square-o"></i></a>
 		<ul class="dropdown-menu">
-			<li ng-if="dashboardMeta.canEdit"><a class="pointer" ng-click="shareDashboard(0)">
-				<i class="fa fa-link"></i>
-				Link to Dashboard</a></li>
-			<li ng-if="dashboardMeta.canEdit"><a class="pointer" ng-click="shareDashboard(1)">
-				<i class="gf-icon gf-icon-snap-multi"></i>
-				Snapshot sharing</a></li>
-		</ul>				
+			<li ng-if="dashboardMeta.canEdit">
+				<a class="pointer" ng-click="shareDashboard(0)">
+					<i class="fa fa-link"></i> Link to Dashboard
+				</a>
+			</li>
+			<li ng-if="dashboardMeta.canEdit">
+				<a class="pointer" ng-click="shareDashboard(1)">
+					<i class="icon-gf icon-gf-snapshot"></i>Snapshot sharing
+				</a>
+			</li>
+		</ul>
 	</li>
 	<li ng-show="dashboardMeta.canSave">
 		<a ng-click="saveDashboard()" bs-tooltip="'Save dashboard'" data-placement="bottom"><i class="fa fa-save"></i></a>

+ 3 - 3
public/app/features/dashboard/dashnav/dashnav.ts

@@ -47,7 +47,7 @@ export class DashNavCtrl {
       modalScope.tabIndex = tabIndex;
 
       $scope.appEvent('show-modal', {
-        src: './app/features/dashboard/partials/shareModal.html',
+        src: 'public/app/features/dashboard/partials/shareModal.html',
         scope: modalScope
       });
     };
@@ -152,7 +152,7 @@ export class DashNavCtrl {
       newScope.clone.hideControls = false;
 
       $scope.appEvent('show-modal', {
-        src: './app/features/dashboard/partials/saveDashboardAs.html',
+        src: 'public/app/features/dashboard/partials/saveDashboardAs.html',
         scope: newScope,
       });
     };
@@ -192,7 +192,7 @@ export class DashNavCtrl {
 export function dashNavDirective() {
   return {
     restrict: 'E',
-    templateUrl: 'app/features/dashboard/dashnav/dashnav.html',
+    templateUrl: 'public/app/features/dashboard/dashnav/dashnav.html',
     controller: DashNavCtrl,
     transclude: true,
   };

+ 1 - 1
public/app/features/dashboard/keybindings.js

@@ -21,7 +21,7 @@ function(angular, $) {
 
         helpModalScope = $rootScope.$new();
         var helpModal = $modal({
-          template: './app/partials/help_modal.html',
+          template: 'public/app/partials/help_modal.html',
           persist: false,
           show: false,
           scope: helpModalScope,

+ 1 - 1
public/app/features/dashboard/partials/import.html

@@ -59,7 +59,7 @@
 			</section>
 		</div>
 
-		<div ng-include="'app/features/dashboard/partials/graphiteImport.html'"></div>
+		<div ng-include="'public/app/features/dashboard/partials/graphiteImport.html'"></div>
 
 	</div>
 </div>

+ 1 - 1
public/app/features/dashboard/submenu/submenu.ts

@@ -34,7 +34,7 @@ export class SubmenuCtrl {
 export function submenuDirective() {
   return {
     restrict: 'E',
-    templateUrl: 'app/features/dashboard/submenu/submenu.html',
+    templateUrl: 'public/app/features/dashboard/submenu/submenu.html',
     controller: SubmenuCtrl,
     bindToController: true,
     controllerAs: 'ctrl',

+ 3 - 3
public/app/features/dashboard/timepicker/timepicker.ts

@@ -101,7 +101,7 @@ export class TimePickerCtrl {
     this.refresh.options.unshift({text: 'off'});
 
     this.$rootScope.appEvent('show-dash-editor', {
-      src: 'app/features/dashboard/timepicker/dropdown.html',
+      src: 'public/app/features/dashboard/timepicker/dropdown.html',
       scope: this.$scope,
       cssClass: 'gf-timepicker-dropdown',
     });
@@ -146,7 +146,7 @@ export class TimePickerCtrl {
 export function settingsDirective() {
   return {
     restrict: 'E',
-    templateUrl: 'app/features/dashboard/timepicker/settings.html',
+    templateUrl: 'public/app/features/dashboard/timepicker/settings.html',
     controller: TimePickerCtrl,
     bindToController: true,
     controllerAs: 'ctrl',
@@ -159,7 +159,7 @@ export function settingsDirective() {
 export function timePickerDirective() {
   return {
     restrict: 'E',
-    templateUrl: 'app/features/dashboard/timepicker/timepicker.html',
+    templateUrl: 'public/app/features/dashboard/timepicker/timepicker.html',
     controller: TimePickerCtrl,
     bindToController: true,
     controllerAs: 'ctrl',

+ 1 - 1
public/app/features/dashboard/unsavedChangesSrv.js

@@ -139,7 +139,7 @@ function(angular, _) {
       };
 
       $rootScope.appEvent('show-modal', {
-        src: './app/partials/unsaved-changes.html',
+        src: 'public/app/partials/unsaved-changes.html',
         modalClass: 'modal-no-header confirm-modal',
         scope: modalScope,
       });

+ 1 - 1
public/app/features/dashlinks/module.js

@@ -21,7 +21,7 @@ function (angular, _) {
     return {
       restrict: 'E',
       controller: 'DashLinkEditorCtrl',
-      templateUrl: 'app/features/dashlinks/editor.html',
+      templateUrl: 'public/app/features/dashlinks/editor.html',
       link: function() {
       }
     };

+ 1 - 1
public/app/features/datasources/edit_ctrl.js

@@ -10,7 +10,7 @@ function (angular, _, config) {
   var datasourceTypes = [];
 
   module.directive('datasourceHttpSettings', function() {
-    return {templateUrl: 'app/features/datasources/partials/http_settings.html'};
+    return {templateUrl: 'public/app/features/datasources/partials/http_settings.html'};
   });
 
   module.controller('DataSourceEditCtrl', function($scope, $q, backendSrv, $routeParams, $location, datasourceSrv) {

+ 1 - 1
public/app/features/org/orgApiKeysCtrl.js

@@ -32,7 +32,7 @@ function (angular) {
         modalScope.key = result.key;
 
         $scope.appEvent('show-modal', {
-          src: './app/features/org/partials/apikeyModal.html',
+          src: 'public/app/features/org/partials/apikeyModal.html',
           scope: modalScope
         });
 

+ 1 - 1
public/app/features/org/orgUsersCtrl.js

@@ -54,7 +54,7 @@ function (angular) {
       };
 
       $scope.appEvent('show-modal', {
-        src: './app/features/org/partials/invite.html',
+        src: 'public/app/features/org/partials/invite.html',
         modalClass: 'modal-no-header invite-modal',
         scope: modalScope
       });

+ 0 - 2
public/app/features/panel/all.js

@@ -1,8 +1,6 @@
 define([
   './panel_menu',
   './panel_directive',
-  './panel_srv',
-  './panel_helper',
   './solo_panel_ctrl',
   './panel_loader',
   './query_editor',

+ 1 - 1
public/app/features/panel/metrics_panel_ctrl.ts

@@ -49,7 +49,7 @@ class MetricsPanelCtrl extends PanelCtrl {
 
   initEditMode() {
     this.addEditorTab('Metrics', 'public/app/partials/metrics.html');
-    this.addEditorTab('Time range', 'app/features/panel/partials/panelTime.html');
+    this.addEditorTab('Time range', 'public/app/features/panel/partials/panelTime.html');
     this.datasources = this.datasourceSrv.getMetricSources();
   }
 

+ 1 - 1
public/app/features/panel/panel_ctrl.ts

@@ -172,7 +172,7 @@ export class PanelCtrl {
    shareScope.dashboard = this.dashboard;
 
    this.publishAppEvent('show-modal', {
-     src: './app/features/dashboard/partials/shareModal.html',
+     src: 'public/app/features/dashboard/partials/shareModal.html',
      scope: shareScope
    });
  }

+ 1 - 0
public/app/features/panel/panel_directive.ts

@@ -6,6 +6,7 @@ import $ from 'jquery';
 import {PanelCtrl} from './panel_ctrl';
 
 export class DefaultPanelCtrl extends PanelCtrl {
+  /** @ngInject */
   constructor($scope, $injector) {
     super($scope, $injector);
   }

+ 5 - 1
public/app/features/panel/panel_loader.ts

@@ -8,7 +8,7 @@ import {UnknownPanel} from '../../plugins/panel/unknown/module';
 var directiveModule = angular.module('grafana.directives');
 
 /** @ngInject */
-function panelLoader($compile, dynamicDirectiveSrv, $http, $q, $injector) {
+function panelLoader($compile, dynamicDirectiveSrv, $http, $q, $injector, $templateCache) {
   return {
     restrict: 'E',
     scope: {
@@ -22,6 +22,10 @@ function panelLoader($compile, dynamicDirectiveSrv, $http, $q, $injector) {
         if (directive.template) {
           return $q.when(directive.template);
         }
+        var cached = $templateCache.get(directive.templateUrl);
+        if (cached) {
+          return $q.when(cached);
+        }
         return $http.get(directive.templateUrl).then(res => {
           return res.data;
         });

+ 4 - 3
public/app/features/panel/panel_menu.js

@@ -12,7 +12,7 @@ function (angular, $, _) {
       var linkTemplate =
           '<span class="panel-title drag-handle pointer">' +
             '<span class="panel-title-text drag-handle">{{ctrl.panel.title | interpolateTemplateVars:this}}</span>' +
-            '<span class="panel-links-btn"><i class="fa fa-link"></i></span>' +
+            '<span class="panel-links-btn"><i class="fa fa-external-link"></i></span>' +
             '<span class="panel-time-info" ng-show="ctrl.timeInfo"><i class="fa fa-clock-o"></i> {{ctrl.timeInfo}}</span>' +
           '</span>';
 
@@ -28,6 +28,7 @@ function (angular, $, _) {
         }
         return template;
       }
+
       function createMenuTemplate(ctrl) {
         var template = '<div class="panel-menu small">';
 
@@ -124,8 +125,8 @@ function (angular, $, _) {
             }
 
             var menuTemplate;
-            if ($(e.target).hasClass('fa-link')) {
-              menuTemplate = createExternalLinkMenu($scope);
+            if ($(e.target).hasClass('fa-external-link')) {
+              menuTemplate = createExternalLinkMenu(ctrl);
             } else {
               menuTemplate = createMenuTemplate(ctrl);
             }

+ 0 - 162
public/app/features/panel/panel_srv.js

@@ -1,162 +0,0 @@
-define([
-  'angular',
-  'lodash',
-  'app/core/config',
-],
-function (angular, _, config) {
-  'use strict';
-
-  var module = angular.module('grafana.services');
-
-  module.service('panelSrv', function($rootScope, $timeout, datasourceSrv, $q) {
-
-    this.init = function($scope) {
-
-      if (!$scope.panel.span) { $scope.panel.span = 12; }
-
-      $scope.inspector = {};
-
-      $scope.editPanel = function() {
-        $scope.toggleFullscreen(true);
-      };
-
-      $scope.sharePanel = function() {
-        $scope.appEvent('show-modal', {
-          src: './app/features/dashboard/partials/shareModal.html',
-          scope: $scope.$new()
-        });
-      };
-
-      $scope.editPanelJson = function() {
-        $scope.appEvent('show-json-editor', { object: $scope.panel, updateHandler: $scope.replacePanel });
-      };
-
-      $scope.duplicatePanel = function() {
-        $scope.dashboard.duplicatePanel($scope.panel, $scope.row);
-      };
-
-      $scope.updateColumnSpan = function(span) {
-        $scope.updatePanelSpan($scope.panel, span);
-
-        $timeout(function() {
-          $scope.$broadcast('render');
-        });
-      };
-
-      $scope.addDataQuery = function(datasource) {
-        $scope.dashboard.addDataQueryTo($scope.panel, datasource);
-      };
-
-      $scope.removeDataQuery = function (query) {
-        $scope.dashboard.removeDataQuery($scope.panel, query);
-        $scope.get_data();
-      };
-
-      $scope.duplicateDataQuery = function(query) {
-        $scope.dashboard.duplicateDataQuery($scope.panel, query);
-      };
-
-      $scope.moveDataQuery = function(fromIndex, toIndex) {
-        $scope.dashboard.moveDataQuery($scope.panel, fromIndex, toIndex);
-      };
-
-      $scope.setDatasource = function(datasource) {
-        // switching to mixed
-        if (datasource.meta.mixed) {
-          _.each($scope.panel.targets, function(target) {
-            target.datasource = $scope.panel.datasource;
-            if (target.datasource === null) {
-              target.datasource = config.defaultDatasource;
-            }
-          });
-        }
-        // switching from mixed
-        else if ($scope.datasource && $scope.datasource.meta.mixed) {
-          _.each($scope.panel.targets, function(target) {
-            delete target.datasource;
-          });
-        }
-
-        $scope.panel.datasource = datasource.value;
-        $scope.datasource = null;
-        $scope.get_data();
-      };
-
-      $scope.toggleEditorHelp = function(index) {
-        if ($scope.editorHelpIndex === index) {
-          $scope.editorHelpIndex = null;
-          return;
-        }
-        $scope.editorHelpIndex = index;
-      };
-
-      $scope.isNewPanel = function() {
-        return $scope.panel.title === config.new_panel_title;
-      };
-
-      $scope.toggleFullscreen = function(edit) {
-        $scope.dashboardViewState.update({ fullscreen: true, edit: edit, panelId: $scope.panel.id });
-      };
-
-      $scope.otherPanelInFullscreenMode = function() {
-        return $scope.dashboardViewState.fullscreen && !$scope.fullscreen;
-      };
-
-      $scope.getCurrentDatasource = function() {
-        if ($scope.datasource) {
-          return $q.when($scope.datasource);
-        }
-
-        return datasourceSrv.get($scope.panel.datasource);
-      };
-
-      $scope.panelRenderingComplete = function() {
-        $rootScope.performance.panelsRendered++;
-      };
-
-      $scope.get_data = function() {
-        if ($scope.otherPanelInFullscreenMode()) { return; }
-
-        if ($scope.panel.snapshotData) {
-          if ($scope.loadSnapshot) {
-            $scope.loadSnapshot($scope.panel.snapshotData);
-          }
-          return;
-        }
-
-        delete $scope.panelMeta.error;
-        $scope.panelMeta.loading = true;
-
-        $scope.getCurrentDatasource().then(function(datasource) {
-          $scope.datasource = datasource;
-          return $scope.refreshData($scope.datasource) || $q.when({});
-        }).then(function() {
-          $scope.panelMeta.loading = false;
-        }, function(err) {
-          console.log('Panel data error:', err);
-          $scope.panelMeta.loading = false;
-          $scope.panelMeta.error = err.message || "Timeseries data request error";
-          $scope.inspector.error = err;
-        });
-      };
-
-      if ($scope.refreshData) {
-        $scope.$on("refresh", $scope.get_data);
-      }
-
-      // Post init phase
-      $scope.fullscreen = false;
-      $scope.editor = { index: 1 };
-
-      $scope.dashboardViewState.registerPanel($scope);
-      $scope.datasources = datasourceSrv.getMetricSources();
-
-      if (!$scope.skipDataOnInit) {
-        $timeout(function() {
-          $scope.get_data();
-        }, 30);
-      }
-    };
-  });
-
-});

+ 1 - 1
public/app/features/panel/query_editor.ts

@@ -87,7 +87,7 @@ function metricsQueryEditor(dynamicDirectiveSrv, datasourceSrv) {
     directive: scope => {
       let datasource = scope.target.datasource || scope.ctrl.panel.datasource;
       return datasourceSrv.get(datasource).then(ds => {
-        scope.ctrl.datasource = ds;
+        scope.datasource = ds;
 
         if (!scope.target.refId) {
           scope.target.refId = 'A';

+ 1 - 1
public/app/features/panellinks/module.js

@@ -15,7 +15,7 @@ function (angular, _) {
         },
         restrict: 'E',
         controller: 'PanelLinksEditorCtrl',
-        templateUrl: 'app/features/panellinks/module.html',
+        templateUrl: 'public/app/features/panellinks/module.html',
         link: function() {
         }
       };

+ 3 - 3
public/app/features/playlist/playlist_routes.js

@@ -11,17 +11,17 @@ function (angular) {
   module.config(function($routeProvider) {
     $routeProvider
       .when('/playlists', {
-        templateUrl: 'app/features/playlist/partials/playlists.html',
+        templateUrl: 'public/app/features/playlist/partials/playlists.html',
         controllerAs: 'ctrl',
         controller : 'PlaylistsCtrl'
       })
       .when('/playlists/create', {
-        templateUrl: 'app/features/playlist/partials/playlist.html',
+        templateUrl: 'public/app/features/playlist/partials/playlist.html',
         controllerAs: 'ctrl',
         controller : 'PlaylistEditCtrl'
       })
       .when('/playlists/edit/:id', {
-        templateUrl: 'app/features/playlist/partials/playlist.html',
+        templateUrl: 'public/app/features/playlist/partials/playlist.html',
         controllerAs: 'ctrl',
         controller : 'PlaylistEditCtrl'
       })

+ 1 - 1
public/app/features/playlist/playlist_search.ts

@@ -70,7 +70,7 @@ export class PlaylistSearchCtrl {
 export function playlistSearchDirective() {
   return {
     restrict: 'E',
-    templateUrl: 'app/features/playlist/partials/playlist_search.html',
+    templateUrl: 'public/app/features/playlist/partials/playlist_search.html',
     controller: PlaylistSearchCtrl,
     bindToController: true,
     controllerAs: 'ctrl',

+ 0 - 5
public/app/partials/dashboard.html

@@ -107,8 +107,3 @@
 		</div>
 
 	</div>
-
-	<div ng-include="'app/partials/console.html'" ng-if="consoleEnabled">
-	</div>
-
-</div>

+ 2 - 1
public/app/partials/login.html

@@ -3,7 +3,8 @@
 	<div class="login-box">
 
 		<div class="login-box-logo">
-			<img src="img/logo_transparent_200x75.png">
+			<img class="logo-icon" src="img/grafana_icon.svg"></img><br>
+			<i class="icon-gf icon-gf-grafana_wordmark"></i>
 		</div>
 
     <div class="login-inner-box">

+ 3 - 3
public/app/plugins/datasource/cloudwatch/module.js

@@ -7,15 +7,15 @@ function (CloudWatchDatasource) {
   'use strict';
 
   function metricsQueryEditor() {
-    return {controller: 'CloudWatchQueryCtrl', templateUrl: 'app/plugins/datasource/cloudwatch/partials/query.editor.html'};
+    return {controller: 'CloudWatchQueryCtrl', templateUrl: 'public/app/plugins/datasource/cloudwatch/partials/query.editor.html'};
   }
 
   function annotationsQueryEditor() {
-    return {templateUrl: 'app/plugins/datasource/cloudwatch/partials/annotations.editor.html'};
+    return {templateUrl: 'public/app/plugins/datasource/cloudwatch/partials/annotations.editor.html'};
   }
 
   function configView() {
-    return {templateUrl: 'app/plugins/datasource/cloudwatch/partials/edit_view.html'};
+    return {templateUrl: 'public/app/plugins/datasource/cloudwatch/partials/edit_view.html'};
   }
 
   return  {

+ 6 - 6
public/app/plugins/datasource/cloudwatch/partials/query.editor.html

@@ -6,14 +6,14 @@
 					<i class="fa fa-bars"></i>
 				</a>
 				<ul class="dropdown-menu pull-right" role="menu">
-					<li role="menuitem"><a tabindex="1" ng-click="duplicateDataQuery(target)">Duplicate</a></li>
-					<li role="menuitem"><a tabindex="1" ng-click="moveDataQuery($index, $index-1)">Move up</a></li>
-					<li role="menuitem"><a tabindex="1" ng-click="moveDataQuery($index, $index+1)">Move down</a></li>
+					<li role="menuitem"><a tabindex="1" ng-click="ctrl.duplicateDataQuery(target)">Duplicate</a></li>
+					<li role="menuitem"><a tabindex="1" ng-click="ctrl.moveDataQuery($index, $index-1)">Move up</a></li>
+					<li role="menuitem"><a tabindex="1" ng-click="ctrl.moveDataQuery($index, $index+1)">Move down</a></li>
 				</ul>
 			</div>
 		</li>
 		<li class="tight-form-item last">
-			<a class="pointer" tabindex="1" ng-click="removeDataQuery(target)">
+			<a class="pointer" tabindex="1" ng-click="ctrl.removeDataQuery(target)">
 				<i class="fa fa-remove"></i>
 			</a>
 		</li>
@@ -25,7 +25,7 @@
 		</li>
 		<li>
 			<a  class="tight-form-item"
-				ng-click="target.hide = !target.hide; get_data();"
+				ng-click="target.hide = !target.hide; ctrl.refresh();"
 				role="menuitem">
 				<i class="fa fa-eye"></i>
 			</a>
@@ -35,4 +35,4 @@
 	<div class="clearfix"></div>
 </div>
 
-<cloudwatch-query-parameter target="target" datasource="datasource" on-change="refreshMetricData()"></cloudwatch-query-parameter>
+<cloudwatch-query-parameter target="target" datasource="ctrl.datasource" on-change="refreshMetricData()"></cloudwatch-query-parameter>

+ 1 - 1
public/app/plugins/datasource/cloudwatch/query_ctrl.js

@@ -16,7 +16,7 @@ function (angular, _) {
     $scope.refreshMetricData = function() {
       if (!_.isEqual($scope.oldTarget, $scope.target)) {
         $scope.oldTarget = angular.copy($scope.target);
-        $scope.get_data();
+        $scope.ctrl.refresh();
       }
     };
 

+ 1 - 1
public/app/plugins/datasource/elasticsearch/bucket_agg.js

@@ -10,7 +10,7 @@ function (angular, _, queryDef) {
 
   module.directive('elasticBucketAgg', function() {
     return {
-      templateUrl: 'app/plugins/datasource/elasticsearch/partials/bucket_agg.html',
+      templateUrl: 'public/app/plugins/datasource/elasticsearch/partials/bucket_agg.html',
       controller: 'ElasticBucketAggCtrl',
       restrict: 'E',
       scope: {

+ 2 - 1
public/app/plugins/datasource/elasticsearch/edit_view.ts

@@ -5,6 +5,7 @@ import _ from 'lodash';
 
 export class EditViewCtrl {
 
+  /** @ngInject */
   constructor($scope) {
     $scope.indexPatternTypes = [
       {name: 'No pattern',  value: undefined},
@@ -29,7 +30,7 @@ export class EditViewCtrl {
 
 function editViewDirective() {
   return {
-    templateUrl: 'app/plugins/datasource/elasticsearch/partials/edit_view.html',
+    templateUrl: 'public/app/plugins/datasource/elasticsearch/partials/edit_view.html',
     controller: EditViewCtrl,
   };
 };

+ 1 - 1
public/app/plugins/datasource/elasticsearch/metric_agg.js

@@ -10,7 +10,7 @@ function (angular, _, queryDef) {
 
   module.directive('elasticMetricAgg', function() {
     return {
-      templateUrl: 'app/plugins/datasource/elasticsearch/partials/metric_agg.html',
+      templateUrl: 'public/app/plugins/datasource/elasticsearch/partials/metric_agg.html',
       controller: 'ElasticMetricAggCtrl',
       restrict: 'E',
       scope: {

+ 3 - 3
public/app/plugins/datasource/elasticsearch/module.js

@@ -8,15 +8,15 @@ function (ElasticDatasource, editView) {
   'use strict';
 
   function metricsQueryEditor() {
-    return {controller: 'ElasticQueryCtrl', templateUrl: 'app/plugins/datasource/elasticsearch/partials/query.editor.html'};
+    return {controller: 'ElasticQueryCtrl', templateUrl: 'public/app/plugins/datasource/elasticsearch/partials/query.editor.html'};
   }
 
   function metricsQueryOptions() {
-    return {templateUrl: 'app/plugins/datasource/elasticsearch/partials/query.options.html'};
+    return {templateUrl: 'public/app/plugins/datasource/elasticsearch/partials/query.options.html'};
   }
 
   function annotationsQueryEditor() {
-    return {templateUrl: 'app/plugins/datasource/elasticsearch/partials/annotations.editor.html'};
+    return {templateUrl: 'public/app/plugins/datasource/elasticsearch/partials/annotations.editor.html'};
   }
 
   return {

+ 7 - 7
public/app/plugins/datasource/elasticsearch/partials/query.editor.html

@@ -14,15 +14,15 @@
 					<i class="fa fa-bars"></i>
 				</a>
 				<ul class="dropdown-menu pull-right" role="menu">
-					<li role="menuitem"><a tabindex="1" ng-click="duplicateDataQuery(target)">Duplicate</a></li>
-					<li role="menuitem"><a tabindex="1" ng-click="moveDataQuery($index, $index-1)">Move up</a></li>
-					<li role="menuitem"><a tabindex="1" ng-click="moveDataQuery($index, $index+1)">Move down</a></li>
+					<li role="menuitem"><a tabindex="1" ng-click="panelCtrl.duplicateDataQuery(target)">Duplicate</a></li>
+					<li role="menuitem"><a tabindex="1" ng-click="panelCtrl.moveDataQuery($index, $index-1)">Move up</a></li>
+					<li role="menuitem"><a tabindex="1" ng-click="panelCtrl.moveDataQuery($index, $index+1)">Move down</a></li>
 				</ul>
 			</div>
 		</li>
 
 		<li class="tight-form-item last">
-			<a class="pointer" tabindex="1" ng-click="removeDataQuery(target)">
+			<a class="pointer" tabindex="1" ng-click="panelCtrl.removeDataQuery(target)">
 				<i class="fa fa-remove"></i>
 			</a>
 		</li>
@@ -33,7 +33,7 @@
 			{{target.refId}}
 		</li>
 		<li>
-			<a class="tight-form-item" ng-click="target.hide = !target.hide; get_data();" role="menuitem">
+			<a class="tight-form-item" ng-click="target.hide = !target.hide; panelCtrl.refresh();" role="menuitem">
 				<i class="fa fa-eye"></i>
 			</a>
 		</li>
@@ -44,13 +44,13 @@
 			Query
 		</li>
 		<li>
-			<input type="text" class="tight-form-input" style="width: 345px;" ng-model="target.query" spellcheck='false' placeholder="Lucene query" ng-blur="get_data()">
+			<input type="text" class="tight-form-input" style="width: 345px;" ng-model="target.query" spellcheck='false' placeholder="Lucene query" ng-blur="panelCtrl.refresh()">
 		</li>
 		<li class="tight-form-item query-keyword">
 			Alias
 		</li>
 		<li>
-			<input type="text" class="tight-form-input" style="width: 200px;" ng-model="target.alias" spellcheck='false' placeholder="alias patterns (empty = auto)" ng-blur="get_data()">
+			<input type="text" class="tight-form-input" style="width: 200px;" ng-model="target.alias" spellcheck='false' placeholder="alias patterns (empty = auto)" ng-blur="panelCtrl.refresh()">
 		</li>
 	</ul>
 	<div class="clearfix"></div>

+ 3 - 3
public/app/plugins/datasource/elasticsearch/partials/query.options.html

@@ -8,7 +8,7 @@
 				Group by time interval
 			</li>
 			<li>
-				<input type="text" class="input-medium tight-form-input" ng-model="panel.interval" ng-blur="get_data();"
+				<input type="text" class="input-medium tight-form-input" ng-model="ctrl.panel.interval" ng-blur="ctrl.refresh();"
 							 spellcheck='false' placeholder="example: >10s">
 			</li>
 			<li class="tight-form-item">
@@ -23,7 +23,7 @@
 				<i class="fa fa-info-circle"></i>
 			</li>
 			<li class="tight-form-item">
-				<a ng-click="toggleEditorHelp(1);" bs-tooltip="'click to show helpful info'" data-placement="bottom">
+				<a ng-click="ctrl.toggleEditorHelp(1);" bs-tooltip="'click to show helpful info'" data-placement="bottom">
 					alias patterns
 				</a>
 			</li>
@@ -34,7 +34,7 @@
 
 <div class="editor-row">
 	<div class="pull-left" style="margin-top: 30px;">
-		<div class="grafana-info-box span6" ng-if="editorHelpIndex === 1">
+		<div class="grafana-info-box span6" ng-if="ctrl.editorHelpIndex === 1">
 			<h5>Alias patterns</h5>
 			<ul ng-non-bindable>
 				<li>{{term fieldname}} = replaced with value of term group by</li>

+ 4 - 3
public/app/plugins/datasource/elasticsearch/query_ctrl.js

@@ -6,8 +6,9 @@ function (angular) {
 
   var module = angular.module('grafana.controllers');
 
-  module.controller('ElasticQueryCtrl', function($scope, $timeout, uiSegmentSrv) {
+  module.controller('ElasticQueryCtrl', function($scope, $rootScope, $timeout, uiSegmentSrv) {
     $scope.esVersion = $scope.datasource.esVersion;
+    $scope.panelCtrl = $scope.ctrl;
 
     $scope.init = function() {
       var target = $scope.target;
@@ -27,10 +28,10 @@ function (angular) {
       var newJson = angular.toJson($scope.datasource.queryBuilder.build($scope.target), true);
       if (newJson !== $scope.oldQueryRaw) {
         $scope.rawQueryOld = newJson;
-        $scope.get_data();
+        $scope.panelCtrl.refresh();
       }
 
-      $scope.appEvent('elastic-query-updated');
+      $rootScope.appEvent('elastic-query-updated');
     };
 
     $scope.handleQueryError = function(err) {

+ 1 - 1
public/app/plugins/datasource/grafana/module.ts

@@ -4,7 +4,7 @@ import angular from 'angular';
 import {GrafanaDatasource} from './datasource';
 
 class GrafanaMetricsQueryEditor {
-  static templateUrl = 'app/plugins/datasource/grafana/partials/query.editor.html';
+  static templateUrl = 'public/app/plugins/datasource/grafana/partials/query.editor.html';
 }
 
 export {

+ 4 - 4
public/app/plugins/datasource/graphite/module.js

@@ -7,20 +7,20 @@ function (GraphiteDatasource) {
   function metricsQueryEditor() {
     return {
       controller: 'GraphiteQueryCtrl',
-      templateUrl: 'app/plugins/datasource/graphite/partials/query.editor.html'
+      templateUrl: 'public/app/plugins/datasource/graphite/partials/query.editor.html'
     };
   }
 
   function metricsQueryOptions() {
-    return {templateUrl: 'app/plugins/datasource/graphite/partials/query.options.html'};
+    return {templateUrl: 'public/app/plugins/datasource/graphite/partials/query.options.html'};
   }
 
   function annotationsQueryEditor() {
-    return {templateUrl: 'app/plugins/datasource/graphite/partials/annotations.editor.html'};
+    return {templateUrl: 'public/app/plugins/datasource/graphite/partials/annotations.editor.html'};
   }
 
   function configView() {
-    return {templateUrl: 'app/plugins/datasource/graphite/partials/config.html'};
+    return {templateUrl: 'public/app/plugins/datasource/graphite/partials/config.html'};
   }
 
   return {

+ 3 - 2
public/app/plugins/datasource/graphite/query_ctrl.js

@@ -12,6 +12,7 @@ function (angular, _, config, gfunc, Parser) {
 
   module.controller('GraphiteQueryCtrl', function($scope, uiSegmentSrv, templateSrv) {
     var panelCtrl = $scope.panelCtrl = $scope.ctrl;
+    var datasource = $scope.datasource;
 
     $scope.init = function() {
       if ($scope.target) {
@@ -126,7 +127,7 @@ function (angular, _, config, gfunc, Parser) {
       }
 
       var path = getSegmentPathUpTo(fromIndex + 1);
-      return panelCtrl.datasource.metricFindQuery(path)
+      return datasource.metricFindQuery(path)
         .then(function(segments) {
           if (segments.length === 0) {
             if (path !== '') {
@@ -160,7 +161,7 @@ function (angular, _, config, gfunc, Parser) {
     $scope.getAltSegments = function (index) {
       var query = index === 0 ?  '*' : getSegmentPathUpTo(index) + '.*';
 
-      return panelCtrl.datasource.metricFindQuery(query).then(function(segments) {
+      return datasource.metricFindQuery(query).then(function(segments) {
         var altSegments = _.map(segments, function(segment) {
           return uiSegmentSrv.newSegment({ value: segment.text, expandable: segment.expandable });
         });

+ 10 - 11
public/app/plugins/datasource/graphite/specs/query_ctrl_specs.ts

@@ -19,14 +19,13 @@ describe('GraphiteQueryCtrl', function() {
     ctx.scope = $rootScope.$new();
     ctx.scope.ctrl = {panel: ctx.panel};
     ctx.panelCtrl = ctx.scope.ctrl;
+    ctx.scope.datasource = ctx.datasource;
+    ctx.scope.datasource.metricFindQuery = sinon.stub().returns(ctx.$q.when([]));
     ctx.controller = $controller('GraphiteQueryCtrl', {$scope: ctx.scope});
   }));
 
   beforeEach(function() {
     ctx.scope.target = {target: 'aliasByNode(scaleToSeconds(test.prod.*,1),2)'};
-
-    ctx.panelCtrl.datasource = ctx.datasource;
-    ctx.panelCtrl.datasource.metricFindQuery = sinon.stub().returns(ctx.$q.when([]));
   });
 
   describe('init', function() {
@@ -36,7 +35,7 @@ describe('GraphiteQueryCtrl', function() {
     });
 
     it('should validate metric key exists', function() {
-      expect(ctx.panelCtrl.datasource.metricFindQuery.getCall(0).args[0]).to.be('test.prod.*');
+      expect(ctx.scope.datasource.metricFindQuery.getCall(0).args[0]).to.be('test.prod.*');
     });
 
     it('should delete last segment if no metrics are found', function() {
@@ -51,7 +50,7 @@ describe('GraphiteQueryCtrl', function() {
   describe('when adding function', function() {
     beforeEach(function() {
       ctx.scope.target.target = 'test.prod.*.count';
-      ctx.panelCtrl.datasource.metricFindQuery.returns(ctx.$q.when([{expandable: false}]));
+      ctx.scope.datasource.metricFindQuery.returns(ctx.$q.when([{expandable: false}]));
       ctx.scope.init();
       ctx.scope.$digest();
 
@@ -75,7 +74,7 @@ describe('GraphiteQueryCtrl', function() {
   describe('when adding function before any metric segment', function() {
     beforeEach(function() {
       ctx.scope.target.target = '';
-      ctx.panelCtrl.datasource.metricFindQuery.returns(ctx.$q.when([{expandable: true}]));
+      ctx.scope.datasource.metricFindQuery.returns(ctx.$q.when([{expandable: true}]));
       ctx.scope.init();
       ctx.scope.$digest();
       ctx.scope.addFunction(gfunc.getFuncDef('asPercent'));
@@ -89,7 +88,7 @@ describe('GraphiteQueryCtrl', function() {
   describe('when initalizing target without metric expression and only function', function() {
     beforeEach(function() {
       ctx.scope.target.target = 'asPercent(#A, #B)';
-      ctx.panelCtrl.datasource.metricFindQuery.returns(ctx.$q.when([]));
+      ctx.scope.datasource.metricFindQuery.returns(ctx.$q.when([]));
       ctx.scope.init();
       ctx.scope.$digest();
     });
@@ -107,7 +106,7 @@ describe('GraphiteQueryCtrl', function() {
   describe('when initializing a target with single param func using variable', function() {
     beforeEach(function() {
       ctx.scope.target.target = 'movingAverage(prod.count, $var)';
-      ctx.panelCtrl.datasource.metricFindQuery.returns(ctx.$q.when([]));
+      ctx.scope.datasource.metricFindQuery.returns(ctx.$q.when([]));
       ctx.scope.init();
       ctx.scope.$digest();
     });
@@ -125,7 +124,7 @@ describe('GraphiteQueryCtrl', function() {
   describe('when initalizing target without metric expression and function with series-ref', function() {
     beforeEach(function() {
       ctx.scope.target.target = 'asPercent(metric.node.count, #A)';
-      ctx.panelCtrl.datasource.metricFindQuery.returns(ctx.$q.when([]));
+      ctx.scope.datasource.metricFindQuery.returns(ctx.$q.when([]));
       ctx.scope.init();
       ctx.scope.$digest();
       ctx.scope.$parent = { get_data: sinon.spy() };
@@ -143,7 +142,7 @@ describe('GraphiteQueryCtrl', function() {
   describe('when getting altSegments and metricFindQuery retuns empty array', function() {
     beforeEach(function() {
       ctx.scope.target.target = 'test.count';
-      ctx.panelCtrl.datasource.metricFindQuery.returns(ctx.$q.when([]));
+      ctx.scope.datasource.metricFindQuery.returns(ctx.$q.when([]));
       ctx.scope.init();
       ctx.scope.getAltSegments(1).then(function(results) {
         ctx.altSegments = results;
@@ -159,7 +158,7 @@ describe('GraphiteQueryCtrl', function() {
 
   describe('targetChanged', function() {
     beforeEach(function() {
-      ctx.panelCtrl.datasource.metricFindQuery.returns(ctx.$q.when([{expandable: false}]));
+      ctx.scope.datasource.metricFindQuery.returns(ctx.$q.when([{expandable: false}]));
       ctx.scope.init();
       ctx.scope.$digest();
 

+ 0 - 1
public/app/plugins/datasource/influxdb/datasource.js

@@ -218,5 +218,4 @@ function (angular, _, dateMath, InfluxSeries, InfluxQuery) {
   }
 
   return InfluxDatasource;
-
 });

+ 4 - 4
public/app/plugins/datasource/influxdb/module.js

@@ -5,19 +5,19 @@ function (InfluxDatasource) {
   'use strict';
 
   function influxMetricsQueryEditor() {
-    return {controller: 'InfluxQueryCtrl', templateUrl: 'app/plugins/datasource/influxdb/partials/query.editor.html'};
+    return {controller: 'InfluxQueryCtrl', templateUrl: 'public/app/plugins/datasource/influxdb/partials/query.editor.html'};
   }
 
   function influxMetricsQueryOptions() {
-    return {templateUrl: 'app/plugins/datasource/influxdb/partials/query.options.html'};
+    return {templateUrl: 'public/app/plugins/datasource/influxdb/partials/query.options.html'};
   }
 
   function influxAnnotationsQueryEditor() {
-    return {templateUrl: 'app/plugins/datasource/influxdb/partials/annotations.editor.html'};
+    return {templateUrl: 'public/app/plugins/datasource/influxdb/partials/annotations.editor.html'};
   }
 
   function influxConfigView() {
-    return {templateUrl: 'app/plugins/datasource/influxdb/partials/config.html'};
+    return {templateUrl: 'public/app/plugins/datasource/influxdb/partials/config.html'};
   }
 
   return {

+ 4 - 4
public/app/plugins/datasource/influxdb/partials/query.editor.html

@@ -16,15 +16,15 @@
 					</a>
 					<ul class="dropdown-menu pull-right" role="menu">
 						<li role="menuitem"><a tabindex="1" ng-click="toggleQueryMode()">Switch editor mode</a></li>
-						<li role="menuitem"><a tabindex="1" ng-click="duplicateDataQuery(target)">Duplicate</a></li>
-						<li role="menuitem"><a tabindex="1" ng-click="moveDataQuery($index, $index-1)">Move up</a></li>
-						<li role="menuitem"><a tabindex="1" ng-click="moveDataQuery($index, $index+1)">Move down</a></li>
+						<li role="menuitem"><a tabindex="1" ng-click="panelCtrl.duplicateDataQuery(target)">Duplicate</a></li>
+						<li role="menuitem"><a tabindex="1" ng-click="panelCtrl.moveDataQuery($index, $index-1)">Move up</a></li>
+						<li role="menuitem"><a tabindex="1" ng-click="panelCtrl.moveDataQuery($index, $index+1)">Move down</a></li>
 					</ul>
 				</div>
 			</li>
 
 			<li class="tight-form-item last">
-				<a class="pointer" tabindex="1" ng-click="removeDataQuery(target)">
+				<a class="pointer" tabindex="1" ng-click="panelCtrl.removeDataQuery(target)">
 					<i class="fa fa-remove"></i>
 				</a>
 			</li>

+ 9 - 8
public/app/plugins/datasource/influxdb/query_ctrl.js

@@ -16,6 +16,7 @@ function (angular, _, InfluxQueryBuilder, InfluxQuery, queryPart) {
 
   module.controller('InfluxQueryCtrl', function($scope, templateSrv, $q, uiSegmentSrv) {
     var panelCtrl = $scope.ctrl;
+    var datasource = $scope.datasource;
     $scope.panelCtrl = panelCtrl;
 
     $scope.init = function() {
@@ -23,7 +24,7 @@ function (angular, _, InfluxQueryBuilder, InfluxQuery, queryPart) {
 
       $scope.target = $scope.target;
       $scope.queryModel = new InfluxQuery($scope.target);
-      $scope.queryBuilder = new InfluxQueryBuilder($scope.target, panelCtrl.datasource.database);
+      $scope.queryBuilder = new InfluxQueryBuilder($scope.target, datasource.database);
       $scope.groupBySegment = uiSegmentSrv.newPlusButton();
       $scope.resultFormats = [
          {text: 'Time series', value: 'time_series'},
@@ -77,7 +78,7 @@ function (angular, _, InfluxQueryBuilder, InfluxQuery, queryPart) {
     $scope.getGroupByOptions = function() {
       var query = $scope.queryBuilder.buildExploreQuery('TAG_KEYS');
 
-      return panelCtrl.datasource.metricFindQuery(query)
+      return datasource.metricFindQuery(query)
       .then(function(tags) {
         var options = [];
         if (!$scope.queryModel.hasFill()) {
@@ -137,7 +138,7 @@ function (angular, _, InfluxQueryBuilder, InfluxQuery, queryPart) {
 
     $scope.getPolicySegments = function() {
       var policiesQuery = $scope.queryBuilder.buildExploreQuery('RETENTION POLICIES');
-      return panelCtrl.datasource.metricFindQuery(policiesQuery)
+      return datasource.metricFindQuery(policiesQuery)
       .then($scope.transformToSegments(false))
       .then(null, $scope.handleQueryError);
     };
@@ -153,19 +154,19 @@ function (angular, _, InfluxQueryBuilder, InfluxQuery, queryPart) {
 
     $scope.getMeasurements = function () {
       var query = $scope.queryBuilder.buildExploreQuery('MEASUREMENTS');
-      return panelCtrl.datasource.metricFindQuery(query)
+      return datasource.metricFindQuery(query)
       .then($scope.transformToSegments(true), $scope.handleQueryError);
     };
 
     $scope.getPartOptions = function(part) {
       if (part.def.type === 'field') {
         var fieldsQuery = $scope.queryBuilder.buildExploreQuery('FIELDS');
-        return panelCtrl.datasource.metricFindQuery(fieldsQuery)
+        return datasource.metricFindQuery(fieldsQuery)
         .then($scope.transformToSegments(true), $scope.handleQueryError);
       }
       if (part.def.type === 'tag') {
         var tagsQuery = $scope.queryBuilder.buildExploreQuery('TAG_KEYS');
-        return panelCtrl.datasource.metricFindQuery(tagsQuery)
+        return datasource.metricFindQuery(tagsQuery)
         .then($scope.transformToSegments(true), $scope.handleQueryError);
       }
     };
@@ -213,7 +214,7 @@ function (angular, _, InfluxQueryBuilder, InfluxQuery, queryPart) {
         addTemplateVars = true;
       }
 
-      return panelCtrl.datasource.metricFindQuery(query)
+      return datasource.metricFindQuery(query)
       .then($scope.transformToSegments(addTemplateVars))
       .then(function(results) {
         if (segment.type === 'key') {
@@ -226,7 +227,7 @@ function (angular, _, InfluxQueryBuilder, InfluxQuery, queryPart) {
 
     $scope.getFieldSegments = function() {
       var fieldsQuery = $scope.queryBuilder.buildExploreQuery('FIELDS');
-      return panelCtrl.datasource.metricFindQuery(fieldsQuery)
+      return datasource.metricFindQuery(fieldsQuery)
       .then($scope.transformToSegments(false))
       .then(null, $scope.handleQueryError);
     };

+ 1 - 1
public/app/plugins/datasource/influxdb/query_part_editor.js

@@ -14,7 +14,7 @@ function (angular, _, $) {
                           ' class="input-mini tight-form-func-param"></input>';
       return {
         restrict: 'E',
-        templateUrl: 'app/plugins/datasource/influxdb/partials/query_part.html',
+        templateUrl: 'public/app/plugins/datasource/influxdb/partials/query_part.html',
         scope: {
           part: "=",
           removeAction: "&",

+ 2 - 2
public/app/plugins/datasource/influxdb/specs/query_ctrl_specs.ts

@@ -15,6 +15,8 @@ describe('InfluxDBQueryCtrl', function() {
     ctx.$q = $q;
     ctx.scope = $rootScope.$new();
     ctx.scope.ctrl = {panel: ctx.panel};
+    ctx.scope.datasource = ctx.datasource;
+    ctx.scope.datasource.metricFindQuery = sinon.stub().returns(ctx.$q.when([]));
     ctx.panelCtrl = ctx.scope.ctrl;
     ctx.controller = $controller('InfluxQueryCtrl', {$scope: ctx.scope});
   }));
@@ -22,8 +24,6 @@ describe('InfluxDBQueryCtrl', function() {
   beforeEach(function() {
     ctx.scope.target = {};
     ctx.panelCtrl.refresh = sinon.spy();
-    ctx.panelCtrl.datasource = ctx.datasource;
-    ctx.panelCtrl.datasource.metricFindQuery = sinon.stub().returns(ctx.$q.when([]));
   });
 
   describe('init', function() {

+ 10 - 0
public/app/plugins/datasource/opentsdb/datasource.js

@@ -13,6 +13,8 @@ function (angular, _, dateMath) {
     this.type = 'opentsdb';
     this.url = instanceSettings.url;
     this.name = instanceSettings.name;
+    this.withCredentials = instanceSettings.withCredentials;
+    this.basicAuth = instanceSettings.basicAuth;
     this.supportMetrics = true;
 
     // Called once per panel (graph)
@@ -71,6 +73,14 @@ function (angular, _, dateMath) {
         url: this.url + '/api/query',
         data: reqBody
       };
+      if (this.basicAuth || this.withCredentials) {
+        options.withCredentials = true;
+      }
+      if (this.basicAuth) {
+        options.headers = {
+          "Authorization": this.basicAuth
+        };
+      }
 
       // In case the backend is 3rd-party hosted and does not suport OPTIONS, urlencoded requests
       // go as POST rather than OPTIONS+POST

+ 2 - 2
public/app/plugins/datasource/opentsdb/module.js

@@ -7,12 +7,12 @@ function (OpenTsDatasource) {
   function metricsQueryEditor() {
     return {
       controller: 'OpenTSDBQueryCtrl',
-      templateUrl: 'app/plugins/datasource/opentsdb/partials/query.editor.html',
+      templateUrl: 'public/app/plugins/datasource/opentsdb/partials/query.editor.html',
     };
   }
 
   function configView() {
-    return {templateUrl: 'app/plugins/datasource/opentsdb/partials/config.html'};
+    return {templateUrl: 'public/app/plugins/datasource/opentsdb/partials/config.html'};
   }
 
   return {

+ 5 - 6
public/app/plugins/datasource/opentsdb/partials/query.editor.html

@@ -9,15 +9,14 @@
 					<i class="fa fa-bars"></i>
 				</a>
 				<ul class="dropdown-menu pull-right" role="menu">
-					<li role="menuitem"><a tabindex="1" ng-click="toggleQueryMode()">Switch editor mode</a></li>
-					<li role="menuitem"><a tabindex="1" ng-click="duplicateDataQuery(target)">Duplicate</a></li>
-					<li role="menuitem"><a tabindex="1" ng-click="moveDataQuery($index, $index-1)">Move up</a></li>
-					<li role="menuitem"><a tabindex="1" ng-click="moveDataQuery($index, $index+1)">Move down</a></li>
+					<li role="menuitem"><a tabindex="1" ng-click="panelCtrl.duplicateDataQuery(target)">Duplicate</a></li>
+					<li role="menuitem"><a tabindex="1" ng-click="panelCtrl.moveDataQuery($index, $index-1)">Move up</a></li>
+					<li role="menuitem"><a tabindex="1" ng-click="panelCtrl.moveDataQuery($index, $index+1)">Move down</a></li>
 				</ul>
 			</div>
 		</li>
 		<li class="tight-form-item last">
-			<a class="pointer" tabindex="1" ng-click="removeDataQuery(target)">
+			<a class="pointer" tabindex="1" ng-click="panelCtrl.removeDataQuery(target)">
 				<i class="fa fa-remove"></i>
 			</a>
 		</li>
@@ -29,7 +28,7 @@
 		</li>
 		<li>
 			<a  class="tight-form-item"
-				ng-click="target.hide = !target.hide; get_data();"
+				ng-click="target.hide = !target.hide; panelCtrl.refresh();"
 				role="menuitem">
 				<i class="fa fa-eye"></i>
 			</a>

+ 1 - 0
public/app/plugins/datasource/opentsdb/queryCtrl.js

@@ -9,6 +9,7 @@ function (angular, _, kbn) {
   var module = angular.module('grafana.controllers');
 
   module.controller('OpenTSDBQueryCtrl', function($scope) {
+    $scope.panelCtrl = $scope.ctrl;
 
     $scope.init = function() {
       $scope.target.errors = validateTarget($scope.target);

+ 2 - 2
public/app/plugins/datasource/prometheus/module.js

@@ -5,11 +5,11 @@ function (PromDatasource) {
   'use strict';
 
   function metricsQueryEditor() {
-    return {controller: 'PrometheusQueryCtrl', templateUrl: 'app/plugins/datasource/prometheus/partials/query.editor.html'};
+    return {controller: 'PrometheusQueryCtrl', templateUrl: 'public/app/plugins/datasource/prometheus/partials/query.editor.html'};
   }
 
   function configView() {
-    return {templateUrl: 'app/plugins/datasource/prometheus/partials/config.html'};
+    return {templateUrl: 'public/app/plugins/datasource/prometheus/partials/config.html'};
   }
 
   return {

+ 5 - 6
public/app/plugins/datasource/prometheus/partials/query.editor.html

@@ -9,15 +9,14 @@
           <i class="fa fa-bars"></i>
         </a>
         <ul class="dropdown-menu pull-right" role="menu">
-          <li role="menuitem"><a tabindex="1" ng-click="toggleQueryMode()">Switch editor mode</a></li>
-          <li role="menuitem"><a tabindex="1" ng-click="duplicateDataQuery(target)">Duplicate</a></li>
-          <li role="menuitem"><a tabindex="1" ng-click="moveDataQuery($index, $index-1)">Move up</a></li>
-          <li role="menuitem"><a tabindex="1" ng-click="moveDataQuery($index, $index+1)">Move down</a></li>
+          <li role="menuitem"><a tabindex="1" ng-click="panelCtrl.duplicateDataQuery(target)">Duplicate</a></li>
+          <li role="menuitem"><a tabindex="1" ng-click="panelCtrl.moveDataQuery($index, $index-1)">Move up</a></li>
+          <li role="menuitem"><a tabindex="1" ng-click="panelCtrl.moveDataQuery($index, $index+1)">Move down</a></li>
         </ul>
       </div>
     </li>
     <li class="tight-form-item last">
-      <a class="pointer" tabindex="1" ng-click="removeDataQuery(target)">
+      <a class="pointer" tabindex="1" ng-click="panelCtr.removeDataQuery(target)">
         <i class="fa fa-remove"></i>
       </a>
     </li>
@@ -29,7 +28,7 @@
     </li>
     <li>
       <a  class="tight-form-item"
-          ng-click="target.hide = !target.hide; get_data();"
+          ng-click="target.hide = !target.hide; panelCtrl.refresh();"
           role="menuitem">
         <i class="fa fa-eye"></i>
       </a>

+ 3 - 1
public/app/plugins/datasource/prometheus/query_ctrl.js

@@ -8,6 +8,8 @@ function (angular, _) {
   var module = angular.module('grafana.controllers');
 
   module.controller('PrometheusQueryCtrl', function($scope, templateSrv) {
+    $scope.panelCtrl = $scope.ctrl;
+    $scope.panel = $scope.panelCtrl.panel;
 
     $scope.init = function() {
       var target = $scope.target;
@@ -29,7 +31,7 @@ function (angular, _) {
     $scope.refreshMetricData = function() {
       if (!_.isEqual($scope.oldTarget, $scope.target)) {
         $scope.oldTarget = angular.copy($scope.target);
-        $scope.get_data();
+        $scope.paneCtrl.refresh();
       }
     };
 

+ 1 - 1
public/app/plugins/panel/dashlist/module.ts

@@ -31,7 +31,7 @@ class DashListCtrl extends PanelCtrl {
     this.modes = ['starred', 'search'];
     this.icon = "fa fa-star";
     this.addEditorTab('Options', () => {
-      return {templateUrl: 'app/plugins/panel/dashlist/editor.html'};
+      return {templateUrl: 'public/app/plugins/panel/dashlist/editor.html'};
     });
   }
 

+ 1 - 1
public/app/plugins/panel/graph/legend.js

@@ -46,7 +46,7 @@ function (angular, _, $) {
           popoverScope.series = seriesInfo;
           popoverSrv.show({
             element: el,
-            templateUrl:  'app/plugins/panel/graph/legend.popover.html',
+            templateUrl:  'public/app/plugins/panel/graph/legend.popover.html',
             scope: popoverScope
           });
         }

+ 1 - 1
public/app/plugins/panel/graph/seriesOverridesCtrl.js

@@ -60,7 +60,7 @@ define([
       popoverSrv.show({
         element: $element.find(".dropdown"),
         placement: 'top',
-        templateUrl:  'app/partials/colorpicker.html',
+        templateUrl:  'public/app/partials/colorpicker.html',
         scope: popoverScope
       });
     };

+ 1 - 1
public/app/plugins/panel/singlestat/module.ts

@@ -7,7 +7,7 @@ import {SingleStatCtrl} from './controller';
 import {PanelDirective} from '../../../features/panel/panel';
 
 class SingleStatPanel extends PanelDirective {
-  templateUrl = 'app/plugins/panel/singlestat/module.html';
+  templateUrl = 'public/app/plugins/panel/singlestat/module.html';
   controller = SingleStatCtrl;
 
   /** @ngInject */

+ 0 - 3
public/app/plugins/panel/singlestat/specs/singlestat-specs.ts

@@ -2,9 +2,6 @@
 
 import {describe, beforeEach, it, sinon, expect, angularMocks} from '../../../../../test/lib/common';
 
-import 'app/features/panel/panel_srv';
-import 'app/features/panel/panel_helper';
-
 import angular from 'angular';
 import helpers from '../../../../../test/specs/helpers';
 import {SingleStatCtrl} from '../controller';

+ 1 - 1
public/app/plugins/panel/table/editor.ts

@@ -136,7 +136,7 @@ export function tablePanelEditor($q, uiSegmentSrv) {
   return {
     restrict: 'E',
     scope: true,
-    templateUrl: 'app/plugins/panel/table/editor.html',
+    templateUrl: 'public/app/plugins/panel/table/editor.html',
     controller: TablePanelEditorCtrl,
   };
 }

+ 1 - 1
public/app/plugins/panel/table/module.ts

@@ -10,7 +10,7 @@ import {TablePanelCtrl} from './controller';
 import {TableRenderer} from './renderer';
 
 class TablePanel extends PanelDirective {
-  templateUrl = 'app/plugins/panel/table/module.html';
+  templateUrl = 'public/app/plugins/panel/table/module.html';
   controller = TablePanelCtrl;
 
   link(scope, elem, attrs, ctrl) {

+ 1 - 1
public/app/plugins/panel/text/module.ts

@@ -78,7 +78,7 @@ export class TextPanelCtrl extends PanelCtrl {
 }
 
 class TextPanel extends PanelDirective {
-  templateUrl = `app/plugins/panel/text/module.html`;
+  templateUrl = `public/app/plugins/panel/text/module.html`;
   controller = TextPanelCtrl;
 }
 

+ 1 - 1
public/app/plugins/panel/unknown/module.html

@@ -1,5 +1,5 @@
 <div class="text-center" style="padding-top: 2rem">
 	Unknown panel type: <strong>{{ctrl.panel.type}}</strong>
-</div
+</div>
 
 

+ 1 - 1
public/app/plugins/plugin_api.md

@@ -37,7 +37,7 @@ Example:
 
 ```javascript
 function metricsQueryEditor() {
-  return {controller: 'ElasticQueryCtrl', templateUrl: 'app/plugins/datasource/elasticsearch/partials/query.editor.html'};
+  return {controller: 'ElasticQueryCtrl', templateUrl: 'public/app/plugins/datasource/elasticsearch/partials/query.editor.html'};
 }
 ```
 

+ 4 - 3
public/dashboards/home.json

@@ -12,10 +12,10 @@
     {
       "collapse": false,
       "editable": true,
-      "height": "100px",
+      "height": "90px",
       "panels": [
         {
-          "content": "<div class=\"text-center dashboard-header\">\nHome Dashboard\n</div>",
+          "content": "<div class=\"text-center dashboard-header\">\n  <span>Home Dashboard</span>\n</div>",
           "editable": true,
           "id": 1,
           "mode": "html",
@@ -23,7 +23,8 @@
           "style": {},
           "title": "",
           "transparent": true,
-          "type": "text"
+          "type": "text",
+          "links": []
         }
       ],
       "title": "New row"

+ 9 - 6
public/less/grafana.less

@@ -391,12 +391,15 @@
 }
 
 .dashboard-header {
-  margin-top: 1rem;
   font-family: "grafana-icons";
   font-size: 22px;
-  padding-bottom: 1rem;
-  border: none;
-  border-bottom: 2px solid transparent;
-  border-image: linear-gradient(to right, rgba(255,213,0,1) 0%, rgba(255,68,0,1) 99%, rgba(255,68,0,1) 100%);
-  border-image-slice: 1;
+  text-align: center;
+  span {
+    display: inline-block;
+    border: none;
+    border-image: linear-gradient(to right, rgba(255,213,0,1) 0%, rgba(255,68,0,1) 99%, rgba(255,68,0,1) 100%);
+    border-image-slice: 1;
+    border-bottom: 2px solid transparent;
+    padding: 1.2rem 3rem 0.8rem 3rem;
+  }
 }

+ 11 - 3
public/less/login.less

@@ -9,15 +9,23 @@
 
 .login-box {
   width: 700px;
-  margin: 100px auto 0 auto;
+  margin: 70px auto 0 auto;
 }
 
 .login-box-logo {
   text-align: center;
-  padding-bottom: 50px;
+  img {
+    width: 125px;
+  }
+  .icon-gf-grafana_wordmark {
+    color: @linkColor;
+    position: relative;
+    top: -90px;
+    font-size: 3rem;
+    text-shadow: 3px 3px 5px black;
+  }
 }
 
-
 .login-inner-box {
   background: @grafanaPanelBackground;
 }

+ 1 - 1
public/less/timepicker.less

@@ -7,7 +7,7 @@
 }
 
 .gf-timepicker-dropdown {
-  margin: -5px -10px;
+  margin: -5px -10px 10px 5px;
   padding: 10px 20px;
   float: right;
   background-color: @grafanaPanelBackground;

+ 0 - 40
public/test/specs/panelSrv-specs.js

@@ -1,40 +0,0 @@
-define([
-  './helpers',
-  'app/features/panel/panel_srv',
-], function() {
-  'use strict';
-
-  describe('PanelSrv', function() {
-    var _panelSrv;
-    var _panelScope;
-    var _datasourceSrvStub;
-
-    beforeEach(module('grafana.services'));
-    beforeEach(module(function($provide) {
-      _datasourceSrvStub = {
-        getMetricSources: sinon.spy(),
-      };
-      $provide.value('datasourceSrv', _datasourceSrvStub);
-    }));
-
-    beforeEach(inject(function(panelSrv, $rootScope) {
-      _panelSrv = panelSrv;
-      _panelScope = $rootScope.$new();
-      _panelScope.panel = {
-        targets: [],
-      };
-      _panelScope.dashboardViewState = {
-        registerPanel: sinon.spy(),
-      };
-    }));
-
-    describe('init', function() {
-      beforeEach(function() {
-        _panelSrv.init(_panelScope);
-      });
-
-    });
-  });
-
-});
-

+ 1 - 0
tasks/options/ngtemplates.js

@@ -5,6 +5,7 @@ module.exports = function(config) {
       src:  ['app/**/*.html'],
       dest: '<%= genDir %>/app/core/partials.js',
       options: {
+        prefix: 'public/',
         bootstrap: function(module, script) {
           return "define('app/core/partials', ['app/core/core_module'], function(coreModule) { \n" +
             "coreModule.default.run(['$templateCache', function($templateCache) { \n" +