mirror of https://github.com/apache/druid.git
Web console: Final explore QA pass (#17240)
* cleanup * remove redundancy * aggregate works for multiple queries
This commit is contained in:
parent
b9634a8613
commit
d1bc369f06
|
@ -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;
|
||||
|
|
|
@ -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%;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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()];
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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',
|
||||
|
|
|
@ -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',
|
||||
|
|
|
@ -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';
|
||||
|
|
|
@ -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',
|
||||
|
|
|
@ -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',
|
||||
|
|
|
@ -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',
|
||||
|
|
|
@ -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',
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue