mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Chore: Remove unused Loki and Cloudwatch syntax providers (#29686)
* Remove syntax provider in Cloudwatch * Remove syntax provider and refactor useLokiLabels
This commit is contained in:
parent
854f6229f7
commit
dbf0470994
@ -7,8 +7,6 @@ import { InlineFormLabel } from '@grafana/ui';
|
||||
import { CloudWatchDatasource } from '../datasource';
|
||||
import { CloudWatchLogsQuery, CloudWatchQuery } from '../types';
|
||||
import { CloudWatchLogsQueryField } from './LogsQueryField';
|
||||
import { useCloudWatchSyntax } from '../useCloudwatchSyntax';
|
||||
import { CloudWatchLanguageProvider } from '../language_provider';
|
||||
import CloudWatchLink from './CloudWatchLink';
|
||||
import { css } from 'emotion';
|
||||
|
||||
@ -36,11 +34,6 @@ export const CloudWatchLogsQueryEditor = memo(function CloudWatchLogsQueryEditor
|
||||
};
|
||||
}
|
||||
|
||||
const { isSyntaxReady, syntax } = useCloudWatchSyntax(
|
||||
datasource.languageProvider as CloudWatchLanguageProvider,
|
||||
absolute
|
||||
);
|
||||
|
||||
return (
|
||||
<CloudWatchLogsQueryField
|
||||
exploreId={exploreId}
|
||||
@ -52,8 +45,6 @@ export const CloudWatchLogsQueryEditor = memo(function CloudWatchLogsQueryEditor
|
||||
history={[]}
|
||||
data={data}
|
||||
absoluteRange={absolute}
|
||||
syntaxLoaded={isSyntaxReady}
|
||||
syntax={syntax}
|
||||
allowCustomValue={allowCustomValue}
|
||||
ExtraFieldElement={
|
||||
<InlineFormLabel className={`gf-form-label--btn ${labelClass}`} width="auto" tooltip="Link to Graph in AWS">
|
||||
|
@ -17,8 +17,6 @@ describe('CloudWatchLogsQueryField', () => {
|
||||
<CloudWatchLogsQueryField
|
||||
history={[]}
|
||||
absoluteRange={{ from: 1, to: 10 }}
|
||||
syntaxLoaded={false}
|
||||
syntax={{} as any}
|
||||
exploreId={ExploreId.left}
|
||||
datasource={
|
||||
{
|
||||
@ -153,8 +151,6 @@ describe('CloudWatchLogsQueryField', () => {
|
||||
<CloudWatchLogsQueryField
|
||||
history={[]}
|
||||
absoluteRange={{ from: 1, to: 10 }}
|
||||
syntaxLoaded={false}
|
||||
syntax={{} as any}
|
||||
exploreId={ExploreId.left}
|
||||
datasource={
|
||||
{
|
||||
|
@ -24,7 +24,7 @@ import syntax from '../syntax';
|
||||
import { ExploreQueryFieldProps, AbsoluteTimeRange, SelectableValue, AppEvents } from '@grafana/data';
|
||||
import { CloudWatchQuery, CloudWatchLogsQuery } from '../types';
|
||||
import { CloudWatchDatasource } from '../datasource';
|
||||
import { Grammar, LanguageMap, languages as prismLanguages } from 'prismjs';
|
||||
import { LanguageMap, languages as prismLanguages } from 'prismjs';
|
||||
import { CloudWatchLanguageProvider } from '../language_provider';
|
||||
import { css } from 'emotion';
|
||||
import { ExploreId } from 'app/types';
|
||||
@ -36,8 +36,6 @@ export interface CloudWatchLogsQueryFieldProps extends ExploreQueryFieldProps<Cl
|
||||
absoluteRange: AbsoluteTimeRange;
|
||||
onLabelsRefresh?: () => void;
|
||||
ExtraFieldElement?: ReactNode;
|
||||
syntaxLoaded: boolean;
|
||||
syntax: Grammar | null;
|
||||
exploreId: ExploreId;
|
||||
allowCustomValue?: boolean;
|
||||
}
|
||||
@ -294,7 +292,7 @@ export class CloudWatchLogsQueryField extends React.PureComponent<CloudWatchLogs
|
||||
};
|
||||
|
||||
render() {
|
||||
const { ExtraFieldElement, data, query, syntaxLoaded, datasource, allowCustomValue } = this.props;
|
||||
const { ExtraFieldElement, data, query, datasource, allowCustomValue } = this.props;
|
||||
const {
|
||||
selectedLogGroups,
|
||||
availableLogGroups,
|
||||
@ -375,7 +373,6 @@ export class CloudWatchLogsQueryField extends React.PureComponent<CloudWatchLogs
|
||||
cleanText={cleanText}
|
||||
placeholder="Enter a CloudWatch Logs Insights query (run with Shift+Enter)"
|
||||
portalOrigin="cloudwatch"
|
||||
syntaxLoaded={syntaxLoaded}
|
||||
disabled={loadingLogGroups || selectedLogGroups.length === 0}
|
||||
/>
|
||||
</div>
|
||||
|
@ -1,66 +0,0 @@
|
||||
import { useState, useEffect } from 'react';
|
||||
import { Grammar } from 'prismjs';
|
||||
import { AbsoluteTimeRange } from '@grafana/data';
|
||||
import { useRefMounted } from 'app/core/hooks/useRefMounted';
|
||||
import { CloudWatchLanguageProvider } from './language_provider';
|
||||
|
||||
/**
|
||||
* 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: CloudWatchLanguageProvider, 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 useCloudwatchSyntax = (languageProvider: CloudWatchLanguageProvider, languageProviderInitialized: boolean) => {
|
||||
// State
|
||||
const [syntax, setSyntax] = useState<Grammar | null>(null);
|
||||
|
||||
// Effects
|
||||
useEffect(() => {
|
||||
if (languageProviderInitialized) {
|
||||
const syntax = languageProvider.getSyntax();
|
||||
setSyntax(syntax);
|
||||
}
|
||||
}, [languageProviderInitialized, languageProvider]);
|
||||
|
||||
return {
|
||||
isSyntaxReady: !!syntax,
|
||||
syntax,
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* Initializes given language provider, exposes Loki syntax and enables loading label option values
|
||||
*/
|
||||
export const useCloudWatchSyntax = (languageProvider: CloudWatchLanguageProvider, absoluteRange: AbsoluteTimeRange) => {
|
||||
const languageProviderInitialized = useInitLanguageProvider(languageProvider, absoluteRange);
|
||||
const { isSyntaxReady, syntax } = useCloudwatchSyntax(languageProvider, languageProviderInitialized);
|
||||
|
||||
return {
|
||||
isSyntaxReady,
|
||||
syntax,
|
||||
};
|
||||
};
|
@ -3,7 +3,7 @@ import React, { memo } from 'react';
|
||||
|
||||
// Types
|
||||
import { LokiQuery } from '../types';
|
||||
import { useLokiSyntaxAndLabels } from './useLokiSyntaxAndLabels';
|
||||
import { useLokiLabels } from './useLokiLabels';
|
||||
import { LokiQueryFieldForm } from './LokiQueryFieldForm';
|
||||
import LokiDatasource from '../datasource';
|
||||
|
||||
@ -22,7 +22,7 @@ export const LokiAnnotationsQueryEditor = memo(function LokiAnnotationQueryEdito
|
||||
to: Date.now(),
|
||||
};
|
||||
|
||||
const { isSyntaxReady, setActiveOption, refreshLabels, syntax, logLabelOptions } = useLokiSyntaxAndLabels(
|
||||
const { setActiveOption, refreshLabels, logLabelOptions, labelsLoaded } = useLokiLabels(
|
||||
datasource.languageProvider,
|
||||
absolute
|
||||
);
|
||||
@ -43,8 +43,7 @@ export const LokiAnnotationsQueryEditor = memo(function LokiAnnotationQueryEdito
|
||||
onLoadOptions={setActiveOption}
|
||||
onLabelsRefresh={refreshLabels}
|
||||
absoluteRange={absolute}
|
||||
syntax={syntax}
|
||||
syntaxLoaded={isSyntaxReady}
|
||||
labelsLoaded={labelsLoaded}
|
||||
logLabelOptions={logLabelOptions}
|
||||
/>
|
||||
</div>
|
||||
|
@ -1,18 +1,18 @@
|
||||
import React, { FunctionComponent } from 'react';
|
||||
import { LokiQueryFieldForm, LokiQueryFieldFormProps } from './LokiQueryFieldForm';
|
||||
import { useLokiSyntaxAndLabels } from './useLokiSyntaxAndLabels';
|
||||
import { useLokiLabels } from './useLokiLabels';
|
||||
import LokiLanguageProvider from '../language_provider';
|
||||
|
||||
type LokiQueryFieldProps = Omit<
|
||||
LokiQueryFieldFormProps,
|
||||
'syntax' | 'syntaxLoaded' | 'onLoadOptions' | 'onLabelsRefresh' | 'logLabelOptions' | 'absoluteRange'
|
||||
'labelsLoaded' | 'onLoadOptions' | 'onLabelsRefresh' | 'logLabelOptions' | 'absoluteRange'
|
||||
>;
|
||||
|
||||
export const LokiQueryField: FunctionComponent<LokiQueryFieldProps> = props => {
|
||||
const { datasource, range, ...otherProps } = props;
|
||||
const absoluteTimeRange = { from: range!.from!.valueOf(), to: range!.to!.valueOf() }; // Range here is never optional
|
||||
|
||||
const { isSyntaxReady, setActiveOption, refreshLabels, syntax, logLabelOptions } = useLokiSyntaxAndLabels(
|
||||
const { setActiveOption, refreshLabels, logLabelOptions, labelsLoaded } = useLokiLabels(
|
||||
datasource.languageProvider as LokiLanguageProvider,
|
||||
absoluteTimeRange
|
||||
);
|
||||
@ -29,8 +29,7 @@ export const LokiQueryField: FunctionComponent<LokiQueryFieldProps> = props => {
|
||||
onLoadOptions={setActiveOption}
|
||||
onLabelsRefresh={refreshLabels}
|
||||
absoluteRange={absoluteTimeRange}
|
||||
syntax={syntax}
|
||||
syntaxLoaded={isSyntaxReady}
|
||||
labelsLoaded={labelsLoaded}
|
||||
logLabelOptions={logLabelOptions}
|
||||
{...otherProps}
|
||||
/>
|
||||
|
@ -20,7 +20,7 @@ import { Plugin, Node } from 'slate';
|
||||
import { DOMUtil } from '@grafana/ui';
|
||||
import { ExploreQueryFieldProps, AbsoluteTimeRange } from '@grafana/data';
|
||||
import { LokiQuery, LokiOptions } from '../types';
|
||||
import { Grammar, LanguageMap, languages as prismLanguages } from 'prismjs';
|
||||
import { LanguageMap, languages as prismLanguages } from 'prismjs';
|
||||
import LokiLanguageProvider, { LokiHistoryItem } from '../language_provider';
|
||||
import LokiDatasource from '../datasource';
|
||||
import LokiOptionFields from './LokiOptionFields';
|
||||
@ -64,9 +64,8 @@ function willApplySuggestion(suggestion: string, { typeaheadContext, typeaheadTe
|
||||
|
||||
export interface LokiQueryFieldFormProps extends ExploreQueryFieldProps<LokiDatasource, LokiQuery, LokiOptions> {
|
||||
history: LokiHistoryItem[];
|
||||
syntax: Grammar | null;
|
||||
logLabelOptions: CascaderOption[];
|
||||
syntaxLoaded: boolean;
|
||||
labelsLoaded: boolean;
|
||||
absoluteRange: AbsoluteTimeRange;
|
||||
onLoadOptions: (selectedOptions: CascaderOption[]) => void;
|
||||
onLabelsRefresh?: () => void;
|
||||
@ -140,18 +139,19 @@ export class LokiQueryFieldForm extends React.PureComponent<LokiQueryFieldFormPr
|
||||
const {
|
||||
ExtraFieldElement,
|
||||
query,
|
||||
syntaxLoaded,
|
||||
labelsLoaded,
|
||||
logLabelOptions,
|
||||
onLoadOptions,
|
||||
onLabelsRefresh,
|
||||
datasource,
|
||||
runOnBlur,
|
||||
} = this.props;
|
||||
|
||||
const lokiLanguageProvider = datasource.languageProvider as LokiLanguageProvider;
|
||||
const cleanText = datasource.languageProvider ? lokiLanguageProvider.cleanText : undefined;
|
||||
const hasLogLabels = logLabelOptions && logLabelOptions.length > 0;
|
||||
const chooserText = getChooserText(syntaxLoaded, hasLogLabels);
|
||||
const buttonDisabled = !(syntaxLoaded && hasLogLabels);
|
||||
const chooserText = getChooserText(labelsLoaded, hasLogLabels);
|
||||
const buttonDisabled = !(labelsLoaded && hasLogLabels);
|
||||
|
||||
return (
|
||||
<>
|
||||
@ -179,7 +179,6 @@ export class LokiQueryFieldForm extends React.PureComponent<LokiQueryFieldFormPr
|
||||
onRunQuery={this.props.onRunQuery}
|
||||
placeholder="Enter a Loki query (run with Shift+Enter)"
|
||||
portalOrigin="loki"
|
||||
syntaxLoaded={syntaxLoaded}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -1,19 +1,25 @@
|
||||
import { renderHook, act } from '@testing-library/react-hooks';
|
||||
import LanguageProvider from 'app/plugins/datasource/loki/language_provider';
|
||||
import { useLokiLabels } from './useLokiLabels';
|
||||
import { getLokiLabels, useLokiLabels } from './useLokiLabels';
|
||||
import { AbsoluteTimeRange } from '@grafana/data';
|
||||
import { makeMockLokiDatasource } from '../mocks';
|
||||
import { CascaderOption } from '@grafana/ui';
|
||||
|
||||
describe('useLokiLabels hook', () => {
|
||||
// Mocks
|
||||
const datasource = makeMockLokiDatasource({});
|
||||
const languageProvider = new LanguageProvider(datasource);
|
||||
|
||||
const logLabelOptionsMock = ['Holy mock!'];
|
||||
const logLabelOptionsMock2 = ['Mock the hell?!'];
|
||||
const logLabelOptionsMock3 = ['Oh my mock!'];
|
||||
|
||||
const rangeMock: AbsoluteTimeRange = {
|
||||
from: 1560153109000,
|
||||
to: 1560153109000,
|
||||
};
|
||||
|
||||
describe('getLokiLabels hook', () => {
|
||||
it('should refresh labels', async () => {
|
||||
const datasource = makeMockLokiDatasource({});
|
||||
const languageProvider = new LanguageProvider(datasource);
|
||||
const logLabelOptionsMock = ['Holy mock!'];
|
||||
const rangeMock: AbsoluteTimeRange = {
|
||||
from: 1560153109000,
|
||||
to: 1560153109000,
|
||||
};
|
||||
|
||||
languageProvider.logLabelOptions = ['initial'];
|
||||
|
||||
languageProvider.refreshLogLabels = () => {
|
||||
@ -21,10 +27,64 @@ describe('useLokiLabels hook', () => {
|
||||
return Promise.resolve();
|
||||
};
|
||||
|
||||
const { result, waitForNextUpdate } = renderHook(() => useLokiLabels(languageProvider, true, rangeMock));
|
||||
const { result, waitForNextUpdate } = renderHook(() => getLokiLabels(languageProvider, true, rangeMock));
|
||||
expect(result.current.logLabelOptions).toEqual(['initial']);
|
||||
act(() => result.current.refreshLabels());
|
||||
await waitForNextUpdate();
|
||||
expect(result.current.logLabelOptions).toEqual(logLabelOptionsMock);
|
||||
});
|
||||
});
|
||||
|
||||
describe('useLokiLabels hook', () => {
|
||||
languageProvider.refreshLogLabels = () => {
|
||||
languageProvider.logLabelOptions = logLabelOptionsMock;
|
||||
return Promise.resolve();
|
||||
};
|
||||
|
||||
languageProvider.fetchLogLabels = () => {
|
||||
languageProvider.logLabelOptions = logLabelOptionsMock2;
|
||||
return Promise.resolve([]);
|
||||
};
|
||||
|
||||
const activeOptionMock: CascaderOption = {
|
||||
label: '',
|
||||
value: '',
|
||||
};
|
||||
|
||||
it('should fetch labels on first call', async () => {
|
||||
const { result, waitForNextUpdate } = renderHook(() => useLokiLabels(languageProvider, rangeMock));
|
||||
expect(result.current.logLabelOptions).toEqual([]);
|
||||
|
||||
await waitForNextUpdate();
|
||||
|
||||
expect(result.current.logLabelOptions).toEqual(logLabelOptionsMock2);
|
||||
});
|
||||
|
||||
it('should try to fetch missing options when active option changes', async () => {
|
||||
const { result, waitForNextUpdate } = renderHook(() => useLokiLabels(languageProvider, rangeMock));
|
||||
await waitForNextUpdate();
|
||||
expect(result.current.logLabelOptions).toEqual(logLabelOptionsMock2);
|
||||
|
||||
languageProvider.fetchLabelValues = (key: string, absoluteRange: AbsoluteTimeRange) => {
|
||||
languageProvider.logLabelOptions = logLabelOptionsMock3;
|
||||
return Promise.resolve([]);
|
||||
};
|
||||
|
||||
act(() => result.current.setActiveOption([activeOptionMock]));
|
||||
|
||||
await waitForNextUpdate();
|
||||
|
||||
expect(result.current.logLabelOptions).toEqual(logLabelOptionsMock3);
|
||||
});
|
||||
|
||||
it('should refresh labels', async () => {
|
||||
const { result, waitForNextUpdate } = renderHook(() => useLokiLabels(languageProvider, rangeMock));
|
||||
|
||||
expect(result.current.logLabelOptions).toEqual([]);
|
||||
|
||||
act(() => result.current.refreshLabels());
|
||||
await waitForNextUpdate();
|
||||
|
||||
expect(result.current.logLabelOptions).toEqual(logLabelOptionsMock);
|
||||
});
|
||||
});
|
||||
|
@ -6,23 +6,50 @@ import { CascaderOption } from '@grafana/ui';
|
||||
import LokiLanguageProvider from 'app/plugins/datasource/loki/language_provider';
|
||||
import { useRefMounted } from 'app/core/hooks/useRefMounted';
|
||||
|
||||
/**
|
||||
* 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;
|
||||
};
|
||||
|
||||
/**
|
||||
*
|
||||
* @param languageProvider
|
||||
* @param languageProviderInitialised
|
||||
* @param languageProviderInitialized
|
||||
* @param absoluteRange
|
||||
*
|
||||
* @description Fetches missing labels and enables labels refresh
|
||||
*/
|
||||
export const useLokiLabels = (
|
||||
export const getLokiLabels = (
|
||||
languageProvider: LokiLanguageProvider,
|
||||
languageProviderInitialised: boolean,
|
||||
languageProviderInitialized: boolean,
|
||||
absoluteRange: AbsoluteTimeRange
|
||||
) => {
|
||||
const mounted = useRefMounted();
|
||||
|
||||
// State
|
||||
const [logLabelOptions, setLogLabelOptions] = useState<any>([]);
|
||||
const [labelsLoaded, setLabelsLoaded] = useState(false);
|
||||
const [shouldTryRefreshLabels, setRefreshLabels] = useState(false);
|
||||
const [prevAbsoluteRange, setPrevAbsoluteRange] = useState<AbsoluteTimeRange | null>(null);
|
||||
/**
|
||||
@ -37,6 +64,7 @@ export const useLokiLabels = (
|
||||
await languageProvider.fetchLabelValues(option, absoluteRange);
|
||||
if (mounted.current) {
|
||||
setLogLabelOptions(languageProvider.logLabelOptions);
|
||||
setLabelsLoaded(true);
|
||||
}
|
||||
};
|
||||
|
||||
@ -56,7 +84,7 @@ export const useLokiLabels = (
|
||||
// It's a subject of activeOption state change only. This is because of specific behavior or rc-cascader
|
||||
// https://github.com/react-component/cascader/blob/master/src/Cascader.jsx#L165
|
||||
useEffect(() => {
|
||||
if (languageProviderInitialised) {
|
||||
if (languageProviderInitialized) {
|
||||
const targetOption = activeOption[activeOption.length - 1];
|
||||
if (targetOption) {
|
||||
const nextOptions = logLabelOptions.map((option: any) => {
|
||||
@ -85,14 +113,35 @@ export const useLokiLabels = (
|
||||
|
||||
// Initialize labels from the provider after it gets initialized (it's initialisation happens outside of this hook)
|
||||
useEffect(() => {
|
||||
if (languageProviderInitialised) {
|
||||
if (languageProviderInitialized) {
|
||||
setLogLabelOptions(languageProvider.logLabelOptions);
|
||||
setLabelsLoaded(true);
|
||||
}
|
||||
}, [languageProviderInitialised]);
|
||||
}, [languageProviderInitialized]);
|
||||
|
||||
return {
|
||||
logLabelOptions,
|
||||
refreshLabels: () => setRefreshLabels(true),
|
||||
setActiveOption,
|
||||
labelsLoaded,
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* Initializes given language provider and enables loading label option values
|
||||
*/
|
||||
export const useLokiLabels = (languageProvider: LokiLanguageProvider, absoluteRange: AbsoluteTimeRange) => {
|
||||
const languageProviderInitialized = useInitLanguageProvider(languageProvider, absoluteRange);
|
||||
const { logLabelOptions, refreshLabels, setActiveOption, labelsLoaded } = getLokiLabels(
|
||||
languageProvider,
|
||||
languageProviderInitialized,
|
||||
absoluteRange
|
||||
);
|
||||
|
||||
return {
|
||||
logLabelOptions,
|
||||
refreshLabels,
|
||||
setActiveOption,
|
||||
labelsLoaded,
|
||||
};
|
||||
};
|
||||
|
@ -1,73 +0,0 @@
|
||||
import { renderHook, act } from '@testing-library/react-hooks';
|
||||
import { AbsoluteTimeRange } from '@grafana/data';
|
||||
import { CascaderOption } from '@grafana/ui';
|
||||
|
||||
import LanguageProvider from 'app/plugins/datasource/loki/language_provider';
|
||||
|
||||
import { useLokiSyntaxAndLabels } from './useLokiSyntaxAndLabels';
|
||||
import { makeMockLokiDatasource } from '../mocks';
|
||||
|
||||
describe('useLokiSyntax hook', () => {
|
||||
const datasource = makeMockLokiDatasource({});
|
||||
const languageProvider = new LanguageProvider(datasource);
|
||||
const logLabelOptionsMock = ['Holy mock!'];
|
||||
const logLabelOptionsMock2 = ['Mock the hell?!'];
|
||||
const logLabelOptionsMock3 = ['Oh my mock!'];
|
||||
|
||||
const rangeMock: AbsoluteTimeRange = {
|
||||
from: 1560153109000,
|
||||
to: 1560163909000,
|
||||
};
|
||||
|
||||
languageProvider.refreshLogLabels = () => {
|
||||
languageProvider.logLabelOptions = logLabelOptionsMock;
|
||||
return Promise.resolve();
|
||||
};
|
||||
|
||||
languageProvider.fetchLogLabels = () => {
|
||||
languageProvider.logLabelOptions = logLabelOptionsMock2;
|
||||
return Promise.resolve([]);
|
||||
};
|
||||
|
||||
const activeOptionMock: CascaderOption = {
|
||||
label: '',
|
||||
value: '',
|
||||
};
|
||||
|
||||
it('should provide Loki syntax when used', async () => {
|
||||
const { result, waitForNextUpdate } = renderHook(() => useLokiSyntaxAndLabels(languageProvider, rangeMock));
|
||||
expect(result.current.syntax).toEqual(null);
|
||||
|
||||
await waitForNextUpdate();
|
||||
|
||||
expect(result.current.syntax).toEqual(languageProvider.getSyntax());
|
||||
});
|
||||
|
||||
it('should fetch labels on first call', async () => {
|
||||
const { result, waitForNextUpdate } = renderHook(() => useLokiSyntaxAndLabels(languageProvider, rangeMock));
|
||||
expect(result.current.isSyntaxReady).toBeFalsy();
|
||||
expect(result.current.logLabelOptions).toEqual([]);
|
||||
|
||||
await waitForNextUpdate();
|
||||
|
||||
expect(result.current.isSyntaxReady).toBeTruthy();
|
||||
expect(result.current.logLabelOptions).toEqual(logLabelOptionsMock2);
|
||||
});
|
||||
|
||||
it('should try to fetch missing options when active option changes', async () => {
|
||||
const { result, waitForNextUpdate } = renderHook(() => useLokiSyntaxAndLabels(languageProvider, rangeMock));
|
||||
await waitForNextUpdate();
|
||||
expect(result.current.logLabelOptions).toEqual(logLabelOptionsMock2);
|
||||
|
||||
languageProvider.fetchLabelValues = (key: string, absoluteRange: AbsoluteTimeRange) => {
|
||||
languageProvider.logLabelOptions = logLabelOptionsMock3;
|
||||
return Promise.resolve([]);
|
||||
};
|
||||
|
||||
act(() => result.current.setActiveOption([activeOptionMock]));
|
||||
|
||||
await waitForNextUpdate();
|
||||
|
||||
expect(result.current.logLabelOptions).toEqual(logLabelOptionsMock3);
|
||||
});
|
||||
});
|
@ -1,76 +0,0 @@
|
||||
import { useState, useEffect } from 'react';
|
||||
import { 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';
|
||||
|
||||
/**
|
||||
* 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>(null);
|
||||
|
||||
// Effects
|
||||
useEffect(() => {
|
||||
if (languageProviderInitialized) {
|
||||
const syntax = languageProvider.getSyntax();
|
||||
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,
|
||||
};
|
||||
};
|
Loading…
Reference in New Issue
Block a user