import React, { useCallback, useState } from 'react';
import { useCopyToClipboard } from 'react-use';
import { SelectableValue } from '@grafana/data';
import { EditorField, EditorHeader, EditorMode, EditorRow, FlexItem, InlineSelect, Space } from '@grafana/experimental';
import { Button, InlineField, InlineSwitch, RadioButtonGroup, Select, Tooltip } from '@grafana/ui';
import { QueryWithDefaults } from '../defaults';
import { SQLQuery, QueryFormat, QueryRowFilter, QUERY_FORMAT_OPTIONS, DB } from '../types';
import { defaultToRawSql } from '../utils/sql.utils';
import { ConfirmModal } from './ConfirmModal';
import { DatasetSelector } from './DatasetSelector';
import { ErrorBoundary } from './ErrorBoundary';
import { TableSelector } from './TableSelector';
interface QueryHeaderProps {
db: DB;
query: QueryWithDefaults;
onChange: (query: SQLQuery) => void;
onRunQuery: () => void;
onQueryRowChange: (queryRowFilter: QueryRowFilter) => void;
queryRowFilter: QueryRowFilter;
isQueryRunnable: boolean;
}
const editorModes = [
{ label: 'Builder', value: EditorMode.Builder },
{ label: 'Code', value: EditorMode.Code },
];
export function QueryHeader({
db,
query,
queryRowFilter,
onChange,
onRunQuery,
onQueryRowChange,
isQueryRunnable,
}: QueryHeaderProps) {
const { editorMode } = query;
const [_, copyToClipboard] = useCopyToClipboard();
const [showConfirm, setShowConfirm] = useState(false);
const toRawSql = db.toRawSql || defaultToRawSql;
const onEditorModeChange = useCallback(
(newEditorMode: EditorMode) => {
if (editorMode === EditorMode.Code) {
setShowConfirm(true);
return;
}
onChange({ ...query, editorMode: newEditorMode });
},
[editorMode, onChange, query]
);
const onFormatChange = (e: SelectableValue) => {
const next = { ...query, format: e.value !== undefined ? e.value : QueryFormat.Table };
onChange(next);
};
const onDatasetChange = (e: SelectableValue) => {
if (e.value === query.dataset) {
return;
}
const next = {
...query,
dataset: e.value,
table: undefined,
sql: undefined,
rawSql: '',
};
onChange(next);
};
const onTableChange = (e: SelectableValue) => {
if (e.value === query.table) {
return;
}
const next: SQLQuery = {
...query,
table: e.value,
sql: undefined,
rawSql: '',
};
onChange(next);
};
return (
<>
{/* Backward compatibility check. Inline select uses SelectContainer that was added in 8.3 */}
}
>
{editorMode === EditorMode.Builder && (
<>
ev.target instanceof HTMLInputElement &&
onQueryRowChange({ ...queryRowFilter, filter: ev.target.checked })
}
/>
ev.target instanceof HTMLInputElement &&
onQueryRowChange({ ...queryRowFilter, group: ev.target.checked })
}
/>
ev.target instanceof HTMLInputElement &&
onQueryRowChange({ ...queryRowFilter, order: ev.target.checked })
}
/>
ev.target instanceof HTMLInputElement &&
onQueryRowChange({ ...queryRowFilter, preview: ev.target.checked })
}
/>
>
)}
{isQueryRunnable ? (
) : (
Your query is invalid. Check below for details.
However, you can still run this query.
>
}
placement="top"
>
)}
{
setShowConfirm(false);
copyToClipboard(query.rawSql!);
onChange({
...query,
rawSql: toRawSql(query),
editorMode: EditorMode.Builder,
});
}}
onDiscard={() => {
setShowConfirm(false);
onChange({
...query,
rawSql: toRawSql(query),
editorMode: EditorMode.Builder,
});
}}
onCancel={() => setShowConfirm(false)}
/>
{editorMode === EditorMode.Builder && (
<>
>
)}
>
);
}