Przeglądaj źródła

Add a @grafana/runtime package with backendSrv interface (#16533)

grafana-runtime/tsconfig.json imports query to avoid a build error  ¯\_(ツ)_/¯
Ryan McKinley 6 lat temu
rodzic
commit
96ba32d0c8
46 zmienionych plików z 255 dodań i 74 usunięć
  1. 3 0
      packages/grafana-runtime/README.md
  2. 7 0
      packages/grafana-runtime/index.js
  3. 37 0
      packages/grafana-runtime/package.json
  4. 50 0
      packages/grafana-runtime/rollup.config.ts
  5. 1 0
      packages/grafana-runtime/src/index.ts
  6. 19 0
      packages/grafana-runtime/src/services/AngularLoader.ts
  7. 42 0
      packages/grafana-runtime/src/services/backendSrv.ts
  8. 15 0
      packages/grafana-runtime/src/services/dataSourceSrv.ts
  9. 3 0
      packages/grafana-runtime/src/services/index.ts
  10. 4 0
      packages/grafana-runtime/tsconfig.build.json
  11. 19 0
      packages/grafana-runtime/tsconfig.json
  12. 6 0
      packages/grafana-runtime/tslint.json
  13. 1 1
      packages/grafana-ui/tslint.json
  14. 1 1
      public/app/core/components/PluginHelp/PluginHelp.tsx
  15. 2 2
      public/app/core/components/SharedPreferences/SharedPreferences.tsx
  16. 3 18
      public/app/core/services/AngularLoader.ts
  17. 5 13
      public/app/core/services/backend_srv.ts
  18. 1 1
      public/app/features/admin/state/apis.ts
  19. 1 1
      public/app/features/alerting/AlertTab.tsx
  20. 1 1
      public/app/features/alerting/StateHistory.tsx
  21. 1 1
      public/app/features/alerting/TestRuleResult.tsx
  22. 1 1
      public/app/features/alerting/state/actions.ts
  23. 1 1
      public/app/features/dashboard/components/DashNav/DashNav.tsx
  24. 1 1
      public/app/features/dashboard/components/DashboardSettings/DashboardSettings.tsx
  25. 1 1
      public/app/features/dashboard/components/SubMenu/SubMenu.tsx
  26. 1 1
      public/app/features/dashboard/dashgrid/DashboardPanel.tsx
  27. 1 1
      public/app/features/dashboard/panel_editor/GeneralTab.tsx
  28. 1 1
      public/app/features/dashboard/panel_editor/PanelEditor.tsx
  29. 1 1
      public/app/features/dashboard/panel_editor/QueryEditorRow.tsx
  30. 1 1
      public/app/features/dashboard/panel_editor/VisualizationTab.tsx
  31. 1 1
      public/app/features/dashboard/state/actions.ts
  32. 1 1
      public/app/features/datasources/settings/PluginSettings.tsx
  33. 1 1
      public/app/features/datasources/state/actions.ts
  34. 1 1
      public/app/features/explore/QueryEditor.tsx
  35. 1 1
      public/app/features/org/state/actions.ts
  36. 3 8
      public/app/features/plugins/datasource_srv.ts
  37. 2 0
      public/app/features/plugins/plugin_loader.ts
  38. 1 1
      public/app/features/plugins/state/actions.ts
  39. 1 1
      public/app/features/plugins/wrappers/AppConfigWrapper.tsx
  40. 1 1
      public/app/features/teams/state/actions.ts
  41. 1 1
      public/app/features/users/state/actions.ts
  42. 1 1
      public/app/plugins/datasource/prometheus/specs/completer.test.ts
  43. 1 1
      public/app/plugins/datasource/stackdriver/components/Filter.tsx
  44. 2 2
      public/app/plugins/datasource/testdata/QueryEditor.tsx
  45. 4 4
      public/app/routes/GrafanaCtrl.ts
  46. 2 1
      scripts/grunt/default_task.js

+ 3 - 0
packages/grafana-runtime/README.md

@@ -0,0 +1,3 @@
+# Grafana Runtime library
+
+Interfaces that let you use the runtime...

+ 7 - 0
packages/grafana-runtime/index.js

@@ -0,0 +1,7 @@
+'use strict'
+
+if (process.env.NODE_ENV === 'production') {
+  module.exports = require('./index.production.js');
+} else {
+  module.exports = require('./index.development.js');
+}

+ 37 - 0
packages/grafana-runtime/package.json

@@ -0,0 +1,37 @@
+{
+  "name": "@grafana/runtime",
+  "version": "6.0.1-alpha.0",
+  "description": "Grafana Runtime Library",
+  "keywords": [
+    "typescript",
+    "react",
+    "react-component"
+  ],
+  "main": "src/index.ts",
+  "scripts": {
+    "tslint": "tslint -c tslint.json --project tsconfig.json",
+    "typecheck": "tsc --noEmit",
+    "clean": "rimraf ./dist ./compiled",
+    "build": "rollup -c rollup.config.ts"
+  },
+  "author": "Grafana Labs",
+  "license": "Apache-2.0",
+  "dependencies": {
+  },
+  "devDependencies": {
+    "awesome-typescript-loader": "^5.2.1",
+    "lodash": "^4.17.10",
+    "pretty-format": "^24.5.0",
+    "rollup": "1.6.0",
+    "rollup-plugin-commonjs": "9.2.1",
+    "rollup-plugin-node-resolve": "4.0.1",
+    "rollup-plugin-sourcemaps": "0.4.2",
+    "rollup-plugin-terser": "4.0.4",
+    "rollup-plugin-typescript2": "0.19.3",
+    "rollup-plugin-visualizer": "0.9.2",
+    "typescript": "3.4.1"
+  },
+  "resolutions": {
+    "@types/lodash": "4.14.119"
+  }
+}

+ 50 - 0
packages/grafana-runtime/rollup.config.ts

@@ -0,0 +1,50 @@
+import resolve from 'rollup-plugin-node-resolve';
+import commonjs from 'rollup-plugin-commonjs';
+import sourceMaps from 'rollup-plugin-sourcemaps';
+import { terser } from 'rollup-plugin-terser';
+
+const pkg = require('./package.json');
+
+const libraryName = pkg.name;
+
+const buildCjsPackage = ({ env }) => {
+  return {
+    input: `compiled/index.js`,
+    output: [
+      {
+        file: `dist/index.${env}.js`,
+        name: libraryName,
+        format: 'cjs',
+        sourcemap: true,
+        exports: 'named',
+        globals: {},
+      },
+    ],
+    external: ['lodash'], // Use Lodash from grafana
+    plugins: [
+      commonjs({
+        include: /node_modules/,
+        namedExports: {
+          '../../node_modules/lodash/lodash.js': [
+            'flatten',
+            'find',
+            'upperFirst',
+            'debounce',
+            'isNil',
+            'isNumber',
+            'flattenDeep',
+            'map',
+            'chunk',
+            'sortBy',
+            'uniqueId',
+            'zip',
+          ],
+        },
+      }),
+      resolve(),
+      sourceMaps(),
+      env === 'production' && terser(),
+    ],
+  };
+};
+export default [buildCjsPackage({ env: 'development' }), buildCjsPackage({ env: 'production' })];

+ 1 - 0
packages/grafana-runtime/src/index.ts

@@ -0,0 +1 @@
+export * from './services';

+ 19 - 0
packages/grafana-runtime/src/services/AngularLoader.ts

@@ -0,0 +1,19 @@
+export interface AngularComponent {
+  destroy(): void;
+  digest(): void;
+  getScope(): any;
+}
+
+export interface AngularLoader {
+  load(elem: any, scopeProps: any, template: string): AngularComponent;
+}
+
+let instance: AngularLoader;
+
+export function setAngularLoader(v: AngularLoader) {
+  instance = v;
+}
+
+export function getAngularLoader(): AngularLoader {
+  return instance;
+}

+ 42 - 0
packages/grafana-runtime/src/services/backendSrv.ts

@@ -0,0 +1,42 @@
+/**
+ * Currently implemented with:
+ * https://docs.angularjs.org/api/ng/service/$http#usage
+ * but that will likely change in the future
+ */
+export type BackendSrvRequest = {
+  url: string;
+  retry?: number;
+  headers?: any;
+  method?: string;
+
+  // Show a message with the result
+  showSuccessAlert?: boolean;
+
+  [key: string]: any;
+};
+
+export interface BackendSrv {
+  get(url: string, params?: any): Promise<any>;
+
+  delete(url: string): Promise<any>;
+
+  post(url: string, data: any): Promise<any>;
+
+  patch(url: string, data: any): Promise<any>;
+
+  put(url: string, data: any): Promise<any>;
+
+  // If there is an error, set: err.isHandled = true
+  // otherwise the backend will show a message for you
+  request(options: BackendSrvRequest): Promise<any>;
+}
+
+let singletonInstance: BackendSrv;
+
+export function setBackendSrv(instance: BackendSrv) {
+  singletonInstance = instance;
+}
+
+export function getBackendSrv(): BackendSrv {
+  return singletonInstance;
+}

+ 15 - 0
packages/grafana-runtime/src/services/dataSourceSrv.ts

@@ -0,0 +1,15 @@
+import { ScopedVars, DataSourceApi } from '@grafana/ui';
+
+export interface DataSourceSrv {
+  get(name?: string, scopedVars?: ScopedVars): Promise<DataSourceApi>;
+}
+
+let singletonInstance: DataSourceSrv;
+
+export function setDataSourceSrv(instance: DataSourceSrv) {
+  singletonInstance = instance;
+}
+
+export function getDataSourceSrv(): DataSourceSrv {
+  return singletonInstance;
+}

+ 3 - 0
packages/grafana-runtime/src/services/index.ts

@@ -0,0 +1,3 @@
+export * from './backendSrv';
+export * from './AngularLoader';
+export * from './dataSourceSrv';

+ 4 - 0
packages/grafana-runtime/tsconfig.build.json

@@ -0,0 +1,4 @@
+{
+  "extends": "./tsconfig.json",
+  "exclude": ["dist", "node_modules", "**/*.test.ts", "**/*.test.tsx"]
+}

+ 19 - 0
packages/grafana-runtime/tsconfig.json

@@ -0,0 +1,19 @@
+{
+  "extends": "../../tsconfig.json",
+  "include": ["src/**/*.ts", "src/**/*.tsx", "../../public/app/types/jquery/*.ts"],
+  "exclude": ["dist", "node_modules"],
+  "compilerOptions": {
+    "rootDirs": ["."],
+    "module": "esnext",
+    "outDir": "compiled",
+    "declaration": true,
+    "declarationDir": "dist",
+    "strict": true,
+    "alwaysStrict": true,
+    "noImplicitAny": true,
+    "strictNullChecks": true,
+    "typeRoots": ["./node_modules/@types", "types"],
+    "skipLibCheck": true, // Temp workaround for Duplicate identifier tsc errors,
+    "removeComments": false
+  }
+}

+ 6 - 0
packages/grafana-runtime/tslint.json

@@ -0,0 +1,6 @@
+{
+  "extends": "../../tslint.json",
+  "rules": {
+    "import-blacklist": [true, ["^@grafana/runtime.*"]]
+  }
+}

+ 1 - 1
packages/grafana-ui/tslint.json

@@ -1,6 +1,6 @@
 {
 {
   "extends": "../../tslint.json",
   "extends": "../../tslint.json",
   "rules": {
   "rules": {
-    "import-blacklist": [true, "moment", ["^@grafana/ui.*"]]
+    "import-blacklist": [true, "moment", ["^@grafana/ui.*"], ["^@grafana/runtime.*"]]
   }
   }
 }
 }

+ 1 - 1
public/app/core/components/PluginHelp/PluginHelp.tsx

@@ -1,7 +1,7 @@
 import React, { PureComponent } from 'react';
 import React, { PureComponent } from 'react';
 // @ts-ignore
 // @ts-ignore
 import Remarkable from 'remarkable';
 import Remarkable from 'remarkable';
-import { getBackendSrv } from '../../services/backend_srv';
+import { getBackendSrv } from '@grafana/runtime';
 
 
 interface Props {
 interface Props {
   plugin: {
   plugin: {

+ 2 - 2
public/app/core/components/SharedPreferences/SharedPreferences.tsx

@@ -1,9 +1,9 @@
 import React, { PureComponent } from 'react';
 import React, { PureComponent } from 'react';
 
 
 import { FormLabel, Select } from '@grafana/ui';
 import { FormLabel, Select } from '@grafana/ui';
-import { getBackendSrv, BackendSrv } from 'app/core/services/backend_srv';
 
 
 import { DashboardSearchHit, DashboardSearchHitType } from 'app/types';
 import { DashboardSearchHit, DashboardSearchHitType } from 'app/types';
+import { getBackendSrv } from 'app/core/services/backend_srv';
 
 
 export interface Props {
 export interface Props {
   resourceUri: string;
   resourceUri: string;
@@ -25,7 +25,7 @@ const timezones = [
 ];
 ];
 
 
 export class SharedPreferences extends PureComponent<Props, State> {
 export class SharedPreferences extends PureComponent<Props, State> {
-  backendSrv: BackendSrv = getBackendSrv();
+  backendSrv = getBackendSrv();
 
 
   constructor(props: Props) {
   constructor(props: Props) {
     super(props);
     super(props);

+ 3 - 18
public/app/core/services/AngularLoader.ts

@@ -2,13 +2,9 @@ import angular from 'angular';
 import coreModule from 'app/core/core_module';
 import coreModule from 'app/core/core_module';
 import _ from 'lodash';
 import _ from 'lodash';
 
 
-export interface AngularComponent {
-  destroy(): void;
-  digest(): void;
-  getScope(): any;
-}
+import { AngularComponent, AngularLoader } from '@grafana/runtime';
 
 
-export class AngularLoader {
+export class AngularLoaderClass implements AngularLoader {
   /** @ngInject */
   /** @ngInject */
   constructor(private $compile: any, private $rootScope: any) {}
   constructor(private $compile: any, private $rootScope: any) {}
 
 
@@ -38,15 +34,4 @@ export class AngularLoader {
   }
   }
 }
 }
 
 
-coreModule.service('angularLoader', AngularLoader);
-
-let angularLoaderInstance: AngularLoader;
-
-export function setAngularLoader(pl: AngularLoader) {
-  angularLoaderInstance = pl;
-}
-
-// away to access it from react
-export function getAngularLoader(): AngularLoader {
-  return angularLoaderInstance;
-}
+coreModule.service('angularLoader', AngularLoaderClass);

+ 5 - 13
public/app/core/services/backend_srv.ts

@@ -7,8 +7,9 @@ import { DashboardModel } from 'app/features/dashboard/state/DashboardModel';
 import { DashboardSearchHit } from 'app/types/search';
 import { DashboardSearchHit } from 'app/types/search';
 import { ContextSrv } from './context_srv';
 import { ContextSrv } from './context_srv';
 import { FolderInfo, DashboardDTO } from 'app/types';
 import { FolderInfo, DashboardDTO } from 'app/types';
+import { BackendSrv as BackendService, getBackendSrv as getBackendService, BackendSrvRequest } from '@grafana/runtime';
 
 
-export class BackendSrv {
+export class BackendSrv implements BackendService {
   private inFlightRequests: { [key: string]: Array<angular.IDeferred<any>> } = {};
   private inFlightRequests: { [key: string]: Array<angular.IDeferred<any>> } = {};
   private HTTP_REQUEST_CANCELED = -1;
   private HTTP_REQUEST_CANCELED = -1;
   private noBackendCache: boolean;
   private noBackendCache: boolean;
@@ -83,7 +84,7 @@ export class BackendSrv {
     throw data;
     throw data;
   }
   }
 
 
-  request(options: any) {
+  request(options: BackendSrvRequest) {
     options.retry = options.retry || 0;
     options.retry = options.retry || 0;
     const requestIsLocal = !options.url.match(/^http/);
     const requestIsLocal = !options.url.match(/^http/);
     const firstAttempt = options.retry === 0;
     const firstAttempt = options.retry === 0;
@@ -385,16 +386,7 @@ export class BackendSrv {
 
 
 coreModule.service('backendSrv', BackendSrv);
 coreModule.service('backendSrv', BackendSrv);
 
 
-//
-// Code below is to expore the service to react components
-//
-
-let singletonInstance: BackendSrv;
-
-export function setBackendSrv(instance: BackendSrv) {
-  singletonInstance = instance;
-}
-
+// Used for testing and things that really need BackendSrv
 export function getBackendSrv(): BackendSrv {
 export function getBackendSrv(): BackendSrv {
-  return singletonInstance;
+  return getBackendService() as BackendSrv;
 }
 }

+ 1 - 1
public/app/features/admin/state/apis.ts

@@ -1,4 +1,4 @@
-import { getBackendSrv } from 'app/core/services/backend_srv';
+import { getBackendSrv } from '@grafana/runtime';
 
 
 export interface ServerStat {
 export interface ServerStat {
   name: string;
   name: string;

+ 1 - 1
public/app/features/alerting/AlertTab.tsx

@@ -2,7 +2,7 @@
 import React, { PureComponent } from 'react';
 import React, { PureComponent } from 'react';
 
 
 // Services & Utils
 // Services & Utils
-import { AngularComponent, getAngularLoader } from 'app/core/services/AngularLoader';
+import { AngularComponent, getAngularLoader } from '@grafana/runtime';
 import appEvents from 'app/core/app_events';
 import appEvents from 'app/core/app_events';
 
 
 // Components
 // Components

+ 1 - 1
public/app/features/alerting/StateHistory.tsx

@@ -1,6 +1,6 @@
 import React, { PureComponent } from 'react';
 import React, { PureComponent } from 'react';
 import alertDef from './state/alertDef';
 import alertDef from './state/alertDef';
-import { getBackendSrv } from 'app/core/services/backend_srv';
+import { getBackendSrv } from '@grafana/runtime';
 import { DashboardModel } from '../dashboard/state/DashboardModel';
 import { DashboardModel } from '../dashboard/state/DashboardModel';
 import appEvents from '../../core/app_events';
 import appEvents from '../../core/app_events';
 
 

+ 1 - 1
public/app/features/alerting/TestRuleResult.tsx

@@ -1,6 +1,6 @@
 import React, { PureComponent } from 'react';
 import React, { PureComponent } from 'react';
 import { JSONFormatter } from 'app/core/components/JSONFormatter/JSONFormatter';
 import { JSONFormatter } from 'app/core/components/JSONFormatter/JSONFormatter';
-import { getBackendSrv } from 'app/core/services/backend_srv';
+import { getBackendSrv } from '@grafana/runtime';
 import { DashboardModel } from '../dashboard/state/DashboardModel';
 import { DashboardModel } from '../dashboard/state/DashboardModel';
 import { LoadingPlaceholder } from '@grafana/ui/src';
 import { LoadingPlaceholder } from '@grafana/ui/src';
 
 

+ 1 - 1
public/app/features/alerting/state/actions.ts

@@ -1,4 +1,4 @@
-import { getBackendSrv } from 'app/core/services/backend_srv';
+import { getBackendSrv } from '@grafana/runtime';
 import { AlertRuleDTO, StoreState } from 'app/types';
 import { AlertRuleDTO, StoreState } from 'app/types';
 import { ThunkAction } from 'redux-thunk';
 import { ThunkAction } from 'redux-thunk';
 
 

+ 1 - 1
public/app/features/dashboard/components/DashNav/DashNav.tsx

@@ -3,7 +3,7 @@ import React, { PureComponent } from 'react';
 import { connect } from 'react-redux';
 import { connect } from 'react-redux';
 
 
 // Utils & Services
 // Utils & Services
-import { AngularComponent, getAngularLoader } from 'app/core/services/AngularLoader';
+import { AngularComponent, getAngularLoader } from '@grafana/runtime';
 import { appEvents } from 'app/core/app_events';
 import { appEvents } from 'app/core/app_events';
 import { PlaylistSrv } from 'app/features/playlist/playlist_srv';
 import { PlaylistSrv } from 'app/features/playlist/playlist_srv';
 
 

+ 1 - 1
public/app/features/dashboard/components/DashboardSettings/DashboardSettings.tsx

@@ -2,7 +2,7 @@
 import React, { PureComponent } from 'react';
 import React, { PureComponent } from 'react';
 
 
 // Utils & Services
 // Utils & Services
-import { AngularComponent, getAngularLoader } from 'app/core/services/AngularLoader';
+import { AngularComponent, getAngularLoader } from '@grafana/runtime';
 
 
 // Types
 // Types
 import { DashboardModel } from '../../state/DashboardModel';
 import { DashboardModel } from '../../state/DashboardModel';

+ 1 - 1
public/app/features/dashboard/components/SubMenu/SubMenu.tsx

@@ -2,7 +2,7 @@
 import React, { PureComponent } from 'react';
 import React, { PureComponent } from 'react';
 
 
 // Utils & Services
 // Utils & Services
-import { AngularComponent, getAngularLoader } from 'app/core/services/AngularLoader';
+import { AngularComponent, getAngularLoader } from '@grafana/runtime';
 
 
 // Types
 // Types
 import { DashboardModel } from '../../state/DashboardModel';
 import { DashboardModel } from '../../state/DashboardModel';

+ 1 - 1
public/app/features/dashboard/dashgrid/DashboardPanel.tsx

@@ -3,7 +3,7 @@ import React, { PureComponent } from 'react';
 import classNames from 'classnames';
 import classNames from 'classnames';
 
 
 // Utils & Services
 // Utils & Services
-import { getAngularLoader, AngularComponent } from 'app/core/services/AngularLoader';
+import { getAngularLoader, AngularComponent } from '@grafana/runtime';
 import { importPanelPlugin } from 'app/features/plugins/plugin_loader';
 import { importPanelPlugin } from 'app/features/plugins/plugin_loader';
 
 
 // Components
 // Components

+ 1 - 1
public/app/features/dashboard/panel_editor/GeneralTab.tsx

@@ -1,6 +1,6 @@
 import React, { PureComponent } from 'react';
 import React, { PureComponent } from 'react';
 
 
-import { getAngularLoader, AngularComponent } from 'app/core/services/AngularLoader';
+import { getAngularLoader, AngularComponent } from '@grafana/runtime';
 import { EditorTabBody } from './EditorTabBody';
 import { EditorTabBody } from './EditorTabBody';
 
 
 import { PanelModel } from '../state/PanelModel';
 import { PanelModel } from '../state/PanelModel';

+ 1 - 1
public/app/features/dashboard/panel_editor/PanelEditor.tsx

@@ -9,7 +9,7 @@ import { AlertTab } from '../../alerting/AlertTab';
 import config from 'app/core/config';
 import config from 'app/core/config';
 import { store } from 'app/store/store';
 import { store } from 'app/store/store';
 import { updateLocation } from 'app/core/actions';
 import { updateLocation } from 'app/core/actions';
-import { AngularComponent } from 'app/core/services/AngularLoader';
+import { AngularComponent } from '@grafana/runtime';
 
 
 import { PanelModel } from '../state/PanelModel';
 import { PanelModel } from '../state/PanelModel';
 import { DashboardModel } from '../state/DashboardModel';
 import { DashboardModel } from '../state/DashboardModel';

+ 1 - 1
public/app/features/dashboard/panel_editor/QueryEditorRow.tsx

@@ -5,7 +5,7 @@ import _ from 'lodash';
 
 
 // Utils & Services
 // Utils & Services
 import { getDatasourceSrv } from 'app/features/plugins/datasource_srv';
 import { getDatasourceSrv } from 'app/features/plugins/datasource_srv';
-import { AngularComponent, getAngularLoader } from 'app/core/services/AngularLoader';
+import { AngularComponent, getAngularLoader } from '@grafana/runtime';
 import { Emitter } from 'app/core/utils/emitter';
 import { Emitter } from 'app/core/utils/emitter';
 import { getTimeSrv } from 'app/features/dashboard/services/TimeSrv';
 import { getTimeSrv } from 'app/features/dashboard/services/TimeSrv';
 
 

+ 1 - 1
public/app/features/dashboard/panel_editor/VisualizationTab.tsx

@@ -2,7 +2,7 @@
 import React, { PureComponent } from 'react';
 import React, { PureComponent } from 'react';
 
 
 // Utils & Services
 // Utils & Services
-import { AngularComponent, getAngularLoader } from 'app/core/services/AngularLoader';
+import { AngularComponent, getAngularLoader } from '@grafana/runtime';
 import { connectWithStore } from 'app/core/utils/connectWithReduxStore';
 import { connectWithStore } from 'app/core/utils/connectWithReduxStore';
 import { StoreState } from 'app/types';
 import { StoreState } from 'app/types';
 import { updateLocation } from 'app/core/actions';
 import { updateLocation } from 'app/core/actions';

+ 1 - 1
public/app/features/dashboard/state/actions.ts

@@ -1,5 +1,5 @@
 // Services & Utils
 // Services & Utils
-import { getBackendSrv } from 'app/core/services/backend_srv';
+import { getBackendSrv } from '@grafana/runtime';
 import { actionCreatorFactory, noPayloadActionCreatorFactory } from 'app/core/redux';
 import { actionCreatorFactory, noPayloadActionCreatorFactory } from 'app/core/redux';
 import { createSuccessNotification } from 'app/core/copy/appNotification';
 import { createSuccessNotification } from 'app/core/copy/appNotification';
 
 

+ 1 - 1
public/app/features/datasources/settings/PluginSettings.tsx

@@ -8,7 +8,7 @@ import {
   DataQuery,
   DataQuery,
   DataSourceJsonData,
   DataSourceJsonData,
 } from '@grafana/ui';
 } from '@grafana/ui';
-import { getAngularLoader, AngularComponent } from 'app/core/services/AngularLoader';
+import { getAngularLoader, AngularComponent } from '@grafana/runtime';
 
 
 export type GenericDataSourcePlugin = DataSourcePlugin<DataSourceApi<DataQuery, DataSourceJsonData>>;
 export type GenericDataSourcePlugin = DataSourcePlugin<DataSourceApi<DataQuery, DataSourceJsonData>>;
 
 

+ 1 - 1
public/app/features/datasources/state/actions.ts

@@ -1,6 +1,6 @@
 import { ThunkAction } from 'redux-thunk';
 import { ThunkAction } from 'redux-thunk';
 import config from '../../../core/config';
 import config from '../../../core/config';
-import { getBackendSrv } from 'app/core/services/backend_srv';
+import { getBackendSrv } from '@grafana/runtime';
 import { getDatasourceSrv } from 'app/features/plugins/datasource_srv';
 import { getDatasourceSrv } from 'app/features/plugins/datasource_srv';
 import { LayoutMode } from 'app/core/components/LayoutSelector/LayoutSelector';
 import { LayoutMode } from 'app/core/components/LayoutSelector/LayoutSelector';
 import { updateLocation, updateNavIndex, UpdateNavIndexAction } from 'app/core/actions';
 import { updateLocation, updateNavIndex, UpdateNavIndexAction } from 'app/core/actions';

+ 1 - 1
public/app/features/explore/QueryEditor.tsx

@@ -2,7 +2,7 @@
 import React, { PureComponent } from 'react';
 import React, { PureComponent } from 'react';
 
 
 // Services
 // Services
-import { getAngularLoader, AngularComponent } from 'app/core/services/AngularLoader';
+import { getAngularLoader, AngularComponent } from '@grafana/runtime';
 import { getTimeSrv } from 'app/features/dashboard/services/TimeSrv';
 import { getTimeSrv } from 'app/features/dashboard/services/TimeSrv';
 
 
 // Types
 // Types

+ 1 - 1
public/app/features/org/state/actions.ts

@@ -1,5 +1,5 @@
 import { Organization, ThunkResult } from 'app/types';
 import { Organization, ThunkResult } from 'app/types';
-import { getBackendSrv } from 'app/core/services/backend_srv';
+import { getBackendSrv } from '@grafana/runtime';
 
 
 export enum ActionTypes {
 export enum ActionTypes {
   LoadOrganization = 'LOAD_ORGANIZATION',
   LoadOrganization = 'LOAD_ORGANIZATION',

+ 3 - 8
public/app/features/plugins/datasource_srv.ts

@@ -5,11 +5,12 @@ import coreModule from 'app/core/core_module';
 // Services & Utils
 // Services & Utils
 import config from 'app/core/config';
 import config from 'app/core/config';
 import { importDataSourcePlugin } from './plugin_loader';
 import { importDataSourcePlugin } from './plugin_loader';
+import { DataSourceSrv as DataSourceService, getDataSourceSrv as getDataSourceService } from '@grafana/runtime';
 
 
 // Types
 // Types
 import { DataSourceApi, DataSourceSelectItem, ScopedVars } from '@grafana/ui/src/types';
 import { DataSourceApi, DataSourceSelectItem, ScopedVars } from '@grafana/ui/src/types';
 
 
-export class DatasourceSrv {
+export class DatasourceSrv implements DataSourceService {
   datasources: { [name: string]: DataSourceApi };
   datasources: { [name: string]: DataSourceApi };
 
 
   /** @ngInject */
   /** @ngInject */
@@ -175,14 +176,8 @@ export class DatasourceSrv {
   }
   }
 }
 }
 
 
-let singleton: DatasourceSrv;
-
-export function setDatasourceSrv(srv: DatasourceSrv) {
-  singleton = srv;
-}
-
 export function getDatasourceSrv(): DatasourceSrv {
 export function getDatasourceSrv(): DatasourceSrv {
-  return singleton;
+  return getDataSourceService() as DatasourceSrv;
 }
 }
 
 
 coreModule.service('datasourceSrv', DatasourceSrv);
 coreModule.service('datasourceSrv', DatasourceSrv);

+ 2 - 0
public/app/features/plugins/plugin_loader.ts

@@ -29,6 +29,7 @@ import impressionSrv from 'app/core/services/impression_srv';
 import builtInPlugins from './built_in_plugins';
 import builtInPlugins from './built_in_plugins';
 import * as d3 from 'd3';
 import * as d3 from 'd3';
 import * as grafanaUI from '@grafana/ui';
 import * as grafanaUI from '@grafana/ui';
+import * as grafanaRT from '@grafana/runtime';
 
 
 // rxjs
 // rxjs
 import { Observable, Subject } from 'rxjs';
 import { Observable, Subject } from 'rxjs';
@@ -68,6 +69,7 @@ function exposeToPlugin(name: string, component: any) {
 }
 }
 
 
 exposeToPlugin('@grafana/ui', grafanaUI);
 exposeToPlugin('@grafana/ui', grafanaUI);
+exposeToPlugin('@grafana/runtime', grafanaRT);
 exposeToPlugin('lodash', _);
 exposeToPlugin('lodash', _);
 exposeToPlugin('moment', moment);
 exposeToPlugin('moment', moment);
 exposeToPlugin('jquery', jquery);
 exposeToPlugin('jquery', jquery);

+ 1 - 1
public/app/features/plugins/state/actions.ts

@@ -1,6 +1,6 @@
 import { StoreState } from 'app/types';
 import { StoreState } from 'app/types';
 import { ThunkAction } from 'redux-thunk';
 import { ThunkAction } from 'redux-thunk';
-import { getBackendSrv } from '../../../core/services/backend_srv';
+import { getBackendSrv } from '@grafana/runtime';
 import { LayoutMode } from '../../../core/components/LayoutSelector/LayoutSelector';
 import { LayoutMode } from '../../../core/components/LayoutSelector/LayoutSelector';
 import { PluginDashboard } from '../../../types/plugins';
 import { PluginDashboard } from '../../../types/plugins';
 import { PluginMeta } from '@grafana/ui';
 import { PluginMeta } from '@grafana/ui';

+ 1 - 1
public/app/features/plugins/wrappers/AppConfigWrapper.tsx

@@ -5,7 +5,7 @@ import extend from 'lodash/extend';
 
 
 import { PluginMeta, AppPlugin, Button } from '@grafana/ui';
 import { PluginMeta, AppPlugin, Button } from '@grafana/ui';
 
 
-import { AngularComponent, getAngularLoader } from 'app/core/services/AngularLoader';
+import { AngularComponent, getAngularLoader } from '@grafana/runtime';
 import { getBackendSrv } from 'app/core/services/backend_srv';
 import { getBackendSrv } from 'app/core/services/backend_srv';
 import { ButtonVariant } from '@grafana/ui/src/components/Button/AbstractButton';
 import { ButtonVariant } from '@grafana/ui/src/components/Button/AbstractButton';
 import { css } from 'emotion';
 import { css } from 'emotion';

+ 1 - 1
public/app/features/teams/state/actions.ts

@@ -1,5 +1,5 @@
 import { ThunkAction } from 'redux-thunk';
 import { ThunkAction } from 'redux-thunk';
-import { getBackendSrv } from 'app/core/services/backend_srv';
+import { getBackendSrv } from '@grafana/runtime';
 import { StoreState, Team, TeamGroup, TeamMember } from 'app/types';
 import { StoreState, Team, TeamGroup, TeamMember } from 'app/types';
 import { updateNavIndex, UpdateNavIndexAction } from 'app/core/actions';
 import { updateNavIndex, UpdateNavIndexAction } from 'app/core/actions';
 import { buildNavModel } from './navModel';
 import { buildNavModel } from './navModel';

+ 1 - 1
public/app/features/users/state/actions.ts

@@ -1,6 +1,6 @@
 import { ThunkAction } from 'redux-thunk';
 import { ThunkAction } from 'redux-thunk';
 import { StoreState } from '../../../types';
 import { StoreState } from '../../../types';
-import { getBackendSrv } from '../../../core/services/backend_srv';
+import { getBackendSrv } from '@grafana/runtime';
 import { Invitee, OrgUser } from 'app/types';
 import { Invitee, OrgUser } from 'app/types';
 
 
 export enum ActionTypes {
 export enum ActionTypes {

+ 1 - 1
public/app/plugins/datasource/prometheus/specs/completer.test.ts

@@ -7,7 +7,7 @@ import { TemplateSrv } from 'app/features/templating/template_srv';
 import { TimeSrv } from 'app/features/dashboard/services/TimeSrv';
 import { TimeSrv } from 'app/features/dashboard/services/TimeSrv';
 import { IQService } from 'angular';
 import { IQService } from 'angular';
 jest.mock('../datasource');
 jest.mock('../datasource');
-jest.mock('app/core/services/backend_srv');
+jest.mock('@grafana/ui');
 
 
 describe('Prometheus editor completer', () => {
 describe('Prometheus editor completer', () => {
   function getSessionStub(data) {
   function getSessionStub(data) {

+ 1 - 1
public/app/plugins/datasource/stackdriver/components/Filter.tsx

@@ -3,7 +3,7 @@ import _ from 'lodash';
 import appEvents from 'app/core/app_events';
 import appEvents from 'app/core/app_events';
 
 
 import { QueryMeta } from '../types';
 import { QueryMeta } from '../types';
-import { getAngularLoader, AngularComponent } from 'app/core/services/AngularLoader';
+import { getAngularLoader, AngularComponent } from '@grafana/runtime';
 import { TemplateSrv } from 'app/features/templating/template_srv';
 import { TemplateSrv } from 'app/features/templating/template_srv';
 import StackdriverDatasource from '../datasource';
 import StackdriverDatasource from '../datasource';
 import '../query_filter_ctrl';
 import '../query_filter_ctrl';

+ 2 - 2
public/app/plugins/datasource/testdata/QueryEditor.tsx

@@ -3,7 +3,7 @@ import React, { PureComponent } from 'react';
 import _ from 'lodash';
 import _ from 'lodash';
 
 
 // Services & Utils
 // Services & Utils
-import { getBackendSrv, BackendSrv } from 'app/core/services/backend_srv';
+import { getBackendSrv } from '@grafana/runtime';
 
 
 // Components
 // Components
 import { FormLabel, Select, SelectOptionItem } from '@grafana/ui';
 import { FormLabel, Select, SelectOptionItem } from '@grafana/ui';
@@ -21,7 +21,7 @@ interface State {
 type Props = QueryEditorProps<TestDataDatasource, TestDataQuery>;
 type Props = QueryEditorProps<TestDataDatasource, TestDataQuery>;
 
 
 export class QueryEditor extends PureComponent<Props> {
 export class QueryEditor extends PureComponent<Props> {
-  backendSrv: BackendSrv = getBackendSrv();
+  backendSrv = getBackendSrv();
 
 
   state: State = {
   state: State = {
     scenarioList: [],
     scenarioList: [],

+ 4 - 4
public/app/routes/GrafanaCtrl.ts

@@ -5,15 +5,15 @@ import Drop from 'tether-drop';
 
 
 // Utils and servies
 // Utils and servies
 import { colors } from '@grafana/ui';
 import { colors } from '@grafana/ui';
+import { setBackendSrv, BackendSrv, setDataSourceSrv } from '@grafana/runtime';
 import config from 'app/core/config';
 import config from 'app/core/config';
 import coreModule from 'app/core/core_module';
 import coreModule from 'app/core/core_module';
 import { profiler } from 'app/core/profiler';
 import { profiler } from 'app/core/profiler';
 import appEvents from 'app/core/app_events';
 import appEvents from 'app/core/app_events';
-import { BackendSrv, setBackendSrv } from 'app/core/services/backend_srv';
 import { TimeSrv, setTimeSrv } from 'app/features/dashboard/services/TimeSrv';
 import { TimeSrv, setTimeSrv } from 'app/features/dashboard/services/TimeSrv';
-import { DatasourceSrv, setDatasourceSrv } from 'app/features/plugins/datasource_srv';
+import { DatasourceSrv } from 'app/features/plugins/datasource_srv';
 import { KeybindingSrv, setKeybindingSrv } from 'app/core/services/keybindingSrv';
 import { KeybindingSrv, setKeybindingSrv } from 'app/core/services/keybindingSrv';
-import { AngularLoader, setAngularLoader } from 'app/core/services/AngularLoader';
+import { AngularLoader, setAngularLoader } from '@grafana/runtime';
 import { configureStore } from 'app/store/configureStore';
 import { configureStore } from 'app/store/configureStore';
 
 
 // Types
 // Types
@@ -37,7 +37,7 @@ export class GrafanaCtrl {
     // make angular loader service available to react components
     // make angular loader service available to react components
     setAngularLoader(angularLoader);
     setAngularLoader(angularLoader);
     setBackendSrv(backendSrv);
     setBackendSrv(backendSrv);
-    setDatasourceSrv(datasourceSrv);
+    setDataSourceSrv(datasourceSrv);
     setTimeSrv(timeSrv);
     setTimeSrv(timeSrv);
     setKeybindingSrv(keybindingSrv);
     setKeybindingSrv(keybindingSrv);
     configureStore();
     configureStore();

+ 2 - 1
scripts/grunt/default_task.js

@@ -34,7 +34,8 @@ module.exports = function(grunt) {
   grunt.registerTask('no-only-tests', function() {
   grunt.registerTask('no-only-tests', function() {
     var files = grunt.file.expand(
     var files = grunt.file.expand(
       'public/**/*@(_specs|.test).@(ts|js|tsx|jsx)',
       'public/**/*@(_specs|.test).@(ts|js|tsx|jsx)',
-      'packages/grafana-ui/**/*@(_specs|.test).@(ts|js|tsx|jsx)'
+      'packages/grafana-ui/**/*@(_specs|.test).@(ts|js|tsx|jsx)',
+      'packages/grafana-runtime/**/*@(_specs|.test).@(ts|js|tsx|jsx)'
     );
     );
     grepFiles(files, '.only(', 'found only statement in test: ');
     grepFiles(files, '.only(', 'found only statement in test: ');
   });
   });