Skip to content

Commit

Permalink
enable default column/filter selection
Browse files Browse the repository at this point in the history
  • Loading branch information
SpencerTorres committed Oct 26, 2023
1 parent d5c0698 commit c4e35bb
Show file tree
Hide file tree
Showing 5 changed files with 82 additions and 60 deletions.
10 changes: 4 additions & 6 deletions src/components/queryBuilder/QueryBuilder.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import React from 'react';
import { Datasource } from 'data/CHDatasource';
import { QueryType, QueryBuilderOptions } from 'types/queryBuilder';
import { CoreApp } from '@grafana/data';
import useColumns from 'hooks/useColumns';
import { LogsQueryBuilder } from './views/LogsQueryBuilder';
import { TimeSeriesQueryBuilder } from './views/TimeSeriesQueryBuilder';
import { TableQueryBuilder } from './views/TableQueryBuilder';
Expand All @@ -22,7 +21,6 @@ interface QueryBuilderProps {

export const QueryBuilder = (props: QueryBuilderProps) => {
const { datasource, builderOptions, onBuilderOptionsChange, generatedSql } = props;
const allColumns = useColumns(datasource, builderOptions.database, builderOptions.table);

const onDatabaseChange = (database: string) => onBuilderOptionsChange({ database, table: '' });
const onTableChange = (table: string) => onBuilderOptionsChange({ table });
Expand All @@ -41,10 +39,10 @@ export const QueryBuilder = (props: QueryBuilderProps) => {
<QueryTypeSwitcher queryType={builderOptions.queryType} onChange={onQueryTypeChange} />
</div>

{ builderOptions.queryType === QueryType.Table && <TableQueryBuilder datasource={datasource} allColumns={allColumns} builderOptions={builderOptions} onBuilderOptionsChange={onBuilderOptionsChange} /> }
{ builderOptions.queryType === QueryType.Logs && <LogsQueryBuilder datasource={datasource} allColumns={allColumns} builderOptions={builderOptions} onBuilderOptionsChange={onBuilderOptionsChange} /> }
{ builderOptions.queryType === QueryType.TimeSeries && <TimeSeriesQueryBuilder datasource={datasource} allColumns={allColumns} builderOptions={builderOptions} onBuilderOptionsChange={onBuilderOptionsChange} /> }
{ builderOptions.queryType === QueryType.Traces && <TraceQueryBuilder datasource={datasource} allColumns={allColumns} builderOptions={builderOptions} onBuilderOptionsChange={onBuilderOptionsChange} /> }
{ builderOptions.queryType === QueryType.Table && <TableQueryBuilder datasource={datasource} builderOptions={builderOptions} onBuilderOptionsChange={onBuilderOptionsChange} /> }
{ builderOptions.queryType === QueryType.Logs && <LogsQueryBuilder datasource={datasource} builderOptions={builderOptions} onBuilderOptionsChange={onBuilderOptionsChange} /> }
{ builderOptions.queryType === QueryType.TimeSeries && <TimeSeriesQueryBuilder datasource={datasource} builderOptions={builderOptions} onBuilderOptionsChange={onBuilderOptionsChange} /> }
{ builderOptions.queryType === QueryType.Traces && <TraceQueryBuilder datasource={datasource} builderOptions={builderOptions} onBuilderOptionsChange={onBuilderOptionsChange} /> }

<SqlPreview sql={generatedSql} />
</div>
Expand Down
93 changes: 57 additions & 36 deletions src/components/queryBuilder/views/LogsQueryBuilder.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import React, { useEffect } from 'react';
import React, { useEffect, useMemo, useRef } from 'react';
import { ColumnsEditor } from '../ColumnsEditor';
import { Filter, TableColumn, OrderBy, QueryBuilderOptions, SelectedColumn, ColumnHint } from 'types/queryBuilder';
import { Filter, OrderBy, QueryBuilderOptions, SelectedColumn, ColumnHint, DateFilterWithoutValue, FilterOperator } from 'types/queryBuilder';
import { ColumnSelect } from '../ColumnSelect';
import { OtelVersionSelect } from '../OtelVersionSelect';
import { OrderByEditor, getOrderByOptions } from '../OrderByEditor';
Expand All @@ -13,9 +13,9 @@ import { Datasource } from 'data/CHDatasource';
import { useBuilderOptionChanges } from 'hooks/useBuilderOptionChanges';
import { versions as otelVersions } from 'otel';
import { Alert, VerticalGroup } from '@grafana/ui';
import useColumns from 'hooks/useColumns';

interface LogsQueryBuilderProps {
allColumns: readonly TableColumn[];
datasource: Datasource;
builderOptions: QueryBuilderOptions,
onBuilderOptionsChange: (nextBuilderOptions: Partial<QueryBuilderOptions>) => void;
Expand All @@ -35,9 +35,10 @@ interface LogsQueryBuilderState {
}

export const LogsQueryBuilder = (props: LogsQueryBuilderProps) => {
const { allColumns, datasource, builderOptions, onBuilderOptionsChange } = props;
const { datasource, builderOptions, onBuilderOptionsChange } = props;
const labels = allLabels.components.LogsQueryBuilder;
const builderState: LogsQueryBuilderState = {
const allColumns = useColumns(datasource, builderOptions.database, builderOptions.table);
const builderState: LogsQueryBuilderState = useMemo(() => ({
otelEnabled: builderOptions.meta?.otelEnabled || false,
otelVersion: builderOptions.meta?.otelVersion || '',
timeColumn: getColumnByHint(builderOptions, ColumnHint.Time),
Expand All @@ -53,7 +54,7 @@ export const LogsQueryBuilder = (props: LogsQueryBuilderProps) => {
orderBy: builderOptions.orderBy || [],
limit: builderOptions.limit || 1000,
filters: builderOptions.filters || [],
};
}), [builderOptions]);
const showConfigWarning = datasource.getDefaultLogsColumns().size === 0;

function setOtelColumns(builderState: LogsQueryBuilderState) {
Expand Down Expand Up @@ -95,7 +96,7 @@ export const LogsQueryBuilder = (props: LogsQueryBuilderProps) => {
nextColumns.push(next.messageColumn);
}

onBuilderOptionsChange({
const nextOptions = {
columns: nextColumns,
filters: next.filters,
orderBy: next.orderBy,
Expand All @@ -104,7 +105,9 @@ export const LogsQueryBuilder = (props: LogsQueryBuilderProps) => {
otelEnabled: next.otelEnabled,
otelVersion: next.otelVersion,
}
});
};

onBuilderOptionsChange(nextOptions);
}, builderState);

useEffect(() => {
Expand Down Expand Up @@ -139,39 +142,57 @@ export const LogsQueryBuilder = (props: LogsQueryBuilderProps) => {
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);

// TODO: default filter
// const timeRangeFilter: DateFilterWithoutValue = {
// type: 'date',
// operator: FilterOperator.WithInGrafanaTimeRange,
// filterType: 'custom',
// key: timeColumn.name,
// id: 'timeRange',
// condition: 'AND'
// };
// Select default time filter on timeColumn change
const lastTimeColumn = useRef<string>(builderState.timeColumn?.name || '');
useEffect(() => {
if (!builderState.timeColumn) {
return;
} else if ((builderState.timeColumn.name === lastTimeColumn.current) || builderState.filters.find(f => f.id === 'timeRange')) {
return;
}

const timeRangeFilter: DateFilterWithoutValue = {
type: 'datetime',
operator: FilterOperator.WithInGrafanaTimeRange,
filterType: 'custom',
key: builderState.timeColumn.name,
id: 'timeRange',
condition: 'AND'
};

// TODO: fix default table selection AND default time column selection
// useEffect(() => {
// if (allColumns.length === 0) {
// return;
// }
lastTimeColumn.current = builderState.timeColumn.name;
onOptionChange('filters')([timeRangeFilter, ...builderState.filters.filter(f => f.id !== 'timeRange')]);
}, [builderState.timeColumn, builderState.filters, onOptionChange]);

// const col = allColumns.filter(columnFilterDateTime)[0];
// const currentColumnExists = (builderState.timeColumn && allColumns.find(c => c.name === builderState.timeColumn?.name));
// if (!col || currentColumnExists) {
// return;
// }
// Find and select a default time column, update when table changes
const lastTable = useRef<string>(builderOptions.table);
const defaultTimeSelected = useRef<boolean>(Boolean(builderState.timeColumn));
useEffect(() => {
if (builderOptions.table !== lastTable.current) {
defaultTimeSelected.current = false;
}

if (allColumns.length === 0 || !builderOptions.table || defaultTimeSelected.current) {
return;
}

const col = allColumns.filter(columnFilterDateTime)[0];
const currentColumnExists = (builderState.timeColumn && allColumns.find(c => c.name === builderState.timeColumn?.name));
if (!col || currentColumnExists) {
return;
}

// const timeColumn: SelectedColumn = {
// name: col.name,
// type: col.type,
// hint: ColumnHint.Time
// };
const timeColumn: SelectedColumn = {
name: col.name,
type: col.type,
hint: ColumnHint.Time
};

// onOptionChange('timeColumn')(timeColumn);
lastTable.current = builderOptions.table;
defaultTimeSelected.current = true;
onOptionChange('timeColumn')(timeColumn);

// // Find and select a default time column, update when table changes
// // eslint-disable-next-line react-hooks/exhaustive-deps
// }, [allColumns, builderOptions.table]);
}, [allColumns, builderOptions.table, builderState.timeColumn, onOptionChange]);

const configWarning = showConfigWarning && (
<Alert title="" severity="warning">
Expand Down
13 changes: 7 additions & 6 deletions src/components/queryBuilder/views/TableQueryBuilder.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import React, { useState } from 'react';
import React, { useMemo, useState } from 'react';
import { ColumnsEditor } from '../ColumnsEditor';
import { AggregateColumn, BuilderMode, Filter, TableColumn, OrderBy, QueryBuilderOptions, SelectedColumn } from 'types/queryBuilder';
import { AggregateColumn, BuilderMode, Filter, OrderBy, QueryBuilderOptions, SelectedColumn } from 'types/queryBuilder';
import { OrderByEditor, getOrderByOptions } from '../OrderByEditor';
import { LimitEditor } from '../LimitEditor';
import { FiltersEditor } from '../FilterEditor';
Expand All @@ -10,9 +10,9 @@ import { AggregateEditor } from '../AggregateEditor';
import { GroupByEditor } from '../GroupByEditor';
import { Datasource } from 'data/CHDatasource';
import { useBuilderOptionChanges } from 'hooks/useBuilderOptionChanges';
import useColumns from 'hooks/useColumns';

interface TableQueryBuilderProps {
allColumns: readonly TableColumn[];
datasource: Datasource;
builderOptions: QueryBuilderOptions,
onBuilderOptionsChange: (nextBuilderOptions: Partial<QueryBuilderOptions>) => void;
Expand All @@ -28,17 +28,18 @@ interface TableQueryBuilderState {
}

export const TableQueryBuilder = (props: TableQueryBuilderProps) => {
const { allColumns, builderOptions, onBuilderOptionsChange } = props;
const { datasource, builderOptions, onBuilderOptionsChange } = props;
const allColumns = useColumns(datasource, builderOptions.database, builderOptions.table);
const labels = allLabels.components.TableQueryBuilder;
const [isAggregateMode, setAggregateMode] = useState<boolean>((builderOptions.aggregates?.length || 0) > 0); // Toggle Simple vs Aggregate mode
const builderState: TableQueryBuilderState = {
const builderState: TableQueryBuilderState = useMemo(() => ({
selectedColumns: builderOptions.columns || [],
aggregates: builderOptions.aggregates || [],
groupBy: builderOptions.groupBy || [],
orderBy: builderOptions.orderBy || [],
limit: builderOptions.limit || 1000,
filters: builderOptions.filters || [],
};
}), [builderOptions]);

const onOptionChange = useBuilderOptionChanges<TableQueryBuilderState>(next => {
onBuilderOptionsChange({
Expand Down
13 changes: 7 additions & 6 deletions src/components/queryBuilder/views/TimeSeriesQueryBuilder.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import React, { useEffect, useState } from 'react';
import React, { useEffect, useMemo, useState } from 'react';
import { ColumnsEditor } from '../ColumnsEditor';
import { AggregateColumn, BuilderMode, Filter, TableColumn, OrderBy, QueryBuilderOptions, ColumnHint, SelectedColumn } from 'types/queryBuilder';
import { AggregateColumn, BuilderMode, Filter, OrderBy, QueryBuilderOptions, ColumnHint, SelectedColumn } from 'types/queryBuilder';
import { OrderByEditor, getOrderByOptions } from '../OrderByEditor';
import { LimitEditor } from '../LimitEditor';
import { FiltersEditor } from '../FilterEditor';
Expand All @@ -13,9 +13,9 @@ import { getColumnByHint } from 'components/queryBuilder/utils';
import { columnFilterDateTime } from 'data/columnFilters';
import { Datasource } from 'data/CHDatasource';
import { useBuilderOptionChanges } from 'hooks/useBuilderOptionChanges';
import useColumns from 'hooks/useColumns';

interface TimeSeriesQueryBuilderProps {
allColumns: readonly TableColumn[];
datasource: Datasource;
builderOptions: QueryBuilderOptions,
onBuilderOptionsChange: (nextBuilderOptions: Partial<QueryBuilderOptions>) => void;
Expand All @@ -32,18 +32,19 @@ interface TimeSeriesQueryBuilderState {
}

export const TimeSeriesQueryBuilder = (props: TimeSeriesQueryBuilderProps) => {
const { allColumns, builderOptions, onBuilderOptionsChange } = props;
const { datasource, builderOptions, onBuilderOptionsChange } = props;
const allColumns = useColumns(datasource, builderOptions.database, builderOptions.table);
const labels = allLabels.components.TimeSeriesQueryBuilder;
const [isAggregateMode, setAggregateMode] = useState<boolean>((builderOptions.aggregates?.length || 0) > 0); // Toggle Simple vs Aggregate mode
const builderState: TimeSeriesQueryBuilderState = {
const builderState: TimeSeriesQueryBuilderState = useMemo(() => ({
timeColumn: getColumnByHint(builderOptions, ColumnHint.Time),
selectedColumns: (builderOptions.columns || []).filter(c => c.hint !== ColumnHint.Time),
aggregates: builderOptions.aggregates || [],
groupBy: builderOptions.groupBy || [],
orderBy: builderOptions.orderBy || [],
limit: builderOptions.limit || 1000,
filters: builderOptions.filters || [],
};
}), [builderOptions]);

const onOptionChange = useBuilderOptionChanges<TimeSeriesQueryBuilderState>(next => {
const nextColumns = next.selectedColumns.slice();
Expand Down
13 changes: 7 additions & 6 deletions src/components/queryBuilder/views/TraceQueryBuilder.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import React, { useEffect, useState } from 'react';
import { Filter, TableColumn, QueryBuilderOptions, SelectedColumn, ColumnHint, TimeUnit } from 'types/queryBuilder';
import React, { useEffect, useMemo, useState } from 'react';
import { Filter, QueryBuilderOptions, SelectedColumn, ColumnHint, TimeUnit } from 'types/queryBuilder';
import { ColumnSelect } from '../ColumnSelect';
import { FiltersEditor } from '../FilterEditor';
import allLabels from 'labels';
Expand All @@ -9,9 +9,9 @@ import { Alert, Collapse, InlineFormLabel, Input, VerticalGroup } from '@grafana
import { DurationUnitSelect } from 'components/queryBuilder/DurationUnitSelect';
import { Datasource } from 'data/CHDatasource';
import { useBuilderOptionChanges } from 'hooks/useBuilderOptionChanges';
import useColumns from 'hooks/useColumns';

interface TraceQueryBuilderProps {
allColumns: readonly TableColumn[];
datasource: Datasource;
builderOptions: QueryBuilderOptions,
onBuilderOptionsChange: (nextBuilderOptions: Partial<QueryBuilderOptions>) => void;
Expand All @@ -34,12 +34,13 @@ interface TraceQueryBuilderState {
}

export const TraceQueryBuilder = (props: TraceQueryBuilderProps) => {
const { allColumns, datasource, builderOptions, onBuilderOptionsChange } = props;
const { datasource, builderOptions, onBuilderOptionsChange } = props;
const allColumns = useColumns(datasource, builderOptions.database, builderOptions.table);
const showConfigWarning = datasource.getDefaultTraceColumns().size === 0;
const [isColumnsOpen, setColumnsOpen] = useState<boolean>(showConfigWarning); // Toggle Columns collapsable section
const [isFiltersOpen, setFiltersOpen] = useState<boolean>(true); // Toggle Filters collapsable section
const labels = allLabels.components.TraceQueryBuilder;
const builderState: TraceQueryBuilderState = {
const builderState: TraceQueryBuilderState = useMemo(() => ({
isSearchMode: builderOptions.meta?.isTraceSearchMode || false,
traceIdColumn: getColumnByHint(builderOptions, ColumnHint.TraceId),
spanIdColumn: getColumnByHint(builderOptions, ColumnHint.TraceSpanId),
Expand All @@ -53,7 +54,7 @@ export const TraceQueryBuilder = (props: TraceQueryBuilderProps) => {
serviceTagsColumn: getColumnByHint(builderOptions, ColumnHint.TraceServiceTags),
traceId: builderOptions.meta?.traceId || '',
filters: builderOptions.filters || [],
};
}), [builderOptions]);

useEffect(() => {
const shouldApplyDefaults = (builderOptions.columns || []).length === 0 && (builderOptions.orderBy || []).length === 0;
Expand Down

0 comments on commit c4e35bb

Please sign in to comment.