mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Explore: adds QueryRowErrors component, moves error display to QueryRow (#22438)
* Explore: adds QueryRowErrors component * Explore: updates QueryRow to use QueryRowErrors component * Explore: updates PromQueryField to remove error render * Explore: updates Elastic query field to remove error render * Explore: updates LokiQueryFieldForm to remove error render * Explore: updates QueryRow component - brings back passing errors down * Explore: removes QueryRowErrors component * Explore: updates ErrorContainer component - moves out data filtering * Explore: updates QueryRow component - changes QueryRowErrors to ErrorContainer * Explore: updates Explore component - adds error filtering for ErrorContainer * Explore: updates ErrorContainer and adds a basic test for it * Explore: updates Explore component props name and adds a basic render test * Explore: adds snapshots for Explore and ErrorContainer * Explore: adds a test for error render * Explore: adds a comment to Explore component explaining the way we filter non-query-row-specific errors * Explore: adds getFirstNonQueryRowSpecificError method to explore utilities * Explore: extracts getFirstNonQueryRowSpecificError method and slightly refactors Explore component * Explore: updates Explore component tests to cover non-query-row-specific errors
This commit is contained in:
parent
bbed213115
commit
688283a5cc
@ -541,3 +541,8 @@ export function getIntervals(range: TimeRange, lowLimit: string, resolution: num
|
|||||||
export function deduplicateLogRowsById(rows: LogRowModel[]) {
|
export function deduplicateLogRowsById(rows: LogRowModel[]) {
|
||||||
return _.uniqBy(rows, 'uid');
|
return _.uniqBy(rows, 'uid');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const getFirstNonQueryRowSpecificError = (queryErrors?: DataQueryError[]) => {
|
||||||
|
const refId = getValueWithRefId(queryErrors);
|
||||||
|
return refId ? null : getFirstQueryErrorWithoutRefId(queryErrors);
|
||||||
|
};
|
||||||
|
36
public/app/features/explore/ErrorContainer.test.tsx
Normal file
36
public/app/features/explore/ErrorContainer.test.tsx
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import { DataQueryError } from '@grafana/data';
|
||||||
|
import { shallow } from 'enzyme';
|
||||||
|
import { ErrorContainer } from './ErrorContainer';
|
||||||
|
|
||||||
|
const makeError = (propOverrides?: DataQueryError): DataQueryError => {
|
||||||
|
const queryError: DataQueryError = {
|
||||||
|
data: {
|
||||||
|
message: 'Error data message',
|
||||||
|
error: 'Error data content',
|
||||||
|
},
|
||||||
|
message: 'Error message',
|
||||||
|
status: 'Error status',
|
||||||
|
statusText: 'Error status text',
|
||||||
|
refId: 'A',
|
||||||
|
cancelled: false,
|
||||||
|
};
|
||||||
|
Object.assign(queryError, propOverrides);
|
||||||
|
return queryError;
|
||||||
|
};
|
||||||
|
|
||||||
|
const setup = (propOverrides?: object) => {
|
||||||
|
const props = {
|
||||||
|
queryError: makeError(propOverrides),
|
||||||
|
};
|
||||||
|
|
||||||
|
const wrapper = shallow(<ErrorContainer {...props} />);
|
||||||
|
return wrapper;
|
||||||
|
};
|
||||||
|
|
||||||
|
describe('ErrorContainer', () => {
|
||||||
|
it('should render component', () => {
|
||||||
|
const wrapper = setup();
|
||||||
|
expect(wrapper).toMatchSnapshot();
|
||||||
|
});
|
||||||
|
});
|
@ -1,16 +1,13 @@
|
|||||||
import React, { FunctionComponent } from 'react';
|
import React, { FunctionComponent } from 'react';
|
||||||
import { DataQueryError } from '@grafana/data';
|
import { DataQueryError } from '@grafana/data';
|
||||||
import { FadeIn } from 'app/core/components/Animations/FadeIn';
|
import { FadeIn } from 'app/core/components/Animations/FadeIn';
|
||||||
import { getFirstQueryErrorWithoutRefId, getValueWithRefId } from 'app/core/utils/explore';
|
|
||||||
|
|
||||||
interface Props {
|
export interface ErrorContainerProps {
|
||||||
queryErrors?: DataQueryError[];
|
queryError?: DataQueryError;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const ErrorContainer: FunctionComponent<Props> = props => {
|
export const ErrorContainer: FunctionComponent<ErrorContainerProps> = props => {
|
||||||
const { queryErrors } = props;
|
const { queryError } = props;
|
||||||
const refId = getValueWithRefId(queryErrors);
|
|
||||||
const queryError = refId ? null : getFirstQueryErrorWithoutRefId(queryErrors);
|
|
||||||
const showError = queryError ? true : false;
|
const showError = queryError ? true : false;
|
||||||
const duration = showError ? 100 : 10;
|
const duration = showError ? 100 : 10;
|
||||||
const message = queryError ? queryError.message : null;
|
const message = queryError ? queryError.message : null;
|
||||||
|
165
public/app/features/explore/Explore.test.tsx
Normal file
165
public/app/features/explore/Explore.test.tsx
Normal file
@ -0,0 +1,165 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import {
|
||||||
|
DataSourceApi,
|
||||||
|
LoadingState,
|
||||||
|
ExploreMode,
|
||||||
|
toUtc,
|
||||||
|
DataQueryError,
|
||||||
|
DataQueryRequest,
|
||||||
|
CoreApp,
|
||||||
|
} from '@grafana/data';
|
||||||
|
import { getFirstNonQueryRowSpecificError } from 'app/core/utils/explore';
|
||||||
|
import { ExploreId } from 'app/types/explore';
|
||||||
|
import { shallow } from 'enzyme';
|
||||||
|
import { Explore, ExploreProps } from './Explore';
|
||||||
|
import { scanStopAction } from './state/actionTypes';
|
||||||
|
import { toggleGraph } from './state/actions';
|
||||||
|
import { Provider } from 'react-redux';
|
||||||
|
import { configureStore } from 'app/store/configureStore';
|
||||||
|
|
||||||
|
const setup = (renderMethod: any, propOverrides?: object) => {
|
||||||
|
const props: ExploreProps = {
|
||||||
|
changeSize: jest.fn(),
|
||||||
|
datasourceInstance: {
|
||||||
|
meta: {
|
||||||
|
metrics: true,
|
||||||
|
logs: true,
|
||||||
|
},
|
||||||
|
components: {
|
||||||
|
ExploreStartPage: {},
|
||||||
|
},
|
||||||
|
} as DataSourceApi,
|
||||||
|
datasourceMissing: false,
|
||||||
|
exploreId: ExploreId.left,
|
||||||
|
initializeExplore: jest.fn(),
|
||||||
|
initialized: true,
|
||||||
|
modifyQueries: jest.fn(),
|
||||||
|
update: {
|
||||||
|
datasource: false,
|
||||||
|
queries: false,
|
||||||
|
range: false,
|
||||||
|
mode: false,
|
||||||
|
ui: false,
|
||||||
|
},
|
||||||
|
refreshExplore: jest.fn(),
|
||||||
|
scanning: false,
|
||||||
|
scanRange: {
|
||||||
|
from: '0',
|
||||||
|
to: '0',
|
||||||
|
},
|
||||||
|
scanStart: jest.fn(),
|
||||||
|
scanStopAction: scanStopAction,
|
||||||
|
setQueries: jest.fn(),
|
||||||
|
split: false,
|
||||||
|
queryKeys: [],
|
||||||
|
initialDatasource: 'test',
|
||||||
|
initialQueries: [],
|
||||||
|
initialRange: {
|
||||||
|
from: toUtc('2019-01-01 10:00:00'),
|
||||||
|
to: toUtc('2019-01-01 16:00:00'),
|
||||||
|
raw: {
|
||||||
|
from: 'now-6h',
|
||||||
|
to: 'now',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
mode: ExploreMode.Metrics,
|
||||||
|
initialUI: {
|
||||||
|
showingTable: false,
|
||||||
|
showingGraph: false,
|
||||||
|
showingLogs: false,
|
||||||
|
},
|
||||||
|
isLive: false,
|
||||||
|
syncedTimes: false,
|
||||||
|
updateTimeRange: jest.fn(),
|
||||||
|
graphResult: [],
|
||||||
|
loading: false,
|
||||||
|
absoluteRange: {
|
||||||
|
from: 0,
|
||||||
|
to: 0,
|
||||||
|
},
|
||||||
|
showingGraph: false,
|
||||||
|
showingTable: false,
|
||||||
|
timeZone: 'UTC',
|
||||||
|
onHiddenSeriesChanged: jest.fn(),
|
||||||
|
toggleGraph: toggleGraph,
|
||||||
|
queryResponse: {
|
||||||
|
state: LoadingState.NotStarted,
|
||||||
|
series: [],
|
||||||
|
request: ({
|
||||||
|
requestId: '1',
|
||||||
|
dashboardId: 0,
|
||||||
|
interval: '1s',
|
||||||
|
panelId: 1,
|
||||||
|
scopedVars: {
|
||||||
|
apps: {
|
||||||
|
value: 'value',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
targets: [
|
||||||
|
{
|
||||||
|
refId: 'A',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
timezone: 'UTC',
|
||||||
|
app: CoreApp.Explore,
|
||||||
|
startTime: 0,
|
||||||
|
} as unknown) as DataQueryRequest,
|
||||||
|
error: {} as DataQueryError,
|
||||||
|
timeRange: {
|
||||||
|
from: toUtc('2019-01-01 10:00:00'),
|
||||||
|
to: toUtc('2019-01-01 16:00:00'),
|
||||||
|
raw: {
|
||||||
|
from: 'now-6h',
|
||||||
|
to: 'now',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
originPanelId: 1,
|
||||||
|
addQueryRow: jest.fn(),
|
||||||
|
};
|
||||||
|
|
||||||
|
const store = configureStore();
|
||||||
|
|
||||||
|
Object.assign(props, propOverrides);
|
||||||
|
return renderMethod(
|
||||||
|
<Provider store={store}>
|
||||||
|
<Explore {...props} />
|
||||||
|
</Provider>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const setupErrors = (hasRefId?: boolean) => {
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
message: 'Error message',
|
||||||
|
status: '400',
|
||||||
|
statusText: 'Bad Request',
|
||||||
|
refId: hasRefId ? 'A' : '',
|
||||||
|
},
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
describe('Explore', () => {
|
||||||
|
it('should render component', () => {
|
||||||
|
const wrapper = setup(shallow);
|
||||||
|
expect(wrapper).toMatchSnapshot();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should filter out a query-row-specific error when looking for non-query-row-specific errors', async () => {
|
||||||
|
const queryErrors = setupErrors(true);
|
||||||
|
const queryError = getFirstNonQueryRowSpecificError(queryErrors);
|
||||||
|
expect(queryError).toBeNull();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should not filter out a generic error when looking for non-query-row-specific errors', async () => {
|
||||||
|
const queryErrors = setupErrors();
|
||||||
|
const queryError = getFirstNonQueryRowSpecificError(queryErrors);
|
||||||
|
expect(queryError).not.toBeNull();
|
||||||
|
expect(queryError).toEqual({
|
||||||
|
message: 'Error message',
|
||||||
|
status: '400',
|
||||||
|
statusText: 'Bad Request',
|
||||||
|
refId: '',
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
@ -50,6 +50,7 @@ import {
|
|||||||
getTimeRangeFromUrl,
|
getTimeRangeFromUrl,
|
||||||
getTimeRange,
|
getTimeRange,
|
||||||
lastUsedDatasourceKeyForOrgId,
|
lastUsedDatasourceKeyForOrgId,
|
||||||
|
getFirstNonQueryRowSpecificError,
|
||||||
} from 'app/core/utils/explore';
|
} from 'app/core/utils/explore';
|
||||||
import { Emitter } from 'app/core/utils/emitter';
|
import { Emitter } from 'app/core/utils/emitter';
|
||||||
import { ExploreToolbar } from './ExploreToolbar';
|
import { ExploreToolbar } from './ExploreToolbar';
|
||||||
@ -72,7 +73,7 @@ const getStyles = stylesFactory(() => {
|
|||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
interface ExploreProps {
|
export interface ExploreProps {
|
||||||
changeSize: typeof changeSize;
|
changeSize: typeof changeSize;
|
||||||
datasourceInstance: DataSourceApi;
|
datasourceInstance: DataSourceApi;
|
||||||
datasourceMissing: boolean;
|
datasourceMissing: boolean;
|
||||||
@ -294,6 +295,10 @@ export class Explore extends React.PureComponent<ExploreProps, ExploreState> {
|
|||||||
const StartPage = datasourceInstance?.components?.ExploreStartPage;
|
const StartPage = datasourceInstance?.components?.ExploreStartPage;
|
||||||
const showStartPage = !queryResponse || queryResponse.state === LoadingState.NotStarted;
|
const showStartPage = !queryResponse || queryResponse.state === LoadingState.NotStarted;
|
||||||
|
|
||||||
|
// gets an error without a refID, so non-query-row-related error, like a connection error
|
||||||
|
const queryErrors = queryResponse.error ? [queryResponse.error] : undefined;
|
||||||
|
const queryError = getFirstNonQueryRowSpecificError(queryErrors);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={exploreClass} ref={this.getRef}>
|
<div className={exploreClass} ref={this.getRef}>
|
||||||
<ExploreToolbar exploreId={exploreId} onChangeTime={this.onChangeTime} />
|
<ExploreToolbar exploreId={exploreId} onChangeTime={this.onChangeTime} />
|
||||||
@ -323,7 +328,7 @@ export class Explore extends React.PureComponent<ExploreProps, ExploreState> {
|
|||||||
<span className="btn-title">{'\xA0' + 'Query history'}</span>
|
<span className="btn-title">{'\xA0' + 'Query history'}</span>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<ErrorContainer queryErrors={queryResponse.error ? [queryResponse.error] : undefined} />
|
<ErrorContainer queryError={queryError} />
|
||||||
<AutoSizer onResize={this.onResize} disableHeight>
|
<AutoSizer onResize={this.onResize} disableHeight>
|
||||||
{({ width }) => {
|
{({ width }) => {
|
||||||
if (width === 0) {
|
if (width === 0) {
|
||||||
|
@ -26,6 +26,7 @@ import {
|
|||||||
import { ExploreItemState, ExploreId } from 'app/types/explore';
|
import { ExploreItemState, ExploreId } from 'app/types/explore';
|
||||||
import { Emitter } from 'app/core/utils/emitter';
|
import { Emitter } from 'app/core/utils/emitter';
|
||||||
import { highlightLogsExpressionAction, removeQueryRowAction } from './state/actionTypes';
|
import { highlightLogsExpressionAction, removeQueryRowAction } from './state/actionTypes';
|
||||||
|
import { ErrorContainer } from './ErrorContainer';
|
||||||
|
|
||||||
interface PropsFromParent {
|
interface PropsFromParent {
|
||||||
exploreId: ExploreId;
|
exploreId: ExploreId;
|
||||||
@ -137,43 +138,46 @@ export class QueryRow extends PureComponent<QueryRowProps, QueryRowState> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="query-row">
|
<>
|
||||||
<div className="query-row-field flex-shrink-1">
|
<div className="query-row">
|
||||||
{QueryField ? (
|
<div className="query-row-field flex-shrink-1">
|
||||||
<QueryField
|
{QueryField ? (
|
||||||
datasource={datasourceInstance}
|
<QueryField
|
||||||
query={query}
|
datasource={datasourceInstance}
|
||||||
history={history}
|
query={query}
|
||||||
onRunQuery={this.onRunQuery}
|
history={history}
|
||||||
onBlur={noopOnBlur}
|
onRunQuery={this.onRunQuery}
|
||||||
onChange={this.onChange}
|
onBlur={noopOnBlur}
|
||||||
data={queryResponse}
|
onChange={this.onChange}
|
||||||
absoluteRange={absoluteRange}
|
data={queryResponse}
|
||||||
exploreMode={mode}
|
absoluteRange={absoluteRange}
|
||||||
/>
|
exploreMode={mode}
|
||||||
) : (
|
/>
|
||||||
<QueryEditor
|
) : (
|
||||||
error={queryErrors}
|
<QueryEditor
|
||||||
datasource={datasourceInstance}
|
error={queryErrors}
|
||||||
onQueryChange={this.onChange}
|
datasource={datasourceInstance}
|
||||||
onExecuteQuery={this.onRunQuery}
|
onQueryChange={this.onChange}
|
||||||
initialQuery={query}
|
onExecuteQuery={this.onRunQuery}
|
||||||
exploreEvents={exploreEvents}
|
initialQuery={query}
|
||||||
range={range}
|
exploreEvents={exploreEvents}
|
||||||
textEditModeEnabled={this.state.textEditModeEnabled}
|
range={range}
|
||||||
/>
|
textEditModeEnabled={this.state.textEditModeEnabled}
|
||||||
)}
|
/>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
<QueryRowActions
|
||||||
|
canToggleEditorModes={canToggleEditorModes}
|
||||||
|
isDisabled={query.hide}
|
||||||
|
isNotStarted={isNotStarted}
|
||||||
|
latency={latency}
|
||||||
|
onClickToggleEditorMode={this.onClickToggleEditorMode}
|
||||||
|
onClickToggleDisabled={this.onClickToggleDisabled}
|
||||||
|
onClickRemoveButton={this.onClickRemoveButton}
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
<QueryRowActions
|
{queryErrors.length > 0 && <ErrorContainer queryError={queryErrors[0]} />}
|
||||||
canToggleEditorModes={canToggleEditorModes}
|
</>
|
||||||
isDisabled={query.hide}
|
|
||||||
isNotStarted={isNotStarted}
|
|
||||||
latency={latency}
|
|
||||||
onClickToggleEditorMode={this.onClickToggleEditorMode}
|
|
||||||
onClickToggleDisabled={this.onClickToggleDisabled}
|
|
||||||
onClickRemoveButton={this.onClickRemoveButton}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,33 @@
|
|||||||
|
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||||
|
|
||||||
|
exports[`ErrorContainer should render component 1`] = `
|
||||||
|
<Component
|
||||||
|
duration={100}
|
||||||
|
in={true}
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
className="alert-container"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
className="alert-error alert"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
className="alert-icon"
|
||||||
|
>
|
||||||
|
<i
|
||||||
|
className="fa fa-exclamation-triangle"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
className="alert-body"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
className="alert-title"
|
||||||
|
>
|
||||||
|
Error message
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</Component>
|
||||||
|
`;
|
147
public/app/features/explore/__snapshots__/Explore.test.tsx.snap
Normal file
147
public/app/features/explore/__snapshots__/Explore.test.tsx.snap
Normal file
@ -0,0 +1,147 @@
|
|||||||
|
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||||
|
|
||||||
|
exports[`Explore should render component 1`] = `
|
||||||
|
<ContextProvider
|
||||||
|
value={
|
||||||
|
Object {
|
||||||
|
"store": Object {
|
||||||
|
"dispatch": [Function],
|
||||||
|
"getState": [Function],
|
||||||
|
"replaceReducer": [Function],
|
||||||
|
"subscribe": [Function],
|
||||||
|
Symbol(observable): [Function],
|
||||||
|
},
|
||||||
|
"subscription": Subscription {
|
||||||
|
"handleChangeWrapper": [Function],
|
||||||
|
"listeners": Object {
|
||||||
|
"notify": [Function],
|
||||||
|
},
|
||||||
|
"onStateChange": [Function],
|
||||||
|
"parentSub": undefined,
|
||||||
|
"store": Object {
|
||||||
|
"dispatch": [Function],
|
||||||
|
"getState": [Function],
|
||||||
|
"replaceReducer": [Function],
|
||||||
|
"subscribe": [Function],
|
||||||
|
Symbol(observable): [Function],
|
||||||
|
},
|
||||||
|
"unsubscribe": null,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<Explore
|
||||||
|
absoluteRange={
|
||||||
|
Object {
|
||||||
|
"from": 0,
|
||||||
|
"to": 0,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
addQueryRow={[MockFunction]}
|
||||||
|
changeSize={[MockFunction]}
|
||||||
|
datasourceInstance={
|
||||||
|
Object {
|
||||||
|
"components": Object {
|
||||||
|
"ExploreStartPage": Object {},
|
||||||
|
},
|
||||||
|
"meta": Object {
|
||||||
|
"logs": true,
|
||||||
|
"metrics": true,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
datasourceMissing={false}
|
||||||
|
exploreId="left"
|
||||||
|
graphResult={Array []}
|
||||||
|
initialDatasource="test"
|
||||||
|
initialQueries={Array []}
|
||||||
|
initialRange={
|
||||||
|
Object {
|
||||||
|
"from": "2019-01-01T10:00:00.000Z",
|
||||||
|
"raw": Object {
|
||||||
|
"from": "now-6h",
|
||||||
|
"to": "now",
|
||||||
|
},
|
||||||
|
"to": "2019-01-01T16:00:00.000Z",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
initialUI={
|
||||||
|
Object {
|
||||||
|
"showingGraph": false,
|
||||||
|
"showingLogs": false,
|
||||||
|
"showingTable": false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
initializeExplore={[MockFunction]}
|
||||||
|
initialized={true}
|
||||||
|
isLive={false}
|
||||||
|
loading={false}
|
||||||
|
mode="Metrics"
|
||||||
|
modifyQueries={[MockFunction]}
|
||||||
|
onHiddenSeriesChanged={[MockFunction]}
|
||||||
|
originPanelId={1}
|
||||||
|
queryKeys={Array []}
|
||||||
|
queryResponse={
|
||||||
|
Object {
|
||||||
|
"error": Object {},
|
||||||
|
"request": Object {
|
||||||
|
"app": "explore",
|
||||||
|
"dashboardId": 0,
|
||||||
|
"interval": "1s",
|
||||||
|
"panelId": 1,
|
||||||
|
"requestId": "1",
|
||||||
|
"scopedVars": Object {
|
||||||
|
"apps": Object {
|
||||||
|
"value": "value",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"startTime": 0,
|
||||||
|
"targets": Array [
|
||||||
|
Object {
|
||||||
|
"refId": "A",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
"timezone": "UTC",
|
||||||
|
},
|
||||||
|
"series": Array [],
|
||||||
|
"state": "NotStarted",
|
||||||
|
"timeRange": Object {
|
||||||
|
"from": "2019-01-01T10:00:00.000Z",
|
||||||
|
"raw": Object {
|
||||||
|
"from": "now-6h",
|
||||||
|
"to": "now",
|
||||||
|
},
|
||||||
|
"to": "2019-01-01T16:00:00.000Z",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
refreshExplore={[MockFunction]}
|
||||||
|
scanRange={
|
||||||
|
Object {
|
||||||
|
"from": "0",
|
||||||
|
"to": "0",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
scanStart={[MockFunction]}
|
||||||
|
scanStopAction={[Function]}
|
||||||
|
scanning={false}
|
||||||
|
setQueries={[MockFunction]}
|
||||||
|
showingGraph={false}
|
||||||
|
showingTable={false}
|
||||||
|
split={false}
|
||||||
|
syncedTimes={false}
|
||||||
|
timeZone="UTC"
|
||||||
|
toggleGraph={[Function]}
|
||||||
|
update={
|
||||||
|
Object {
|
||||||
|
"datasource": false,
|
||||||
|
"mode": false,
|
||||||
|
"queries": false,
|
||||||
|
"range": false,
|
||||||
|
"ui": false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
updateTimeRange={[MockFunction]}
|
||||||
|
/>
|
||||||
|
</ContextProvider>
|
||||||
|
`;
|
@ -59,7 +59,7 @@ class ElasticsearchQueryField extends React.PureComponent<Props, State> {
|
|||||||
};
|
};
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { data, query } = this.props;
|
const { query } = this.props;
|
||||||
const { syntaxLoaded } = this.state;
|
const { syntaxLoaded } = this.state;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@ -77,7 +77,6 @@ class ElasticsearchQueryField extends React.PureComponent<Props, State> {
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{data && data.error ? <div className="prom-query-field-info text-error">{data.error.message}</div> : null}
|
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -137,7 +137,6 @@ export class LokiQueryFieldForm extends React.PureComponent<LokiQueryFieldFormPr
|
|||||||
render() {
|
render() {
|
||||||
const {
|
const {
|
||||||
ExtraFieldElement,
|
ExtraFieldElement,
|
||||||
data,
|
|
||||||
query,
|
query,
|
||||||
syntaxLoaded,
|
syntaxLoaded,
|
||||||
logLabelOptions,
|
logLabelOptions,
|
||||||
@ -150,7 +149,6 @@ export class LokiQueryFieldForm extends React.PureComponent<LokiQueryFieldFormPr
|
|||||||
const hasLogLabels = logLabelOptions && logLabelOptions.length > 0;
|
const hasLogLabels = logLabelOptions && logLabelOptions.length > 0;
|
||||||
const chooserText = getChooserText(syntaxLoaded, hasLogLabels);
|
const chooserText = getChooserText(syntaxLoaded, hasLogLabels);
|
||||||
const buttonDisabled = !(syntaxLoaded && hasLogLabels);
|
const buttonDisabled = !(syntaxLoaded && hasLogLabels);
|
||||||
const showError = data && data.error && data.error.refId === query.refId;
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
@ -183,11 +181,6 @@ export class LokiQueryFieldForm extends React.PureComponent<LokiQueryFieldFormPr
|
|||||||
</div>
|
</div>
|
||||||
{ExtraFieldElement}
|
{ExtraFieldElement}
|
||||||
</div>
|
</div>
|
||||||
{showError ? (
|
|
||||||
<div className="query-row-break">
|
|
||||||
<div className="prom-query-field-info text-error">{data.error.message}</div>
|
|
||||||
</div>
|
|
||||||
) : null}
|
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -292,12 +292,11 @@ class PromQueryField extends React.PureComponent<PromQueryFieldProps, PromQueryF
|
|||||||
};
|
};
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { data, query, ExtraFieldElement } = this.props;
|
const { query, ExtraFieldElement } = this.props;
|
||||||
const { metricsOptions, syntaxLoaded, hint } = this.state;
|
const { metricsOptions, syntaxLoaded, hint } = this.state;
|
||||||
const cleanText = this.languageProvider ? this.languageProvider.cleanText : undefined;
|
const cleanText = this.languageProvider ? this.languageProvider.cleanText : undefined;
|
||||||
const chooserText = getChooserText(syntaxLoaded, metricsOptions);
|
const chooserText = getChooserText(syntaxLoaded, metricsOptions);
|
||||||
const buttonDisabled = !(syntaxLoaded && metricsOptions && metricsOptions.length > 0);
|
const buttonDisabled = !(syntaxLoaded && metricsOptions && metricsOptions.length > 0);
|
||||||
const showError = data && data.error && data.error.refId === query.refId;
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
@ -324,11 +323,6 @@ class PromQueryField extends React.PureComponent<PromQueryFieldProps, PromQueryF
|
|||||||
</div>
|
</div>
|
||||||
{ExtraFieldElement}
|
{ExtraFieldElement}
|
||||||
</div>
|
</div>
|
||||||
{showError ? (
|
|
||||||
<div className="query-row-break">
|
|
||||||
<div className="prom-query-field-info text-error">{data.error.message}</div>
|
|
||||||
</div>
|
|
||||||
) : null}
|
|
||||||
{hint ? (
|
{hint ? (
|
||||||
<div className="query-row-break">
|
<div className="query-row-break">
|
||||||
<div className="prom-query-field-info text-warning">
|
<div className="prom-query-field-info text-warning">
|
||||||
|
Loading…
Reference in New Issue
Block a user