diff --git a/src/legacy/core_plugins/timelion/public/components/timelion_expression_input.tsx b/src/legacy/core_plugins/timelion/public/components/timelion_expression_input.tsx index ed0b2dbb9e18f..f3d5fafc54b2a 100644 --- a/src/legacy/core_plugins/timelion/public/components/timelion_expression_input.tsx +++ b/src/legacy/core_plugins/timelion/public/components/timelion_expression_input.tsx @@ -82,6 +82,28 @@ function TimelionExpressionInput({ [argValueSuggestions] ); + const provideHover = useCallback( + async (model: monacoEditor.editor.ITextModel, position: monacoEditor.Position) => { + const suggestions = await suggest( + model.getValue(), + functionList.current, + // it's important to offset the cursor position on 1 point left + // because of PEG parser starts the line with 0, but monaco with 1 + position.column - 1, + argValueSuggestions + ); + + return { + contents: suggestions + ? suggestions.list.map((s: ITimelionFunction | TimelionFunctionArgs) => ({ + value: s.help, + })) + : [], + }; + }, + [argValueSuggestions] + ); + useEffect(() => { http.get('../api/timelion/functions').then(data => { functionList.current = data; @@ -106,6 +128,7 @@ function TimelionExpressionInput({ triggerCharacters: ['.', '(', '=', ':'], provideCompletionItems, }} + hoverProvider={{ provideHover }} options={{ fontSize: 16, scrollBeyondLastLine: false, diff --git a/src/legacy/core_plugins/timelion/public/components/timelion_interval.tsx b/src/legacy/core_plugins/timelion/public/components/timelion_interval.tsx index e7cac126321fd..978c37b318d99 100644 --- a/src/legacy/core_plugins/timelion/public/components/timelion_interval.tsx +++ b/src/legacy/core_plugins/timelion/public/components/timelion_interval.tsx @@ -20,6 +20,7 @@ import React, { useMemo } from 'react'; import { EuiFormRow, EuiComboBox, EuiComboBoxOptionProps } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; +import { useValidation } from 'ui/vis/editors/default/controls/agg_utils'; const intervalOptions = [ { @@ -69,9 +70,10 @@ const intervalOptions = [ interface TimelionIntervalProps { value: string; setValue(value: string): void; + setValidity(valid: boolean): void; } -function TimelionInterval({ value, setValue }: TimelionIntervalProps) { +function TimelionInterval({ value, setValue, setValidity }: TimelionIntervalProps) { const onCustomInterval = (customValue: string) => { setValue(customValue.trim()); }; @@ -85,6 +87,10 @@ function TimelionInterval({ value, setValue }: TimelionIntervalProps) { [value] ); + const isValid = !!value; + + useValidation(setValidity, isValid); + return ( diff --git a/src/legacy/core_plugins/timelion/public/vis/timelion_options.tsx b/src/legacy/core_plugins/timelion/public/vis/timelion_options.tsx index 9eee9ff512a5b..d23b10bf5f1ce 100644 --- a/src/legacy/core_plugins/timelion/public/vis/timelion_options.tsx +++ b/src/legacy/core_plugins/timelion/public/vis/timelion_options.tsx @@ -34,6 +34,7 @@ function TimelionOptions({ stateParams, setValue, uiSettings, + setValidity, }: VisOptionsProps & TimelionExpressionInputDependencies) { const setInterval = useCallback((value: VisParams['interval']) => setValue('interval', value), [ setValue, @@ -45,7 +46,11 @@ function TimelionOptions({ return ( - +