react-panel: Finish the data source search on query tab and start moving switch-data-source-logic from angular
This commit is contained in:
@@ -2,13 +2,14 @@ import React, { PureComponent } from 'react';
|
|||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
import _ from 'lodash';
|
import _ from 'lodash';
|
||||||
|
|
||||||
import { getDatasourceSrv } from 'app/features/plugins/datasource_srv';
|
|
||||||
import { DataSourceSelectItem } from 'app/types';
|
import { DataSourceSelectItem } from 'app/types';
|
||||||
|
|
||||||
interface Props {}
|
interface Props {
|
||||||
|
onChangeDataSource: (ds: any) => void;
|
||||||
|
datasources: DataSourceSelectItem[];
|
||||||
|
}
|
||||||
|
|
||||||
interface State {
|
interface State {
|
||||||
datasources: DataSourceSelectItem[];
|
|
||||||
searchQuery: string;
|
searchQuery: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -17,31 +18,32 @@ export class DataSourcePicker extends PureComponent<Props, State> {
|
|||||||
|
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
|
|
||||||
this.state = {
|
this.state = {
|
||||||
datasources: getDatasourceSrv().getMetricSources(),
|
|
||||||
searchQuery: '',
|
searchQuery: '',
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
getDataSources() {
|
getDataSources() {
|
||||||
const { datasources, searchQuery } = this.state;
|
const { searchQuery } = this.state;
|
||||||
const regex = new RegExp(searchQuery, 'i');
|
const regex = new RegExp(searchQuery, 'i');
|
||||||
|
const { datasources } = this.props;
|
||||||
|
|
||||||
const filtered = datasources.filter(item => {
|
const filtered = datasources.filter(item => {
|
||||||
return regex.test(item.name) || regex.test(item.meta.name);
|
return regex.test(item.name) || regex.test(item.meta.name);
|
||||||
});
|
});
|
||||||
|
|
||||||
return _.sortBy(filtered, 'sort');
|
return filtered;
|
||||||
}
|
}
|
||||||
|
|
||||||
renderDataSource = (ds: DataSourceSelectItem, index) => {
|
renderDataSource = (ds: DataSourceSelectItem, index: number) => {
|
||||||
|
const { onChangeDataSource } = this.props;
|
||||||
|
const onClick = () => onChangeDataSource(ds);
|
||||||
const cssClass = classNames({
|
const cssClass = classNames({
|
||||||
'ds-picker-list__item': true,
|
'ds-picker-list__item': true,
|
||||||
});
|
});
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div key={index} className={cssClass} title={ds.name}>
|
<div key={index} className={cssClass} title={ds.name} onClick={onClick}>
|
||||||
<img className="ds-picker-list__img" src={ds.meta.info.logos.small} />
|
<img className="ds-picker-list__img" src={ds.meta.info.logos.small} />
|
||||||
<div className="ds-picker-list__name">{ds.name}</div>
|
<div className="ds-picker-list__name">{ds.name}</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -54,7 +56,16 @@ export class DataSourcePicker extends PureComponent<Props, State> {
|
|||||||
}, 300);
|
}, 300);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
onSearchQueryChange = evt => {
|
||||||
|
const value = evt.target.value;
|
||||||
|
this.setState(prevState => ({
|
||||||
|
...prevState,
|
||||||
|
searchQuery: value,
|
||||||
|
}));
|
||||||
|
};
|
||||||
|
|
||||||
renderFilters() {
|
renderFilters() {
|
||||||
|
const { searchQuery } = this.state;
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<label className="gf-form--has-input-icon">
|
<label className="gf-form--has-input-icon">
|
||||||
@@ -63,6 +74,8 @@ export class DataSourcePicker extends PureComponent<Props, State> {
|
|||||||
className="gf-form-input width-13"
|
className="gf-form-input width-13"
|
||||||
placeholder=""
|
placeholder=""
|
||||||
ref={elem => (this.searchInput = elem)}
|
ref={elem => (this.searchInput = elem)}
|
||||||
|
onChange={this.onSearchQueryChange}
|
||||||
|
value={searchQuery}
|
||||||
/>
|
/>
|
||||||
<i className="gf-form-input-icon fa fa-search" />
|
<i className="gf-form-input-icon fa fa-search" />
|
||||||
</label>
|
</label>
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ export interface EditorToolBarView {
|
|||||||
title: string;
|
title: string;
|
||||||
imgSrc?: string;
|
imgSrc?: string;
|
||||||
icon?: string;
|
icon?: string;
|
||||||
render: () => JSX.Element;
|
render: (closeFunction: any) => JSX.Element;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface State {
|
interface State {
|
||||||
@@ -64,7 +64,7 @@ export class EditorTabBody extends PureComponent<Props, State> {
|
|||||||
<button className="toolbar-subview__close" onClick={this.onCloseOpenView}>
|
<button className="toolbar-subview__close" onClick={this.onCloseOpenView}>
|
||||||
<i className="fa fa-chevron-up" />
|
<i className="fa fa-chevron-up" />
|
||||||
</button>
|
</button>
|
||||||
{view.render()}
|
{view.render(this.onCloseOpenView)}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -72,7 +72,6 @@ export class EditorTabBody extends PureComponent<Props, State> {
|
|||||||
render() {
|
render() {
|
||||||
const { children, toolbarItems, main } = this.props;
|
const { children, toolbarItems, main } = this.props;
|
||||||
const { openView } = this.state;
|
const { openView } = this.state;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
{main && (
|
{main && (
|
||||||
|
|||||||
@@ -7,18 +7,33 @@ import { DataSourcePicker } from './DataSourcePicker';
|
|||||||
import { PanelModel } from '../panel_model';
|
import { PanelModel } from '../panel_model';
|
||||||
import { DashboardModel } from '../dashboard_model';
|
import { DashboardModel } from '../dashboard_model';
|
||||||
import './../../panel/metrics_tab';
|
import './../../panel/metrics_tab';
|
||||||
|
import config from 'app/core/config';
|
||||||
|
|
||||||
|
// Services
|
||||||
|
import { getDatasourceSrv } from 'app/features/plugins/datasource_srv';
|
||||||
|
import { DataSourceSelectItem } from 'app/types';
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
panel: PanelModel;
|
panel: PanelModel;
|
||||||
dashboard: DashboardModel;
|
dashboard: DashboardModel;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class QueriesTab extends PureComponent<Props> {
|
interface State {
|
||||||
|
currentDatasource: DataSourceSelectItem;
|
||||||
|
}
|
||||||
|
|
||||||
|
export class QueriesTab extends PureComponent<Props, State> {
|
||||||
element: any;
|
element: any;
|
||||||
component: AngularComponent;
|
component: AngularComponent;
|
||||||
|
datasources: DataSourceSelectItem[] = getDatasourceSrv().getMetricSources();
|
||||||
|
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
|
const { panel } = props;
|
||||||
|
|
||||||
|
this.state = {
|
||||||
|
currentDatasource: this.datasources.find(datasource => datasource.value === panel.datasource),
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
@@ -47,11 +62,47 @@ export class QueriesTab extends PureComponent<Props> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
onChangeDataSource = datasource => {
|
||||||
|
const { panel } = this.props;
|
||||||
|
const { currentDatasource } = this.state;
|
||||||
|
// switching to mixed
|
||||||
|
if (datasource.meta.mixed) {
|
||||||
|
panel.targets.forEach(target => {
|
||||||
|
target.datasource = panel.datasource;
|
||||||
|
if (!target.datasource) {
|
||||||
|
target.datasource = config.defaultDatasource;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else if (currentDatasource && currentDatasource.meta.mixed) {
|
||||||
|
panel.targets.forEach(target => {
|
||||||
|
delete target.datasource;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
panel.datasource = datasource.value;
|
||||||
|
panel.refresh();
|
||||||
|
|
||||||
|
this.setState(prevState => ({
|
||||||
|
...prevState,
|
||||||
|
currentDatasource: datasource,
|
||||||
|
}));
|
||||||
|
// this.component.digest();
|
||||||
|
};
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const currentDataSource = {
|
const { currentDatasource } = this.state;
|
||||||
title: 'ProductionDB',
|
const dsInformation = {
|
||||||
imgSrc: 'public/app/plugins/datasource/prometheus/img/prometheus_logo.svg',
|
title: currentDatasource.name,
|
||||||
render: () => <DataSourcePicker />,
|
imgSrc: currentDatasource.meta.info.logos.small,
|
||||||
|
render: closeOpenView => (
|
||||||
|
<DataSourcePicker
|
||||||
|
datasources={this.datasources}
|
||||||
|
onChangeDataSource={ds => {
|
||||||
|
closeOpenView();
|
||||||
|
this.onChangeDataSource(ds);
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
),
|
||||||
};
|
};
|
||||||
|
|
||||||
const queryInspector = {
|
const queryInspector = {
|
||||||
@@ -66,7 +117,7 @@ export class QueriesTab extends PureComponent<Props> {
|
|||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<EditorTabBody main={currentDataSource} toolbarItems={[queryInspector, dsHelp]}>
|
<EditorTabBody main={dsInformation} toolbarItems={[queryInspector, dsHelp]}>
|
||||||
<div ref={element => (this.element = element)} style={{ width: '100%' }} />
|
<div ref={element => (this.element = element)} style={{ width: '100%' }} />
|
||||||
</EditorTabBody>
|
</EditorTabBody>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ export class MetricsTabCtrl {
|
|||||||
this.datasources = datasourceSrv.getMetricSources();
|
this.datasources = datasourceSrv.getMetricSources();
|
||||||
this.panelDsValue = this.panelCtrl.panel.datasource;
|
this.panelDsValue = this.panelCtrl.panel.datasource;
|
||||||
|
|
||||||
// addded here as old query controller expects this on panelCtrl but
|
// added here as old query controller expects this on panelCtrl but
|
||||||
// they are getting MetricsTabCtrl instead
|
// they are getting MetricsTabCtrl instead
|
||||||
this.events = this.panel.events;
|
this.events = this.panel.events;
|
||||||
|
|
||||||
|
|||||||
@@ -37,6 +37,7 @@ export interface PluginMeta {
|
|||||||
logs?: boolean;
|
logs?: boolean;
|
||||||
explore?: boolean;
|
explore?: boolean;
|
||||||
annotations?: boolean;
|
annotations?: boolean;
|
||||||
|
mixed?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface PluginInclude {
|
export interface PluginInclude {
|
||||||
|
|||||||
Reference in New Issue
Block a user