mirror of
https://github.com/grafana/grafana.git
synced 2025-08-06 20:59:35 +08:00
SQL Query Editor: Fix label-for IDs, associate "Table" label (#86944)
* SQL Query Editor: Fix label-for IDs, associate "Table" label * Fix mysql e2e test --------- Co-authored-by: Zoltán Bedi <zoltan.bedi@gmail.com>
This commit is contained in:
@ -54,7 +54,7 @@ test('visual query builder should handle time filter macro', async ({ explorePag
|
|||||||
await select.locator(page.getByText('createdAt')).click();
|
await select.locator(page.getByText('createdAt')).click();
|
||||||
|
|
||||||
// Toggle where row
|
// Toggle where row
|
||||||
await page.getByLabel('Filter').click();
|
await page.getByLabel('Filter').last().click();
|
||||||
|
|
||||||
// Click add filter button
|
// Click add filter button
|
||||||
await page.getByRole('button', { name: 'Add filter' }).click();
|
await page.getByRole('button', { name: 'Add filter' }).click();
|
||||||
|
@ -14,9 +14,17 @@ export interface DatasetSelectorProps extends ResourceSelectorProps {
|
|||||||
preconfiguredDataset: string;
|
preconfiguredDataset: string;
|
||||||
dialect: SQLDialect;
|
dialect: SQLDialect;
|
||||||
onChange: (v: SelectableValue) => void;
|
onChange: (v: SelectableValue) => void;
|
||||||
|
inputId?: string | undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const DatasetSelector = ({ dataset, db, dialect, onChange, preconfiguredDataset }: DatasetSelectorProps) => {
|
export const DatasetSelector = ({
|
||||||
|
dataset,
|
||||||
|
db,
|
||||||
|
dialect,
|
||||||
|
onChange,
|
||||||
|
inputId,
|
||||||
|
preconfiguredDataset,
|
||||||
|
}: DatasetSelectorProps) => {
|
||||||
/*
|
/*
|
||||||
The behavior of this component - for MSSQL and MySQL datasources - is based on whether the user chose to create a datasource
|
The behavior of this component - for MSSQL and MySQL datasources - is based on whether the user chose to create a datasource
|
||||||
with or without a default database (preconfiguredDataset). If the user configured a default database, this selector
|
with or without a default database (preconfiguredDataset). If the user configured a default database, this selector
|
||||||
@ -68,6 +76,7 @@ export const DatasetSelector = ({ dataset, db, dialect, onChange, preconfiguredD
|
|||||||
return (
|
return (
|
||||||
<Select
|
<Select
|
||||||
aria-label="Dataset selector"
|
aria-label="Dataset selector"
|
||||||
|
inputId={inputId}
|
||||||
value={dataset}
|
value={dataset}
|
||||||
options={state.value}
|
options={state.value}
|
||||||
onChange={onChange}
|
onChange={onChange}
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
import React, { useCallback, useState } from 'react';
|
import React, { useCallback, useId, useState } from 'react';
|
||||||
import { useCopyToClipboard } from 'react-use';
|
import { useCopyToClipboard } from 'react-use';
|
||||||
import { v4 as uuidv4 } from 'uuid';
|
|
||||||
|
|
||||||
import { SelectableValue } from '@grafana/data';
|
import { SelectableValue } from '@grafana/data';
|
||||||
import { selectors } from '@grafana/e2e-selectors';
|
import { selectors } from '@grafana/e2e-selectors';
|
||||||
@ -49,6 +48,8 @@ export function QueryHeader({
|
|||||||
const [showConfirm, setShowConfirm] = useState(false);
|
const [showConfirm, setShowConfirm] = useState(false);
|
||||||
const toRawSql = db.toRawSql;
|
const toRawSql = db.toRawSql;
|
||||||
|
|
||||||
|
const htmlId = useId();
|
||||||
|
|
||||||
const onEditorModeChange = useCallback(
|
const onEditorModeChange = useCallback(
|
||||||
(newEditorMode: EditorMode) => {
|
(newEditorMode: EditorMode) => {
|
||||||
if (newEditorMode === EditorMode.Code) {
|
if (newEditorMode === EditorMode.Code) {
|
||||||
@ -136,7 +137,7 @@ export function QueryHeader({
|
|||||||
{editorMode === EditorMode.Builder && (
|
{editorMode === EditorMode.Builder && (
|
||||||
<>
|
<>
|
||||||
<InlineSwitch
|
<InlineSwitch
|
||||||
id={`sql-filter-${uuidv4()}}`}
|
id={`sql-filter-${htmlId}`}
|
||||||
label="Filter"
|
label="Filter"
|
||||||
data-testid={selectors.components.SQLQueryEditor.headerFilterSwitch}
|
data-testid={selectors.components.SQLQueryEditor.headerFilterSwitch}
|
||||||
transparent={true}
|
transparent={true}
|
||||||
@ -157,7 +158,7 @@ export function QueryHeader({
|
|||||||
/>
|
/>
|
||||||
|
|
||||||
<InlineSwitch
|
<InlineSwitch
|
||||||
id={`sql-group-${uuidv4()}}`}
|
id={`sql-group-${htmlId}`}
|
||||||
label="Group"
|
label="Group"
|
||||||
data-testid={selectors.components.SQLQueryEditor.headerGroupSwitch}
|
data-testid={selectors.components.SQLQueryEditor.headerGroupSwitch}
|
||||||
transparent={true}
|
transparent={true}
|
||||||
@ -178,7 +179,7 @@ export function QueryHeader({
|
|||||||
/>
|
/>
|
||||||
|
|
||||||
<InlineSwitch
|
<InlineSwitch
|
||||||
id={`sql-order-${uuidv4()}}`}
|
id={`sql-order-${htmlId}`}
|
||||||
label="Order"
|
label="Order"
|
||||||
data-testid={selectors.components.SQLQueryEditor.headerOrderSwitch}
|
data-testid={selectors.components.SQLQueryEditor.headerOrderSwitch}
|
||||||
transparent={true}
|
transparent={true}
|
||||||
@ -199,7 +200,7 @@ export function QueryHeader({
|
|||||||
/>
|
/>
|
||||||
|
|
||||||
<InlineSwitch
|
<InlineSwitch
|
||||||
id={`sql-preview-${uuidv4()}}`}
|
id={`sql-preview-${htmlId}`}
|
||||||
label="Preview"
|
label="Preview"
|
||||||
data-testid={selectors.components.SQLQueryEditor.headerPreviewSwitch}
|
data-testid={selectors.components.SQLQueryEditor.headerPreviewSwitch}
|
||||||
transparent={true}
|
transparent={true}
|
||||||
@ -297,6 +298,7 @@ export function QueryHeader({
|
|||||||
<EditorField label="Dataset" width={25}>
|
<EditorField label="Dataset" width={25}>
|
||||||
<DatasetSelector
|
<DatasetSelector
|
||||||
db={db}
|
db={db}
|
||||||
|
inputId={`sql-dataset-${htmlId}`}
|
||||||
dataset={query.dataset}
|
dataset={query.dataset}
|
||||||
dialect={dialect}
|
dialect={dialect}
|
||||||
preconfiguredDataset={preconfiguredDataset}
|
preconfiguredDataset={preconfiguredDataset}
|
||||||
@ -307,6 +309,7 @@ export function QueryHeader({
|
|||||||
<EditorField label="Table" width={25}>
|
<EditorField label="Table" width={25}>
|
||||||
<TableSelector
|
<TableSelector
|
||||||
db={db}
|
db={db}
|
||||||
|
inputId={`sql-tableselect-${htmlId}`}
|
||||||
dataset={query.dataset || preconfiguredDataset}
|
dataset={query.dataset || preconfiguredDataset}
|
||||||
table={query.table}
|
table={query.table}
|
||||||
onChange={onTableChange}
|
onChange={onTableChange}
|
||||||
|
@ -12,9 +12,10 @@ export interface TableSelectorProps extends ResourceSelectorProps {
|
|||||||
table: string | undefined;
|
table: string | undefined;
|
||||||
dataset: string | undefined;
|
dataset: string | undefined;
|
||||||
onChange: (v: SelectableValue) => void;
|
onChange: (v: SelectableValue) => void;
|
||||||
|
inputId?: string | undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const TableSelector = ({ db, dataset, table, className, onChange }: TableSelectorProps) => {
|
export const TableSelector = ({ db, dataset, table, className, onChange, inputId }: TableSelectorProps) => {
|
||||||
const state = useAsync(async () => {
|
const state = useAsync(async () => {
|
||||||
// No need to attempt to fetch tables for an unknown dataset.
|
// No need to attempt to fetch tables for an unknown dataset.
|
||||||
if (!dataset) {
|
if (!dataset) {
|
||||||
@ -30,6 +31,7 @@ export const TableSelector = ({ db, dataset, table, className, onChange }: Table
|
|||||||
className={className}
|
className={className}
|
||||||
disabled={state.loading}
|
disabled={state.loading}
|
||||||
aria-label="Table selector"
|
aria-label="Table selector"
|
||||||
|
inputId={inputId}
|
||||||
data-testid={selectors.components.SQLQueryEditor.headerTableSelector}
|
data-testid={selectors.components.SQLQueryEditor.headerTableSelector}
|
||||||
value={table}
|
value={table}
|
||||||
options={state.value}
|
options={state.value}
|
||||||
|
Reference in New Issue
Block a user