@grafana/data#AbsoluteTimeRange TypeScript Examples
The following examples show how to use
@grafana/data#AbsoluteTimeRange.
You can vote up the ones you like or vote down the ones you don't like,
and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: timePicker.test.ts From grafana-chinese with Apache License 2.0 | 6 votes |
describe('getZoomedTimeRange', () => {
describe('when called', () => {
it('then it should return correct result', () => {
const { range } = setup();
const expectedRange: AbsoluteTimeRange = {
from: toUtc('2019-01-01 07:00:00').valueOf(),
to: toUtc('2019-01-01 19:00:00').valueOf(),
};
const result = getZoomedTimeRange(range, 2);
expect(result).toEqual(expectedRange);
});
});
});
Example #2
Source File: language_provider.ts From grafana-chinese with Apache License 2.0 | 6 votes |
/**
* Fetch labels for a selector. This is cached by it's args but also by the global timeRange currently selected as
* they can change over requested time.
* @param name
*/
fetchSeriesLabels = async (match: string, absoluteRange: AbsoluteTimeRange): Promise<Record<string, string[]>> => {
const rangeParams: { start?: number; end?: number } = absoluteRange ? rangeToParams(absoluteRange) : {};
const url = '/loki/api/v1/series';
const { start, end } = rangeParams;
const cacheKey = this.generateCacheKey(url, start, end, match);
const params = { match, start, end };
let value = this.seriesCache.get(cacheKey);
if (!value) {
// Clear value when requesting new one. Empty object being truthy also makes sure we don't request twice.
this.seriesCache.set(cacheKey, {});
const data = await this.request(url, params);
const { values } = processLabels(data);
value = values;
this.seriesCache.set(cacheKey, value);
}
return value;
};
Example #3
Source File: language_provider.ts From grafana-chinese with Apache License 2.0 | 6 votes |
async fetchLabelValues(key: string, absoluteRange: AbsoluteTimeRange): Promise<string[]> {
const url = `/api/prom/label/${key}/values`;
let values: string[] = [];
const rangeParams: { start?: number; end?: number } = absoluteRange ? rangeToParams(absoluteRange) : {};
const { start, end } = rangeParams;
const cacheKey = this.generateCacheKey(url, start, end, key);
const params = { start, end };
let value = this.labelsCache.get(cacheKey);
if (!value) {
try {
// Clear value when requesting new one. Empty object being truthy also makes sure we don't request twice.
this.labelsCache.set(cacheKey, []);
const res = await this.request(url, params);
values = res.slice().sort();
value = values;
this.labelsCache.set(cacheKey, value);
// Add to label options
this.logLabelOptions = this.logLabelOptions.map(keyOption => {
if (keyOption.value === key) {
return {
...keyOption,
children: values.map(value => ({ label: value, value })),
};
}
return keyOption;
});
} catch (e) {
console.error(e);
}
}
return value;
}
Example #4
Source File: language_provider.ts From grafana-chinese with Apache License 2.0 | 6 votes |
/**
* Fetches all label keys
* @param absoluteRange Fetches
*/
async fetchLogLabels(absoluteRange: AbsoluteTimeRange): Promise<any> {
const url = '/api/prom/label';
try {
this.logLabelFetchTs = Date.now();
const rangeParams = absoluteRange ? rangeToParams(absoluteRange) : {};
const res = await this.request(url, rangeParams);
this.labelKeys = res.slice().sort();
this.logLabelOptions = this.labelKeys.map((key: string) => ({ label: key, value: key, isLeaf: false }));
} catch (e) {
console.error(e);
}
return [];
}
Example #5
Source File: language_provider.ts From grafana-chinese with Apache License 2.0 | 6 votes |
async getSeriesLabels(selector: string, absoluteRange: AbsoluteTimeRange) {
if (this.lookupsDisabled) {
return undefined;
}
try {
return await this.fetchSeriesLabels(selector, absoluteRange);
} catch (error) {
// TODO: better error handling
console.error(error);
return undefined;
}
}
Example #6
Source File: language_provider.test.ts From grafana-chinese with Apache License 2.0 | 6 votes |
describe('Labels refresh', () => {
const datasource = makeMockLokiDatasource({});
const instance = new LanguageProvider(datasource);
const rangeMock: AbsoluteTimeRange = {
from: 1560153109000,
to: 1560163909000,
};
beforeEach(() => {
instance.fetchLogLabels = jest.fn();
});
afterEach(() => {
jest.clearAllMocks();
clear();
});
it("should not refresh labels if refresh interval hasn't passed", () => {
advanceTo(new Date(2019, 1, 1, 0, 0, 0));
instance.logLabelFetchTs = Date.now();
advanceBy(LABEL_REFRESH_INTERVAL / 2);
instance.refreshLogLabels(rangeMock);
expect(instance.fetchLogLabels).not.toBeCalled();
});
it('should refresh labels if refresh interval passed', () => {
advanceTo(new Date(2019, 1, 1, 0, 0, 0));
instance.logLabelFetchTs = Date.now();
advanceBy(LABEL_REFRESH_INTERVAL + 1);
instance.refreshLogLabels(rangeMock);
expect(instance.fetchLogLabels).toBeCalled();
});
});
Example #7
Source File: language_provider.test.ts From grafana-chinese with Apache License 2.0 | 6 votes |
describe('Request URL', () => {
it('should contain range params', async () => {
const rangeMock: AbsoluteTimeRange = {
from: 1560153109000,
to: 1560163909000,
};
const datasourceWithLabels = makeMockLokiDatasource({ other: [] });
const datasourceSpy = jest.spyOn(datasourceWithLabels as any, 'metadataRequest');
const instance = new LanguageProvider(datasourceWithLabels, { initialRange: rangeMock });
await instance.refreshLogLabels(rangeMock, true);
const expectedUrl = '/api/prom/label';
expect(datasourceSpy).toHaveBeenCalledWith(expectedUrl, rangeToParams(rangeMock));
});
});
Example #8
Source File: useLokiSyntaxAndLabels.ts From grafana-chinese with Apache License 2.0 | 6 votes |
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,
};
}
Example #9
Source File: useLokiSyntaxAndLabels.ts From grafana-chinese with Apache License 2.0 | 6 votes |
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;
}
Example #10
Source File: useLokiLabels.test.ts From grafana-chinese with Apache License 2.0 | 6 votes |
describe('useLokiLabels 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 = () => {
languageProvider.logLabelOptions = logLabelOptionsMock;
return Promise.resolve();
};
const { result, waitForNextUpdate } = renderHook(() => useLokiLabels(languageProvider, true, rangeMock));
expect(result.current.logLabelOptions).toEqual(['initial']);
act(() => result.current.refreshLabels());
await waitForNextUpdate();
expect(result.current.logLabelOptions).toEqual(logLabelOptionsMock);
});
});
Example #11
Source File: LokiQueryEditor.tsx From grafana-chinese with Apache License 2.0 | 6 votes |
LokiQueryEditor = memo(function LokiQueryEditor(props: Props) {
const { query, data, datasource, onChange, onRunQuery } = props;
let absolute: AbsoluteTimeRange;
if (data && data.request) {
const { range } = data.request;
absolute = {
from: range.from.valueOf(),
to: range.to.valueOf(),
};
} else {
absolute = {
from: Date.now() - 10000,
to: Date.now(),
};
}
return (
<div>
<LokiQueryField
datasource={datasource}
query={query}
onChange={onChange}
onRunQuery={onRunQuery}
history={[]}
data={data}
absoluteRange={absolute}
/>
</div>
);
})
Example #12
Source File: actions.ts From grafana-chinese with Apache License 2.0 | 6 votes |
updateTime = (config: {
exploreId: ExploreId;
rawRange?: RawTimeRange;
absoluteRange?: AbsoluteTimeRange;
}): ThunkResult<void> => {
return (dispatch, getState) => {
const { exploreId, absoluteRange: absRange, rawRange: actionRange } = config;
const itemState = getState().explore[exploreId];
const timeZone = getTimeZone(getState().user);
const { range: rangeInState } = itemState;
let rawRange: RawTimeRange = rangeInState.raw;
if (absRange) {
rawRange = {
from: dateTimeForTimeZone(timeZone, absRange.from),
to: dateTimeForTimeZone(timeZone, absRange.to),
};
}
if (actionRange) {
rawRange = actionRange;
}
const range = getTimeRange(timeZone, rawRange);
const absoluteRange: AbsoluteTimeRange = { from: range.from.valueOf(), to: range.to.valueOf() };
getTimeSrv().init({
time: range.raw,
refresh: false,
getTimezone: () => timeZone,
timeRangeUpdated: (): any => undefined,
});
dispatch(changeRangeAction({ exploreId, range, absoluteRange }));
};
}
Example #13
Source File: actions.ts From grafana-chinese with Apache License 2.0 | 6 votes |
updateTimeRange = (options: {
exploreId: ExploreId;
rawRange?: RawTimeRange;
absoluteRange?: AbsoluteTimeRange;
}): ThunkResult<void> => {
return (dispatch, getState) => {
const { syncedTimes } = getState().explore;
if (syncedTimes) {
dispatch(updateTime({ ...options, exploreId: ExploreId.left }));
dispatch(runQueries(ExploreId.left));
dispatch(updateTime({ ...options, exploreId: ExploreId.right }));
dispatch(runQueries(ExploreId.right));
} else {
dispatch(updateTime({ ...options }));
dispatch(runQueries(options.exploreId));
}
};
}
Example #14
Source File: timePicker.ts From grafana-chinese with Apache License 2.0 | 6 votes |
getShiftedTimeRange = (direction: number, origRange: TimeRange): AbsoluteTimeRange => {
const range = {
from: toUtc(origRange.from),
to: toUtc(origRange.to),
};
const timespan = (range.to.valueOf() - range.from.valueOf()) / 2;
let to: number, from: number;
if (direction === -1) {
to = range.to.valueOf() - timespan;
from = range.from.valueOf() - timespan;
} else if (direction === 1) {
to = range.to.valueOf() + timespan;
from = range.from.valueOf() + timespan;
if (to > Date.now() && range.to.valueOf() < Date.now()) {
to = Date.now();
from = range.from.valueOf();
}
} else {
to = range.to.valueOf();
from = range.from.valueOf();
}
return { from, to };
}
Example #15
Source File: timePicker.ts From grafana-chinese with Apache License 2.0 | 6 votes |
getZoomedTimeRange = (range: TimeRange, factor: number): AbsoluteTimeRange => {
const timespan = range.to.valueOf() - range.from.valueOf();
const center = range.to.valueOf() - timespan / 2;
const to = center + (timespan * factor) / 2;
const from = center - (timespan * factor) / 2;
return { from, to };
}
Example #16
Source File: LokiExploreQueryEditor.tsx From grafana-chinese with Apache License 2.0 | 5 votes |
export function LokiExploreQueryEditor(props: Props) {
const { query, data, datasource, exploreMode, history, onChange, onRunQuery } = props;
let absolute: AbsoluteTimeRange;
if (data && !_.isEmpty(data.request)) {
const { range } = data.request;
absolute = {
from: range.from.valueOf(),
to: range.to.valueOf(),
};
} else {
absolute = {
from: Date.now() - 10000,
to: Date.now(),
};
}
function onChangeQueryLimit(value: string) {
const { query, onChange } = props;
const nextQuery = { ...query, maxLines: preprocessMaxLines(value) };
onChange(nextQuery);
}
function preprocessMaxLines(value: string): number {
if (value.length === 0) {
// empty input - falls back to dataSource.maxLines limit
return NaN;
} else if (value.length > 0 && (isNaN(+value) || +value < 0)) {
// input with at least 1 character and that is either incorrect (value in the input field is not a number) or negative
// falls back to the limit of 0 lines
return 0;
} else {
// default case - correct input
return +value;
}
}
function onMaxLinesChange(e: React.SyntheticEvent<HTMLInputElement>) {
if (query.maxLines !== preprocessMaxLines(e.currentTarget.value)) {
onChangeQueryLimit(e.currentTarget.value);
}
}
function onReturnKeyDown(e: React.KeyboardEvent<HTMLInputElement>) {
if (e.key === 'Enter') {
onRunQuery();
}
}
return (
<LokiQueryField
datasource={datasource}
query={query}
onChange={onChange}
onRunQuery={onRunQuery}
history={history}
data={data}
absoluteRange={absolute}
ExtraFieldElement={
exploreMode === ExploreMode.Logs ? (
<LokiExploreExtraField
label={'Line limit'}
onChangeFunc={onMaxLinesChange}
onKeyDownFunc={onReturnKeyDown}
value={query?.maxLines?.toString() || ''}
type={'number'}
min={0}
/>
) : null
}
/>
);
}
Example #17
Source File: language_provider.ts From grafana-chinese with Apache License 2.0 | 5 votes |
rangeToParams = (range: AbsoluteTimeRange) => ({ start: range.from * NS_IN_MS, end: range.to * NS_IN_MS })
Example #18
Source File: timePicker.test.ts From grafana-chinese with Apache License 2.0 | 5 votes |
describe('getShiftedTimeRange', () => {
describe('when called with a direction of -1', () => {
it('then it should return correct result', () => {
const { range, direction } = setup({ direction: -1 });
const expectedRange: AbsoluteTimeRange = {
from: toUtc('2019-01-01 07:00:00').valueOf(),
to: toUtc('2019-01-01 13:00:00').valueOf(),
};
const result = getShiftedTimeRange(direction, range);
expect(result).toEqual(expectedRange);
});
});
describe('when called with a direction of 1', () => {
it('then it should return correct result', () => {
const { range, direction } = setup({ direction: 1 });
const expectedRange: AbsoluteTimeRange = {
from: toUtc('2019-01-01 13:00:00').valueOf(),
to: toUtc('2019-01-01 19:00:00').valueOf(),
};
const result = getShiftedTimeRange(direction, range);
expect(result).toEqual(expectedRange);
});
});
describe('when called with any other direction', () => {
it('then it should return correct result', () => {
const { range, direction } = setup({ direction: 0 });
const expectedRange: AbsoluteTimeRange = {
from: toUtc('2019-01-01 10:00:00').valueOf(),
to: toUtc('2019-01-01 16:00:00').valueOf(),
};
const result = getShiftedTimeRange(direction, range);
expect(result).toEqual(expectedRange);
});
});
});
Example #19
Source File: language_provider.ts From grafana-chinese with Apache License 2.0 | 5 votes |
initialRange: AbsoluteTimeRange;
Example #20
Source File: language_provider.ts From grafana-chinese with Apache License 2.0 | 5 votes |
async refreshLogLabels(absoluteRange: AbsoluteTimeRange, forceRefresh?: boolean) {
if ((this.labelKeys && Date.now() - this.logLabelFetchTs > LABEL_REFRESH_INTERVAL) || forceRefresh) {
await this.fetchLogLabels(absoluteRange);
}
}
Example #21
Source File: PanelChrome.tsx From grafana-chinese with Apache License 2.0 | 5 votes |
onChangeTimeRange = (timeRange: AbsoluteTimeRange) => {
this.timeSrv.setTime({
from: toUtc(timeRange.from),
to: toUtc(timeRange.to),
});
};
Example #22
Source File: Explore.tsx From grafana-chinese with Apache License 2.0 | 5 votes |
onUpdateTimeRange = (absoluteRange: AbsoluteTimeRange) => {
const { exploreId, updateTimeRange } = this.props;
updateTimeRange({ exploreId, absoluteRange });
};
Example #23
Source File: language_provider.test.ts From grafana-chinese with Apache License 2.0 | 5 votes |
describe('Query imports', () => {
const datasource = makeMockLokiDatasource({});
const rangeMock: AbsoluteTimeRange = {
from: 1560153109000,
to: 1560163909000,
};
it('returns empty queries for unknown origin datasource', async () => {
const instance = new LanguageProvider(datasource, { initialRange: rangeMock });
const result = await instance.importQueries([{ refId: 'bar', expr: 'foo' }], 'unknown');
expect(result).toEqual([{ refId: 'bar', expr: '' }]);
});
describe('prometheus query imports', () => {
it('returns empty query from metric-only query', async () => {
const instance = new LanguageProvider(datasource, { initialRange: rangeMock });
const result = await instance.importPrometheusQuery('foo');
expect(result).toEqual('');
});
it('returns empty query from selector query if label is not available', async () => {
const datasourceWithLabels = makeMockLokiDatasource({ other: [] });
const instance = new LanguageProvider(datasourceWithLabels, { initialRange: rangeMock });
const result = await instance.importPrometheusQuery('{foo="bar"}');
expect(result).toEqual('{}');
});
it('returns selector query from selector query with common labels', async () => {
const datasourceWithLabels = makeMockLokiDatasource({ foo: [] });
const instance = new LanguageProvider(datasourceWithLabels, { initialRange: rangeMock });
const result = await instance.importPrometheusQuery('metric{foo="bar",baz="42"}');
expect(result).toEqual('{foo="bar"}');
});
it('returns selector query from selector query with all labels if logging label list is empty', async () => {
const datasourceWithLabels = makeMockLokiDatasource({});
const instance = new LanguageProvider(datasourceWithLabels, { initialRange: rangeMock });
const result = await instance.importPrometheusQuery('metric{foo="bar",baz="42"}');
expect(result).toEqual('{baz="42",foo="bar"}');
});
});
});
Example #24
Source File: LogsContainer.tsx From grafana-chinese with Apache License 2.0 | 5 votes |
onChangeTime = (absoluteRange: AbsoluteTimeRange) => {
const { exploreId, updateTimeRange } = this.props;
updateTimeRange({ exploreId, absoluteRange });
};
Example #25
Source File: useLokiSyntaxAndLabels.test.ts From grafana-chinese with Apache License 2.0 | 5 votes |
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);
});
});
Example #26
Source File: useLokiLabels.ts From grafana-chinese with Apache License 2.0 | 5 votes |
useLokiLabels = (
languageProvider: LokiLanguageProvider,
languageProviderInitialised: boolean,
absoluteRange: AbsoluteTimeRange
) => {
const mounted = useRefMounted();
// State
const [logLabelOptions, setLogLabelOptions] = useState([]);
const [shouldTryRefreshLabels, setRefreshLabels] = 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
const fetchOptionValues = async (option: string) => {
await languageProvider.fetchLabelValues(option, absoluteRange);
if (mounted.current) {
setLogLabelOptions(languageProvider.logLabelOptions);
}
};
const tryLabelsRefresh = async () => {
await languageProvider.refreshLogLabels(absoluteRange);
if (mounted.current) {
setRefreshLabels(false);
setLogLabelOptions(languageProvider.logLabelOptions);
}
};
// Effects
// This effect performs loading of options that hasn't been loaded yet
// 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) {
const targetOption = activeOption[activeOption.length - 1];
if (targetOption) {
const nextOptions = logLabelOptions.map(option => {
if (option.value === targetOption.value) {
return {
...option,
loading: true,
};
}
return option;
});
setLogLabelOptions(nextOptions); // to set loading
fetchOptionValues(targetOption.value);
}
}
}, [activeOption]);
// 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
// when previous refresh hasn't finished yet
useEffect(() => {
if (shouldTryRefreshLabels) {
tryLabelsRefresh();
}
}, [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 {
logLabelOptions,
refreshLabels: () => setRefreshLabels(true),
setActiveOption,
};
}
Example #27
Source File: language_provider.test.ts From grafana-chinese with Apache License 2.0 | 4 votes |
describe('Language completion provider', () => {
const datasource = makeMockLokiDatasource({});
const rangeMock: AbsoluteTimeRange = {
from: 1560153109000,
to: 1560163909000,
};
describe('query suggestions', () => {
it('returns no suggestions on empty context', async () => {
const instance = new LanguageProvider(datasource);
const value = Plain.deserialize('');
const result = await instance.provideCompletionItems({ text: '', prefix: '', value, wrapperClasses: [] });
expect(result.context).toBeUndefined();
expect(result.suggestions.length).toEqual(0);
});
it('returns history on empty context when history was provided', async () => {
const instance = new LanguageProvider(datasource);
const value = Plain.deserialize('');
const history: LokiHistoryItem[] = [
{
query: { refId: '1', expr: '{app="foo"}' },
ts: 1,
},
];
const result = await instance.provideCompletionItems(
{ text: '', prefix: '', value, wrapperClasses: [] },
{ history, absoluteRange: rangeMock }
);
expect(result.context).toBeUndefined();
expect(result.suggestions).toMatchObject([
{
label: 'History',
items: [
{
label: '{app="foo"}',
},
],
},
]);
});
it('returns function and history suggestions', async () => {
const instance = new LanguageProvider(datasource);
const input = createTypeaheadInput('m', 'm', undefined, 1, [], instance);
// Historic expressions don't have to match input, filtering is done in field
const history: LokiHistoryItem[] = [
{
query: { refId: '1', expr: '{app="foo"}' },
ts: 1,
},
];
const result = await instance.provideCompletionItems(input, { history });
expect(result.context).toBeUndefined();
expect(result.suggestions.length).toEqual(2);
expect(result.suggestions[0].label).toEqual('History');
expect(result.suggestions[1].label).toEqual('Functions');
});
});
describe('label key suggestions', () => {
it('returns all label suggestions on empty selector', async () => {
const datasource = makeMockLokiDatasource({ label1: [], label2: [] });
const provider = await getLanguageProvider(datasource);
const input = createTypeaheadInput('{}', '', '', 1);
const result = await provider.provideCompletionItems(input, { absoluteRange: rangeMock });
expect(result.context).toBe('context-labels');
expect(result.suggestions).toEqual([{ items: [{ label: 'label1' }, { label: 'label2' }], label: 'Labels' }]);
});
it('returns all label suggestions on selector when starting to type', async () => {
const datasource = makeMockLokiDatasource({ label1: [], label2: [] });
const provider = await getLanguageProvider(datasource);
const input = createTypeaheadInput('{l}', '', '', 2);
const result = await provider.provideCompletionItems(input, { absoluteRange: rangeMock });
expect(result.context).toBe('context-labels');
expect(result.suggestions).toEqual([{ items: [{ label: 'label1' }, { label: 'label2' }], label: 'Labels' }]);
});
});
describe('label suggestions facetted', () => {
it('returns facetted label suggestions based on selector', async () => {
const datasource = makeMockLokiDatasource(
{ label1: [], label2: [] },
{ '{foo="bar"}': [{ label1: 'label_val1' }] }
);
const provider = await getLanguageProvider(datasource);
const input = createTypeaheadInput('{foo="bar",}', '', '', 11);
const result = await provider.provideCompletionItems(input, { absoluteRange: rangeMock });
expect(result.context).toBe('context-labels');
expect(result.suggestions).toEqual([{ items: [{ label: 'label1' }], label: 'Labels' }]);
});
it('returns facetted label suggestions for multipule selectors', async () => {
const datasource = makeMockLokiDatasource(
{ label1: [], label2: [] },
{ '{baz="42",foo="bar"}': [{ label2: 'label_val2' }] }
);
const provider = await getLanguageProvider(datasource);
const input = createTypeaheadInput('{baz="42",foo="bar",}', '', '', 20);
const result = await provider.provideCompletionItems(input, { absoluteRange: rangeMock });
expect(result.context).toBe('context-labels');
expect(result.suggestions).toEqual([{ items: [{ label: 'label2' }], label: 'Labels' }]);
});
});
describe('label suggestions', () => {
it('returns label values suggestions from Loki', async () => {
const datasource = makeMockLokiDatasource({ label1: ['label1_val1', 'label1_val2'], label2: [] });
const provider = await getLanguageProvider(datasource);
const input = createTypeaheadInput('{label1=}', '=', 'label1');
let result = await provider.provideCompletionItems(input, { absoluteRange: rangeMock });
result = await provider.provideCompletionItems(input, { absoluteRange: rangeMock });
expect(result.context).toBe('context-label-values');
expect(result.suggestions).toEqual([
{ items: [{ label: 'label1_val1' }, { label: 'label1_val2' }], label: 'Label values for "label1"' },
]);
});
});
});
Example #28
Source File: time_region_manager.ts From grafana-chinese with Apache License 2.0 | 4 votes |
addFlotOptions(options: any, panel: any) {
if (!panel.timeRegions || panel.timeRegions.length === 0) {
return;
}
const tRange = {
from: dateTime(this.panelCtrl.range.from).utc(),
to: dateTime(this.panelCtrl.range.to).utc(),
};
let i: number,
hRange: { from: any; to: any },
timeRegion: any,
regions: AbsoluteTimeRange[],
fromStart: DateTime,
fromEnd: DateTime,
timeRegionColor: TimeRegionColorDefinition;
const timeRegionsCopy = panel.timeRegions.map((a: any) => ({ ...a }));
for (i = 0; i < timeRegionsCopy.length; i++) {
timeRegion = timeRegionsCopy[i];
if (!(timeRegion.fromDayOfWeek || timeRegion.from) && !(timeRegion.toDayOfWeek || timeRegion.to)) {
continue;
}
if (timeRegion.from && !timeRegion.to) {
timeRegion.to = timeRegion.from;
}
if (!timeRegion.from && timeRegion.to) {
timeRegion.from = timeRegion.to;
}
hRange = {
from: this.parseTimeRange(timeRegion.from),
to: this.parseTimeRange(timeRegion.to),
};
if (!timeRegion.fromDayOfWeek && timeRegion.toDayOfWeek) {
timeRegion.fromDayOfWeek = timeRegion.toDayOfWeek;
}
if (!timeRegion.toDayOfWeek && timeRegion.fromDayOfWeek) {
timeRegion.toDayOfWeek = timeRegion.fromDayOfWeek;
}
if (timeRegion.fromDayOfWeek) {
hRange.from.dayOfWeek = Number(timeRegion.fromDayOfWeek);
}
if (timeRegion.toDayOfWeek) {
hRange.to.dayOfWeek = Number(timeRegion.toDayOfWeek);
}
if (hRange.from.dayOfWeek && hRange.from.h === null && hRange.from.m === null) {
hRange.from.h = 0;
hRange.from.m = 0;
hRange.from.s = 0;
}
if (hRange.to.dayOfWeek && hRange.to.h === null && hRange.to.m === null) {
hRange.to.h = 23;
hRange.to.m = 59;
hRange.to.s = 59;
}
if (!hRange.from || !hRange.to) {
continue;
}
regions = [];
fromStart = dateTime(tRange.from);
fromStart.set('hour', 0);
fromStart.set('minute', 0);
fromStart.set('second', 0);
fromStart.add(hRange.from.h, 'hours');
fromStart.add(hRange.from.m, 'minutes');
fromStart.add(hRange.from.s, 'seconds');
while (fromStart.unix() <= tRange.to.unix()) {
while (hRange.from.dayOfWeek && hRange.from.dayOfWeek !== fromStart.isoWeekday()) {
fromStart.add(24, 'hours');
}
if (fromStart.unix() > tRange.to.unix()) {
break;
}
fromEnd = dateTime(fromStart);
if (hRange.from.h <= hRange.to.h) {
fromEnd.add(hRange.to.h - hRange.from.h, 'hours');
} else if (hRange.from.h > hRange.to.h) {
while (fromEnd.hour() !== hRange.to.h) {
fromEnd.add(1, 'hours');
}
} else {
fromEnd.add(24 - hRange.from.h, 'hours');
while (fromEnd.hour() !== hRange.to.h) {
fromEnd.add(1, 'hours');
}
}
fromEnd.set('minute', hRange.to.m);
fromEnd.set('second', hRange.to.s);
while (hRange.to.dayOfWeek && hRange.to.dayOfWeek !== fromEnd.isoWeekday()) {
fromEnd.add(24, 'hours');
}
const outsideRange =
(fromStart.unix() < tRange.from.unix() && fromEnd.unix() < tRange.from.unix()) ||
(fromStart.unix() > tRange.to.unix() && fromEnd.unix() > tRange.to.unix());
if (!outsideRange) {
regions.push({ from: fromStart.valueOf(), to: fromEnd.valueOf() });
}
fromStart.add(24, 'hours');
}
timeRegionColor = getColor(timeRegion, this.theme);
for (let j = 0; j < regions.length; j++) {
const r = regions[j];
if (timeRegion.fill) {
options.grid.markings.push({
xaxis: { from: r.from, to: r.to },
color: timeRegionColor.fill,
});
}
if (timeRegion.line) {
options.grid.markings.push({
xaxis: { from: r.from, to: r.from },
color: timeRegionColor.line,
});
options.grid.markings.push({
xaxis: { from: r.to, to: r.to },
color: timeRegionColor.line,
});
}
}
}
}