Skip to content

feat: design query tab #2077

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 18 commits into from
Apr 7, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/components/ConnectToDB/ConnectToDBDialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ function ConnectToDBDialog({open, onClose, database, endpoint}: ConnectToDBDialo
language={activeTab}
text={snippet}
transparentBackground={false}
withCopy
withClipboardButton={{alwaysVisible: true}}
/>
</div>
{docsLink ? (
Expand Down
2 changes: 1 addition & 1 deletion src/components/DateRange/DateRange.scss
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
.date-range {
&__range-input {
&_s {
width: 200px;
width: 130px;
}

&_m {
Expand Down
24 changes: 9 additions & 15 deletions src/components/DateRange/DateRange.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
import React from 'react';

import type {RelativeRangeDatePickerProps} from '@gravity-ui/date-components';
import type {
RelativeRangeDatePickerProps,
RelativeRangeDatePickerValue,
} from '@gravity-ui/date-components';
import {RelativeRangeDatePicker} from '@gravity-ui/date-components';

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

const DEFAULT_VALUE = {
start: {
value: 'now-1h',
type: 'relative',
},
end: {
value: 'now',
type: 'relative',
},
} as const;

interface DateRangeProps extends DateRangeValues {
className?: string;
defaultValue?: RelativeRangeDatePickerValue;
onChange?: (value: DateRangeValues) => void;
}

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

// eslint-disable-next-line new-cap
const timeZoneString = Intl.DateTimeFormat().resolvedOptions().timeZone;
const currentValue = value || defaultValue;
return (
<div className={b(null, className)}>
<RelativeRangeDatePicker
withPresets
className={b('range-input', {[getdatePickerSize(value)]: true})}
className={b('range-input', {[getdatePickerSize(currentValue)]: true})}
timeZone={timeZoneString}
value={value || DEFAULT_VALUE}
value={currentValue}
allowNullableValues
size="m"
format={i18n('date-time-format')}
Expand Down
9 changes: 9 additions & 0 deletions src/components/ResizeableDataTable/ResizeableDataTable.scss
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,13 @@

// padding for easier resize of the last column
padding-right: 20px;

&__row-skeleton {
width: 100%;
height: 50%;
}

&__row-skeleton::after {
animation: none !important;
}
}
15 changes: 13 additions & 2 deletions src/components/ResizeableDataTable/ResizeableDataTable.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import type {DataTableProps, Settings} from '@gravity-ui/react-data-table';
import type {Column, DataTableProps, Settings} from '@gravity-ui/react-data-table';
import DataTable, {updateColumnsWidth} from '@gravity-ui/react-data-table';
import {Skeleton} from '@gravity-ui/uikit';

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

export function ResizeableDataTable<T>({
columnsWidthLSKey,
columns,
settings,
wrapperClassName,
loading,
...props
}: ResizeableDataTableProps<T>) {
const [tableColumnsWidth, setTableColumnsWidth] = useTableResize(columnsWidthLSKey);

const updatedColumns = updateColumnsWidth(columns, tableColumnsWidth);
// If loading is true, override the render method of each column to display a Skeleton
const processedColumns = loading
? columns.map((column: Column<T>) => ({
...column,
render: () => <Skeleton className={b('row-skeleton')} />,
}))
: columns;

const updatedColumns = updateColumnsWidth(processedColumns, tableColumnsWidth);

const newSettings: Settings = {
...settings,
Expand Down
13 changes: 13 additions & 0 deletions src/components/SyntaxHighlighter/YDBSyntaxHighlighter.scss
Original file line number Diff line number Diff line change
Expand Up @@ -16,5 +16,18 @@
position: absolute;
top: 13px;
right: 14px;

pointer-events: all;

opacity: 0;

&_visible {
opacity: 1;
}
}

.data-table__row:hover &__copy,
.ydb-paginated-table__row:hover &__copy {
opacity: 1;
}
}
33 changes: 26 additions & 7 deletions src/components/SyntaxHighlighter/YDBSyntaxHighlighter.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,20 +23,28 @@ async function registerLanguage(lang: Language) {
}
}

interface ClipboardButtonOptions {
alwaysVisible?: boolean;
copyText?: string;
withLabel?: boolean;
}

export type WithClipboardButtonProp = ClipboardButtonOptions | boolean;

type YDBSyntaxHighlighterProps = {
text: string;
language: Language;
className?: string;
transparentBackground?: boolean;
withCopy?: boolean;
withClipboardButton?: WithClipboardButtonProp;
};

export function YDBSyntaxHighlighter({
text,
language,
className,
transparentBackground = true,
withCopy,
withClipboardButton,
}: YDBSyntaxHighlighterProps) {
const [highlighterKey, setHighlighterKey] = React.useState('');

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

const renderCopyButton = () => {
if (withCopy) {
if (withClipboardButton) {
return (
<div className={b('sticky-container')}>
<div className={b('sticky-container')} onClick={(e) => e.stopPropagation()}>
<ClipboardButton
view="flat-secondary"
size="s"
className={b('copy')}
text={text}
className={b('copy', {
visible:
typeof withClipboardButton === 'object' &&
withClipboardButton.alwaysVisible,
})}
text={
(typeof withClipboardButton === 'object' &&
withClipboardButton.copyText) ||
text
}
>
{i18n('copy')}
{typeof withClipboardButton === 'object' &&
withClipboardButton.withLabel === false
? null
: i18n('copy')}
</ClipboardButton>
</div>
);
Expand Down
40 changes: 37 additions & 3 deletions src/components/TruncatedQuery/TruncatedQuery.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,16 @@ const b = cn('kv-truncated-query');
interface TruncatedQueryProps {
value?: string;
maxQueryHeight?: number;
hasClipboardButton?: boolean;
clipboardButtonAlwaysVisible?: boolean;
}

export const TruncatedQuery = ({value = '', maxQueryHeight = 6}: TruncatedQueryProps) => {
export const TruncatedQuery = ({
value = '',
maxQueryHeight = 6,
hasClipboardButton,
clipboardButtonAlwaysVisible,
}: TruncatedQueryProps) => {
const lines = value.split('\n');
const truncated = lines.length > maxQueryHeight;

Expand All @@ -22,10 +29,37 @@ export const TruncatedQuery = ({value = '', maxQueryHeight = 6}: TruncatedQueryP
'\n...\nThe request was truncated. Click on the line to show the full query on the query tab';
return (
<React.Fragment>
<YDBSyntaxHighlighter language="yql" className={b()} text={content} />
<YDBSyntaxHighlighter
language="yql"
className={b()}
text={content}
withClipboardButton={
hasClipboardButton
? {
alwaysVisible: clipboardButtonAlwaysVisible,
copyText: value,
withLabel: false,
}
: false
}
/>
<span className={b('message', {color: 'secondary'})}>{message}</span>
</React.Fragment>
);
}
return <YDBSyntaxHighlighter language="yql" text={value} />;
return (
<YDBSyntaxHighlighter
language="yql"
text={value}
withClipboardButton={
hasClipboardButton
? {
alwaysVisible: clipboardButtonAlwaysVisible,
copyText: value,
withLabel: false,
}
: false
}
/>
);
};
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,10 @@ import {
TENANT_PAGES_IDS,
TENANT_QUERY_TABS_ID,
} from '../../../../../store/reducers/tenant/constants';
import {TENANT_OVERVIEW_TABLES_SETTINGS} from '../../../../../utils/constants';
import {
TENANT_OVERVIEW_TABLES_LIMIT,
TENANT_OVERVIEW_TABLES_SETTINGS,
} from '../../../../../utils/constants';
import {useAutoRefreshInterval, useTypedDispatch} from '../../../../../utils/hooks';
import {useChangeInputWithConfirmation} from '../../../../../utils/hooks/withConfirmation/useChangeInputWithConfirmation';
import {parseQueryErrorToString} from '../../../../../utils/query';
Expand Down Expand Up @@ -45,7 +48,7 @@ export function TopQueries({tenantName}: TopQueriesProps) {
}, []);

const {currentData, isFetching, error} = topQueriesApi.useGetTopQueriesQuery(
{database: tenantName},
{database: tenantName, timeFrame: 'hour', limit: TENANT_OVERVIEW_TABLES_LIMIT},
{pollingInterval: autoRefreshInterval},
);

Expand Down
Loading
Loading