Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
6a92b5a
feat: show streaming query stats in Info tab
DaryaVorontsova Nov 10, 2025
ace6893
Merge branch 'main' into feat/streaming-query-info
DaryaVorontsova Nov 10, 2025
9ce4a5c
Add error display
DaryaVorontsova Nov 10, 2025
ccbc5b2
Fix i18n
DaryaVorontsova Nov 10, 2025
c6912ad
Merge branch 'main' into feat/streaming-query-info
DaryaVorontsova Nov 11, 2025
ab27dde
Fix modal
DaryaVorontsova Nov 11, 2025
4fb7854
Fix error displaying
DaryaVorontsova Nov 11, 2025
97f455c
Merge branch 'main' into feat/streaming-query-info
DaryaVorontsova Nov 11, 2025
fca7538
Fix styles
DaryaVorontsova Nov 12, 2025
93a7f11
Fix gap
DaryaVorontsova Nov 12, 2025
c5117d4
Merge branch 'main' into feat/streaming-query-info
DaryaVorontsova Nov 12, 2025
ad41dd7
Fix issues bug
DaryaVorontsova Nov 12, 2025
9aadde9
rollback package-lock.json to base branch state
DaryaVorontsova Nov 12, 2025
82c0102
Merge branch 'main' into feat/streaming-query-info
DaryaVorontsova Nov 12, 2025
66e7175
Fix bugs
DaryaVorontsova Nov 13, 2025
88915a2
Fix bugs
DaryaVorontsova Nov 13, 2025
f654979
Merge branch 'main' into feat/streaming-query-info
DaryaVorontsova Nov 13, 2025
f0d64cf
Fix error displaying
DaryaVorontsova Nov 11, 2025
aa621f2
Fix issues bug
DaryaVorontsova Nov 12, 2025
46b85da
rollback package-lock.json to base branch state
DaryaVorontsova Nov 12, 2025
48967af
Fix bugs
DaryaVorontsova Nov 13, 2025
a06dcca
Fix query text displaying
DaryaVorontsova Nov 13, 2025
62a0382
Fix i18n
DaryaVorontsova Nov 13, 2025
37517ac
Fix i18n
DaryaVorontsova Nov 13, 2025
8536622
Fix bugs
DaryaVorontsova Nov 13, 2025
06121ac
Fix i18n
DaryaVorontsova Nov 13, 2025
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
Original file line number Diff line number Diff line change
Expand Up @@ -25,4 +25,9 @@
top: 23px;
right: 13px;
}

// Delete padding for all query text on Diagnostics -> Info tab
pre {
padding: 0;
}
}
5 changes: 4 additions & 1 deletion src/containers/Tenant/Diagnostics/Overview/Overview.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import {ViewInfo} from '../../Info/View/View';

import {AsyncReplicationInfo} from './AsyncReplicationInfo';
import {ChangefeedInfo} from './ChangefeedInfo';
import {StreamingQueryInfo} from './StreamingQueryInfo';
import {TableInfo} from './TableInfo';
import {TopicInfo} from './TopicInfo';
import {TransferInfo} from './TransferInfo';
Expand Down Expand Up @@ -77,7 +78,9 @@ function Overview({type, path, database, databaseFullPath}: OverviewProps) {
data={data}
/>
),
[EPathType.EPathTypeStreamingQuery]: undefined,
[EPathType.EPathTypeStreamingQuery]: () => (
<StreamingQueryInfo data={data} path={path} database={database} />
),
};

return (type && pathTypeToComponent[type]?.()) || <TableInfo data={data} type={type} />;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
import React from 'react';

import {Label} from '@gravity-ui/uikit';

import {YDBSyntaxHighlighter} from '../../../../../components/SyntaxHighlighter/YDBSyntaxHighlighter';
import {YDBDefinitionList} from '../../../../../components/YDBDefinitionList/YDBDefinitionList';
import type {YDBDefinitionListItem} from '../../../../../components/YDBDefinitionList/YDBDefinitionList';
import {streamingQueriesApi} from '../../../../../store/reducers/streamingQuery/streamingQuery';
import type {ErrorResponse} from '../../../../../types/api/query';
import type {TEvDescribeSchemeResult} from '../../../../../types/api/schema';
import type {IQueryResult} from '../../../../../types/store/query';
import {
getStringifiedData,
stripIndentByFirstLine,
trimOuterEmptyLines,
} from '../../../../../utils/dataFormatters/dataFormatters';
import {isErrorResponse} from '../../../../../utils/query';
import {ResultIssuesModal} from '../../../Query/Issues/Issues';
import {getEntityName} from '../../../utils';

import i18n from './i18n';

interface StreamingQueryProps {
data?: TEvDescribeSchemeResult;
database: string;
path: string;
}

/** Displays overview for StreamingQuery EPathType */
export function StreamingQueryInfo({data, database, path}: StreamingQueryProps) {
const entityName = getEntityName(data?.PathDescription);

if (!data) {
return (
<div className="error">
{i18n('alert_no-data')} {entityName}
</div>
);
}

const {data: sysData} = streamingQueriesApi.useGetStreamingQueryInfoQuery(
{database, path},
{skip: !database || !path},
);

const items = prepareStreamingQueryItems(sysData);

return <YDBDefinitionList title={entityName} items={items} />;
}

const STATE_THEME_MAP: Record<string, React.ComponentProps<typeof Label>['theme']> = {
CREATING: 'info',
CREATED: 'normal',
STARTING: 'info',
RUNNING: 'success',
STOPPING: 'info',
STOPPED: 'normal',
COMPLETED: 'success',
SUSPENDED: 'warning',
FAILED: 'danger',
};

function StateLabel({state}: {state?: string}) {
if (!state) {
return null;
}

const theme = STATE_THEME_MAP[state] ?? 'normal';

return <Label theme={theme}>{state}</Label>;
}

function prepareStreamingQueryItems(sysData?: IQueryResult): YDBDefinitionListItem[] {
if (!sysData) {
return [];
}

const info: YDBDefinitionListItem[] = [];
const state = getStringifiedData(sysData.resultSets?.[0]?.result?.[0]?.State);

const queryText = getStringifiedData(sysData.resultSets?.[0]?.result?.[0]?.Text);
let normalizedQueryText = trimOuterEmptyLines(queryText);
normalizedQueryText = stripIndentByFirstLine(normalizedQueryText);

const errorRaw = sysData.resultSets?.[0]?.result?.[0]?.Error;

// We use custom error check, because error type can be non-standard
const errorData = parseErrorData(errorRaw);

info.push({
name: i18n('field_query-state'),
content: <StateLabel state={state} />,
});

if (errorData) {
info.push({
name: i18n('field_query-error'),
content: <ResultIssuesModal data={errorData} />,
});
}

info.push({
name: i18n('field_query-text'),
copyText: normalizedQueryText,
content: normalizedQueryText ? (
<YDBSyntaxHighlighter language="yql" text={normalizedQueryText} />
) : null,
});

return info;
}

function parseErrorData(raw: unknown): ErrorResponse | string | undefined {
if (typeof raw === 'string') {
try {
const parsed = JSON.parse(raw);
return isErrorResponse(parsed) ? parsed : undefined;
} catch {
return raw;
}
}

if (isErrorResponse(raw)) {
return raw;
}

return undefined;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"alert_no-data": "No data for entity:",
"field_query-state": "State",
"field_query-error": "Error",
"field_query-text": "Text"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import {registerKeysets} from '../../../../../../utils/i18n';

import en from './en.json';

const COMPONENT = 'ydb-diagnostics-streaming-query-info';

export default registerKeysets(COMPONENT, {en});
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './StreamingQueryInfo';
4 changes: 0 additions & 4 deletions src/containers/Tenant/Query/Issues/Issues.scss
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
.kv-result-issues {
padding: 0 10px;

&__error-message {
position: sticky;
z-index: 2;
Expand All @@ -10,8 +8,6 @@
display: flex;
align-items: center;

padding: 10px 0;

background-color: var(--g-color-base-background);
}

Expand Down
Loading
Loading