Web console: Final explore QA pass (#17240)

* cleanup

* remove redundancy

* aggregate works for multiple queries
This commit is contained in:
Vadim Ogievetsky 2024-10-03 19:52:17 -07:00 committed by GitHub
parent b9634a8613
commit d1bc369f06
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
13 changed files with 37 additions and 42 deletions

View File

@ -22,6 +22,8 @@
display: flex;
flex-wrap: wrap;
gap: 5px;
align-items: flex-start;
align-content: flex-start;
.filter-icon-button {
pointer-events: none;

View File

@ -47,20 +47,4 @@
left: 0;
}
}
.tile-content {
width: 100%;
height: 100%;
&.issue {
display: flex;
justify-content: center;
align-items: center;
}
& > * {
width: 100%;
height: 100%;
}
}
}

View File

@ -17,24 +17,27 @@
*/
import { Button, ButtonGroup, Menu, MenuItem, Popover, Position } from '@blueprintjs/core';
import type { IconName } from '@blueprintjs/icons';
import { IconNames } from '@blueprintjs/icons';
import type { JSX } from 'react';
import React from 'react';
import { ModuleRepository } from '../../module-repository/module-repository';
import './module-picker.scss';
export interface ModulePickerProps {
modules: readonly { id: string; icon: IconName; label: string }[];
selectedModuleId: string | undefined;
onSelectedModuleIdChange(newSelectedModuleId: string): void;
moreMenu?: JSX.Element;
}
export const ModulePicker = React.memo(function ModulePicker(props: ModulePickerProps) {
const { modules, selectedModuleId, onSelectedModuleIdChange, moreMenu } = props;
const { selectedModuleId, onSelectedModuleIdChange, moreMenu } = props;
const selectedTileManifest = modules.find(module => module.id === selectedModuleId);
const modules = ModuleRepository.getAllModuleEntries();
const selectedModule = selectedModuleId
? ModuleRepository.getModule(selectedModuleId)
: undefined;
return (
<ButtonGroup className="module-picker" fill>
<Popover
@ -48,7 +51,7 @@ export const ModulePicker = React.memo(function ModulePicker(props: ModulePicker
<MenuItem
key={i}
icon={module.icon}
text={module.label}
text={module.title}
onClick={() => onSelectedModuleIdChange(module.id)}
/>
))}
@ -56,8 +59,8 @@ export const ModulePicker = React.memo(function ModulePicker(props: ModulePicker
}
>
<Button
icon={selectedTileManifest ? selectedTileManifest.icon : IconNames.BOX}
text={selectedTileManifest ? selectedTileManifest.label : 'Select module'}
icon={selectedModule ? selectedModule.icon : IconNames.BOX}
text={selectedModule ? selectedModule.title : 'Select module'}
fill
minimal
rightIcon={IconNames.CARET_DOWN}

View File

@ -323,14 +323,6 @@ export const ExploreView = React.memo(function ExploreView() {
}}
/>
<ModulePicker
modules={[
{ id: 'grouping-table', icon: IconNames.PANEL_TABLE, label: 'Grouping table' },
{ id: 'record-table', icon: IconNames.TH, label: 'Record table' },
{ id: 'time-chart', icon: IconNames.TIMELINE_LINE_CHART, label: 'Time chart' },
{ id: 'bar-chart', icon: IconNames.VERTICAL_BAR_CHART_DESC, label: 'Bar chart' },
{ id: 'pie-chart', icon: IconNames.PIE_CHART, label: 'Pie chart' },
{ id: 'multi-axis-chart', icon: IconNames.SERIES_ADD, label: 'Multi-axis chart' },
]}
selectedModuleId={moduleId}
onSelectedModuleIdChange={newModuleId => {
const newParameterValues = getStickyParameterValuesForModule(newModuleId);

View File

@ -16,6 +16,7 @@
* limitations under the License.
*/
import type { IconName } from '@blueprintjs/icons';
import type { QueryResult, SqlExpression, SqlQuery } from '@druid-toolkit/query';
import type { CancelToken } from 'axios';
@ -23,6 +24,7 @@ import type { ParameterDefinition, QuerySource, Stage } from '../models';
interface ModuleDefinition<P> {
id: string;
icon: IconName;
title: string;
parameters: Record<keyof P, ParameterDefinition>;
component: (props: ModuleComponentProps<P>) => any;
@ -52,7 +54,7 @@ export class ModuleRepository {
return ModuleRepository.repo.get(id);
}
static getAllModuleIds(): string[] {
return [...ModuleRepository.repo.keys()];
static getAllModuleEntries(): ModuleDefinition<any>[] {
return [...ModuleRepository.repo.values()];
}
}

View File

@ -16,6 +16,7 @@
* limitations under the License.
*/
import { IconNames } from '@blueprintjs/icons';
import { L } from '@druid-toolkit/query';
import type { ECharts } from 'echarts';
import * as echarts from 'echarts';
@ -43,6 +44,7 @@ interface BarChartParameterValues {
ModuleRepository.registerModule<BarChartParameterValues>({
id: 'bar-chart',
title: 'Bar chart',
icon: IconNames.VERTICAL_BAR_CHART_DESC,
parameters: {
splitColumn: {
type: 'expression',

View File

@ -17,6 +17,7 @@
*/
import { Button } from '@blueprintjs/core';
import { IconNames } from '@blueprintjs/icons';
import type { SqlExpression, SqlOrderByDirection, SqlQuery } from '@druid-toolkit/query';
import { C, F } from '@druid-toolkit/query';
import React, { useMemo } from 'react';
@ -70,6 +71,7 @@ interface GroupingTableParameterValues {
ModuleRepository.registerModule<GroupingTableParameterValues>({
id: 'grouping-table',
title: 'Grouping table',
icon: IconNames.PANEL_TABLE,
parameters: {
splitColumns: {
type: 'expressions',

View File

@ -18,7 +18,7 @@
import './grouping-table-module';
import './record-table-module';
import './time-chart-module';
import './bar-chart-module';
import './pie-chart-module';
import './time-chart-module';
import './multi-axis-chart-module';

View File

@ -16,6 +16,7 @@
* limitations under the License.
*/
import { IconNames } from '@blueprintjs/icons';
import type { SqlQuery } from '@druid-toolkit/query';
import { C, F, L } from '@druid-toolkit/query';
import type { ECharts } from 'echarts';
@ -46,6 +47,7 @@ interface MultiAxisChartParameterValues {
ModuleRepository.registerModule<MultiAxisChartParameterValues>({
id: 'multi-axis-chart',
title: 'Multi-axis chart',
icon: IconNames.SERIES_ADD,
parameters: {
timeGranularity: {
type: 'option',

View File

@ -16,6 +16,7 @@
* limitations under the License.
*/
import { IconNames } from '@blueprintjs/icons';
import { C, L } from '@druid-toolkit/query';
import type { ECharts } from 'echarts';
import * as echarts from 'echarts';
@ -63,6 +64,7 @@ interface PieChartParameterValues {
ModuleRepository.registerModule<PieChartParameterValues>({
id: 'pie-chart',
title: 'Pie chart',
icon: IconNames.PIE_CHART,
parameters: {
splitColumn: {
type: 'expression',

View File

@ -16,6 +16,7 @@
* limitations under the License.
*/
import { IconNames } from '@blueprintjs/icons';
import { C, SqlQuery } from '@druid-toolkit/query';
import React, { useMemo } from 'react';
@ -38,6 +39,7 @@ interface RecordTableParameterValues {
ModuleRepository.registerModule<RecordTableParameterValues>({
id: 'record-table',
title: 'Record table',
icon: IconNames.TH,
parameters: {
maxRows: {
type: 'number',

View File

@ -16,6 +16,7 @@
* limitations under the License.
*/
import { IconNames } from '@blueprintjs/icons';
import { C, F, L, SqlCase } from '@druid-toolkit/query';
import type { ECharts } from 'echarts';
import * as echarts from 'echarts';
@ -73,6 +74,7 @@ interface TimeChartParameterValues {
ModuleRepository.registerModule<TimeChartParameterValues>({
id: 'time-chart',
title: 'Time chart',
icon: IconNames.TIMELINE_LINE_CHART,
parameters: {
timeGranularity: {
type: 'option',

View File

@ -24,7 +24,7 @@ import { KNOWN_AGGREGATIONS } from '../utils';
export function rewriteAggregate(query: SqlQuery, measures: Measure[]): SqlQuery {
const usedMeasures: Map<string, boolean> = new Map();
let queryToRewrite: SqlQuery | undefined;
const queriesToRewrite: SqlQuery[] = [];
const newQuery = query.walk(ex => {
if (ex instanceof SqlFunction && ex.getEffectiveFunctionName() === Measure.AGGREGATE) {
if (ex.numArgs() !== 1)
@ -51,27 +51,27 @@ export function rewriteAggregate(query: SqlQuery, measures: Measure[]): SqlQuery
if (ex instanceof SqlQuery) {
const queryMeasures = Measure.extractQueryMeasures(ex);
if (queryMeasures.length) {
queryToRewrite = ex;
queriesToRewrite.push(ex);
}
}
return ex;
}) as SqlQuery;
if (!queryToRewrite) return newQuery;
if (!queriesToRewrite.length) return newQuery;
return newQuery.walk(ex => {
if (ex === queryToRewrite) {
return queryToRewrite.applyForEach(
return newQuery.walk(subQuery => {
if (subQuery instanceof SqlQuery && queriesToRewrite.includes(subQuery)) {
return subQuery.applyForEach(
uniq(
filterMap(measures, queryMeasure =>
usedMeasures.get(queryMeasure.name) ? queryMeasure.expression : undefined,
).flatMap(ex => ex.getUsedColumnNames()),
).filter(columnName => queryToRewrite!.getSelectIndexForOutputColumn(columnName) === -1),
).filter(columnName => subQuery.getSelectIndexForOutputColumn(columnName) === -1),
(q, columnName) => q.addSelect(C(columnName)),
);
}
return ex;
return subQuery;
}) as SqlQuery;
}