Merge pull request #14936 from grafana/plugin-types-refactor

Plugin types refactor
This commit is contained in:
Torkel Ödegaard
2019-01-18 08:21:29 +01:00
committed by GitHub
50 changed files with 508 additions and 391 deletions

View File

@@ -0,0 +1,71 @@
import { TimeRange, RawTimeRange } from './time';
import { TimeSeries } from './series';
import { PluginMeta } from './plugin';
export interface DataQueryResponse {
data: TimeSeries[];
}
export interface DataQuery {
refId: string;
[key: string]: any;
}
export interface DataQueryOptions {
timezone: string;
range: TimeRange;
rangeRaw: RawTimeRange;
targets: DataQuery[];
panelId: number;
dashboardId: number;
cacheTimeout?: string;
interval: string;
intervalMs: number;
maxDataPoints: number;
scopedVars: object;
}
export interface QueryFix {
type: string;
label: string;
action?: QueryFixAction;
}
export interface QueryFixAction {
type: string;
query?: string;
preventSubmit?: boolean;
}
export interface QueryHint {
type: string;
label: string;
fix?: QueryFix;
}
export interface DataSourceSettings {
id: number;
orgId: number;
name: string;
typeLogoUrl: string;
type: string;
access: string;
url: string;
password: string;
user: string;
database: string;
basicAuth: boolean;
basicAuthPassword: string;
basicAuthUser: string;
isDefault: boolean;
jsonData: { authType: string; defaultRegion: string };
readOnly: boolean;
withCredentials: boolean;
}
export interface DataSourceSelectItem {
name: string;
value: string | null;
meta: PluginMeta;
sort: string;
}

View File

@@ -1,3 +1,5 @@
export * from './series'; export * from './series';
export * from './time'; export * from './time';
export * from './panel'; export * from './panel';
export * from './plugin';
export * from './datasource';

View File

@@ -0,0 +1,115 @@
import { ComponentClass } from 'react';
import { PanelProps, PanelOptionsProps } from './panel';
import { DataQueryOptions, DataQuery, DataQueryResponse, QueryHint } from './datasource';
export interface DataSourceApi {
name: string;
meta: PluginMeta;
pluginExports: PluginExports;
/**
* min interval range
*/
interval?: string;
/**
* Imports queries from a different datasource
*/
importQueries?(queries: DataQuery[], originMeta: PluginMeta): Promise<DataQuery[]>;
/**
* Initializes a datasource after instantiation
*/
init?: () => void;
/**
* Main metrics / data query action
*/
query(options: DataQueryOptions): Promise<DataQueryResponse>;
/**
* Test & verify datasource settings & connection details
*/
testDatasource(): Promise<any>;
/**
* Get hints for query improvements
*/
getQueryHints(query: DataQuery, results: any[], ...rest: any): QueryHint[];
}
export interface QueryEditorProps {
datasource: DataSourceApi;
query: DataQuery;
onExecuteQuery?: () => void;
onQueryChange?: (value: DataQuery) => void;
}
export interface PluginExports {
Datasource?: any;
QueryCtrl?: any;
QueryEditor?: ComponentClass<QueryEditorProps>;
ConfigCtrl?: any;
AnnotationsQueryCtrl?: any;
VariableQueryEditor?: any;
ExploreQueryField?: any;
ExploreStartPage?: any;
// Panel plugin
PanelCtrl?: any;
Panel?: ComponentClass<PanelProps>;
PanelOptions?: ComponentClass<PanelOptionsProps>;
PanelDefaults?: any;
}
export interface PluginMeta {
id: string;
name: string;
info: PluginMetaInfo;
includes: PluginInclude[];
// Datasource-specific
metrics?: boolean;
tables?: boolean;
logs?: boolean;
explore?: boolean;
annotations?: boolean;
mixed?: boolean;
hasQueryHelp?: boolean;
queryOptions?: PluginMetaQueryOptions;
}
interface PluginMetaQueryOptions {
cacheTimeout?: boolean;
maxDataPoints?: boolean;
minInterval?: boolean;
}
export interface PluginInclude {
type: string;
name: string;
path: string;
}
interface PluginMetaInfoLink {
name: string;
url: string;
}
export interface PluginMetaInfo {
author: {
name: string;
url?: string;
};
description: string;
links: PluginMetaInfoLink[];
logos: {
large: string;
small: string;
};
screenshots: any[];
updated: string;
version: string;
}

View File

@@ -6,7 +6,7 @@ import _ from 'lodash';
import { Select } from '@grafana/ui'; import { Select } from '@grafana/ui';
// Types // Types
import { DataSourceSelectItem } from 'app/types'; import { DataSourceSelectItem } from '@grafana/ui/src/types';
export interface Props { export interface Props {
onChange: (ds: DataSourceSelectItem) => void; onChange: (ds: DataSourceSelectItem) => void;

View File

@@ -1,14 +1,18 @@
// Libraries
import _ from 'lodash'; import _ from 'lodash';
import { colors, RawTimeRange, IntervalValues } from '@grafana/ui';
// Services & Utils
import * as dateMath from 'app/core/utils/datemath'; import * as dateMath from 'app/core/utils/datemath';
import { renderUrl } from 'app/core/utils/url'; import { renderUrl } from 'app/core/utils/url';
import kbn from 'app/core/utils/kbn'; import kbn from 'app/core/utils/kbn';
import store from 'app/core/store'; import store from 'app/core/store';
import { parse as parseDate } from 'app/core/utils/datemath'; import { parse as parseDate } from 'app/core/utils/datemath';
import { colors } from '@grafana/ui';
import TimeSeries from 'app/core/time_series2';
import TableModel, { mergeTablesIntoModel } from 'app/core/table_model'; import TableModel, { mergeTablesIntoModel } from 'app/core/table_model';
// Types
import { RawTimeRange, IntervalValues, DataQuery } from '@grafana/ui/src/types';
import TimeSeries from 'app/core/time_series2';
import { import {
ExploreUrlState, ExploreUrlState,
HistoryItem, HistoryItem,
@@ -17,7 +21,6 @@ import {
QueryIntervals, QueryIntervals,
QueryOptions, QueryOptions,
} from 'app/types/explore'; } from 'app/types/explore';
import { DataQuery } from 'app/types/series';
export const DEFAULT_RANGE = { export const DEFAULT_RANGE = {
from: 'now-6h', from: 'now-6h',

View File

@@ -12,8 +12,7 @@ import { getDatasourceSrv, DatasourceSrv } from 'app/features/plugins/datasource
import kbn from 'app/core/utils/kbn'; import kbn from 'app/core/utils/kbn';
// Types // Types
import { DataQueryOptions, DataQueryResponse } from 'app/types'; import { TimeRange, TimeSeries, LoadingState, DataQueryResponse, DataQueryOptions } from '@grafana/ui/src/types';
import { TimeRange, TimeSeries, LoadingState } from '@grafana/ui';
const DEFAULT_PLUGIN_ERROR = 'Error in plugin'; const DEFAULT_PLUGIN_ERROR = 'Error in plugin';

View File

@@ -18,7 +18,7 @@ import config from 'app/core/config';
// Types // Types
import { PanelModel } from '../panel_model'; import { PanelModel } from '../panel_model';
import { DashboardModel } from '../dashboard_model'; import { DashboardModel } from '../dashboard_model';
import { DataQuery, DataSourceSelectItem } from 'app/types'; import { DataQuery, DataSourceSelectItem } from '@grafana/ui/src/types';
import { PluginHelp } from 'app/core/components/PluginHelp/PluginHelp'; import { PluginHelp } from 'app/core/components/PluginHelp/PluginHelp';
interface Props { interface Props {

View File

@@ -10,7 +10,7 @@ import { Emitter } from 'app/core/utils/emitter';
// Types // Types
import { PanelModel } from '../panel_model'; import { PanelModel } from '../panel_model';
import { DataQuery, DataSourceApi } from 'app/types/series'; import { DataQuery, DataSourceApi } from '@grafana/ui';
interface Props { interface Props {
panel: PanelModel; panel: PanelModel;
@@ -103,7 +103,17 @@ export class QueryEditorRow extends PureComponent<Props, State> {
this.setState({ isCollapsed: !this.state.isCollapsed }); this.setState({ isCollapsed: !this.state.isCollapsed });
}; };
onQueryChange = (query: DataQuery) => {
Object.assign(this.props.query, query);
this.onExecuteQuery();
};
onExecuteQuery = () => {
this.props.panel.refresh();
};
renderPluginEditor() { renderPluginEditor() {
const { query } = this.props;
const { datasource } = this.state; const { datasource } = this.state;
if (datasource.pluginExports.QueryCtrl) { if (datasource.pluginExports.QueryCtrl) {
@@ -112,7 +122,14 @@ export class QueryEditorRow extends PureComponent<Props, State> {
if (datasource.pluginExports.QueryEditor) { if (datasource.pluginExports.QueryEditor) {
const QueryEditor = datasource.pluginExports.QueryEditor; const QueryEditor = datasource.pluginExports.QueryEditor;
return <QueryEditor />; return (
<QueryEditor
query={query}
datasource={datasource}
onQueryChange={this.onQueryChange}
onExecuteQuery={this.onExecuteQuery}
/>
);
} }
return <div>Data source plugin does not export any Query Editor component</div>; return <div>Data source plugin does not export any Query Editor component</div>;

View File

@@ -14,7 +14,8 @@ import { FormLabel } from '@grafana/ui';
// Types // Types
import { PanelModel } from '../panel_model'; import { PanelModel } from '../panel_model';
import { ValidationEvents, DataSourceSelectItem } from 'app/types'; import { DataSourceSelectItem } from '@grafana/ui/src/types';
import { ValidationEvents } from 'app/types';
const timeRangeValidationEvents: ValidationEvents = { const timeRangeValidationEvents: ValidationEvents = {
[EventsWithValidation.onBlur]: [ [EventsWithValidation.onBlur]: [

View File

@@ -1,7 +1,10 @@
import { Emitter } from 'app/core/utils/emitter'; // Libraries
import _ from 'lodash'; import _ from 'lodash';
// Types
import { Emitter } from 'app/core/utils/emitter';
import { PANEL_OPTIONS_KEY_PREFIX } from 'app/core/constants'; import { PANEL_OPTIONS_KEY_PREFIX } from 'app/core/constants';
import { DataQuery } from 'app/types'; import { DataQuery } from '@grafana/ui/src/types';
export interface GridPos { export interface GridPos {
x: number; x: number;

View File

@@ -1,13 +1,14 @@
import React from 'react'; import React from 'react';
import { shallow } from 'enzyme'; import { shallow } from 'enzyme';
import { DataSourceDashboards, Props } from './DataSourceDashboards'; import { DataSourceDashboards, Props } from './DataSourceDashboards';
import { DataSource, NavModel, PluginDashboard } from 'app/types'; import { DataSourceSettings } from '@grafana/ui/src/types';
import { NavModel, PluginDashboard } from 'app/types';
const setup = (propOverrides?: object) => { const setup = (propOverrides?: object) => {
const props: Props = { const props: Props = {
navModel: {} as NavModel, navModel: {} as NavModel,
dashboards: [] as PluginDashboard[], dashboards: [] as PluginDashboard[],
dataSource: {} as DataSource, dataSource: {} as DataSourceSettings,
pageId: 1, pageId: 1,
importDashboard: jest.fn(), importDashboard: jest.fn(),
loadDataSource: jest.fn(), loadDataSource: jest.fn(),

View File

@@ -1,9 +1,13 @@
// Libraries
import React, { PureComponent } from 'react'; import React, { PureComponent } from 'react';
import { hot } from 'react-hot-loader'; import { hot } from 'react-hot-loader';
import { connect } from 'react-redux'; import { connect } from 'react-redux';
// Components
import PageHeader from 'app/core/components/PageHeader/PageHeader'; import PageHeader from 'app/core/components/PageHeader/PageHeader';
import DashboardTable from './DashboardsTable'; import DashboardTable from './DashboardsTable';
import { DataSource, NavModel, PluginDashboard } from 'app/types';
// Actions & Selectors
import { getNavModel } from 'app/core/selectors/navModel'; import { getNavModel } from 'app/core/selectors/navModel';
import { getRouteParamsId } from 'app/core/selectors/location'; import { getRouteParamsId } from 'app/core/selectors/location';
import { loadDataSource } from './state/actions'; import { loadDataSource } from './state/actions';
@@ -11,10 +15,14 @@ import { loadPluginDashboards } from '../plugins/state/actions';
import { importDashboard, removeDashboard } from '../dashboard/state/actions'; import { importDashboard, removeDashboard } from '../dashboard/state/actions';
import { getDataSource } from './state/selectors'; import { getDataSource } from './state/selectors';
// Types
import { NavModel, PluginDashboard } from 'app/types';
import { DataSourceSettings } from '@grafana/ui/src/types';
export interface Props { export interface Props {
navModel: NavModel; navModel: NavModel;
dashboards: PluginDashboard[]; dashboards: PluginDashboard[];
dataSource: DataSource; dataSource: DataSourceSettings;
pageId: number; pageId: number;
importDashboard: typeof importDashboard; importDashboard: typeof importDashboard;
loadDataSource: typeof loadDataSource; loadDataSource: typeof loadDataSource;

View File

@@ -1,11 +1,16 @@
// Libraries
import React, { PureComponent } from 'react'; import React, { PureComponent } from 'react';
import classNames from 'classnames'; import classNames from 'classnames';
// Components
import DataSourcesListItem from './DataSourcesListItem'; import DataSourcesListItem from './DataSourcesListItem';
import { DataSource } from 'app/types';
// Types
import { DataSourceSettings } from '@grafana/ui/src/types';
import { LayoutMode, LayoutModes } from '../../core/components/LayoutSelector/LayoutSelector'; import { LayoutMode, LayoutModes } from '../../core/components/LayoutSelector/LayoutSelector';
export interface Props { export interface Props {
dataSources: DataSource[]; dataSources: DataSourceSettings[];
layoutMode: LayoutMode; layoutMode: LayoutMode;
} }

View File

@@ -1,8 +1,8 @@
import React, { PureComponent } from 'react'; import React, { PureComponent } from 'react';
import { DataSource } from 'app/types'; import { DataSourceSettings } from '@grafana/ui/src/types';
export interface Props { export interface Props {
dataSource: DataSource; dataSource: DataSourceSettings;
} }
export class DataSourcesListItem extends PureComponent<Props> { export class DataSourcesListItem extends PureComponent<Props> {

View File

@@ -1,13 +1,14 @@
import React from 'react'; import React from 'react';
import { shallow } from 'enzyme'; import { shallow } from 'enzyme';
import { DataSourcesListPage, Props } from './DataSourcesListPage'; import { DataSourcesListPage, Props } from './DataSourcesListPage';
import { DataSource, NavModel } from 'app/types'; import { NavModel } from 'app/types';
import { DataSourceSettings } from '@grafana/ui/src/types';
import { LayoutModes } from '../../core/components/LayoutSelector/LayoutSelector'; import { LayoutModes } from '../../core/components/LayoutSelector/LayoutSelector';
import { getMockDataSources } from './__mocks__/dataSourcesMocks'; import { getMockDataSources } from './__mocks__/dataSourcesMocks';
const setup = (propOverrides?: object) => { const setup = (propOverrides?: object) => {
const props: Props = { const props: Props = {
dataSources: [] as DataSource[], dataSources: [] as DataSourceSettings[],
layoutMode: LayoutModes.Grid, layoutMode: LayoutModes.Grid,
loadDataSources: jest.fn(), loadDataSources: jest.fn(),
navModel: { navModel: {

View File

@@ -1,12 +1,20 @@
// Libraries
import React, { PureComponent } from 'react'; import React, { PureComponent } from 'react';
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import { hot } from 'react-hot-loader'; import { hot } from 'react-hot-loader';
// Components
import Page from 'app/core/components/Page/Page'; import Page from 'app/core/components/Page/Page';
import OrgActionBar from 'app/core/components/OrgActionBar/OrgActionBar'; import OrgActionBar from 'app/core/components/OrgActionBar/OrgActionBar';
import EmptyListCTA from 'app/core/components/EmptyListCTA/EmptyListCTA'; import EmptyListCTA from 'app/core/components/EmptyListCTA/EmptyListCTA';
import DataSourcesList from './DataSourcesList'; import DataSourcesList from './DataSourcesList';
import { DataSource, NavModel, StoreState } from 'app/types';
// Types
import { DataSourceSettings } from '@grafana/ui/src/types';
import { NavModel, StoreState } from 'app/types';
import { LayoutMode } from 'app/core/components/LayoutSelector/LayoutSelector'; import { LayoutMode } from 'app/core/components/LayoutSelector/LayoutSelector';
// Actions
import { loadDataSources, setDataSourcesLayoutMode, setDataSourcesSearchQuery } from './state/actions'; import { loadDataSources, setDataSourcesLayoutMode, setDataSourcesSearchQuery } from './state/actions';
import { getNavModel } from 'app/core/selectors/navModel'; import { getNavModel } from 'app/core/selectors/navModel';
@@ -19,7 +27,7 @@ import {
export interface Props { export interface Props {
navModel: NavModel; navModel: NavModel;
dataSources: DataSource[]; dataSources: DataSourceSettings[];
dataSourcesCount: number; dataSourcesCount: number;
layoutMode: LayoutMode; layoutMode: LayoutMode;
searchQuery: string; searchQuery: string;

View File

@@ -1,6 +1,6 @@
import { DataSource } from 'app/types'; import { DataSourceSettings } from '@grafana/ui/src/types';
export const getMockDataSources = (amount: number): DataSource[] => { export const getMockDataSources = (amount: number): DataSourceSettings[] => {
const dataSources = []; const dataSources = [];
for (let i = 0; i <= amount; i++) { for (let i = 0; i <= amount; i++) {
@@ -25,7 +25,7 @@ export const getMockDataSources = (amount: number): DataSource[] => {
return dataSources; return dataSources;
}; };
export const getMockDataSource = (): DataSource => { export const getMockDataSource = (): DataSourceSettings => {
return { return {
access: '', access: '',
basicAuth: false, basicAuth: false,

View File

@@ -1,7 +1,8 @@
import React from 'react'; import React from 'react';
import { shallow } from 'enzyme'; import { shallow } from 'enzyme';
import { DataSourceSettings, Props } from './DataSourceSettings'; import { DataSourceSettingsPage, Props } from './DataSourceSettingsPage';
import { DataSource, NavModel } from '../../../types'; import { NavModel } from 'app/types';
import { DataSourceSettings } from '@grafana/ui';
import { getMockDataSource } from '../__mocks__/dataSourcesMocks'; import { getMockDataSource } from '../__mocks__/dataSourcesMocks';
import { getMockPlugin } from '../../plugins/__mocks__/pluginMocks'; import { getMockPlugin } from '../../plugins/__mocks__/pluginMocks';
@@ -20,7 +21,7 @@ const setup = (propOverrides?: object) => {
Object.assign(props, propOverrides); Object.assign(props, propOverrides);
return shallow(<DataSourceSettings {...props} />); return shallow(<DataSourceSettingsPage {...props} />);
}; };
describe('Render', () => { describe('Render', () => {
@@ -32,7 +33,7 @@ describe('Render', () => {
it('should render loader', () => { it('should render loader', () => {
const wrapper = setup({ const wrapper = setup({
dataSource: {} as DataSource, dataSource: {} as DataSourceSettings,
}); });
expect(wrapper).toMatchSnapshot(); expect(wrapper).toMatchSnapshot();

View File

@@ -1,28 +1,34 @@
// Libraries
import React, { PureComponent } from 'react'; import React, { PureComponent } from 'react';
import { hot } from 'react-hot-loader'; import { hot } from 'react-hot-loader';
import { connect } from 'react-redux'; import { connect } from 'react-redux';
// Components
import PageHeader from 'app/core/components/PageHeader/PageHeader'; import PageHeader from 'app/core/components/PageHeader/PageHeader';
import PageLoader from 'app/core/components/PageLoader/PageLoader'; import PageLoader from 'app/core/components/PageLoader/PageLoader';
import PluginSettings from './PluginSettings'; import PluginSettings from './PluginSettings';
import BasicSettings from './BasicSettings'; import BasicSettings from './BasicSettings';
import ButtonRow from './ButtonRow'; import ButtonRow from './ButtonRow';
// Services & Utils
import appEvents from 'app/core/app_events'; import appEvents from 'app/core/app_events';
import { getBackendSrv } from 'app/core/services/backend_srv'; import { getBackendSrv } from 'app/core/services/backend_srv';
import { getDatasourceSrv } from 'app/features/plugins/datasource_srv'; import { getDatasourceSrv } from 'app/features/plugins/datasource_srv';
// Actions & selectors
import { getDataSource, getDataSourceMeta } from '../state/selectors'; import { getDataSource, getDataSourceMeta } from '../state/selectors';
import { deleteDataSource, loadDataSource, setDataSourceName, setIsDefault, updateDataSource } from '../state/actions'; import { deleteDataSource, loadDataSource, setDataSourceName, setIsDefault, updateDataSource } from '../state/actions';
import { getNavModel } from 'app/core/selectors/navModel'; import { getNavModel } from 'app/core/selectors/navModel';
import { getRouteParamsId } from 'app/core/selectors/location'; import { getRouteParamsId } from 'app/core/selectors/location';
import { DataSource, NavModel, Plugin } from 'app/types/'; // Types
import { NavModel, Plugin } from 'app/types/';
import { DataSourceSettings } from '@grafana/ui/src/types/';
import { getDataSourceLoadingNav } from '../state/navModel'; import { getDataSourceLoadingNav } from '../state/navModel';
export interface Props { export interface Props {
navModel: NavModel; navModel: NavModel;
dataSource: DataSource; dataSource: DataSourceSettings;
dataSourceMeta: Plugin; dataSourceMeta: Plugin;
pageId: number; pageId: number;
deleteDataSource: typeof deleteDataSource; deleteDataSource: typeof deleteDataSource;
@@ -33,7 +39,7 @@ export interface Props {
} }
interface State { interface State {
dataSource: DataSource; dataSource: DataSourceSettings;
isTesting?: boolean; isTesting?: boolean;
testingMessage?: string; testingMessage?: string;
testingStatus?: string; testingStatus?: string;
@@ -44,12 +50,12 @@ enum DataSourceStates {
Beta = 'beta', Beta = 'beta',
} }
export class DataSourceSettings extends PureComponent<Props, State> { export class DataSourceSettingsPage extends PureComponent<Props, State> {
constructor(props) { constructor(props) {
super(props); super(props);
this.state = { this.state = {
dataSource: {} as DataSource, dataSource: {} as DataSourceSettings,
}; };
} }
@@ -246,4 +252,4 @@ const mapDispatchToProps = {
setIsDefault, setIsDefault,
}; };
export default hot(module)(connect(mapStateToProps, mapDispatchToProps)(DataSourceSettings)); export default hot(module)(connect(mapStateToProps, mapDispatchToProps)(DataSourceSettingsPage));

View File

@@ -1,20 +1,21 @@
import React, { PureComponent } from 'react'; import React, { PureComponent } from 'react';
import _ from 'lodash'; import _ from 'lodash';
import { DataSource, Plugin } from 'app/types/'; import { Plugin } from 'app/types';
import { DataSourceSettings } from '@grafana/ui/src/types';
import { getAngularLoader, AngularComponent } from 'app/core/services/AngularLoader'; import { getAngularLoader, AngularComponent } from 'app/core/services/AngularLoader';
export interface Props { export interface Props {
dataSource: DataSource; dataSource: DataSourceSettings;
dataSourceMeta: Plugin; dataSourceMeta: Plugin;
onModelChange: (dataSource: DataSource) => void; onModelChange: (dataSource: DataSourceSettings) => void;
} }
export class PluginSettings extends PureComponent<Props> { export class PluginSettings extends PureComponent<Props> {
element: any; element: any;
component: AngularComponent; component: AngularComponent;
scopeProps: { scopeProps: {
ctrl: { datasourceMeta: Plugin; current: DataSource }; ctrl: { datasourceMeta: Plugin; current: DataSourceSettings };
onModelChanged: (dataSource: DataSource) => void; onModelChanged: (dataSource: DataSourceSettings) => void;
}; };
constructor(props) { constructor(props) {
@@ -51,7 +52,7 @@ export class PluginSettings extends PureComponent<Props> {
} }
} }
onModelChanged = (dataSource: DataSource) => { onModelChanged = (dataSource: DataSourceSettings) => {
this.props.onModelChange(dataSource); this.props.onModelChange(dataSource);
}; };

View File

@@ -6,7 +6,8 @@ import { LayoutMode } from 'app/core/components/LayoutSelector/LayoutSelector';
import { updateLocation, updateNavIndex, UpdateNavIndexAction } from 'app/core/actions'; import { updateLocation, updateNavIndex, UpdateNavIndexAction } from 'app/core/actions';
import { UpdateLocationAction } from 'app/core/actions/location'; import { UpdateLocationAction } from 'app/core/actions/location';
import { buildNavModel } from './navModel'; import { buildNavModel } from './navModel';
import { DataSource, Plugin, StoreState } from 'app/types'; import { DataSourceSettings } from '@grafana/ui/src/types';
import { Plugin, StoreState } from 'app/types';
export enum ActionTypes { export enum ActionTypes {
LoadDataSources = 'LOAD_DATA_SOURCES', LoadDataSources = 'LOAD_DATA_SOURCES',
@@ -22,7 +23,7 @@ export enum ActionTypes {
interface LoadDataSourcesAction { interface LoadDataSourcesAction {
type: ActionTypes.LoadDataSources; type: ActionTypes.LoadDataSources;
payload: DataSource[]; payload: DataSourceSettings[];
} }
interface SetDataSourcesSearchQueryAction { interface SetDataSourcesSearchQueryAction {
@@ -47,7 +48,7 @@ interface SetDataSourceTypeSearchQueryAction {
interface LoadDataSourceAction { interface LoadDataSourceAction {
type: ActionTypes.LoadDataSource; type: ActionTypes.LoadDataSource;
payload: DataSource; payload: DataSourceSettings;
} }
interface LoadDataSourceMetaAction { interface LoadDataSourceMetaAction {
@@ -65,12 +66,12 @@ interface SetIsDefaultAction {
payload: boolean; payload: boolean;
} }
const dataSourcesLoaded = (dataSources: DataSource[]): LoadDataSourcesAction => ({ const dataSourcesLoaded = (dataSources: DataSourceSettings[]): LoadDataSourcesAction => ({
type: ActionTypes.LoadDataSources, type: ActionTypes.LoadDataSources,
payload: dataSources, payload: dataSources,
}); });
const dataSourceLoaded = (dataSource: DataSource): LoadDataSourceAction => ({ const dataSourceLoaded = (dataSource: DataSourceSettings): LoadDataSourceAction => ({
type: ActionTypes.LoadDataSource, type: ActionTypes.LoadDataSource,
payload: dataSource, payload: dataSource,
}); });
@@ -171,7 +172,7 @@ export function loadDataSourceTypes(): ThunkResult<void> {
}; };
} }
export function updateDataSource(dataSource: DataSource): ThunkResult<void> { export function updateDataSource(dataSource: DataSourceSettings): ThunkResult<void> {
return async dispatch => { return async dispatch => {
await getBackendSrv().put(`/api/datasources/${dataSource.id}`, dataSource); await getBackendSrv().put(`/api/datasources/${dataSource.id}`, dataSource);
await updateFrontendSettings(); await updateFrontendSettings();

View File

@@ -1,7 +1,8 @@
import { DataSource, NavModel, NavModelItem, PluginMeta } from 'app/types'; import { NavModel, NavModelItem } from 'app/types';
import { PluginMeta, DataSourceSettings } from '@grafana/ui/src/types';
import config from 'app/core/config'; import config from 'app/core/config';
export function buildNavModel(dataSource: DataSource, pluginMeta: PluginMeta): NavModelItem { export function buildNavModel(dataSource: DataSourceSettings, pluginMeta: PluginMeta): NavModelItem {
const navModel = { const navModel = {
img: pluginMeta.info.logos.large, img: pluginMeta.info.logos.large,
id: 'datasource-' + dataSource.id, id: 'datasource-' + dataSource.id,

View File

@@ -1,10 +1,11 @@
import { DataSource, DataSourcesState, Plugin } from 'app/types'; import { DataSourcesState, Plugin } from 'app/types';
import { DataSourceSettings } from '@grafana/ui/src/types';
import { Action, ActionTypes } from './actions'; import { Action, ActionTypes } from './actions';
import { LayoutModes } from '../../../core/components/LayoutSelector/LayoutSelector'; import { LayoutModes } from 'app/core/components/LayoutSelector/LayoutSelector';
const initialState: DataSourcesState = { const initialState: DataSourcesState = {
dataSources: [] as DataSource[], dataSources: [] as DataSourceSettings[],
dataSource: {} as DataSource, dataSource: {} as DataSourceSettings,
layoutMode: LayoutModes.List, layoutMode: LayoutModes.List,
searchQuery: '', searchQuery: '',
dataSourcesCount: 0, dataSourcesCount: 0,

View File

@@ -1,4 +1,4 @@
import { DataSource } from '../../../types'; import { DataSourceSettings } from '@grafana/ui/src/types';
export const getDataSources = state => { export const getDataSources = state => {
const regex = new RegExp(state.searchQuery, 'i'); const regex = new RegExp(state.searchQuery, 'i');
@@ -16,11 +16,11 @@ export const getDataSourceTypes = state => {
}); });
}; };
export const getDataSource = (state, dataSourceId): DataSource | null => { export const getDataSource = (state, dataSourceId): DataSourceSettings | null => {
if (state.dataSource.id === parseInt(dataSourceId, 10)) { if (state.dataSource.id === parseInt(dataSourceId, 10)) {
return state.dataSource; return state.dataSource;
} }
return {} as DataSource; return {} as DataSourceSettings;
}; };
export const getDataSourceMeta = (state, type): Plugin => { export const getDataSourceMeta = (state, type): Plugin => {

View File

@@ -1,19 +1,25 @@
// Libraries
import React from 'react'; import React from 'react';
import { hot } from 'react-hot-loader'; import { hot } from 'react-hot-loader';
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import _ from 'lodash'; import _ from 'lodash';
import { AutoSizer } from 'react-virtualized'; import { AutoSizer } from 'react-virtualized';
import { RawTimeRange, TimeRange } from '@grafana/ui';
import { DataSourceSelectItem } from 'app/types/datasources'; // Services & Utils
import { ExploreItemState, ExploreUrlState, RangeScanner, ExploreId } from 'app/types/explore';
import { DataQuery } from 'app/types/series';
import { StoreState } from 'app/types';
import store from 'app/core/store'; import store from 'app/core/store';
import { LAST_USED_DATASOURCE_KEY, ensureQueries, DEFAULT_RANGE } from 'app/core/utils/explore';
import { DataSourcePicker } from 'app/core/components/Select/DataSourcePicker';
import { Emitter } from 'app/core/utils/emitter';
// Components
import { DataSourceSelectItem } from '@grafana/ui/src/types';
import { DataSourcePicker } from 'app/core/components/Select/DataSourcePicker';
import { Alert } from './Error';
import ErrorBoundary from './ErrorBoundary';
import GraphContainer from './GraphContainer';
import LogsContainer from './LogsContainer';
import QueryRows from './QueryRows';
import TableContainer from './TableContainer';
import TimePicker, { parseTime } from './TimePicker';
// Actions
import { import {
changeDatasource, changeDatasource,
changeSize, changeSize,
@@ -29,13 +35,12 @@ import {
splitOpen, splitOpen,
} from './state/actions'; } from './state/actions';
import { Alert } from './Error'; // Types
import ErrorBoundary from './ErrorBoundary'; import { RawTimeRange, TimeRange, DataQuery } from '@grafana/ui';
import GraphContainer from './GraphContainer'; import { ExploreItemState, ExploreUrlState, RangeScanner, ExploreId } from 'app/types/explore';
import LogsContainer from './LogsContainer'; import { StoreState } from 'app/types';
import QueryRows from './QueryRows'; import { LAST_USED_DATASOURCE_KEY, ensureQueries, DEFAULT_RANGE } from 'app/core/utils/explore';
import TableContainer from './TableContainer'; import { Emitter } from 'app/core/utils/emitter';
import TimePicker, { parseTime } from './TimePicker';
interface ExploreProps { interface ExploreProps {
StartPage?: any; StartPage?: any;

View File

@@ -1,10 +1,14 @@
// Libraries
import React, { PureComponent } from 'react'; import React, { PureComponent } from 'react';
// Services
import { getAngularLoader, AngularComponent } from 'app/core/services/AngularLoader'; import { getAngularLoader, AngularComponent } from 'app/core/services/AngularLoader';
import { Emitter } from 'app/core/utils/emitter';
import { getIntervals } from 'app/core/utils/explore'; import { getIntervals } from 'app/core/utils/explore';
import { DataQuery } from 'app/types';
import { RawTimeRange } from '@grafana/ui';
import { getTimeSrv } from 'app/features/dashboard/time_srv'; import { getTimeSrv } from 'app/features/dashboard/time_srv';
// Types
import { Emitter } from 'app/core/utils/emitter';
import { RawTimeRange, DataQuery } from '@grafana/ui';
import 'app/features/plugins/plugin_loader'; import 'app/features/plugins/plugin_loader';
interface QueryEditorProps { interface QueryEditorProps {

View File

@@ -1,16 +1,14 @@
// Libraries
import React, { PureComponent } from 'react'; import React, { PureComponent } from 'react';
import _ from 'lodash';
import { hot } from 'react-hot-loader'; import { hot } from 'react-hot-loader';
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import { RawTimeRange } from '@grafana/ui';
import _ from 'lodash';
import { QueryTransaction, HistoryItem, QueryHint, ExploreItemState, ExploreId } from 'app/types/explore'; // Components
import { Emitter } from 'app/core/utils/emitter';
import { DataQuery, StoreState } from 'app/types';
// import DefaultQueryField from './QueryField';
import QueryEditor from './QueryEditor'; import QueryEditor from './QueryEditor';
import QueryTransactionStatus from './QueryTransactionStatus'; import QueryTransactionStatus from './QueryTransactionStatus';
// Actions
import { import {
addQueryRow, addQueryRow,
changeQuery, changeQuery,
@@ -20,6 +18,12 @@ import {
runQueries, runQueries,
} from './state/actions'; } from './state/actions';
// Types
import { StoreState } from 'app/types';
import { RawTimeRange, DataQuery, QueryHint } from '@grafana/ui';
import { QueryTransaction, HistoryItem, ExploreItemState, ExploreId } from 'app/types/explore';
import { Emitter } from 'app/core/utils/emitter';
function getFirstHintFromTransactions(transactions: QueryTransaction[]): QueryHint { function getFirstHintFromTransactions(transactions: QueryTransaction[]): QueryHint {
const transaction = transactions.find(qt => qt.hints && qt.hints.length > 0); const transaction = transactions.find(qt => qt.hints && qt.hints.length > 0);
if (transaction) { if (transaction) {

View File

@@ -1,17 +1,21 @@
// Libraries
import React, { PureComponent } from 'react'; import React, { PureComponent } from 'react';
import { Emitter } from 'app/core/utils/emitter'; // Components
import { DataQuery } from 'app/types';
import { ExploreId } from 'app/types/explore';
import QueryRow from './QueryRow'; import QueryRow from './QueryRow';
// Types
import { Emitter } from 'app/core/utils/emitter';
import { DataQuery } from '@grafana/ui/src/types';
import { ExploreId } from 'app/types/explore';
interface QueryRowsProps { interface QueryRowsProps {
className?: string; className?: string;
exploreEvents: Emitter; exploreEvents: Emitter;
exploreId: ExploreId; exploreId: ExploreId;
initialQueries: DataQuery[]; initialQueries: DataQuery[];
} }
export default class QueryRows extends PureComponent<QueryRowsProps> { export default class QueryRows extends PureComponent<QueryRowsProps> {
render() { render() {
const { className = '', exploreEvents, exploreId, initialQueries } = this.props; const { className = '', exploreEvents, exploreId, initialQueries } = this.props;

View File

@@ -1,6 +1,6 @@
import { RawTimeRange, TimeRange } from '@grafana/ui'; // Types
import { Emitter } from 'app/core/core'; import { Emitter } from 'app/core/core';
import { RawTimeRange, TimeRange, DataQuery, DataSourceSelectItem } from '@grafana/ui/src/types';
import { import {
ExploreId, ExploreId,
ExploreItemState, ExploreItemState,
@@ -9,8 +9,6 @@ import {
ResultType, ResultType,
QueryTransaction, QueryTransaction,
} from 'app/types/explore'; } from 'app/types/explore';
import { DataSourceSelectItem } from 'app/types/datasources';
import { DataQuery } from 'app/types';
export enum ActionTypes { export enum ActionTypes {
AddQueryRow = 'explore/ADD_QUERY_ROW', AddQueryRow = 'explore/ADD_QUERY_ROW',

View File

@@ -1,7 +1,9 @@
// Libraries
import _ from 'lodash'; import _ from 'lodash';
import { ThunkAction } from 'redux-thunk'; import { ThunkAction } from 'redux-thunk';
import { RawTimeRange, TimeRange } from '@grafana/ui';
// Services & Utils
import store from 'app/core/store';
import { import {
LAST_USED_DATASOURCE_KEY, LAST_USED_DATASOURCE_KEY,
clearQueryKeys, clearQueryKeys,
@@ -14,10 +16,12 @@ import {
serializeStateToUrlParam, serializeStateToUrlParam,
} from 'app/core/utils/explore'; } from 'app/core/utils/explore';
// Actions
import { updateLocation } from 'app/core/actions'; import { updateLocation } from 'app/core/actions';
import store from 'app/core/store';
import { DataSourceSelectItem } from 'app/types/datasources'; // Types
import { DataQuery, StoreState } from 'app/types'; import { StoreState } from 'app/types';
import { DataQuery, DataSourceSelectItem, QueryHint } from '@grafana/ui/src/types';
import { getDatasourceSrv } from 'app/features/plugins/datasource_srv'; import { getDatasourceSrv } from 'app/features/plugins/datasource_srv';
import { import {
ExploreId, ExploreId,
@@ -26,11 +30,10 @@ import {
ResultType, ResultType,
QueryOptions, QueryOptions,
QueryTransaction, QueryTransaction,
QueryHint,
QueryHintGetter,
} from 'app/types/explore'; } from 'app/types/explore';
import { Emitter } from 'app/core/core';
import { Emitter } from 'app/core/core';
import { RawTimeRange, TimeRange } from '@grafana/ui';
import { import {
Action as ThunkableAction, Action as ThunkableAction,
ActionTypes, ActionTypes,
@@ -45,6 +48,7 @@ import {
ScanStopAction, ScanStopAction,
} from './actionTypes'; } from './actionTypes';
type ThunkResult<R> = ThunkAction<R, StoreState, undefined, ThunkableAction>; type ThunkResult<R> = ThunkAction<R, StoreState, undefined, ThunkableAction>;
/** /**
@@ -460,7 +464,7 @@ export function queryTransactionSuccess(
// Get query hints // Get query hints
let hints: QueryHint[]; let hints: QueryHint[];
if (datasourceInstance.getQueryHints as QueryHintGetter) { if (datasourceInstance.getQueryHints) {
hints = datasourceInstance.getQueryHints(transaction.query, result); hints = datasourceInstance.getQueryHints(transaction.query, result);
} }

View File

@@ -5,7 +5,7 @@ import {
ensureQueries, ensureQueries,
} from 'app/core/utils/explore'; } from 'app/core/utils/explore';
import { ExploreItemState, ExploreState, QueryTransaction } from 'app/types/explore'; import { ExploreItemState, ExploreState, QueryTransaction } from 'app/types/explore';
import { DataQuery } from 'app/types/series'; import { DataQuery } from '@grafana/ui/src/types';
import { Action, ActionTypes } from './actionTypes'; import { Action, ActionTypes } from './actionTypes';

View File

@@ -1,14 +1,16 @@
// Libraries
import _ from 'lodash'; import _ from 'lodash';
import coreModule from 'app/core/core_module'; import coreModule from 'app/core/core_module';
// Services & Utils
import config from 'app/core/config'; import config from 'app/core/config';
import { importPluginModule } from './plugin_loader'; import { importPluginModule } from './plugin_loader';
import { DataSourceApi } from 'app/types/series'; // Types
import { DataSource, DataSourceSelectItem } from 'app/types'; import { DataSourceApi, DataSourceSelectItem } from '@grafana/ui/src/types';
export class DatasourceSrv { export class DatasourceSrv {
datasources: { [name: string]: DataSource }; datasources: { [name: string]: DataSourceApi };
/** @ngInject */ /** @ngInject */
constructor(private $q, private $injector, private $rootScope, private templateSrv) { constructor(private $q, private $injector, private $rootScope, private templateSrv) {
@@ -59,7 +61,7 @@ export class DatasourceSrv {
throw new Error('Plugin module is missing Datasource constructor'); throw new Error('Plugin module is missing Datasource constructor');
} }
const instance: DataSource = this.$injector.instantiate(plugin.Datasource, { instanceSettings: dsConfig }); const instance: DataSourceApi = this.$injector.instantiate(plugin.Datasource, { instanceSettings: dsConfig });
instance.meta = pluginDef; instance.meta = pluginDef;
instance.name = name; instance.name = name;
instance.pluginExports = plugin; instance.pluginExports = plugin;

View File

@@ -18,7 +18,7 @@ import config from 'app/core/config';
import TimeSeries from 'app/core/time_series2'; import TimeSeries from 'app/core/time_series2';
import TableModel from 'app/core/table_model'; import TableModel from 'app/core/table_model';
import { coreModule, appEvents, contextSrv } from 'app/core/core'; import { coreModule, appEvents, contextSrv } from 'app/core/core';
import { PluginExports } from 'app/types/plugins'; import { PluginExports } from '@grafana/ui';
import * as datemath from 'app/core/utils/datemath'; import * as datemath from 'app/core/utils/datemath';
import * as fileExport from 'app/core/utils/file_export'; import * as fileExport from 'app/core/utils/file_export';
import * as flatten from 'app/core/utils/flatten'; import * as flatten from 'app/core/utils/flatten';

View File

@@ -1,8 +1,14 @@
// Libraries
import _ from 'lodash'; import _ from 'lodash';
import { DataSource, PluginMeta, NavModel } from 'app/types';
// Utils & Services
import config from 'app/core/config'; import config from 'app/core/config';
export function buildNavModel(ds: DataSource, plugin: PluginMeta, currentPage: string): NavModel { // Types
import { NavModel } from 'app/types';
import { PluginMeta, DataSourceSettings } from '@grafana/ui/src/types';
export function buildNavModel(ds: DataSourceSettings, plugin: PluginMeta, currentPage: string): NavModel {
let title = 'New'; let title = 'New';
const subTitle = `Type: ${plugin.name}`; const subTitle = `Type: ${plugin.name}`;

View File

@@ -3,6 +3,7 @@ import Cascader from 'rc-cascader';
import PluginPrism from 'slate-prism'; import PluginPrism from 'slate-prism';
import Prism from 'prismjs'; import Prism from 'prismjs';
import { DataQuery } from '@grafana/ui/src/types';
import { TypeaheadOutput } from 'app/types/explore'; import { TypeaheadOutput } from 'app/types/explore';
// dom also includes Element polyfills // dom also includes Element polyfills
@@ -10,7 +11,6 @@ import { getNextCharacter, getPreviousCousin } from 'app/features/explore/utils/
import BracesPlugin from 'app/features/explore/slate-plugins/braces'; import BracesPlugin from 'app/features/explore/slate-plugins/braces';
import RunnerPlugin from 'app/features/explore/slate-plugins/runner'; import RunnerPlugin from 'app/features/explore/slate-plugins/runner';
import QueryField, { TypeaheadInput, QueryFieldState } from 'app/features/explore/QueryField'; import QueryField, { TypeaheadInput, QueryFieldState } from 'app/features/explore/QueryField';
import { DataQuery } from 'app/types';
const PRISM_SYNTAX = 'promql'; const PRISM_SYNTAX = 'promql';

View File

@@ -2,7 +2,7 @@ import _ from 'lodash';
import * as dateMath from 'app/core/utils/datemath'; import * as dateMath from 'app/core/utils/datemath';
import { LogsStream, LogsModel, makeSeriesForLogs } from 'app/core/logs_model'; import { LogsStream, LogsModel, makeSeriesForLogs } from 'app/core/logs_model';
import { PluginMeta, DataQuery } from 'app/types'; import { PluginMeta, DataQuery } from '@grafana/ui/src/types';
import { addLabelToSelector } from 'app/plugins/datasource/prometheus/add_label_to_query'; import { addLabelToSelector } from 'app/plugins/datasource/prometheus/add_label_to_query';
import LanguageProvider from './language_provider'; import LanguageProvider from './language_provider';

View File

@@ -11,7 +11,7 @@ import {
} from 'app/types/explore'; } from 'app/types/explore';
import { parseSelector, labelRegexp, selectorRegexp } from 'app/plugins/datasource/prometheus/language_utils'; import { parseSelector, labelRegexp, selectorRegexp } from 'app/plugins/datasource/prometheus/language_utils';
import syntax from './syntax'; import syntax from './syntax';
import { DataQuery } from 'app/types'; import { DataQuery } from '@grafana/ui/src/types';
const DEFAULT_KEYS = ['job', 'namespace']; const DEFAULT_KEYS = ['job', 'namespace'];
const EMPTY_SELECTOR = '{}'; const EMPTY_SELECTOR = '{}';

View File

@@ -11,7 +11,7 @@ import { getNextCharacter, getPreviousCousin } from 'app/features/explore/utils/
import BracesPlugin from 'app/features/explore/slate-plugins/braces'; import BracesPlugin from 'app/features/explore/slate-plugins/braces';
import RunnerPlugin from 'app/features/explore/slate-plugins/runner'; import RunnerPlugin from 'app/features/explore/slate-plugins/runner';
import QueryField, { TypeaheadInput, QueryFieldState } from 'app/features/explore/QueryField'; import QueryField, { TypeaheadInput, QueryFieldState } from 'app/features/explore/QueryField';
import { DataQuery } from 'app/types'; import { DataQuery } from '@grafana/ui/src/types';
const HISTOGRAM_GROUP = '__histograms__'; const HISTOGRAM_GROUP = '__histograms__';
const METRIC_MARK = 'metric'; const METRIC_MARK = 'metric';

View File

@@ -11,7 +11,7 @@ import { BackendSrv } from 'app/core/services/backend_srv';
import addLabelToQuery from './add_label_to_query'; import addLabelToQuery from './add_label_to_query';
import { getQueryHints } from './query_hints'; import { getQueryHints } from './query_hints';
import { expandRecordingRules } from './language_utils'; import { expandRecordingRules } from './language_utils';
import { DataQuery } from 'app/types'; import { DataQuery } from '@grafana/ui/src/types';
import { ExploreUrlState } from 'app/types/explore'; import { ExploreUrlState } from 'app/types/explore';
export function alignRange(start, end, step) { export function alignRange(start, end, step) {

View File

@@ -1,6 +1,5 @@
import _ from 'lodash'; import _ from 'lodash';
import { QueryHint } from '@grafana/ui/src/types';
import { QueryHint } from 'app/types/explore';
/** /**
* Number of time series results needed before starting to suggest sum aggregation hints * Number of time series results needed before starting to suggest sum aggregation hints

View File

@@ -0,0 +1,66 @@
// Libraries
import React, { PureComponent } from 'react';
import _ from 'lodash';
// Services & Utils
import { getBackendSrv, BackendSrv } from 'app/core/services/backend_srv';
// Components
import { FormLabel, Select, SelectOptionItem } from '@grafana/ui';
// Types
import { QueryEditorProps } from '@grafana/ui/src/types';
interface Scenario {
id: string;
name: string;
}
interface State {
scenarioList: Scenario[];
current: Scenario | null;
}
export class QueryEditor extends PureComponent<QueryEditorProps> {
backendSrv: BackendSrv = getBackendSrv();
state: State = {
scenarioList: [],
current: null,
};
async componentDidMount() {
const { query } = this.props;
query.scenarioId = query.scenarioId || 'random_walk';
const scenarioList = await this.backendSrv.get('/api/tsdb/testdata/scenarios');
const current = _.find(scenarioList, { id: query.scenarioId });
this.setState({ scenarioList: scenarioList, current: current });
}
onScenarioChange = (item: SelectOptionItem) => {
this.props.onQueryChange({
scenarioId: item.value,
...this.props.query
});
}
render() {
const { query } = this.props;
const options = this.state.scenarioList.map(item => ({ label: item.name, value: item.id }));
const current = options.find(item => item.value === query.scenarioId);
return (
<div className="gf-form-inline">
<div className="gf-form">
<FormLabel className="query-keyword" width={7}>
Scenario
</FormLabel>
<Select options={options} value={current} onChange={this.onScenarioChange} />
</div>
</div>
);
}
}

View File

@@ -1,5 +1,6 @@
import { TestDataDatasource } from './datasource'; import { TestDataDatasource } from './datasource';
import { TestDataQueryCtrl } from './query_ctrl'; import { TestDataQueryCtrl } from './query_ctrl';
// import { QueryEditor } from './QueryEditor';
class TestDataAnnotationsQueryCtrl { class TestDataAnnotationsQueryCtrl {
annotation: any; annotation: any;
@@ -10,7 +11,7 @@ class TestDataAnnotationsQueryCtrl {
} }
export { export {
TestDataDatasource, // QueryEditor,
TestDataDatasource as Datasource, TestDataDatasource as Datasource,
TestDataQueryCtrl as QueryCtrl, TestDataQueryCtrl as QueryCtrl,
TestDataAnnotationsQueryCtrl as AnnotationsQueryCtrl, TestDataAnnotationsQueryCtrl as AnnotationsQueryCtrl,

View File

@@ -14,7 +14,7 @@ import DataSourcesListPage from 'app/features/datasources/DataSourcesListPage';
import NewDataSourcePage from '../features/datasources/NewDataSourcePage'; import NewDataSourcePage from '../features/datasources/NewDataSourcePage';
import UsersListPage from 'app/features/users/UsersListPage'; import UsersListPage from 'app/features/users/UsersListPage';
import DataSourceDashboards from 'app/features/datasources/DataSourceDashboards'; import DataSourceDashboards from 'app/features/datasources/DataSourceDashboards';
import DataSourceSettings from '../features/datasources/settings/DataSourceSettings'; import DataSourceSettingsPage from '../features/datasources/settings/DataSourceSettingsPage';
import OrgDetailsPage from '../features/org/OrgDetailsPage'; import OrgDetailsPage from '../features/org/OrgDetailsPage';
/** @ngInject */ /** @ngInject */
@@ -78,7 +78,7 @@ export function setupAngularRoutes($routeProvider, $locationProvider) {
.when('/datasources/edit/:id/', { .when('/datasources/edit/:id/', {
template: '<react-container />', template: '<react-container />',
resolve: { resolve: {
component: () => DataSourceSettings, component: () => DataSourceSettingsPage,
}, },
}) })
.when('/datasources/edit/:id/dashboards', { .when('/datasources/edit/:id/dashboards', {

View File

@@ -1,43 +1,15 @@
import { LayoutMode } from '../core/components/LayoutSelector/LayoutSelector'; import { LayoutMode } from '../core/components/LayoutSelector/LayoutSelector';
import { Plugin, PluginExports, PluginMeta } from './plugins'; import { Plugin } from './plugins';
import { DataSourceSettings } from '@grafana/ui/src/types';
export interface DataSource {
id: number;
orgId: number;
name: string;
typeLogoUrl: string;
type: string;
access: string;
url: string;
password: string;
user: string;
database: string;
basicAuth: boolean;
basicAuthPassword: string;
basicAuthUser: string;
isDefault: boolean;
jsonData: { authType: string; defaultRegion: string };
readOnly: boolean;
withCredentials: boolean;
meta?: PluginMeta;
pluginExports?: PluginExports;
}
export interface DataSourceSelectItem {
name: string;
value: string | null;
meta: PluginMeta;
sort: string;
}
export interface DataSourcesState { export interface DataSourcesState {
dataSources: DataSource[]; dataSources: DataSourceSettings[];
searchQuery: string; searchQuery: string;
dataSourceTypeSearchQuery: string; dataSourceTypeSearchQuery: string;
layoutMode: LayoutMode; layoutMode: LayoutMode;
dataSourcesCount: number; dataSourcesCount: number;
dataSourceTypes: Plugin[]; dataSourceTypes: Plugin[];
dataSource: DataSource; dataSource: DataSourceSettings;
dataSourceMeta: Plugin; dataSourceMeta: Plugin;
hasFetched: boolean; hasFetched: boolean;
} }

View File

@@ -1,12 +1,9 @@
import { Value } from 'slate'; import { Value } from 'slate';
import { RawTimeRange, TimeRange } from '@grafana/ui'; import { RawTimeRange, TimeRange, DataQuery, DataSourceSelectItem, DataSourceApi, QueryHint } from '@grafana/ui';
import { Emitter } from 'app/core/core'; import { Emitter } from 'app/core/core';
import { LogsModel } from 'app/core/logs_model'; import { LogsModel } from 'app/core/logs_model';
import TableModel from 'app/core/table_model'; import TableModel from 'app/core/table_model';
import { DataSourceSelectItem } from 'app/types/datasources';
import { DataQuery } from './series';
export interface CompletionItem { export interface CompletionItem {
/** /**
@@ -113,7 +110,7 @@ export interface ExploreItemState {
/** /**
* Datasource instance that has been selected. Datasource-specific logic can be run on this object. * Datasource instance that has been selected. Datasource-specific logic can be run on this object.
*/ */
datasourceInstance: any; datasourceInstance: DataSourceApi;
/** /**
* Error to be shown when datasource loading or testing failed. * Error to be shown when datasource loading or testing failed.
*/ */
@@ -276,28 +273,6 @@ export interface TypeaheadOutput {
suggestions: CompletionItemGroup[]; suggestions: CompletionItemGroup[];
} }
export interface QueryFix {
type: string;
label: string;
action?: QueryFixAction;
}
export interface QueryFixAction {
type: string;
query?: string;
preventSubmit?: boolean;
}
export interface QueryHint {
type: string;
label: string;
fix?: QueryFix;
}
export interface QueryHintGetter {
(query: DataQuery, results: any[], ...rest: any): QueryHint[];
}
export interface QueryIntervals { export interface QueryIntervals {
interval: string; interval: string;
intervalMs: number; intervalMs: number;

View File

@@ -1,90 +1,19 @@
import { Team, TeamsState, TeamState, TeamGroup, TeamMember } from './teams'; export * from './teams';
import { AlertRuleDTO, AlertRule, AlertRulesState } from './alerting'; export * from './alerting';
import { LocationState, LocationUpdate, UrlQueryMap, UrlQueryValue } from './location'; export * from './location';
import { NavModel, NavModelItem, NavIndex } from './navModel'; export * from './navModel';
import { FolderDTO, FolderState, FolderInfo } from './folders'; export * from './folders';
import { DashboardState } from './dashboard'; export * from './dashboard';
import { DashboardAcl, OrgRole, PermissionLevel } from './acl'; export * from './acl';
import { ApiKey, ApiKeysState, NewApiKey } from './apiKeys'; export * from './apiKeys';
import { Invitee, OrgUser, User, UsersState, UserState } from './user'; export * from './user';
import { DataSource, DataSourceSelectItem, DataSourcesState } from './datasources'; export * from './datasources';
import { DataQuery, DataQueryResponse, DataQueryOptions } from './series'; export * from './plugins';
import { PluginDashboard, PluginMeta, Plugin, PanelPlugin, PluginsState } from './plugins'; export * from './organization';
import { Organization, OrganizationState } from './organization'; export * from './appNotifications';
import { export * from './search';
AppNotification, export * from './form';
AppNotificationSeverity, export * from './explore';
AppNotificationsState, export * from './store';
AppNotificationTimeout,
} from './appNotifications';
import { DashboardSearchHit } from './search';
import { ValidationEvents, ValidationRule } from './form';
import { ExploreState } from './explore';
export {
Team,
TeamsState,
TeamState,
TeamGroup,
TeamMember,
AlertRuleDTO,
AlertRule,
AlertRulesState,
LocationState,
LocationUpdate,
NavModel,
NavModelItem,
NavIndex,
UrlQueryMap,
UrlQueryValue,
FolderDTO,
FolderState,
FolderInfo,
DashboardState,
DashboardAcl,
OrgRole,
PermissionLevel,
DataSource,
DataSourceSelectItem,
PluginMeta,
ApiKey,
ApiKeysState,
NewApiKey,
Plugin,
PluginsState,
DataSourcesState,
Invitee,
OrgUser,
User,
UsersState,
PanelPlugin,
DataQuery,
DataQueryResponse,
DataQueryOptions,
PluginDashboard,
Organization,
OrganizationState,
AppNotification,
AppNotificationsState,
AppNotificationSeverity,
AppNotificationTimeout,
DashboardSearchHit,
UserState,
ValidationEvents,
ValidationRule,
};
export interface StoreState {
navIndex: NavIndex;
location: LocationState;
alertRules: AlertRulesState;
teams: TeamsState;
team: TeamState;
folder: FolderState;
dashboard: DashboardState;
dataSources: DataSourcesState;
explore: ExploreState;
users: UsersState;
organization: OrganizationState;
appNotifications: AppNotificationsState;
user: UserState;
}

View File

@@ -1,22 +1,4 @@
import { ComponentClass } from 'react'; import { PluginExports, PluginMetaInfo } from '@grafana/ui/src/types';
import { PanelProps, PanelOptionsProps } from '@grafana/ui';
export interface PluginExports {
Datasource?: any;
QueryCtrl?: any;
QueryEditor?: any;
ConfigCtrl?: any;
AnnotationsQueryCtrl?: any;
VariableQueryEditor?: any;
ExploreQueryField?: any;
ExploreStartPage?: any;
// Panel plugin
PanelCtrl?;
Panel?: ComponentClass<PanelProps>;
PanelOptions?: ComponentClass<PanelOptionsProps>;
PanelDefaults?: any;
}
export interface PanelPlugin { export interface PanelPlugin {
id: string; id: string;
@@ -29,56 +11,6 @@ export interface PanelPlugin {
exports?: PluginExports; exports?: PluginExports;
} }
interface PluginMetaQueryOptions {
cacheTimeout?: boolean;
maxDataPoints?: boolean;
minInterval?: boolean;
}
export interface PluginMeta {
id: string;
name: string;
info: PluginMetaInfo;
includes: PluginInclude[];
// Datasource-specific
metrics?: boolean;
tables?: boolean;
logs?: boolean;
explore?: boolean;
annotations?: boolean;
mixed?: boolean;
hasQueryHelp?: boolean;
queryOptions?: PluginMetaQueryOptions;
}
export interface PluginInclude {
type: string;
name: string;
path: string;
}
interface PluginMetaInfoLink {
name: string;
url: string;
}
export interface PluginMetaInfo {
author: {
name: string;
url?: string;
};
description: string;
links: PluginMetaInfoLink[];
logos: {
large: string;
small: string;
};
screenshots: any[];
updated: string;
version: string;
}
export interface Plugin { export interface Plugin {
defaultNavUrl: string; defaultNavUrl: string;
enabled: boolean; enabled: boolean;

View File

@@ -1,56 +0,0 @@
import { PluginMeta, PluginExports } from './plugins';
import { TimeSeries, TimeRange, RawTimeRange } from '@grafana/ui';
export interface DataQueryResponse {
data: TimeSeries[];
}
export interface DataQuery {
refId: string;
[key: string]: any;
}
export interface DataQueryOptions {
timezone: string;
range: TimeRange;
rangeRaw: RawTimeRange;
targets: DataQuery[];
panelId: number;
dashboardId: number;
cacheTimeout?: string;
interval: string;
intervalMs: number;
maxDataPoints: number;
scopedVars: object;
}
export interface DataSourceApi {
name: string;
meta: PluginMeta;
pluginExports: PluginExports;
/**
* min interval range
*/
interval?: string;
/**
* Imports queries from a different datasource
*/
importQueries?(queries: DataQuery[], originMeta: PluginMeta): Promise<DataQuery[]>;
/**
* Initializes a datasource after instantiation
*/
init?: () => void;
/**
* Main metrics / data query action
*/
query(options: DataQueryOptions): Promise<DataQueryResponse>;
/**
* Test & verify datasource settings & connection details
*/
testDatasource(): Promise<any>;
}

27
public/app/types/store.ts Normal file
View File

@@ -0,0 +1,27 @@
import { NavIndex } from './navModel';
import { LocationState } from './location';
import { AlertRulesState } from './alerting';
import { TeamsState, TeamState } from './teams';
import { FolderState } from './folders';
import { DashboardState } from './dashboard';
import { DataSourcesState } from './datasources';
import { ExploreState } from './explore';
import { UsersState, UserState } from './user';
import { OrganizationState } from './organization';
import { AppNotificationsState } from './appNotifications';
export interface StoreState {
navIndex: NavIndex;
location: LocationState;
alertRules: AlertRulesState;
teams: TeamsState;
team: TeamState;
folder: FolderState;
dashboard: DashboardState;
dataSources: DataSourcesState;
explore: ExploreState;
users: UsersState;
organization: OrganizationState;
appNotifications: AppNotificationsState;
user: UserState;
}