import React, { SyntheticEvent, useCallback, useEffect, useState } from 'react'; import { CoreApp, LoadingState } from '@grafana/data'; import { selectors } from '@grafana/e2e-selectors'; import { EditorHeader, EditorRows, FlexItem, Space } from '@grafana/experimental'; import { reportInteraction } from '@grafana/runtime'; import { Button, ConfirmModal } from '@grafana/ui'; import { QueryEditorModeToggle } from 'app/plugins/datasource/prometheus/querybuilder/shared/QueryEditorModeToggle'; import { QueryHeaderSwitch } from 'app/plugins/datasource/prometheus/querybuilder/shared/QueryHeaderSwitch'; import { QueryEditorMode } from 'app/plugins/datasource/prometheus/querybuilder/shared/types'; import { lokiQueryEditorExplainKey, lokiQueryEditorRawQueryKey, useFlag, } from '../../prometheus/querybuilder/shared/hooks/useFlag'; import { LokiQueryBuilderContainer } from '../querybuilder/components/LokiQueryBuilderContainer'; import { LokiQueryBuilderOptions } from '../querybuilder/components/LokiQueryBuilderOptions'; import { LokiQueryCodeEditor } from '../querybuilder/components/LokiQueryCodeEditor'; import { QueryPatternsModal } from '../querybuilder/components/QueryPatternsModal'; import { buildVisualQueryFromString } from '../querybuilder/parsing'; import { changeEditorMode, getQueryWithDefaults } from '../querybuilder/state'; import { LokiQuery } from '../types'; import { LokiQueryEditorProps } from './types'; export const testIds = { editor: 'loki-editor', }; export const LokiQueryEditor = React.memo((props) => { const { onChange, onRunQuery, onAddQuery, data, app, queries } = props; const [parseModalOpen, setParseModalOpen] = useState(false); const [queryPatternsModalOpen, setQueryPatternsModalOpen] = useState(false); const [dataIsStale, setDataIsStale] = useState(false); const { flag: explain, setFlag: setExplain } = useFlag(lokiQueryEditorExplainKey); const { flag: rawQuery, setFlag: setRawQuery } = useFlag(lokiQueryEditorRawQueryKey, true); const query = getQueryWithDefaults(props.query); // This should be filled in from the defaults by now. const editorMode = query.editorMode!; const onExplainChange = (event: SyntheticEvent) => { setExplain(event.currentTarget.checked); }; const onEditorModeChange = useCallback( (newEditorMode: QueryEditorMode) => { reportInteraction('grafana_loki_editor_mode_clicked', { newEditor: newEditorMode, previousEditor: query.editorMode ?? '', newQuery: !query.expr, app: app ?? '', }); if (newEditorMode === QueryEditorMode.Builder) { const result = buildVisualQueryFromString(query.expr || ''); // If there are errors, give user a chance to decide if they want to go to builder as that can lose some data. if (result.errors.length) { setParseModalOpen(true); return; } } changeEditorMode(query, newEditorMode, onChange); }, [onChange, query, app] ); useEffect(() => { setDataIsStale(false); }, [data]); const onChangeInternal = (query: LokiQuery) => { setDataIsStale(true); onChange(query); }; const onQueryPreviewChange = (event: SyntheticEvent) => { const isEnabled = event.currentTarget.checked; setRawQuery(isEnabled); }; return ( <> { onChange({ ...query, editorMode: QueryEditorMode.Builder }); setParseModalOpen(false); }} onDismiss={() => setParseModalOpen(false)} /> setQueryPatternsModalOpen(false)} query={query} queries={queries} app={app} onChange={onChange} onAddQuery={onAddQuery} /> {editorMode === QueryEditorMode.Builder && ( <> )} {app !== CoreApp.Explore && ( )} {editorMode === QueryEditorMode.Code && ( )} {editorMode === QueryEditorMode.Builder && ( )} ); }); LokiQueryEditor.displayName = 'LokiQueryEditor';