Tempo: Add a placeholder to the TraceQL query editor (#55257)

This commit is contained in:
Hamas Shafiq 2022-09-28 15:07:10 +01:00 committed by GitHub
parent 6aef353b59
commit 0ec253bfa0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 49 additions and 4 deletions

View File

@ -34,6 +34,7 @@ export function QueryEditor(props: Props) {
</a>
</InlineLabel>
<TraceQLEditor
placeholder="Enter a TraceQL query (run with Shift+Enter)"
value={query.query}
onChange={onEditorChange}
datasource={props.datasource}

View File

@ -3,7 +3,7 @@ import type { languages } from 'monaco-editor';
import React, { useEffect, useRef } from 'react';
import { GrafanaTheme2 } from '@grafana/data';
import { CodeEditor, Monaco, useStyles2, monacoTypes } from '@grafana/ui';
import { CodeEditor, Monaco, monacoTypes, useTheme2 } from '@grafana/ui';
import { createErrorNotification } from '../../../../core/copy/appNotification';
import { notifyApp } from '../../../../core/reducers/appNotification';
@ -14,6 +14,7 @@ import { CompletionProvider } from './autocomplete';
import { languageDefinition } from './traceql';
interface Props {
placeholder: string;
value: string;
onChange: (val: string) => void;
onRunQuery: () => void;
@ -21,9 +22,11 @@ interface Props {
}
export function TraceQLEditor(props: Props) {
const { onRunQuery } = props;
const { onRunQuery, placeholder } = props;
const setupAutocompleteFn = useAutocomplete(props.datasource);
const styles = useStyles2(getStyles);
const theme = useTheme2();
const styles = getStyles(theme, placeholder);
return (
<CodeEditor
value={props.value}
@ -50,11 +53,40 @@ export function TraceQLEditor(props: Props) {
onEditorDidMount={(editor, monaco) => {
setupAutocompleteFn(editor, monaco);
setupActions(editor, monaco, onRunQuery);
setupPlaceholder(editor, monaco, styles);
}}
/>
);
}
function setupPlaceholder(editor: monacoTypes.editor.IStandaloneCodeEditor, monaco: Monaco, styles: EditorStyles) {
const placeholderDecorators = [
{
range: new monaco.Range(1, 1, 1, 1),
options: {
className: styles.placeholder, // The placeholder text is in styles.placeholder
isWholeLine: true,
},
},
];
let decorators: string[] = [];
const checkDecorators = (): void => {
const model = editor.getModel();
if (!model) {
return;
}
const newDecorators = model.getValueLength() === 0 ? placeholderDecorators : [];
decorators = model.deltaDecorations(decorators, newDecorators);
};
checkDecorators();
editor.onDidChangeModelContent(checkDecorators);
}
function setupActions(editor: monacoTypes.editor.IStandaloneCodeEditor, monaco: Monaco, onRunQuery: () => void) {
editor.addAction({
id: 'run-query',
@ -135,12 +167,24 @@ function ensureTraceQL(monaco: Monaco) {
}
}
const getStyles = (theme: GrafanaTheme2) => {
interface EditorStyles {
placeholder: string;
queryField: string;
}
const getStyles = (theme: GrafanaTheme2, placeholder: string): EditorStyles => {
return {
queryField: css`
border-radius: ${theme.shape.borderRadius()};
border: 1px solid ${theme.components.input.borderColor};
flex: 1;
`,
placeholder: css`
::after {
content: '${placeholder}';
font-family: ${theme.typography.fontFamilyMonospace};
opacity: 0.3;
}
`,
};
};