Skip to content

Commit 06d243d

Browse files
astandrikAnton Standrik
andauthored
feat: design query tab (#2077)
Co-authored-by: Anton Standrik <[email protected]>
1 parent 22bc779 commit 06d243d

File tree

31 files changed

+1134
-526
lines changed

31 files changed

+1134
-526
lines changed

src/components/ConnectToDB/ConnectToDBDialog.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ function ConnectToDBDialog({open, onClose, database, endpoint}: ConnectToDBDialo
5656
language={activeTab}
5757
text={snippet}
5858
transparentBackground={false}
59-
withCopy
59+
withClipboardButton={{alwaysVisible: true}}
6060
/>
6161
</div>
6262
{docsLink ? (

src/components/DateRange/DateRange.scss

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
.date-range {
22
&__range-input {
33
&_s {
4-
width: 200px;
4+
width: 130px;
55
}
66

77
&_m {

src/components/DateRange/DateRange.tsx

Lines changed: 9 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
import React from 'react';
22

3-
import type {RelativeRangeDatePickerProps} from '@gravity-ui/date-components';
3+
import type {
4+
RelativeRangeDatePickerProps,
5+
RelativeRangeDatePickerValue,
6+
} from '@gravity-ui/date-components';
47
import {RelativeRangeDatePicker} from '@gravity-ui/date-components';
58

69
import {cn} from '../../utils/cn';
@@ -19,23 +22,13 @@ export interface DateRangeValues {
1922
to?: string;
2023
}
2124

22-
const DEFAULT_VALUE = {
23-
start: {
24-
value: 'now-1h',
25-
type: 'relative',
26-
},
27-
end: {
28-
value: 'now',
29-
type: 'relative',
30-
},
31-
} as const;
32-
3325
interface DateRangeProps extends DateRangeValues {
3426
className?: string;
27+
defaultValue?: RelativeRangeDatePickerValue;
3528
onChange?: (value: DateRangeValues) => void;
3629
}
3730

38-
export const DateRange = ({from, to, className, onChange}: DateRangeProps) => {
31+
export const DateRange = ({from, to, className, defaultValue, onChange}: DateRangeProps) => {
3932
const handleUpdate = React.useCallback<NonNullable<RelativeRangeDatePickerProps['onUpdate']>>(
4033
(pickerValue) => onChange?.(toDateRangeValues(pickerValue)),
4134
[onChange],
@@ -50,13 +43,14 @@ export const DateRange = ({from, to, className, onChange}: DateRangeProps) => {
5043

5144
// eslint-disable-next-line new-cap
5245
const timeZoneString = Intl.DateTimeFormat().resolvedOptions().timeZone;
46+
const currentValue = value || defaultValue;
5347
return (
5448
<div className={b(null, className)}>
5549
<RelativeRangeDatePicker
5650
withPresets
57-
className={b('range-input', {[getdatePickerSize(value)]: true})}
51+
className={b('range-input', {[getdatePickerSize(currentValue)]: true})}
5852
timeZone={timeZoneString}
59-
value={value || DEFAULT_VALUE}
53+
value={currentValue}
6054
allowNullableValues
6155
size="m"
6256
format={i18n('date-time-format')}

src/components/ResizeableDataTable/ResizeableDataTable.scss

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,13 @@
55

66
// padding for easier resize of the last column
77
padding-right: 20px;
8+
9+
&__row-skeleton {
10+
width: 100%;
11+
height: 50%;
12+
}
13+
14+
&__row-skeleton::after {
15+
animation: none !important;
16+
}
817
}

src/components/ResizeableDataTable/ResizeableDataTable.tsx

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
1-
import type {DataTableProps, Settings} from '@gravity-ui/react-data-table';
1+
import type {Column, DataTableProps, Settings} from '@gravity-ui/react-data-table';
22
import DataTable, {updateColumnsWidth} from '@gravity-ui/react-data-table';
3+
import {Skeleton} from '@gravity-ui/uikit';
34

45
import {cn} from '../../utils/cn';
56
import {useTableResize} from '../../utils/hooks/useTableResize';
@@ -11,18 +12,28 @@ const b = cn('ydb-resizeable-data-table');
1112
export interface ResizeableDataTableProps<T> extends Omit<DataTableProps<T>, 'theme' | 'onResize'> {
1213
columnsWidthLSKey?: string;
1314
wrapperClassName?: string;
15+
loading?: boolean;
1416
}
1517

1618
export function ResizeableDataTable<T>({
1719
columnsWidthLSKey,
1820
columns,
1921
settings,
2022
wrapperClassName,
23+
loading,
2124
...props
2225
}: ResizeableDataTableProps<T>) {
2326
const [tableColumnsWidth, setTableColumnsWidth] = useTableResize(columnsWidthLSKey);
2427

25-
const updatedColumns = updateColumnsWidth(columns, tableColumnsWidth);
28+
// If loading is true, override the render method of each column to display a Skeleton
29+
const processedColumns = loading
30+
? columns.map((column: Column<T>) => ({
31+
...column,
32+
render: () => <Skeleton className={b('row-skeleton')} />,
33+
}))
34+
: columns;
35+
36+
const updatedColumns = updateColumnsWidth(processedColumns, tableColumnsWidth);
2637

2738
const newSettings: Settings = {
2839
...settings,

src/components/SyntaxHighlighter/YDBSyntaxHighlighter.scss

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,5 +16,18 @@
1616
position: absolute;
1717
top: 13px;
1818
right: 14px;
19+
20+
pointer-events: all;
21+
22+
opacity: 0;
23+
24+
&_visible {
25+
opacity: 1;
26+
}
27+
}
28+
29+
.data-table__row:hover &__copy,
30+
.ydb-paginated-table__row:hover &__copy {
31+
opacity: 1;
1932
}
2033
}

src/components/SyntaxHighlighter/YDBSyntaxHighlighter.tsx

Lines changed: 26 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -23,20 +23,28 @@ async function registerLanguage(lang: Language) {
2323
}
2424
}
2525

26+
interface ClipboardButtonOptions {
27+
alwaysVisible?: boolean;
28+
copyText?: string;
29+
withLabel?: boolean;
30+
}
31+
32+
export type WithClipboardButtonProp = ClipboardButtonOptions | boolean;
33+
2634
type YDBSyntaxHighlighterProps = {
2735
text: string;
2836
language: Language;
2937
className?: string;
3038
transparentBackground?: boolean;
31-
withCopy?: boolean;
39+
withClipboardButton?: WithClipboardButtonProp;
3240
};
3341

3442
export function YDBSyntaxHighlighter({
3543
text,
3644
language,
3745
className,
3846
transparentBackground = true,
39-
withCopy,
47+
withClipboardButton,
4048
}: YDBSyntaxHighlighterProps) {
4149
const [highlighterKey, setHighlighterKey] = React.useState('');
4250

@@ -51,16 +59,27 @@ export function YDBSyntaxHighlighter({
5159
}, [language]);
5260

5361
const renderCopyButton = () => {
54-
if (withCopy) {
62+
if (withClipboardButton) {
5563
return (
56-
<div className={b('sticky-container')}>
64+
<div className={b('sticky-container')} onClick={(e) => e.stopPropagation()}>
5765
<ClipboardButton
5866
view="flat-secondary"
5967
size="s"
60-
className={b('copy')}
61-
text={text}
68+
className={b('copy', {
69+
visible:
70+
typeof withClipboardButton === 'object' &&
71+
withClipboardButton.alwaysVisible,
72+
})}
73+
text={
74+
(typeof withClipboardButton === 'object' &&
75+
withClipboardButton.copyText) ||
76+
text
77+
}
6278
>
63-
{i18n('copy')}
79+
{typeof withClipboardButton === 'object' &&
80+
withClipboardButton.withLabel === false
81+
? null
82+
: i18n('copy')}
6483
</ClipboardButton>
6584
</div>
6685
);

src/components/TruncatedQuery/TruncatedQuery.tsx

Lines changed: 37 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,16 @@ const b = cn('kv-truncated-query');
1010
interface TruncatedQueryProps {
1111
value?: string;
1212
maxQueryHeight?: number;
13+
hasClipboardButton?: boolean;
14+
clipboardButtonAlwaysVisible?: boolean;
1315
}
1416

15-
export const TruncatedQuery = ({value = '', maxQueryHeight = 6}: TruncatedQueryProps) => {
17+
export const TruncatedQuery = ({
18+
value = '',
19+
maxQueryHeight = 6,
20+
hasClipboardButton,
21+
clipboardButtonAlwaysVisible,
22+
}: TruncatedQueryProps) => {
1623
const lines = value.split('\n');
1724
const truncated = lines.length > maxQueryHeight;
1825

@@ -22,10 +29,37 @@ export const TruncatedQuery = ({value = '', maxQueryHeight = 6}: TruncatedQueryP
2229
'\n...\nThe request was truncated. Click on the line to show the full query on the query tab';
2330
return (
2431
<React.Fragment>
25-
<YDBSyntaxHighlighter language="yql" className={b()} text={content} />
32+
<YDBSyntaxHighlighter
33+
language="yql"
34+
className={b()}
35+
text={content}
36+
withClipboardButton={
37+
hasClipboardButton
38+
? {
39+
alwaysVisible: clipboardButtonAlwaysVisible,
40+
copyText: value,
41+
withLabel: false,
42+
}
43+
: false
44+
}
45+
/>
2646
<span className={b('message', {color: 'secondary'})}>{message}</span>
2747
</React.Fragment>
2848
);
2949
}
30-
return <YDBSyntaxHighlighter language="yql" text={value} />;
50+
return (
51+
<YDBSyntaxHighlighter
52+
language="yql"
53+
text={value}
54+
withClipboardButton={
55+
hasClipboardButton
56+
? {
57+
alwaysVisible: clipboardButtonAlwaysVisible,
58+
copyText: value,
59+
withLabel: false,
60+
}
61+
: false
62+
}
63+
/>
64+
);
3165
};

src/containers/Tenant/Diagnostics/TenantOverview/TenantCpu/TopQueries.tsx

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,10 @@ import {
1515
TENANT_PAGES_IDS,
1616
TENANT_QUERY_TABS_ID,
1717
} from '../../../../../store/reducers/tenant/constants';
18-
import {TENANT_OVERVIEW_TABLES_SETTINGS} from '../../../../../utils/constants';
18+
import {
19+
TENANT_OVERVIEW_TABLES_LIMIT,
20+
TENANT_OVERVIEW_TABLES_SETTINGS,
21+
} from '../../../../../utils/constants';
1922
import {useAutoRefreshInterval, useTypedDispatch} from '../../../../../utils/hooks';
2023
import {useChangeInputWithConfirmation} from '../../../../../utils/hooks/withConfirmation/useChangeInputWithConfirmation';
2124
import {parseQueryErrorToString} from '../../../../../utils/query';
@@ -45,7 +48,7 @@ export function TopQueries({tenantName}: TopQueriesProps) {
4548
}, []);
4649

4750
const {currentData, isFetching, error} = topQueriesApi.useGetTopQueriesQuery(
48-
{database: tenantName},
51+
{database: tenantName, timeFrame: 'hour', limit: TENANT_OVERVIEW_TABLES_LIMIT},
4952
{pollingInterval: autoRefreshInterval},
5053
);
5154

0 commit comments

Comments
 (0)