mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Loki: Refactor editor and syntax hooks (#21687)
This commit is contained in:
parent
b28eac2626
commit
39f7cff7c7
@ -3,7 +3,7 @@ import React, { memo } from 'react';
|
|||||||
|
|
||||||
// Types
|
// Types
|
||||||
import { LokiQuery } from '../types';
|
import { LokiQuery } from '../types';
|
||||||
import { useLokiSyntax } from './useLokiSyntax';
|
import { useLokiSyntaxAndLabels } from './useLokiSyntaxAndLabels';
|
||||||
import { LokiQueryFieldForm } from './LokiQueryFieldForm';
|
import { LokiQueryFieldForm } from './LokiQueryFieldForm';
|
||||||
import LokiDatasource from '../datasource';
|
import LokiDatasource from '../datasource';
|
||||||
|
|
||||||
@ -22,7 +22,7 @@ export const LokiAnnotationsQueryEditor = memo(function LokiAnnotationQueryEdito
|
|||||||
to: Date.now(),
|
to: Date.now(),
|
||||||
};
|
};
|
||||||
|
|
||||||
const { isSyntaxReady, setActiveOption, refreshLabels, ...syntaxProps } = useLokiSyntax(
|
const { isSyntaxReady, setActiveOption, refreshLabels, syntax, logLabelOptions } = useLokiSyntaxAndLabels(
|
||||||
datasource.languageProvider,
|
datasource.languageProvider,
|
||||||
absolute
|
absolute
|
||||||
);
|
);
|
||||||
@ -43,9 +43,10 @@ export const LokiAnnotationsQueryEditor = memo(function LokiAnnotationQueryEdito
|
|||||||
data={null}
|
data={null}
|
||||||
onLoadOptions={setActiveOption}
|
onLoadOptions={setActiveOption}
|
||||||
onLabelsRefresh={refreshLabels}
|
onLabelsRefresh={refreshLabels}
|
||||||
syntaxLoaded={isSyntaxReady}
|
|
||||||
absoluteRange={absolute}
|
absoluteRange={absolute}
|
||||||
{...syntaxProps}
|
syntax={syntax}
|
||||||
|
syntaxLoaded={isSyntaxReady}
|
||||||
|
logLabelOptions={logLabelOptions}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
@ -6,7 +6,6 @@ import { AbsoluteTimeRange, QueryEditorProps } from '@grafana/data';
|
|||||||
import { LokiDatasource } from '../datasource';
|
import { LokiDatasource } from '../datasource';
|
||||||
import { LokiQuery } from '../types';
|
import { LokiQuery } from '../types';
|
||||||
import { LokiQueryField } from './LokiQueryField';
|
import { LokiQueryField } from './LokiQueryField';
|
||||||
import { useLokiSyntax } from './useLokiSyntax';
|
|
||||||
|
|
||||||
type Props = QueryEditorProps<LokiDatasource, LokiQuery>;
|
type Props = QueryEditorProps<LokiDatasource, LokiQuery>;
|
||||||
|
|
||||||
@ -27,11 +26,6 @@ export const LokiQueryEditor = memo(function LokiQueryEditor(props: Props) {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
const { isSyntaxReady, setActiveOption, refreshLabels, ...syntaxProps } = useLokiSyntax(
|
|
||||||
datasource.languageProvider,
|
|
||||||
absolute
|
|
||||||
);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<LokiQueryField
|
<LokiQueryField
|
||||||
@ -41,11 +35,7 @@ export const LokiQueryEditor = memo(function LokiQueryEditor(props: Props) {
|
|||||||
onRunQuery={onRunQuery}
|
onRunQuery={onRunQuery}
|
||||||
history={[]}
|
history={[]}
|
||||||
data={data}
|
data={data}
|
||||||
onLoadOptions={setActiveOption}
|
|
||||||
onLabelsRefresh={refreshLabels}
|
|
||||||
syntaxLoaded={isSyntaxReady}
|
|
||||||
absoluteRange={absolute}
|
absoluteRange={absolute}
|
||||||
{...syntaxProps}
|
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
@ -1,18 +1,23 @@
|
|||||||
import React, { FunctionComponent } from 'react';
|
import React, { FunctionComponent } from 'react';
|
||||||
import { LokiQueryFieldForm, LokiQueryFieldFormProps } from './LokiQueryFieldForm';
|
import { LokiQueryFieldForm, LokiQueryFieldFormProps } from './LokiQueryFieldForm';
|
||||||
import { useLokiSyntax } from './useLokiSyntax';
|
import { useLokiSyntaxAndLabels } from './useLokiSyntaxAndLabels';
|
||||||
import LokiLanguageProvider from '../language_provider';
|
import LokiLanguageProvider from '../language_provider';
|
||||||
|
|
||||||
export const LokiQueryField: FunctionComponent<LokiQueryFieldFormProps> = ({ datasource, ...otherProps }) => {
|
type LokiQueryFieldProps = Omit<
|
||||||
const { isSyntaxReady, setActiveOption, refreshLabels, ...syntaxProps } = useLokiSyntax(
|
LokiQueryFieldFormProps,
|
||||||
|
'syntax' | 'syntaxLoaded' | 'onLoadOptions' | 'onLabelsRefresh' | 'logLabelOptions'
|
||||||
|
>;
|
||||||
|
|
||||||
|
export const LokiQueryField: FunctionComponent<LokiQueryFieldProps> = props => {
|
||||||
|
const { datasource, absoluteRange, ...otherProps } = props;
|
||||||
|
const { isSyntaxReady, setActiveOption, refreshLabels, syntax, logLabelOptions } = useLokiSyntaxAndLabels(
|
||||||
datasource.languageProvider as LokiLanguageProvider,
|
datasource.languageProvider as LokiLanguageProvider,
|
||||||
otherProps.absoluteRange
|
absoluteRange
|
||||||
);
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<LokiQueryFieldForm
|
<LokiQueryFieldForm
|
||||||
datasource={datasource}
|
datasource={datasource}
|
||||||
syntaxLoaded={isSyntaxReady}
|
|
||||||
/**
|
/**
|
||||||
* setActiveOption name is intentional. Because of the way rc-cascader requests additional data
|
* setActiveOption name is intentional. Because of the way rc-cascader requests additional data
|
||||||
* https://github.com/react-component/cascader/blob/master/src/Cascader.jsx#L165
|
* https://github.com/react-component/cascader/blob/master/src/Cascader.jsx#L165
|
||||||
@ -21,7 +26,10 @@ export const LokiQueryField: FunctionComponent<LokiQueryFieldFormProps> = ({ dat
|
|||||||
*/
|
*/
|
||||||
onLoadOptions={setActiveOption}
|
onLoadOptions={setActiveOption}
|
||||||
onLabelsRefresh={refreshLabels}
|
onLabelsRefresh={refreshLabels}
|
||||||
{...syntaxProps}
|
absoluteRange={absoluteRange}
|
||||||
|
syntax={syntax}
|
||||||
|
syntaxLoaded={isSyntaxReady}
|
||||||
|
logLabelOptions={logLabelOptions}
|
||||||
{...otherProps}
|
{...otherProps}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
|
@ -73,8 +73,6 @@ export interface LokiQueryFieldFormProps extends ExploreQueryFieldProps<LokiData
|
|||||||
|
|
||||||
export class LokiQueryFieldForm extends React.PureComponent<LokiQueryFieldFormProps> {
|
export class LokiQueryFieldForm extends React.PureComponent<LokiQueryFieldFormProps> {
|
||||||
plugins: Plugin[];
|
plugins: Plugin[];
|
||||||
modifiedSearch: string;
|
|
||||||
modifiedQuery: string;
|
|
||||||
|
|
||||||
constructor(props: LokiQueryFieldFormProps, context: React.Context<any>) {
|
constructor(props: LokiQueryFieldFormProps, context: React.Context<any>) {
|
||||||
super(props, context);
|
super(props, context);
|
||||||
|
@ -14,14 +14,16 @@ describe('useLokiLabels hook', () => {
|
|||||||
to: 1560153109000,
|
to: 1560153109000,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
languageProvider.logLabelOptions = ['initial'];
|
||||||
|
|
||||||
languageProvider.refreshLogLabels = () => {
|
languageProvider.refreshLogLabels = () => {
|
||||||
languageProvider.logLabelOptions = logLabelOptionsMock;
|
languageProvider.logLabelOptions = logLabelOptionsMock;
|
||||||
return Promise.resolve();
|
return Promise.resolve();
|
||||||
};
|
};
|
||||||
|
|
||||||
const { result, waitForNextUpdate } = renderHook(() => useLokiLabels(languageProvider, true, [], rangeMock));
|
const { result, waitForNextUpdate } = renderHook(() => useLokiLabels(languageProvider, true, rangeMock));
|
||||||
|
expect(result.current.logLabelOptions).toEqual(['initial']);
|
||||||
act(() => result.current.refreshLabels());
|
act(() => result.current.refreshLabels());
|
||||||
expect(result.current.logLabelOptions).toEqual([]);
|
|
||||||
await waitForNextUpdate();
|
await waitForNextUpdate();
|
||||||
expect(result.current.logLabelOptions).toEqual(logLabelOptionsMock);
|
expect(result.current.logLabelOptions).toEqual(logLabelOptionsMock);
|
||||||
});
|
});
|
||||||
|
@ -9,14 +9,13 @@ import { useRefMounted } from 'app/core/hooks/useRefMounted';
|
|||||||
*
|
*
|
||||||
* @param languageProvider
|
* @param languageProvider
|
||||||
* @param languageProviderInitialised
|
* @param languageProviderInitialised
|
||||||
* @param activeOption rc-cascader provided option used to fetch option's values that hasn't been loaded yet
|
* @param absoluteRange
|
||||||
*
|
*
|
||||||
* @description Fetches missing labels and enables labels refresh
|
* @description Fetches missing labels and enables labels refresh
|
||||||
*/
|
*/
|
||||||
export const useLokiLabels = (
|
export const useLokiLabels = (
|
||||||
languageProvider: LokiLanguageProvider,
|
languageProvider: LokiLanguageProvider,
|
||||||
languageProviderInitialised: boolean,
|
languageProviderInitialised: boolean,
|
||||||
activeOption: CascaderOption[],
|
|
||||||
absoluteRange: AbsoluteTimeRange
|
absoluteRange: AbsoluteTimeRange
|
||||||
) => {
|
) => {
|
||||||
const mounted = useRefMounted();
|
const mounted = useRefMounted();
|
||||||
@ -24,7 +23,12 @@ export const useLokiLabels = (
|
|||||||
// State
|
// State
|
||||||
const [logLabelOptions, setLogLabelOptions] = useState([]);
|
const [logLabelOptions, setLogLabelOptions] = useState([]);
|
||||||
const [shouldTryRefreshLabels, setRefreshLabels] = useState(false);
|
const [shouldTryRefreshLabels, setRefreshLabels] = useState(false);
|
||||||
const [shouldForceRefreshLabels, setForceRefreshLabels] = useState(false);
|
/**
|
||||||
|
* Holds information about currently selected option from rc-cascader to perform effect
|
||||||
|
* that loads option values not fetched yet. Based on that useLokiLabels hook decides whether or not
|
||||||
|
* the option requires additional data fetching
|
||||||
|
*/
|
||||||
|
const [activeOption, setActiveOption] = useState<CascaderOption[]>([]);
|
||||||
|
|
||||||
// Async
|
// Async
|
||||||
const fetchOptionValues = async (option: string) => {
|
const fetchOptionValues = async (option: string) => {
|
||||||
@ -35,11 +39,10 @@ export const useLokiLabels = (
|
|||||||
};
|
};
|
||||||
|
|
||||||
const tryLabelsRefresh = async () => {
|
const tryLabelsRefresh = async () => {
|
||||||
await languageProvider.refreshLogLabels(absoluteRange, shouldForceRefreshLabels);
|
await languageProvider.refreshLogLabels(absoluteRange);
|
||||||
|
|
||||||
if (mounted.current) {
|
if (mounted.current) {
|
||||||
setRefreshLabels(false);
|
setRefreshLabels(false);
|
||||||
setForceRefreshLabels(false);
|
|
||||||
setLogLabelOptions(languageProvider.logLabelOptions);
|
setLogLabelOptions(languageProvider.logLabelOptions);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -68,18 +71,25 @@ export const useLokiLabels = (
|
|||||||
}
|
}
|
||||||
}, [activeOption]);
|
}, [activeOption]);
|
||||||
|
|
||||||
// This effect is performed on shouldTryRefreshLabels or shouldForceRefreshLabels state change only.
|
// This effect is performed on shouldTryRefreshLabels state change only.
|
||||||
// Since shouldTryRefreshLabels is reset AFTER the labels are refreshed we are secured in case of trying to refresh
|
// Since shouldTryRefreshLabels is reset AFTER the labels are refreshed we are secured in case of trying to refresh
|
||||||
// when previous refresh hasn't finished yet
|
// when previous refresh hasn't finished yet
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (shouldTryRefreshLabels || shouldForceRefreshLabels) {
|
if (shouldTryRefreshLabels) {
|
||||||
tryLabelsRefresh();
|
tryLabelsRefresh();
|
||||||
}
|
}
|
||||||
}, [shouldTryRefreshLabels, shouldForceRefreshLabels]);
|
}, [shouldTryRefreshLabels]);
|
||||||
|
|
||||||
|
// Initialize labels from the provider after it gets initialized (it's initialisation happens outside of this hook)
|
||||||
|
useEffect(() => {
|
||||||
|
if (languageProviderInitialised) {
|
||||||
|
setLogLabelOptions(languageProvider.logLabelOptions);
|
||||||
|
}
|
||||||
|
}, [languageProviderInitialised]);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
logLabelOptions,
|
logLabelOptions,
|
||||||
setLogLabelOptions,
|
|
||||||
refreshLabels: () => setRefreshLabels(true),
|
refreshLabels: () => setRefreshLabels(true),
|
||||||
|
setActiveOption,
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
@ -1,60 +0,0 @@
|
|||||||
import { useState, useEffect } from 'react';
|
|
||||||
import Prism from 'prismjs';
|
|
||||||
import { AbsoluteTimeRange } from '@grafana/data';
|
|
||||||
import { CascaderOption } from '@grafana/ui';
|
|
||||||
import LokiLanguageProvider from 'app/plugins/datasource/loki/language_provider';
|
|
||||||
import { useLokiLabels } from 'app/plugins/datasource/loki/components/useLokiLabels';
|
|
||||||
import { useRefMounted } from 'app/core/hooks/useRefMounted';
|
|
||||||
|
|
||||||
const PRISM_SYNTAX = 'promql';
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @param languageProvider
|
|
||||||
* @description Initializes given language provider, exposes Loki syntax and enables loading label option values
|
|
||||||
*/
|
|
||||||
export const useLokiSyntax = (languageProvider: LokiLanguageProvider, absoluteRange: AbsoluteTimeRange) => {
|
|
||||||
const mounted = useRefMounted();
|
|
||||||
// State
|
|
||||||
const [languageProviderInitialized, setLanguageProviderInitilized] = useState(false);
|
|
||||||
const [syntax, setSyntax] = useState(null);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Holds information about currently selected option from rc-cascader to perform effect
|
|
||||||
* that loads option values not fetched yet. Based on that useLokiLabels hook decides whether or not
|
|
||||||
* the option requires additional data fetching
|
|
||||||
*/
|
|
||||||
const [activeOption, setActiveOption] = useState<CascaderOption[]>();
|
|
||||||
|
|
||||||
const { logLabelOptions, setLogLabelOptions, refreshLabels } = useLokiLabels(
|
|
||||||
languageProvider,
|
|
||||||
languageProviderInitialized,
|
|
||||||
activeOption,
|
|
||||||
absoluteRange
|
|
||||||
);
|
|
||||||
|
|
||||||
// Async
|
|
||||||
const initializeLanguageProvider = async () => {
|
|
||||||
languageProvider.initialRange = absoluteRange;
|
|
||||||
await languageProvider.start();
|
|
||||||
Prism.languages[PRISM_SYNTAX] = languageProvider.getSyntax();
|
|
||||||
if (mounted.current) {
|
|
||||||
setLogLabelOptions(languageProvider.logLabelOptions);
|
|
||||||
setSyntax(languageProvider.getSyntax());
|
|
||||||
setLanguageProviderInitilized(true);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// Effects
|
|
||||||
useEffect(() => {
|
|
||||||
initializeLanguageProvider();
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
return {
|
|
||||||
isSyntaxReady: languageProviderInitialized,
|
|
||||||
syntax,
|
|
||||||
logLabelOptions,
|
|
||||||
setActiveOption,
|
|
||||||
refreshLabels,
|
|
||||||
};
|
|
||||||
};
|
|
@ -4,7 +4,7 @@ import { CascaderOption } from '@grafana/ui';
|
|||||||
|
|
||||||
import LanguageProvider from 'app/plugins/datasource/loki/language_provider';
|
import LanguageProvider from 'app/plugins/datasource/loki/language_provider';
|
||||||
|
|
||||||
import { useLokiSyntax } from './useLokiSyntax';
|
import { useLokiSyntaxAndLabels } from './useLokiSyntaxAndLabels';
|
||||||
import { makeMockLokiDatasource } from '../mocks';
|
import { makeMockLokiDatasource } from '../mocks';
|
||||||
|
|
||||||
describe('useLokiSyntax hook', () => {
|
describe('useLokiSyntax hook', () => {
|
||||||
@ -35,7 +35,7 @@ describe('useLokiSyntax hook', () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
it('should provide Loki syntax when used', async () => {
|
it('should provide Loki syntax when used', async () => {
|
||||||
const { result, waitForNextUpdate } = renderHook(() => useLokiSyntax(languageProvider, rangeMock));
|
const { result, waitForNextUpdate } = renderHook(() => useLokiSyntaxAndLabels(languageProvider, rangeMock));
|
||||||
expect(result.current.syntax).toEqual(null);
|
expect(result.current.syntax).toEqual(null);
|
||||||
|
|
||||||
await waitForNextUpdate();
|
await waitForNextUpdate();
|
||||||
@ -44,7 +44,7 @@ describe('useLokiSyntax hook', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should fetch labels on first call', async () => {
|
it('should fetch labels on first call', async () => {
|
||||||
const { result, waitForNextUpdate } = renderHook(() => useLokiSyntax(languageProvider, rangeMock));
|
const { result, waitForNextUpdate } = renderHook(() => useLokiSyntaxAndLabels(languageProvider, rangeMock));
|
||||||
expect(result.current.isSyntaxReady).toBeFalsy();
|
expect(result.current.isSyntaxReady).toBeFalsy();
|
||||||
expect(result.current.logLabelOptions).toEqual([]);
|
expect(result.current.logLabelOptions).toEqual([]);
|
||||||
|
|
||||||
@ -55,7 +55,7 @@ describe('useLokiSyntax hook', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should try to fetch missing options when active option changes', async () => {
|
it('should try to fetch missing options when active option changes', async () => {
|
||||||
const { result, waitForNextUpdate } = renderHook(() => useLokiSyntax(languageProvider, rangeMock));
|
const { result, waitForNextUpdate } = renderHook(() => useLokiSyntaxAndLabels(languageProvider, rangeMock));
|
||||||
await waitForNextUpdate();
|
await waitForNextUpdate();
|
||||||
expect(result.current.logLabelOptions).toEqual(logLabelOptionsMock2);
|
expect(result.current.logLabelOptions).toEqual(logLabelOptionsMock2);
|
||||||
|
|
@ -0,0 +1,79 @@
|
|||||||
|
import { useState, useEffect } from 'react';
|
||||||
|
import Prism, { Grammar } from 'prismjs';
|
||||||
|
import { AbsoluteTimeRange } from '@grafana/data';
|
||||||
|
import LokiLanguageProvider from 'app/plugins/datasource/loki/language_provider';
|
||||||
|
import { useLokiLabels } from 'app/plugins/datasource/loki/components/useLokiLabels';
|
||||||
|
import { useRefMounted } from 'app/core/hooks/useRefMounted';
|
||||||
|
|
||||||
|
const PRISM_SYNTAX = 'promql';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialise the language provider. Returns a languageProviderInitialized boolean cause there does not seem other way
|
||||||
|
* to know if the provider is already initialised or not. By the initialisation it modifies the provided
|
||||||
|
* languageProvider directly.
|
||||||
|
*/
|
||||||
|
const useInitLanguageProvider = (languageProvider: LokiLanguageProvider, absoluteRange: AbsoluteTimeRange) => {
|
||||||
|
const mounted = useRefMounted();
|
||||||
|
|
||||||
|
const [languageProviderInitialized, setLanguageProviderInitialized] = useState(false);
|
||||||
|
|
||||||
|
// Async
|
||||||
|
const initializeLanguageProvider = async () => {
|
||||||
|
languageProvider.initialRange = absoluteRange;
|
||||||
|
await languageProvider.start();
|
||||||
|
if (mounted.current) {
|
||||||
|
setLanguageProviderInitialized(true);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
initializeLanguageProvider();
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
return languageProviderInitialized;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns syntax from languageProvider and initialises global Prism syntax. Waits until languageProvider itself is
|
||||||
|
* initialised (outside of this hook).
|
||||||
|
*/
|
||||||
|
const useLokiSyntax = (languageProvider: LokiLanguageProvider, languageProviderInitialized: boolean) => {
|
||||||
|
// State
|
||||||
|
const [syntax, setSyntax] = useState<Grammar>(null);
|
||||||
|
|
||||||
|
// Effects
|
||||||
|
useEffect(() => {
|
||||||
|
if (languageProviderInitialized) {
|
||||||
|
const syntax = languageProvider.getSyntax();
|
||||||
|
Prism.languages[PRISM_SYNTAX] = syntax;
|
||||||
|
setSyntax(syntax);
|
||||||
|
}
|
||||||
|
}, [languageProviderInitialized, languageProvider]);
|
||||||
|
|
||||||
|
return {
|
||||||
|
isSyntaxReady: !!syntax,
|
||||||
|
syntax,
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initializes given language provider, exposes Loki syntax and enables loading label option values
|
||||||
|
*/
|
||||||
|
export const useLokiSyntaxAndLabels = (languageProvider: LokiLanguageProvider, absoluteRange: AbsoluteTimeRange) => {
|
||||||
|
const languageProviderInitialized = useInitLanguageProvider(languageProvider, absoluteRange);
|
||||||
|
|
||||||
|
const { logLabelOptions, refreshLabels, setActiveOption } = useLokiLabels(
|
||||||
|
languageProvider,
|
||||||
|
languageProviderInitialized,
|
||||||
|
absoluteRange
|
||||||
|
);
|
||||||
|
const { isSyntaxReady, syntax } = useLokiSyntax(languageProvider, languageProviderInitialized);
|
||||||
|
|
||||||
|
return {
|
||||||
|
isSyntaxReady,
|
||||||
|
syntax,
|
||||||
|
logLabelOptions,
|
||||||
|
setActiveOption,
|
||||||
|
refreshLabels,
|
||||||
|
};
|
||||||
|
};
|
@ -13,6 +13,7 @@ import { RATE_RANGES } from '../prometheus/promql';
|
|||||||
|
|
||||||
import LokiDatasource from './datasource';
|
import LokiDatasource from './datasource';
|
||||||
import { CompletionItem, TypeaheadInput, TypeaheadOutput } from '@grafana/ui';
|
import { CompletionItem, TypeaheadInput, TypeaheadOutput } from '@grafana/ui';
|
||||||
|
import { Grammar } from 'prismjs';
|
||||||
|
|
||||||
const DEFAULT_KEYS = ['job', 'namespace'];
|
const DEFAULT_KEYS = ['job', 'namespace'];
|
||||||
const EMPTY_SELECTOR = '{}';
|
const EMPTY_SELECTOR = '{}';
|
||||||
@ -70,7 +71,7 @@ export default class LokiLanguageProvider extends LanguageProvider {
|
|||||||
// Strip syntax chars
|
// Strip syntax chars
|
||||||
cleanText = (s: string) => s.replace(/[{}[\]="(),!~+\-*/^%]/g, '').trim();
|
cleanText = (s: string) => s.replace(/[{}[\]="(),!~+\-*/^%]/g, '').trim();
|
||||||
|
|
||||||
getSyntax() {
|
getSyntax(): Grammar {
|
||||||
return syntax;
|
return syntax;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -188,9 +188,9 @@ class PromQueryField extends React.PureComponent<PromQueryFieldProps, PromQueryF
|
|||||||
remaining.map((task: Promise<any>) => task.then(this.onUpdateLanguage).catch(() => {}));
|
remaining.map((task: Promise<any>) => task.then(this.onUpdateLanguage).catch(() => {}));
|
||||||
})
|
})
|
||||||
.then(() => this.onUpdateLanguage())
|
.then(() => this.onUpdateLanguage())
|
||||||
.catch(({ isCanceled }) => {
|
.catch(err => {
|
||||||
if (isCanceled) {
|
if (!err.isCanceled) {
|
||||||
console.warn('PromQueryField has unmounted, language provider intialization was canceled');
|
throw err;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user