| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193 |
- // Libraries
- import React, { PureComponent } from 'react';
- // Types
- import { Select, DataQuery, DataQueryError, PanelData } from '@grafana/ui';
- import { DataFrame, SelectableValue } from '@grafana/data';
- import { DashboardQuery } from './types';
- import config from 'app/core/config';
- import { css } from 'emotion';
- import { getDatasourceSrv } from 'app/features/plugins/datasource_srv';
- import { PanelModel } from 'app/features/dashboard/state';
- import { SHARED_DASHBODARD_QUERY } from './SharedQueryRunner';
- import { getDashboardSrv } from 'app/features/dashboard/services/DashboardSrv';
- import { filterPanelDataToQuery } from 'app/features/dashboard/panel_editor/QueryEditorRow';
- type ResultInfo = {
- img: string; // The Datasource
- refId: string;
- query: string; // As text
- data: DataFrame[];
- error?: DataQueryError;
- };
- function getQueryDisplayText(query: DataQuery): string {
- return JSON.stringify(query);
- }
- interface Props {
- panel: PanelModel;
- panelData: PanelData;
- onChange: (query: DashboardQuery) => void;
- }
- type State = {
- defaultDatasource: string;
- results: ResultInfo[];
- };
- export class DashboardQueryEditor extends PureComponent<Props, State> {
- constructor(props: Props) {
- super(props);
- this.state = {
- defaultDatasource: '',
- results: [],
- };
- }
- getQuery(): DashboardQuery {
- const { panel } = this.props;
- return panel.targets[0] as DashboardQuery;
- }
- async componentDidMount() {
- this.componentDidUpdate(null);
- }
- async componentDidUpdate(prevProps: Props) {
- const { panelData } = this.props;
- if (!prevProps || prevProps.panelData !== panelData) {
- const query = this.props.panel.targets[0] as DashboardQuery;
- const defaultDS = await getDatasourceSrv().get(null);
- const dashboard = getDashboardSrv().getCurrent();
- const panel = dashboard.getPanelById(query.panelId);
- if (!panel) {
- this.setState({ defaultDatasource: defaultDS.name });
- return;
- }
- const mainDS = await getDatasourceSrv().get(panel.datasource);
- const info: ResultInfo[] = [];
- for (const query of panel.targets) {
- const ds = query.datasource ? await getDatasourceSrv().get(query.datasource) : mainDS;
- const fmt = ds.getQueryDisplayText ? ds.getQueryDisplayText : getQueryDisplayText;
- const qData = filterPanelDataToQuery(panelData, query.refId);
- const queryData = qData ? qData : panelData;
- info.push({
- refId: query.refId,
- query: fmt(query),
- img: ds.meta.info.logos.small,
- data: queryData.series,
- error: queryData.error,
- });
- }
- this.setState({ defaultDatasource: defaultDS.name, results: info });
- }
- }
- onPanelChanged = (id: number) => {
- const { onChange } = this.props;
- const query = this.getQuery();
- query.panelId = id;
- onChange(query);
- // Update the
- this.props.panel.refresh();
- };
- renderQueryData(editURL: string) {
- const { results } = this.state;
- return (
- <div>
- {results.map((target, index) => {
- return (
- <div className="query-editor-row__header" key={index}>
- <div className="query-editor-row__ref-id">
- <img src={target.img} width={16} className={css({ marginRight: '8px' })} />
- {target.refId}:
- </div>
- <div className="query-editor-row__collapsed-text">
- <a href={editURL}>
- {target.query}
-
- <i className="fa fa-external-link" />
- </a>
- </div>
- </div>
- );
- })}
- </div>
- );
- }
- getPanelDescription = (panel: PanelModel): string => {
- const { defaultDatasource } = this.state;
- const dsname = panel.datasource ? panel.datasource : defaultDatasource;
- if (panel.targets.length === 1) {
- return '1 query to ' + dsname;
- }
- return panel.targets.length + ' queries to ' + dsname;
- };
- render() {
- const dashboard = getDashboardSrv().getCurrent();
- const query = this.getQuery();
- let selected: SelectableValue<number>;
- const panels: Array<SelectableValue<number>> = [];
- for (const panel of dashboard.panels) {
- if (panel.targets && panel.datasource !== SHARED_DASHBODARD_QUERY) {
- const plugin = config.panels[panel.type];
- const item = {
- value: panel.id,
- label: panel.title ? panel.title : 'Panel ' + panel.id,
- description: this.getPanelDescription(panel),
- imgUrl: plugin.info.logos.small,
- };
- panels.push(item);
- if (query.panelId === panel.id) {
- selected = item;
- }
- }
- }
- if (panels.length < 1) {
- return (
- <div className={css({ padding: '10px' })}>
- This dashboard does not have other panels. Add queries to other panels and try again
- </div>
- );
- }
- // Same as current URL, but different panelId
- const editURL = `d/${dashboard.uid}/${dashboard.title}?&fullscreen&edit&panelId=${query.panelId}`;
- return (
- <div>
- <div className="gf-form">
- <div className="gf-form-label">Use results from panel</div>
- <Select
- placeholder="Choose Panel"
- isSearchable={true}
- options={panels}
- value={selected}
- onChange={item => this.onPanelChanged(item.value)}
- />
- </div>
- <div className={css({ padding: '16px' })}>{query.panelId && this.renderQueryData(editURL)}</div>
- </div>
- );
- }
- }
|