Skip to content

Commit 4e9ed0e

Browse files
authored
fix(cubejs-playground): update query builder (#9175)
1 parent 164b783 commit 4e9ed0e

File tree

10 files changed

+100
-43
lines changed

10 files changed

+100
-43
lines changed

packages/cubejs-playground/src/QueryBuilderV2/QueryBuilderExtras.tsx

Lines changed: 19 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ import { TCubeMemberType } from '@cubejs-client/core';
2727

2828
import { useStoredTimezones, useEvent } from './hooks';
2929
import { MemberLabel } from './components/MemberLabel';
30+
import { InfoIconButton } from './components/InfoIconButton';
3031
import { useQueryBuilderContext } from './context';
3132
import { ORDER_LABEL_BY_TYPE } from './utils/labels';
3233
import { formatNumber } from './utils/formatters';
@@ -42,7 +43,7 @@ const ALL_TIMEZONES: {
4243
}[] = [
4344
{
4445
tzCode: '',
45-
label: 'UTC (Default)',
46+
label: 'UTC (default)',
4647
name: 'Coordinated Universal Time',
4748
utc: '+00:00',
4849
},
@@ -53,8 +54,8 @@ const AVAILABLE_TIMEZONES = ALL_TIMEZONES.map((tz) => tz.tzCode);
5354
const LIMIT_OPTIONS: { key: number; label: string }[] = [
5455
{ key: 100, label: '100' },
5556
{ key: 1000, label: '1,000' },
56-
{ key: 5000, label: '5,000 (Default)' },
57-
{ key: 0, label: 'Max Row Limit' },
57+
{ key: 5000, label: '5,000' },
58+
{ key: 0, label: 'Default limit' },
5859
];
5960
const LIMIT_OPTION_VALUES = LIMIT_OPTIONS.map((option) => option.key) as number[];
6061

@@ -369,23 +370,15 @@ export function QueryBuilderExtras() {
369370
<Dialog width="36x">
370371
<Content padding="1x 1.5x" gap="1.5x">
371372
<Flow gap="1x">
372-
<Space gap=".75x">
373+
<Space gap=".25x">
373374
<Title level={4} preset="h6">
374375
Query
375376
</Title>
376-
<TooltipProvider
377-
title="Click to learn more about query format"
378-
width="max-content"
379-
>
380-
<Button
381-
to="!https://cube.dev/docs/product/apis-integrations/rest-api/query-format#query-properties"
382-
aria-label="Query format"
383-
width="3x"
384-
height="3x"
385-
type="clear"
386-
icon={<InfoCircleIcon />}
387-
/>
388-
</TooltipProvider>
377+
<InfoIconButton
378+
tooltip="Click to learn more about the query format"
379+
tooltipSuffix=""
380+
to="!https://cube.dev/docs/product/apis-integrations/rest-api/query-format#query-properties"
381+
/>
389382
</Space>
390383
<Checkbox
391384
aria-label="Ungrouped"
@@ -398,14 +391,14 @@ export function QueryBuilderExtras() {
398391
Ungrouped
399392
</Checkbox>
400393
<Checkbox
401-
aria-label="Show total rows"
394+
aria-label="Show total number of rows"
402395
isSelected={query.total ?? false}
403396
onChange={(total) => {
404397
updateQuery({ total: total || undefined });
405398
close();
406399
}}
407400
>
408-
Show total rows
401+
Show total number of rows
409402
</Checkbox>
410403
</Flow>
411404
<ComboBox
@@ -602,6 +595,13 @@ export function QueryBuilderLimitSelect() {
602595
</Link>
603596
) : null
604597
}
598+
labelSuffix={
599+
<InfoIconButton
600+
tooltip="Click to learn more about the row limit"
601+
tooltipSuffix=""
602+
to="!https://cube.dev/docs/product/apis-integrations/queries#row-limit"
603+
/>
604+
}
605605
selectedKey={query.limit == null ? '0' : String(query.limit)}
606606
onSelectionChange={(val: Key) => {
607607
updateQuery(() => ({ limit: val === '0' ? undefined : Number(val as string) }));

packages/cubejs-playground/src/QueryBuilderV2/QueryBuilderFilters.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { useEffect, useRef, useState } from 'react';
2-
import { Button, Flex, Flow, Space, tasty } from '@cube-dev/ui-kit';
2+
import { Button, ClearIcon, Flex, Flow, Space, tasty } from '@cube-dev/ui-kit';
33
import { TCubeDimension, TCubeMeasure } from '@cubejs-client/core';
44

55
import { useQueryBuilderContext } from './context';
@@ -112,7 +112,7 @@ export function QueryBuilderFilters({ onToggle }: { onToggle?: (isExpanded: bool
112112
}
113113
extra={
114114
timeCounter || dimensionCounter || measureCounter || segmentsCounter ? (
115-
<Button size="small" theme="danger" onPress={onClearAction}>
115+
<Button icon={<ClearIcon />} size="small" theme="danger" onPress={onClearAction}>
116116
Remove All
117117
</Button>
118118
) : null

packages/cubejs-playground/src/QueryBuilderV2/QueryBuilderSidePanel.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import {
1313
CloseIcon,
1414
TooltipProvider,
1515
ResizablePanel,
16+
ClearIcon,
1617
} from '@cube-dev/ui-kit';
1718
import {
1819
ReactNode,
@@ -434,7 +435,7 @@ export function QueryBuilderSidePanel({
434435
size="small"
435436
type="secondary"
436437
theme="danger"
437-
icon={<CloseIcon />}
438+
icon={<ClearIcon />}
438439
onPress={() => {
439440
clearQuery();
440441
setOpenCubes(

packages/cubejs-playground/src/QueryBuilderV2/components/AddFilterInput.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -205,7 +205,7 @@ export function AddFilterInput(props: AddFilterInputProps) {
205205
items.push({ value: 'and', label: 'AND Branch' }, { value: 'or', label: 'OR Branch' });
206206

207207
return items;
208-
}, [onDateRangeAdd]);
208+
}, [onDateRangeAdd, onSegmentAdd]);
209209

210210
const disabledKeys = useMemo(() => {
211211
const disabledKeys: string[] = [];

packages/cubejs-playground/src/QueryBuilderV2/components/CopyButton.tsx

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
1-
import { Button, useToastsApi, copy, tasty, CubeButtonProps } from '@cube-dev/ui-kit';
2-
import { CopyOutlined } from '@ant-design/icons';
1+
import {
2+
Button,
3+
useToastsApi,
4+
copy,
5+
tasty,
6+
CubeButtonProps,
7+
CopyIcon as CopyIconUIKit,
8+
} from '@cube-dev/ui-kit';
39
import { useState } from 'react';
410
import { unstable_batchedUpdates } from 'react-dom';
511

@@ -18,7 +24,7 @@ const CopyButtonElement = tasty(Button, {
1824
label: 'Copy value to clipboard',
1925
type: 'clear',
2026
size: 'small',
21-
icon: <CopyOutlined />,
27+
icon: <CopyIconUIKit />,
2228
});
2329

2430
export function CopyButton(props: CopyButtonProps) {

packages/cubejs-playground/src/QueryBuilderV2/components/CopyIcon.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
import { CheckOutlined, CopyOutlined } from '@ant-design/icons';
2-
import { Styles, tasty } from '@cube-dev/ui-kit';
1+
import { CheckOutlined } from '@ant-design/icons';
2+
import { Styles, tasty, CopyIcon as CopyIconUIKit } from '@cube-dev/ui-kit';
33
import { memo, useRef } from 'react';
44

55
import { useDebouncedCallback } from '../hooks';
@@ -45,7 +45,7 @@ const CopyIconElement = tasty({
4545
copied: '0.1s',
4646
},
4747
},
48-
children: <CopyOutlined />,
48+
children: <CopyIconUIKit />,
4949
});
5050

5151
const CopiedIconElement = tasty({

packages/cubejs-playground/src/QueryBuilderV2/components/FilterOptionsButton.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ export interface FilterOptionsButtonProps {
2424

2525
export function FilterOptionsButton({ type, disableKeys, onAction }: FilterOptionsButtonProps) {
2626
const items = useMemo(() => {
27-
const items: { key: string, label: string, color?: string }[] = [];
27+
const items: { key: string; label: string; color?: string }[] = [];
2828

2929
if (type === 'or' || type === 'and') {
3030
if (type === 'and') {
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
import { Action, CubeActionProps, TooltipProvider, tasty, InfoCircleIcon } from '@cube-dev/ui-kit';
2+
3+
export type InfoTooltipButtonProps = {
4+
tooltipSuffix?: string;
5+
tooltip: string;
6+
} & CubeActionProps;
7+
8+
const TooltipButton = tasty(Action, {
9+
styles: {
10+
display: 'inline-grid',
11+
placeItems: 'center',
12+
radius: '1r',
13+
width: '2.5x',
14+
height: '2.5x',
15+
color: {
16+
'': '#purple-text',
17+
pressed: '#purple',
18+
},
19+
verticalAlign: 'middle',
20+
preset: 't3',
21+
},
22+
});
23+
24+
const DEFAULT_TOOLTIP_SUFFIX = 'Click the icon to learn more.';
25+
26+
export function InfoIconButton(props: InfoTooltipButtonProps) {
27+
const { tooltipSuffix = DEFAULT_TOOLTIP_SUFFIX, tooltip, ...rest } = props;
28+
29+
return (
30+
<TooltipProvider
31+
title={
32+
<>
33+
{tooltip} {DEFAULT_TOOLTIP_SUFFIX !== tooltipSuffix || rest.to ? tooltipSuffix : ''}
34+
</>
35+
}
36+
width="initial max-content 40x"
37+
>
38+
<TooltipButton {...rest}>
39+
<InfoCircleIcon />
40+
</TooltipButton>
41+
</TooltipProvider>
42+
);
43+
}

packages/cubejs-playground/src/QueryBuilderV2/components/ValuesInput.tsx

Lines changed: 18 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -144,8 +144,10 @@ export function ValuesInput(props: ValuesInputProps) {
144144
}, [isOpen]);
145145

146146
useEffect(() => {
147-
focusOnInput();
148-
}, [suggestions]);
147+
if (!isSuggestionLoading) {
148+
focusOnInput();
149+
}
150+
}, [isSuggestionLoading]);
149151

150152
// Add current value to the value list and clear the input value
151153
const addValue = useEvent(() => {
@@ -219,17 +221,17 @@ export function ValuesInput(props: ValuesInputProps) {
219221

220222
const input =
221223
type === 'string' ? (
222-
memberType === 'dimension' && allowSuggestions && showSuggestions && suggestions.length ? (
224+
memberType === 'dimension' && allowSuggestions && showSuggestions ? (
223225
<ComboBox
224226
allowsCustomValue
225227
aria-label="Text value input"
226228
inputRef={inputRef}
227229
size="small"
228230
inputValue={textValue}
229231
placeholder={
230-
isSuggestionLoading && !suggestions.length
232+
isSuggestionLoading
231233
? 'Loading values...'
232-
: (placeholder ?? 'Type value to add...')
234+
: (placeholder ?? `Type ${suggestions.length ? 'or select ' : ''}value to add...`)
233235
}
234236
validationState={hasError ? 'invalid' : undefined}
235237
suffix={
@@ -243,6 +245,7 @@ export function ValuesInput(props: ValuesInputProps) {
243245
width="30x"
244246
menuTrigger="focus"
245247
isLoading={isSuggestionLoading && !suggestions.length}
248+
disabledKeys={suggestions.length ? undefined : ['no-suggestions']}
246249
onSelectionChange={(key: Key | null) => {
247250
key && onTextChange(key as string);
248251
addValueLazy();
@@ -253,19 +256,23 @@ export function ValuesInput(props: ValuesInputProps) {
253256
onKeyDown={onKeyDown}
254257
onFocus={onFocus}
255258
>
256-
{suggestions.map((suggestion) => (
257-
<ComboBox.Item key={suggestion} textValue={suggestion}>
258-
{suggestion}
259-
</ComboBox.Item>
260-
))}
259+
{suggestions.length ? (
260+
suggestions.map((suggestion) => (
261+
<ComboBox.Item key={suggestion} textValue={suggestion}>
262+
{suggestion}
263+
</ComboBox.Item>
264+
))
265+
) : (
266+
<ComboBox.Item key="no-suggestions">No values loaded</ComboBox.Item>
267+
)}
261268
</ComboBox>
262269
) : (
263270
<TextInput
264271
aria-label="Text value input"
265272
inputRef={inputRef}
266273
size="small"
267274
value={textValue}
268-
placeholder={placeholder || 'Type value to add...'}
275+
placeholder={placeholder || `Type ${allowSuggestions ? 'or select ' : ''}value to add...`}
269276
validationState={hasError ? 'invalid' : undefined}
270277
isLoading={isSuggestionLoading}
271278
suffix={

packages/cubejs-playground/src/QueryBuilderV2/hooks/query-builder.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -525,7 +525,7 @@ export function useQueryBuilder(props: UseQueryBuilderProps) {
525525
}
526526
}
527527

528-
return names;
528+
return names.reverse();
529529
});
530530

531531
// Updaters with simple common logic for dimensions, measures and segments
@@ -540,7 +540,7 @@ export function useQueryBuilder(props: UseQueryBuilderProps) {
540540
return false;
541541
}
542542

543-
let names: string[];
543+
let names: string[] = [name];
544544

545545
if (type === 'dimensions') {
546546
names = getConnectedDimensionNames(name);

0 commit comments

Comments
 (0)