;
// Use Grafana Dark theme by default
export const ThemeContext = React.createContext(getTheme(GrafanaThemeType.Dark));
+ThemeContext.displayName = 'ThemeContext';
export const withTheme = (Component: React.ComponentType
) => {
const WithTheme: React.FunctionComponent> = props => {
diff --git a/packages/grafana-ui/src/types/completion.ts b/packages/grafana-ui/src/types/completion.ts
new file mode 100644
index 00000000000..e93162c511e
--- /dev/null
+++ b/packages/grafana-ui/src/types/completion.ts
@@ -0,0 +1,109 @@
+import { Value } from 'slate';
+import { Editor } from '@grafana/slate-react';
+
+export interface CompletionItemGroup {
+ /**
+ * Label that will be displayed for all entries of this group.
+ */
+ label: string;
+
+ /**
+ * List of suggestions of this group.
+ */
+ items: CompletionItem[];
+
+ /**
+ * If true, match only by prefix (and not mid-word).
+ */
+ prefixMatch?: boolean;
+
+ /**
+ * If true, do not filter items in this group based on the search.
+ */
+ skipFilter?: boolean;
+
+ /**
+ * If true, do not sort items.
+ */
+ skipSort?: boolean;
+}
+
+export enum CompletionItemKind {
+ GroupTitle = 'GroupTitle',
+}
+
+export interface CompletionItem {
+ /**
+ * The label of this completion item. By default
+ * this is also the text that is inserted when selecting
+ * this completion.
+ */
+ label: string;
+
+ /**
+ * The kind of this completion item. An icon is chosen
+ * by the editor based on the kind.
+ */
+ kind?: CompletionItemKind | string;
+
+ /**
+ * A human-readable string with additional information
+ * about this item, like type or symbol information.
+ */
+ detail?: string;
+
+ /**
+ * A human-readable string, can be Markdown, that represents a doc-comment.
+ */
+ documentation?: string;
+
+ /**
+ * A string that should be used when comparing this item
+ * with other items. When `falsy` the `label` is used.
+ */
+ sortText?: string;
+
+ /**
+ * A string that should be used when filtering a set of
+ * completion items. When `falsy` the `label` is used.
+ */
+ filterText?: string;
+
+ /**
+ * A string or snippet that should be inserted in a document when selecting
+ * this completion. When `falsy` the `label` is used.
+ */
+ insertText?: string;
+
+ /**
+ * Delete number of characters before the caret position,
+ * by default the letters from the beginning of the word.
+ */
+ deleteBackwards?: number;
+
+ /**
+ * Number of steps to move after the insertion, can be negative.
+ */
+ move?: number;
+}
+
+export interface TypeaheadOutput {
+ context?: string;
+ suggestions: CompletionItemGroup[];
+}
+
+export interface TypeaheadInput {
+ text: string;
+ prefix: string;
+ wrapperClasses: string[];
+ labelKey?: string;
+ value?: Value;
+ editor?: Editor;
+}
+
+export interface SuggestionsState {
+ groupedItems: CompletionItemGroup[];
+ typeaheadPrefix: string;
+ typeaheadContext: string;
+ typeaheadText: string;
+}
diff --git a/packages/grafana-ui/src/types/datasource.ts b/packages/grafana-ui/src/types/datasource.ts
index dae57884912..31a78d46dec 100644
--- a/packages/grafana-ui/src/types/datasource.ts
+++ b/packages/grafana-ui/src/types/datasource.ts
@@ -549,3 +549,19 @@ export interface AnnotationQueryRequest {
name: string;
} & MoreOptions;
}
+
+export interface HistoryItem {
+ ts: number;
+ query: TQuery;
+}
+
+export abstract class LanguageProvider {
+ datasource!: DataSourceApi;
+ request!: (url: string, params?: any) => Promise;
+ /**
+ * Returns startTask that resolves with a task list when main syntax is loaded.
+ * Task list consists of secondary promises that load more detailed language features.
+ */
+ start!: () => Promise;
+ startTask?: Promise;
+}
diff --git a/packages/grafana-ui/src/types/index.ts b/packages/grafana-ui/src/types/index.ts
index a4e07453bca..f636f38041c 100644
--- a/packages/grafana-ui/src/types/index.ts
+++ b/packages/grafana-ui/src/types/index.ts
@@ -1,9 +1,10 @@
+export * from './app';
+export * from './completion';
+export * from './datasource';
+export * from './input';
export * from './panel';
export * from './plugin';
-export * from './app';
-export * from './datasource';
export * from './theme';
-export * from './input';
import * as PanelEvents from './events';
export { PanelEvents };
diff --git a/public/app/features/explore/utils/typeahead.ts b/packages/grafana-ui/src/utils/typeahead.ts
similarity index 95%
rename from public/app/features/explore/utils/typeahead.ts
rename to packages/grafana-ui/src/utils/typeahead.ts
index e501e2ab60a..b3491e0a2a7 100644
--- a/public/app/features/explore/utils/typeahead.ts
+++ b/packages/grafana-ui/src/utils/typeahead.ts
@@ -1,7 +1,6 @@
-import { GrafanaTheme } from '@grafana/ui';
import { default as calculateSize } from 'calculate-size';
-
-import { CompletionItemGroup, CompletionItem, CompletionItemKind } from 'app/types';
+import { CompletionItemGroup, CompletionItem, CompletionItemKind } from '../types/completion';
+import { GrafanaTheme } from '..';
export const flattenGroupItems = (groupedItems: CompletionItemGroup[]): CompletionItem[] => {
return groupedItems.reduce((all, current) => {
@@ -10,7 +9,7 @@ export const flattenGroupItems = (groupedItems: CompletionItemGroup[]): Completi
kind: CompletionItemKind.GroupTitle,
};
return all.concat(titleItem, current.items);
- }, []);
+ }, new Array());
};
export const calculateLongestLabel = (allItems: CompletionItem[]): string => {
diff --git a/public/app/core/utils/explore.ts b/public/app/core/utils/explore.ts
index 2bb45b3d321..bcae86b757c 100644
--- a/public/app/core/utils/explore.ts
+++ b/public/app/core/utils/explore.ts
@@ -19,9 +19,18 @@ import { renderUrl } from 'app/core/utils/url';
import store from 'app/core/store';
import kbn from 'app/core/utils/kbn';
import { getNextRefIdChar } from './query';
+
// Types
-import { DataQuery, DataSourceApi, DataQueryError, DataQueryRequest, PanelModel, RefreshPicker } from '@grafana/ui';
-import { ExploreUrlState, HistoryItem, QueryTransaction, QueryOptions, ExploreMode } from 'app/types/explore';
+import {
+ DataQuery,
+ DataSourceApi,
+ DataQueryError,
+ DataQueryRequest,
+ PanelModel,
+ RefreshPicker,
+ HistoryItem,
+} from '@grafana/ui';
+import { ExploreUrlState, QueryTransaction, QueryOptions, ExploreMode } from 'app/types/explore';
import { config } from '../config';
import { TimeSrv } from 'app/features/dashboard/services/TimeSrv';
diff --git a/public/app/features/explore/QueryRow.tsx b/public/app/features/explore/QueryRow.tsx
index d9fb09a8f40..61bb0112e09 100644
--- a/public/app/features/explore/QueryRow.tsx
+++ b/public/app/features/explore/QueryRow.tsx
@@ -13,8 +13,8 @@ import { changeQuery, modifyQueries, runQueries, addQueryRow } from './state/act
// Types
import { StoreState } from 'app/types';
import { TimeRange, AbsoluteTimeRange, LoadingState } from '@grafana/data';
-import { DataQuery, DataSourceApi, QueryFixAction, PanelData } from '@grafana/ui';
-import { HistoryItem, ExploreItemState, ExploreId, ExploreMode } from 'app/types/explore';
+import { DataQuery, DataSourceApi, QueryFixAction, PanelData, HistoryItem } from '@grafana/ui';
+import { ExploreItemState, ExploreId, ExploreMode } from 'app/types/explore';
import { Emitter } from 'app/core/utils/emitter';
import { highlightLogsExpressionAction, removeQueryRowAction } from './state/actionTypes';
import QueryStatus from './QueryStatus';
diff --git a/public/app/features/explore/TypeaheadInfo.tsx b/public/app/features/explore/TypeaheadInfo.tsx
deleted file mode 100644
index 85edae36606..00000000000
--- a/public/app/features/explore/TypeaheadInfo.tsx
+++ /dev/null
@@ -1,63 +0,0 @@
-import React, { PureComponent } from 'react';
-import { css, cx } from 'emotion';
-
-import { Themeable, selectThemeVariant } from '@grafana/ui';
-
-import { CompletionItem } from 'app/types/explore';
-
-interface Props extends Themeable {
- item: CompletionItem;
- width: number;
- height: number;
-}
-
-export class TypeaheadInfo extends PureComponent {
- constructor(props: Props) {
- super(props);
- }
-
- getStyles = (visible: boolean) => {
- const { height, theme } = this.props;
-
- return {
- typeaheadItem: css`
- label: type-ahead-item;
- padding: ${theme.spacing.sm} ${theme.spacing.sm} ${theme.spacing.sm} ${theme.spacing.md};
- border-radius: ${theme.border.radius.md};
- border: ${selectThemeVariant(
- { light: `solid 1px ${theme.colors.gray5}`, dark: `solid 1px ${theme.colors.dark1}` },
- theme.type
- )};
- overflow-y: scroll;
- overflow-x: hidden;
- outline: none;
- background: ${selectThemeVariant({ light: theme.colors.white, dark: theme.colors.dark4 }, theme.type)};
- color: ${theme.colors.text};
- box-shadow: ${selectThemeVariant(
- { light: `0 5px 10px 0 ${theme.colors.gray5}`, dark: `0 5px 10px 0 ${theme.colors.black}` },
- theme.type
- )};
- visibility: ${visible === true ? 'visible' : 'hidden'};
- width: 250px;
- height: ${height + parseInt(theme.spacing.xxs, 10)}px;
- position: relative;
- `,
- };
- };
-
- render() {
- const { item } = this.props;
- const visible = item && !!item.documentation;
- const label = item ? item.label : '';
- const documentation = item && item.documentation ? item.documentation : '';
- const styles = this.getStyles(visible);
-
- return (
-
- {label}
-
- {documentation}
-
- );
- }
-}
diff --git a/public/app/features/explore/slate-plugins/runner.ts b/public/app/features/explore/slate-plugins/runner.ts
deleted file mode 100644
index bb3a10f8759..00000000000
--- a/public/app/features/explore/slate-plugins/runner.ts
+++ /dev/null
@@ -1,17 +0,0 @@
-import { Editor as SlateEditor } from 'slate';
-
-export default function RunnerPlugin({ handler }: any) {
- return {
- onKeyDown(event: KeyboardEvent, editor: SlateEditor, next: Function) {
- // Handle enter
- if (handler && event.key === 'Enter' && !event.shiftKey) {
- // Submit on Enter
- event.preventDefault();
- handler(event);
- return true;
- }
-
- return next();
- },
- };
-}
diff --git a/public/app/features/explore/state/actionTypes.ts b/public/app/features/explore/state/actionTypes.ts
index 180c7474f09..59c581acf29 100644
--- a/public/app/features/explore/state/actionTypes.ts
+++ b/public/app/features/explore/state/actionTypes.ts
@@ -1,10 +1,10 @@
// Types
import { Unsubscribable } from 'rxjs';
import { Emitter } from 'app/core/core';
-import { DataQuery, DataSourceSelectItem, DataSourceApi, QueryFixAction, PanelData } from '@grafana/ui';
+import { DataQuery, DataSourceSelectItem, DataSourceApi, QueryFixAction, PanelData, HistoryItem } from '@grafana/ui';
import { LogLevel, TimeRange, LoadingState, AbsoluteTimeRange } from '@grafana/data';
-import { ExploreId, ExploreItemState, HistoryItem, ExploreUIState, ExploreMode } from 'app/types/explore';
+import { ExploreId, ExploreItemState, ExploreUIState, ExploreMode } from 'app/types/explore';
import { actionCreatorFactory, ActionOf } from 'app/core/redux/actionCreatorFactory';
/** Higher order actions
diff --git a/public/app/plugins/datasource/elasticsearch/components/ElasticsearchQueryField.tsx b/public/app/plugins/datasource/elasticsearch/components/ElasticsearchQueryField.tsx
index 6c3b00933f1..473b12130ce 100644
--- a/public/app/plugins/datasource/elasticsearch/components/ElasticsearchQueryField.tsx
+++ b/public/app/plugins/datasource/elasticsearch/components/ElasticsearchQueryField.tsx
@@ -4,8 +4,7 @@ import React from 'react';
import { SlatePrism } from '@grafana/ui';
// dom also includes Element polyfills
-import QueryField from 'app/features/explore/QueryField';
-import { ExploreQueryFieldProps } from '@grafana/ui';
+import { QueryField, ExploreQueryFieldProps } from '@grafana/ui';
import { ElasticDatasource } from '../datasource';
import { ElasticsearchOptions, ElasticsearchQuery } from '../types';
diff --git a/public/app/plugins/datasource/grafana-azure-monitor-datasource/editor/query_field.tsx b/public/app/plugins/datasource/grafana-azure-monitor-datasource/editor/query_field.tsx
index 2a701839ba3..fd05ef7172f 100644
--- a/public/app/plugins/datasource/grafana-azure-monitor-datasource/editor/query_field.tsx
+++ b/public/app/plugins/datasource/grafana-azure-monitor-datasource/editor/query_field.tsx
@@ -1,9 +1,5 @@
import PluginPrism from 'app/features/explore/slate-plugins/prism';
-import BracesPlugin from 'app/features/explore/slate-plugins/braces';
-import ClearPlugin from 'app/features/explore/slate-plugins/clear';
-import NewlinePlugin from 'app/features/explore/slate-plugins/newline';
-import RunnerPlugin from 'app/features/explore/slate-plugins/runner';
-
+import { BracesPlugin, ClearPlugin, RunnerPlugin, NewlinePlugin } from '@grafana/ui';
import Typeahead from './typeahead';
import { getKeybindingSrv, KeybindingSrv } from 'app/core/services/keybindingSrv';
diff --git a/public/app/plugins/datasource/loki/components/LokiQueryFieldForm.tsx b/public/app/plugins/datasource/loki/components/LokiQueryFieldForm.tsx
index dcf430f624e..4188d5f64c9 100644
--- a/public/app/plugins/datasource/loki/components/LokiQueryFieldForm.tsx
+++ b/public/app/plugins/datasource/loki/components/LokiQueryFieldForm.tsx
@@ -3,23 +3,18 @@ import React from 'react';
// @ts-ignore
import Cascader from 'rc-cascader';
-import { SlatePrism } from '@grafana/ui';
+import { SlatePrism, TypeaheadOutput, SuggestionsState, QueryField, TypeaheadInput, BracesPlugin } from '@grafana/ui';
-// Components
-import QueryField, { TypeaheadInput } from 'app/features/explore/QueryField';
// Utils & Services
// dom also includes Element polyfills
-import BracesPlugin from 'app/features/explore/slate-plugins/braces';
import { Plugin, Node } from 'slate';
// Types
import { LokiQuery } from '../types';
-import { TypeaheadOutput } from 'app/types/explore';
import { ExploreQueryFieldProps, DOMUtil } from '@grafana/ui';
import { AbsoluteTimeRange } from '@grafana/data';
import { Grammar } from 'prismjs';
import LokiLanguageProvider, { LokiHistoryItem } from '../language_provider';
-import { SuggestionsState } from 'app/features/explore/slate-plugins/suggestions';
import LokiDatasource from '../datasource';
function getChooserText(hasSyntax: boolean, hasLogLabels: boolean) {
diff --git a/public/app/plugins/datasource/loki/language_provider.test.ts b/public/app/plugins/datasource/loki/language_provider.test.ts
index 0b8caa16f0a..4e27c22fc63 100644
--- a/public/app/plugins/datasource/loki/language_provider.test.ts
+++ b/public/app/plugins/datasource/loki/language_provider.test.ts
@@ -3,10 +3,10 @@ import { Editor as SlateEditor } from 'slate';
import LanguageProvider, { LABEL_REFRESH_INTERVAL, LokiHistoryItem, rangeToParams } from './language_provider';
import { AbsoluteTimeRange } from '@grafana/data';
+import { TypeaheadInput } from '@grafana/ui';
import { advanceTo, clear, advanceBy } from 'jest-date-mock';
import { beforeEach } from 'test/lib/common';
-import { TypeaheadInput } from '../../../types';
import { makeMockLokiDatasource } from './mocks';
import LokiDatasource from './datasource';
diff --git a/public/app/plugins/datasource/loki/language_provider.ts b/public/app/plugins/datasource/loki/language_provider.ts
index ac5f877f8d4..d9812c1a536 100644
--- a/public/app/plugins/datasource/loki/language_provider.ts
+++ b/public/app/plugins/datasource/loki/language_provider.ts
@@ -6,12 +6,12 @@ import { parseSelector, labelRegexp, selectorRegexp } from 'app/plugins/datasour
import syntax from './syntax';
// Types
-import { CompletionItem, LanguageProvider, TypeaheadInput, TypeaheadOutput, HistoryItem } from 'app/types/explore';
import { LokiQuery } from './types';
import { dateTime, AbsoluteTimeRange } from '@grafana/data';
import { PromQuery } from '../prometheus/types';
import LokiDatasource from './datasource';
+import { CompletionItem, TypeaheadInput, TypeaheadOutput, LanguageProvider, HistoryItem } from '@grafana/ui';
const DEFAULT_KEYS = ['job', 'namespace'];
const EMPTY_SELECTOR = '{}';
diff --git a/public/app/plugins/datasource/prometheus/components/PromQueryField.tsx b/public/app/plugins/datasource/prometheus/components/PromQueryField.tsx
index 65b5f784177..4d8442c8f62 100644
--- a/public/app/plugins/datasource/prometheus/components/PromQueryField.tsx
+++ b/public/app/plugins/datasource/prometheus/components/PromQueryField.tsx
@@ -3,21 +3,19 @@ import React from 'react';
// @ts-ignore
import Cascader from 'rc-cascader';
-import { SlatePrism } from '@grafana/ui';
+import { Plugin } from 'slate';
+import { SlatePrism, TypeaheadInput, TypeaheadOutput, QueryField, BracesPlugin, HistoryItem } from '@grafana/ui';
import Prism from 'prismjs';
-import { TypeaheadOutput, HistoryItem } from 'app/types/explore';
// dom also includes Element polyfills
-import BracesPlugin from 'app/features/explore/slate-plugins/braces';
-import QueryField, { TypeaheadInput } from 'app/features/explore/QueryField';
import { PromQuery, PromContext, PromOptions } from '../types';
import { CancelablePromise, makePromiseCancelable } from 'app/core/utils/CancelablePromise';
import { ExploreQueryFieldProps, QueryHint, DOMUtil } from '@grafana/ui';
import { isDataFrame, toLegacyResponseData } from '@grafana/data';
+import { SuggestionsState } from '@grafana/ui';
import { PrometheusDatasource } from '../datasource';
import PromQlLanguageProvider from '../language_provider';
-import { SuggestionsState } from 'app/features/explore/slate-plugins/suggestions';
const HISTOGRAM_GROUP = '__histograms__';
const METRIC_MARK = 'metric';
@@ -114,7 +112,7 @@ interface PromQueryFieldState {
}
class PromQueryField extends React.PureComponent {
- plugins: any[];
+ plugins: Plugin[];
languageProvider: PromQlLanguageProvider;
languageProviderInitializationPromise: CancelablePromise;
diff --git a/public/app/plugins/datasource/prometheus/language_provider.ts b/public/app/plugins/datasource/prometheus/language_provider.ts
index 018b32e4981..290621a5a13 100644
--- a/public/app/plugins/datasource/prometheus/language_provider.ts
+++ b/public/app/plugins/datasource/prometheus/language_provider.ts
@@ -1,15 +1,14 @@
import _ from 'lodash';
import { dateTime } from '@grafana/data';
-
import {
CompletionItem,
- CompletionItemGroup,
- LanguageProvider,
TypeaheadInput,
TypeaheadOutput,
+ CompletionItemGroup,
+ LanguageProvider,
HistoryItem,
-} from 'app/types/explore';
+} from '@grafana/ui';
import { parseSelector, processLabels, processHistogramLabels } from './language_utils';
import PromqlSyntax, { FUNCTIONS, RATE_RANGES } from './promql';
diff --git a/public/app/plugins/datasource/prometheus/promql.ts b/public/app/plugins/datasource/prometheus/promql.ts
index d827677ee2d..0bde2da9c2f 100644
--- a/public/app/plugins/datasource/prometheus/promql.ts
+++ b/public/app/plugins/datasource/prometheus/promql.ts
@@ -1,6 +1,4 @@
-/* tslint:disable max-line-length */
-
-import { CompletionItem } from 'app/types/explore';
+import { CompletionItem } from '@grafana/ui';
export const RATE_RANGES: CompletionItem[] = [
{ label: '$__interval', sortText: '$__interval' },
diff --git a/public/app/plugins/datasource/prometheus/specs/language_provider.test.ts b/public/app/plugins/datasource/prometheus/specs/language_provider.test.ts
index 9171201fc37..8095922b80a 100644
--- a/public/app/plugins/datasource/prometheus/specs/language_provider.test.ts
+++ b/public/app/plugins/datasource/prometheus/specs/language_provider.test.ts
@@ -2,7 +2,7 @@ import Plain from 'slate-plain-serializer';
import { Editor as SlateEditor } from 'slate';
import LanguageProvider from '../language_provider';
import { PrometheusDatasource } from '../datasource';
-import { HistoryItem } from 'app/types';
+import { HistoryItem } from '@grafana/ui';
import { PromQuery } from '../types';
describe('Language completion provider', () => {
diff --git a/public/app/types/explore.ts b/public/app/types/explore.ts
index 92ec9194606..8cf7c13b353 100644
--- a/public/app/types/explore.ts
+++ b/public/app/types/explore.ts
@@ -8,6 +8,7 @@ import {
ExploreStartPageProps,
PanelData,
DataQueryRequest,
+ HistoryItem,
} from '@grafana/ui';
import {
@@ -23,100 +24,11 @@ import {
import { Emitter } from 'app/core/core';
import TableModel from 'app/core/table_model';
-import { Value } from 'slate';
-
-import { Editor } from '@grafana/slate-react';
export enum ExploreMode {
Metrics = 'Metrics',
Logs = 'Logs',
}
-export enum CompletionItemKind {
- GroupTitle = 'GroupTitle',
-}
-
-export interface CompletionItem {
- /**
- * The label of this completion item. By default
- * this is also the text that is inserted when selecting
- * this completion.
- */
- label: string;
-
- /**
- * The kind of this completion item. An icon is chosen
- * by the editor based on the kind.
- */
- kind?: CompletionItemKind | string;
-
- /**
- * A human-readable string with additional information
- * about this item, like type or symbol information.
- */
- detail?: string;
-
- /**
- * A human-readable string, can be Markdown, that represents a doc-comment.
- */
- documentation?: string;
-
- /**
- * A string that should be used when comparing this item
- * with other items. When `falsy` the `label` is used.
- */
- sortText?: string;
-
- /**
- * A string that should be used when filtering a set of
- * completion items. When `falsy` the `label` is used.
- */
- filterText?: string;
-
- /**
- * A string or snippet that should be inserted in a document when selecting
- * this completion. When `falsy` the `label` is used.
- */
- insertText?: string;
-
- /**
- * Delete number of characters before the caret position,
- * by default the letters from the beginning of the word.
- */
- deleteBackwards?: number;
-
- /**
- * Number of steps to move after the insertion, can be negative.
- */
- move?: number;
-}
-
-export interface CompletionItemGroup {
- /**
- * Label that will be displayed for all entries of this group.
- */
- label: string;
-
- /**
- * List of suggestions of this group.
- */
- items: CompletionItem[];
-
- /**
- * If true, match only by prefix (and not mid-word).
- */
- prefixMatch?: boolean;
-
- /**
- * If true, do not filter items in this group based on the search.
- */
- skipFilter?: boolean;
-
- /**
- * If true, do not sort items.
- */
- skipSort?: boolean;
-}
-
export enum ExploreId {
left = 'left',
right = 'right',
@@ -308,36 +220,6 @@ export interface ExploreUrlState {
context?: string;
}
-export interface HistoryItem {
- ts: number;
- query: TQuery;
-}
-
-export abstract class LanguageProvider {
- datasource: DataSourceApi;
- request: (url: string, params?: any) => Promise;
- /**
- * Returns startTask that resolves with a task list when main syntax is loaded.
- * Task list consists of secondary promises that load more detailed language features.
- */
- start: () => Promise;
- startTask?: Promise;
-}
-
-export interface TypeaheadInput {
- text: string;
- prefix: string;
- wrapperClasses: string[];
- labelKey?: string;
- value?: Value;
- editor?: Editor;
-}
-
-export interface TypeaheadOutput {
- context?: string;
- suggestions: CompletionItemGroup[];
-}
-
export interface QueryIntervals {
interval: string;
intervalMs: number;