mirror of
https://github.com/grafana/grafana.git
synced 2024-11-30 20:54:22 -06:00
prometheus: query-field: monaco: implement open-help-by-default (#41112)
* prometheus: query-field: monaco: implement open-help-by-default * better comment Co-authored-by: Ivana Huckova <30407135+ivanahuckova@users.noreply.github.com> * fixed typo in comment Co-authored-by: Ivana Huckova <30407135+ivanahuckova@users.noreply.github.com> * better log-message * fixed comment spelling Co-authored-by: Piotr Jamróz <pm.jamroz@gmail.com> * better setting Co-authored-by: Ivana Huckova <30407135+ivanahuckova@users.noreply.github.com> Co-authored-by: Piotr Jamróz <pm.jamroz@gmail.com>
This commit is contained in:
parent
a5f747104c
commit
244e149c34
@ -6,6 +6,7 @@ import { useLatest } from 'react-use';
|
||||
import { promLanguageDefinition } from 'monaco-promql';
|
||||
import { getCompletionProvider } from './monaco-completion-provider';
|
||||
import { Props } from './MonacoQueryFieldProps';
|
||||
import { getOverrideServices } from './getOverrideServices';
|
||||
|
||||
const options: monacoTypes.editor.IStandaloneEditorConstructionOptions = {
|
||||
codeLens: false,
|
||||
@ -75,6 +76,8 @@ const getStyles = (theme: GrafanaTheme2) => {
|
||||
};
|
||||
|
||||
const MonacoQueryField = (props: Props) => {
|
||||
// we need only one instance of `overrideServices` during the lifetime of the react component
|
||||
const overrideServicesRef = useRef(getOverrideServices());
|
||||
const containerRef = useRef<HTMLDivElement>(null);
|
||||
const { languageProvider, history, onBlur, onRunQuery, initialValue } = props;
|
||||
|
||||
@ -102,6 +105,7 @@ const MonacoQueryField = (props: Props) => {
|
||||
ref={containerRef}
|
||||
>
|
||||
<ReactMonacoEditor
|
||||
overrideServices={overrideServicesRef.current}
|
||||
options={options}
|
||||
language="promql"
|
||||
value={initialValue}
|
||||
|
@ -0,0 +1,116 @@
|
||||
import { monacoTypes } from '@grafana/ui';
|
||||
|
||||
// this thing here is a workaround in a way.
|
||||
// what we want to achieve, is that when the autocomplete-window
|
||||
// opens, the "second, extra popup" with the extra help,
|
||||
// also opens automatically.
|
||||
// but there is no API to achieve it.
|
||||
// the way to do it is to implement the `storageService`
|
||||
// interface, and provide our custom implementation,
|
||||
// which will default to `true` for the correct string-key.
|
||||
// unfortunately, while the typescript-interface exists,
|
||||
// it is not exported from monaco-editor,
|
||||
// so we cannot rely on typescript to make sure
|
||||
// we do it right. all we can do is to manually
|
||||
// lookup the interface, and make sure we code our code right.
|
||||
// our code is a "best effort" approach,
|
||||
// i am not 100% how the `scope` and `target` things work,
|
||||
// but so far it seems to work ok.
|
||||
// i would use an another approach, if there was one available.
|
||||
|
||||
function makeStorageService() {
|
||||
// we need to return an object that fulfills this interface:
|
||||
// https://github.com/microsoft/vscode/blob/ff1e16eebb93af79fd6d7af1356c4003a120c563/src/vs/platform/storage/common/storage.ts#L37
|
||||
// unfortunately it is not export from monaco-editor
|
||||
|
||||
const strings = new Map<string, string>();
|
||||
|
||||
// we want this to be true by default
|
||||
strings.set('expandSuggestionDocs', true.toString());
|
||||
|
||||
return {
|
||||
// we do not implement the on* handlers
|
||||
onDidChangeValue: (data: unknown): void => undefined,
|
||||
onDidChangeTarget: (data: unknown): void => undefined,
|
||||
onWillSaveState: (data: unknown): void => undefined,
|
||||
|
||||
get: (key: string, scope: unknown, fallbackValue?: string): string | undefined => {
|
||||
return strings.get(key) ?? fallbackValue;
|
||||
},
|
||||
|
||||
getBoolean: (key: string, scope: unknown, fallbackValue?: boolean): boolean | undefined => {
|
||||
const val = strings.get(key);
|
||||
if (val !== undefined) {
|
||||
// the interface-docs say the value will be converted
|
||||
// to a boolean but do not specify how, so we improvise
|
||||
return val === 'true';
|
||||
} else {
|
||||
return fallbackValue;
|
||||
}
|
||||
},
|
||||
|
||||
getNumber: (key: string, scope: unknown, fallbackValue?: number): number | undefined => {
|
||||
const val = strings.get(key);
|
||||
if (val !== undefined) {
|
||||
return parseInt(val, 10);
|
||||
} else {
|
||||
return fallbackValue;
|
||||
}
|
||||
},
|
||||
|
||||
store: (
|
||||
key: string,
|
||||
value: string | boolean | number | undefined | null,
|
||||
scope: unknown,
|
||||
target: unknown
|
||||
): void => {
|
||||
// the interface-docs say if the value is nullish, it should act as delete
|
||||
if (value === null || value === undefined) {
|
||||
strings.delete(key);
|
||||
} else {
|
||||
strings.set(key, value.toString());
|
||||
}
|
||||
},
|
||||
|
||||
remove: (key: string, scope: unknown): void => {
|
||||
strings.delete(key);
|
||||
},
|
||||
|
||||
keys: (scope: unknown, target: unknown): string[] => {
|
||||
return Array.from(strings.keys());
|
||||
},
|
||||
|
||||
logStorage: (): void => {
|
||||
console.log('logStorage: not implemented');
|
||||
},
|
||||
|
||||
migrate: (): Promise<void> => {
|
||||
// we do not implement this
|
||||
return Promise.resolve(undefined);
|
||||
},
|
||||
|
||||
isNew: (scope: unknown): boolean => {
|
||||
// we create a new storage for every session, we do not persist it,
|
||||
// so we return `true`.
|
||||
return true;
|
||||
},
|
||||
|
||||
flush: (reason?: unknown): Promise<void> => {
|
||||
// we do not implement this
|
||||
return Promise.resolve(undefined);
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
let overrideServices: monacoTypes.editor.IEditorOverrideServices | null = null;
|
||||
|
||||
export function getOverrideServices(): monacoTypes.editor.IEditorOverrideServices {
|
||||
// only have one instance of this for every query editor
|
||||
if (overrideServices === null) {
|
||||
overrideServices = {
|
||||
storageService: makeStorageService(),
|
||||
};
|
||||
}
|
||||
|
||||
return overrideServices;
|
||||
}
|
Loading…
Reference in New Issue
Block a user