ydb-embedded-ui 22.2.0-hotfix.1 → 22.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/Graph/GravityGraph.js +9 -2
- package/dist/components/Graph/GravityGraph.js.map +1 -1
- package/dist/components/Graph/utils.d.ts +2 -1
- package/dist/components/Graph/utils.js +7 -0
- package/dist/components/Graph/utils.js.map +1 -1
- package/dist/containers/Authentication/Authentication.js +29 -30
- package/dist/containers/Authentication/Authentication.js.map +1 -1
- package/dist/containers/Authentication/utils.d.ts +2 -2
- package/dist/containers/Authentication/utils.js +1 -1
- package/dist/containers/Authentication/utils.js.map +1 -1
- package/dist/containers/Tenant/Diagnostics/DiagnosticsPages.js +5 -1
- package/dist/containers/Tenant/Diagnostics/DiagnosticsPages.js.map +1 -1
- package/dist/containers/Tenant/Diagnostics/Overview/Overview.js +7 -1
- package/dist/containers/Tenant/Diagnostics/Overview/Overview.js.map +1 -1
- package/dist/containers/Tenant/Diagnostics/Overview/ResourcePoolInfo/ResourcePoolInfo.scss +24 -0
- package/dist/containers/Tenant/Diagnostics/Overview/ResourcePoolInfo/ResourcePoolUsage.d.ts +8 -0
- package/dist/containers/Tenant/Diagnostics/Overview/ResourcePoolInfo/ResourcePoolUsage.js +34 -0
- package/dist/containers/Tenant/Diagnostics/Overview/ResourcePoolInfo/ResourcePoolUsage.js.map +1 -0
- package/dist/containers/Tenant/Diagnostics/Overview/ResourcePoolInfo/i18n/en.json +4 -1
- package/dist/containers/Tenant/Diagnostics/Overview/ResourcePoolInfo/i18n/index.d.ts +1 -1
- package/dist/containers/Tenant/Diagnostics/Overview/ResourcePoolInfo/index.d.ts +1 -0
- package/dist/containers/Tenant/Diagnostics/Overview/ResourcePoolInfo/index.js +1 -0
- package/dist/containers/Tenant/Diagnostics/Overview/ResourcePoolInfo/index.js.map +1 -1
- package/dist/containers/Tenant/Diagnostics/Overview/SchemaObjectInfo/SchemaObjectInfo.js +1 -1
- package/dist/containers/Tenant/Diagnostics/Overview/SchemaObjectInfo/SchemaObjectInfo.js.map +1 -1
- package/dist/containers/Tenant/Diagnostics/Overview/StreamingQueryInfo/StreamingQueryInfo.js +2 -17
- package/dist/containers/Tenant/Diagnostics/Overview/StreamingQueryInfo/StreamingQueryInfo.js.map +1 -1
- package/dist/containers/Tenant/Diagnostics/Overview/TableInfo/i18n/en.json +4 -0
- package/dist/containers/Tenant/Diagnostics/Overview/TableInfo/i18n/index.d.ts +1 -1
- package/dist/containers/Tenant/Diagnostics/Overview/TableInfo/prepareTableInfo/prepareColumnTableInfo.js +4 -1
- package/dist/containers/Tenant/Diagnostics/Overview/TableInfo/prepareTableInfo/prepareColumnTableInfo.js.map +1 -1
- package/dist/containers/Tenant/Diagnostics/Overview/TableInfo/prepareTableInfo/prepareRowTableInfo.js +4 -1
- package/dist/containers/Tenant/Diagnostics/Overview/TableInfo/prepareTableInfo/prepareRowTableInfo.js.map +1 -1
- package/dist/containers/Tenant/Diagnostics/Overview/TableInfo/prepareTableInfo/prepareTTL.js +41 -3
- package/dist/containers/Tenant/Diagnostics/Overview/TableInfo/prepareTableInfo/prepareTTL.js.map +1 -1
- package/dist/containers/Tenant/Diagnostics/StreamingQueryGraph/StreamingQueryGraph.d.ts +7 -0
- package/dist/containers/Tenant/Diagnostics/StreamingQueryGraph/StreamingQueryGraph.js +38 -0
- package/dist/containers/Tenant/Diagnostics/StreamingQueryGraph/StreamingQueryGraph.js.map +1 -0
- package/dist/containers/Tenant/Diagnostics/StreamingQueryGraph/StreamingQueryGraph.scss +18 -0
- package/dist/containers/Tenant/Diagnostics/StreamingQueryGraph/i18n/en.json +5 -0
- package/dist/containers/Tenant/Diagnostics/StreamingQueryGraph/i18n/index.d.ts +2 -0
- package/dist/containers/Tenant/Diagnostics/StreamingQueryGraph/i18n/index.js +5 -0
- package/dist/containers/Tenant/Diagnostics/StreamingQueryGraph/i18n/index.js.map +1 -0
- package/dist/containers/Tenant/Diagnostics/StreamingQueryGraph/index.d.ts +1 -0
- package/dist/containers/Tenant/Diagnostics/StreamingQueryGraph/index.js +2 -0
- package/dist/containers/Tenant/Diagnostics/StreamingQueryGraph/index.js.map +1 -0
- package/dist/containers/Tenant/Diagnostics/i18n/en.json +1 -0
- package/dist/containers/Tenant/Diagnostics/i18n/index.d.ts +1 -1
- package/dist/containers/Tenant/Diagnostics/tabsContent.js +2 -0
- package/dist/containers/Tenant/Diagnostics/tabsContent.js.map +1 -1
- package/dist/containers/Tenant/Query/QueryEditor/YqlEditor/YqlEditor.js +8 -1
- package/dist/containers/Tenant/Query/QueryEditor/YqlEditor/YqlEditor.js.map +1 -1
- package/dist/store/reducers/executeTopQueries/executeTopQueries.d.ts +7 -0
- package/dist/store/reducers/executeTopQueries/executeTopQueries.js +38 -0
- package/dist/store/reducers/executeTopQueries/executeTopQueries.js.map +1 -1
- package/dist/store/reducers/query/parsers/prepareStreamingQueryPlan.d.ts +8 -0
- package/dist/store/reducers/query/parsers/prepareStreamingQueryPlan.js +53 -0
- package/dist/store/reducers/query/parsers/prepareStreamingQueryPlan.js.map +1 -0
- package/dist/store/reducers/streamingQuery/streamingQuery.d.ts +5 -1
- package/dist/store/reducers/streamingQuery/streamingQuery.js +35 -10
- package/dist/store/reducers/streamingQuery/streamingQuery.js.map +1 -1
- package/dist/store/reducers/tenant/constants.d.ts +1 -0
- package/dist/store/reducers/tenant/constants.js +1 -0
- package/dist/store/reducers/tenant/constants.js.map +1 -1
- package/dist/types/api/schema/columnEntity.d.ts +2 -1
- package/dist/types/api/schema/sysView.d.ts +59 -2
- package/dist/types/api/schema/sysView.js +53 -1
- package/dist/types/api/schema/sysView.js.map +1 -1
- package/dist/types/api/schema/table.d.ts +8 -0
- package/dist/types/api/schema/table.js.map +1 -1
- package/dist/utils/query.d.ts +1 -0
- package/dist/utils/query.js +40 -0
- package/dist/utils/query.js.map +1 -1
- package/dist/utils/schema.d.ts +6 -2
- package/dist/utils/schema.js +14 -4
- package/dist/utils/schema.js.map +1 -1
- package/package.json +1 -1
- package/src/components/Graph/GravityGraph.tsx +9 -2
- package/src/components/Graph/utils.ts +9 -1
- package/src/containers/Authentication/Authentication.tsx +29 -34
- package/src/containers/Authentication/utils.ts +3 -3
- package/src/containers/Tenant/Diagnostics/DiagnosticsPages.ts +6 -1
- package/src/containers/Tenant/Diagnostics/Overview/Overview.tsx +17 -1
- package/src/containers/Tenant/Diagnostics/Overview/ResourcePoolInfo/ResourcePoolInfo.scss +24 -0
- package/src/containers/Tenant/Diagnostics/Overview/ResourcePoolInfo/ResourcePoolUsage.tsx +53 -0
- package/src/containers/Tenant/Diagnostics/Overview/ResourcePoolInfo/i18n/en.json +4 -1
- package/src/containers/Tenant/Diagnostics/Overview/ResourcePoolInfo/index.ts +1 -0
- package/src/containers/Tenant/Diagnostics/Overview/SchemaObjectInfo/SchemaObjectInfo.tsx +7 -1
- package/src/containers/Tenant/Diagnostics/Overview/StreamingQueryInfo/StreamingQueryInfo.tsx +2 -20
- package/src/containers/Tenant/Diagnostics/Overview/TableInfo/i18n/en.json +4 -0
- package/src/containers/Tenant/Diagnostics/Overview/TableInfo/prepareTableInfo/prepareColumnTableInfo.tsx +11 -1
- package/src/containers/Tenant/Diagnostics/Overview/TableInfo/prepareTableInfo/prepareRowTableInfo.tsx +11 -1
- package/src/containers/Tenant/Diagnostics/Overview/TableInfo/prepareTableInfo/prepareTTL.ts +45 -3
- package/src/containers/Tenant/Diagnostics/StreamingQueryGraph/StreamingQueryGraph.scss +18 -0
- package/src/containers/Tenant/Diagnostics/StreamingQueryGraph/StreamingQueryGraph.tsx +79 -0
- package/src/containers/Tenant/Diagnostics/StreamingQueryGraph/i18n/en.json +5 -0
- package/src/containers/Tenant/Diagnostics/StreamingQueryGraph/i18n/index.ts +7 -0
- package/src/containers/Tenant/Diagnostics/StreamingQueryGraph/index.ts +1 -0
- package/src/containers/Tenant/Diagnostics/i18n/en.json +1 -0
- package/src/containers/Tenant/Diagnostics/tabsContent.tsx +4 -0
- package/src/containers/Tenant/Query/QueryEditor/YqlEditor/YqlEditor.tsx +8 -1
- package/src/store/reducers/executeTopQueries/executeTopQueries.ts +46 -0
- package/src/store/reducers/query/parsers/prepareStreamingQueryPlan.ts +74 -0
- package/src/store/reducers/streamingQuery/streamingQuery.ts +43 -16
- package/src/store/reducers/tenant/constants.ts +1 -0
- package/src/types/api/schema/columnEntity.ts +2 -1
- package/src/types/api/schema/sysView.ts +60 -37
- package/src/types/api/schema/table.ts +7 -0
- package/src/utils/query.ts +55 -0
- package/src/utils/schema.ts +22 -5
|
@@ -11,7 +11,7 @@ export function createSsoAuthorizeUrl(host: string, returnTo: string) {
|
|
|
11
11
|
return url.href;
|
|
12
12
|
}
|
|
13
13
|
|
|
14
|
-
interface
|
|
14
|
+
interface GetAuthReturnToParams {
|
|
15
15
|
currentUrl: URL;
|
|
16
16
|
fallbackPath: string;
|
|
17
17
|
isDirectAuthPage: boolean;
|
|
@@ -28,12 +28,12 @@ function isSafeLocalReturnTo(path: string) {
|
|
|
28
28
|
);
|
|
29
29
|
}
|
|
30
30
|
|
|
31
|
-
export function
|
|
31
|
+
export function getAuthReturnTo({
|
|
32
32
|
currentUrl,
|
|
33
33
|
fallbackPath,
|
|
34
34
|
isDirectAuthPage,
|
|
35
35
|
returnUrl,
|
|
36
|
-
}:
|
|
36
|
+
}: GetAuthReturnToParams) {
|
|
37
37
|
if (!isDirectAuthPage) {
|
|
38
38
|
const path = `${currentUrl.pathname}${currentUrl.search}${currentUrl.hash}`;
|
|
39
39
|
return isSafeLocalReturnTo(path) ? path : fallbackPath;
|
|
@@ -115,6 +115,11 @@ const graph = {
|
|
|
115
115
|
title: i18n('title_graph'),
|
|
116
116
|
};
|
|
117
117
|
|
|
118
|
+
const computationGraph = {
|
|
119
|
+
id: TENANT_DIAGNOSTICS_TABS_IDS.computationGraph,
|
|
120
|
+
title: i18n('title_computation-graph'),
|
|
121
|
+
};
|
|
122
|
+
|
|
118
123
|
const consumers = {
|
|
119
124
|
id: TENANT_DIAGNOSTICS_TABS_IDS.consumers,
|
|
120
125
|
title: i18n('title_consumers'),
|
|
@@ -241,7 +246,7 @@ const EXTERNAL_TABLE_PAGES = [overview, schema, describe, access];
|
|
|
241
246
|
|
|
242
247
|
const VIEW_PAGES = [overview, schema, describe, access];
|
|
243
248
|
|
|
244
|
-
const STREAMING_QUERY_PAGES = [overview, describe, access];
|
|
249
|
+
const STREAMING_QUERY_PAGES = [overview, computationGraph, describe, access];
|
|
245
250
|
const SECRET_PAGES = [overview, describe, access];
|
|
246
251
|
|
|
247
252
|
// verbose mapping to guarantee correct tabs for new path types
|
|
@@ -6,6 +6,7 @@ import {Loader} from '../../../../components/Loader';
|
|
|
6
6
|
import {useClusterWithProxy} from '../../../../store/reducers/cluster/cluster';
|
|
7
7
|
import {overviewApi} from '../../../../store/reducers/overview/overview';
|
|
8
8
|
import {EPathType} from '../../../../types/api/schema';
|
|
9
|
+
import {cn} from '../../../../utils/cn';
|
|
9
10
|
import {useAutoRefreshInterval} from '../../../../utils/hooks';
|
|
10
11
|
import {ViewInfo} from '../../Info/View/View';
|
|
11
12
|
import {isDomain} from '../../ObjectSummary/transformPath';
|
|
@@ -16,6 +17,7 @@ import {ChangefeedInfo} from './ChangefeedInfo';
|
|
|
16
17
|
import {DatabaseInfo} from './DatabaseInfo/DatabaseInfo';
|
|
17
18
|
import {DefaultEntityInfo} from './DefaultEntityInfo';
|
|
18
19
|
import {ResourcePoolInfo} from './ResourcePoolInfo';
|
|
20
|
+
import {ResourcePoolUsage} from './ResourcePoolInfo/ResourcePoolUsage';
|
|
19
21
|
import {SchemaObjectInfoContainer} from './SchemaObjectInfo/SchemaObjectInfoContainer';
|
|
20
22
|
import {StreamingQueryInfo} from './StreamingQueryInfo';
|
|
21
23
|
import {TableInfo} from './TableInfo';
|
|
@@ -29,6 +31,8 @@ interface OverviewProps {
|
|
|
29
31
|
databaseFullPath: string;
|
|
30
32
|
}
|
|
31
33
|
|
|
34
|
+
const b = cn('ydb-diagnostics-resource-pool-info');
|
|
35
|
+
|
|
32
36
|
function Overview({type, path, database, databaseFullPath}: OverviewProps) {
|
|
33
37
|
const [autoRefreshInterval] = useAutoRefreshInterval();
|
|
34
38
|
const useMetaProxy = useClusterWithProxy();
|
|
@@ -56,7 +60,19 @@ function Overview({type, path, database, databaseFullPath}: OverviewProps) {
|
|
|
56
60
|
const pathTypeToComponent: Record<EPathType, (() => React.ReactNode) | undefined> = {
|
|
57
61
|
[EPathType.EPathTypeInvalid]: undefined,
|
|
58
62
|
[EPathType.EPathTypeDir]: undefined,
|
|
59
|
-
[EPathType.EPathTypeResourcePool]: () =>
|
|
63
|
+
[EPathType.EPathTypeResourcePool]: () => (
|
|
64
|
+
<div className={b('row')}>
|
|
65
|
+
<div className={b('col')}>
|
|
66
|
+
<ResourcePoolInfo data={data} />
|
|
67
|
+
</div>
|
|
68
|
+
<div className={b('col')}>
|
|
69
|
+
<ResourcePoolUsage
|
|
70
|
+
database={database}
|
|
71
|
+
poolName={data?.PathDescription?.ResourcePoolDescription?.Name || ''}
|
|
72
|
+
/>
|
|
73
|
+
</div>
|
|
74
|
+
</div>
|
|
75
|
+
),
|
|
60
76
|
[EPathType.EPathTypeSecret]: undefined,
|
|
61
77
|
[EPathType.EPathTypeTable]: renderTableInfo,
|
|
62
78
|
[EPathType.EPathTypeSysView]: undefined,
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
.ydb-diagnostics-resource-pool-info {
|
|
2
|
+
$column-width: 310px;
|
|
3
|
+
|
|
4
|
+
&__row {
|
|
5
|
+
display: flex;
|
|
6
|
+
flex-wrap: wrap;
|
|
7
|
+
justify-content: flex-start;
|
|
8
|
+
align-items: flex-start;
|
|
9
|
+
gap: var(--g-spacing-9);
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
&__col {
|
|
13
|
+
display: flex;
|
|
14
|
+
flex-direction: column;
|
|
15
|
+
justify-content: flex-start;
|
|
16
|
+
align-items: stretch;
|
|
17
|
+
|
|
18
|
+
width: $column-width;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
&__loader {
|
|
22
|
+
margin-top: 50px;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import {Loader} from '../../../../../components/Loader';
|
|
2
|
+
import {YDBDefinitionList} from '../../../../../components/YDBDefinitionList/YDBDefinitionList';
|
|
3
|
+
import {topQueriesApi} from '../../../../../store/reducers/executeTopQueries/executeTopQueries';
|
|
4
|
+
import {cn} from '../../../../../utils/cn';
|
|
5
|
+
import {EMPTY_DATA_PLACEHOLDER} from '../../../../../utils/constants';
|
|
6
|
+
import {useAutoRefreshInterval} from '../../../../../utils/hooks';
|
|
7
|
+
|
|
8
|
+
import i18n from './i18n';
|
|
9
|
+
|
|
10
|
+
import './ResourcePoolInfo.scss';
|
|
11
|
+
|
|
12
|
+
const b = cn('ydb-diagnostics-resource-pool-info');
|
|
13
|
+
|
|
14
|
+
interface ResourcePoolUsageProps {
|
|
15
|
+
database: string;
|
|
16
|
+
poolName: string;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/** Displays running/queued query counts for a resource pool */
|
|
20
|
+
export function ResourcePoolUsage({database, poolName}: ResourcePoolUsageProps) {
|
|
21
|
+
const [autoRefreshInterval] = useAutoRefreshInterval();
|
|
22
|
+
const {currentData, isFetching, error} = topQueriesApi.useGetRunningQueriesByPoolQuery(
|
|
23
|
+
{database, poolName},
|
|
24
|
+
{skip: !poolName, pollingInterval: autoRefreshInterval, refetchOnMountOrArgChange: true},
|
|
25
|
+
);
|
|
26
|
+
|
|
27
|
+
const loading = isFetching && currentData === undefined;
|
|
28
|
+
|
|
29
|
+
if (loading) {
|
|
30
|
+
return <Loader size="s" className={b('loader')} />;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
if (error || !poolName) {
|
|
34
|
+
return null;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
return (
|
|
38
|
+
<YDBDefinitionList
|
|
39
|
+
items={[
|
|
40
|
+
{
|
|
41
|
+
name: i18n('field_running-queries'),
|
|
42
|
+
content: currentData?.runningQueriesCount ?? EMPTY_DATA_PLACEHOLDER,
|
|
43
|
+
},
|
|
44
|
+
{
|
|
45
|
+
name: i18n('field_queued-queries'),
|
|
46
|
+
content: currentData?.queuedQueriesCount ?? EMPTY_DATA_PLACEHOLDER,
|
|
47
|
+
},
|
|
48
|
+
]}
|
|
49
|
+
title={i18n('title_usage')}
|
|
50
|
+
responsive
|
|
51
|
+
/>
|
|
52
|
+
);
|
|
53
|
+
}
|
|
@@ -1,9 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"title_pool-settings": "Pool Settings",
|
|
3
|
+
"title_usage": "Usage",
|
|
3
4
|
"group_queue": "Queue & Concurrency",
|
|
4
5
|
"group_cpu": "CPU",
|
|
5
6
|
"field_concurrent-query-limit": "Concurrent query limit",
|
|
6
7
|
"field_queue-size": "Queue size",
|
|
7
8
|
"field_database-load-cpu-threshold": "Database load CPU threshold",
|
|
8
|
-
"field_total-cpu-limit-percent-per-node": "Total CPU limit % per node"
|
|
9
|
+
"field_total-cpu-limit-percent-per-node": "Total CPU limit % per node",
|
|
10
|
+
"field_running-queries": "Running queries",
|
|
11
|
+
"field_queued-queries": "Queued queries"
|
|
9
12
|
}
|
|
@@ -42,6 +42,12 @@ export function SchemaObjectInfo({
|
|
|
42
42
|
);
|
|
43
43
|
|
|
44
44
|
return (
|
|
45
|
-
<YDBDefinitionList
|
|
45
|
+
<YDBDefinitionList
|
|
46
|
+
items={items}
|
|
47
|
+
responsive
|
|
48
|
+
className={b('list')}
|
|
49
|
+
wrapperClassName={b()}
|
|
50
|
+
dataQa="schema-object-info"
|
|
51
|
+
/>
|
|
46
52
|
);
|
|
47
53
|
}
|
package/src/containers/Tenant/Diagnostics/Overview/StreamingQueryInfo/StreamingQueryInfo.tsx
CHANGED
|
@@ -7,7 +7,6 @@ import type {YDBDefinitionListItem} from '../../../../../components/YDBDefinitio
|
|
|
7
7
|
import {YDBDefinitionList} from '../../../../../components/YDBDefinitionList/YDBDefinitionList';
|
|
8
8
|
import {YQLCodePreview} from '../../../../../components/YQLCodePreview/YQLCodePreview';
|
|
9
9
|
import {streamingQueriesApi} from '../../../../../store/reducers/streamingQuery/streamingQuery';
|
|
10
|
-
import type {ErrorResponse} from '../../../../../types/api/query';
|
|
11
10
|
import type {IQueryResult} from '../../../../../types/store/query';
|
|
12
11
|
import {cn} from '../../../../../utils/cn';
|
|
13
12
|
import {
|
|
@@ -15,7 +14,7 @@ import {
|
|
|
15
14
|
stripIndentByFirstLine,
|
|
16
15
|
trimOuterEmptyLines,
|
|
17
16
|
} from '../../../../../utils/dataFormatters/dataFormatters';
|
|
18
|
-
import {
|
|
17
|
+
import {parseIssuesData} from '../../../../../utils/query';
|
|
19
18
|
import {ResultIssuesModal} from '../../../Query/Issues/Issues';
|
|
20
19
|
|
|
21
20
|
import i18n from './i18n';
|
|
@@ -89,7 +88,7 @@ function prepareStreamingQueryItems(sysData?: IQueryResult) {
|
|
|
89
88
|
const errorRaw = sysData.resultSets?.[0]?.result?.[0]?.Error;
|
|
90
89
|
|
|
91
90
|
// We use custom error check, because error type can be non-standard
|
|
92
|
-
const errorData =
|
|
91
|
+
const errorData = parseIssuesData(errorRaw);
|
|
93
92
|
|
|
94
93
|
info.push({
|
|
95
94
|
name: i18n('field_query-state'),
|
|
@@ -105,20 +104,3 @@ function prepareStreamingQueryItems(sysData?: IQueryResult) {
|
|
|
105
104
|
|
|
106
105
|
return {items: info, queryText: normalizedQueryText};
|
|
107
106
|
}
|
|
108
|
-
|
|
109
|
-
function parseErrorData(raw: unknown): ErrorResponse | string | undefined {
|
|
110
|
-
if (typeof raw === 'string') {
|
|
111
|
-
try {
|
|
112
|
-
const parsed = JSON.parse(raw);
|
|
113
|
-
return isErrorResponse(parsed) ? parsed : undefined;
|
|
114
|
-
} catch {
|
|
115
|
-
return raw;
|
|
116
|
-
}
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
if (isErrorResponse(raw)) {
|
|
120
|
-
return raw;
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
return undefined;
|
|
124
|
-
}
|
|
@@ -26,6 +26,10 @@
|
|
|
26
26
|
"field_compression-groups": "Compression & families",
|
|
27
27
|
|
|
28
28
|
"value_ttl-config": "column: '{{columnName}}', expire after: {{expireTime}}",
|
|
29
|
+
"value_ttl-tiered-config": "column: '{{columnName}}'\n{{tiers}}",
|
|
30
|
+
"value_ttl-evict": "evict to: '{{storageName}}', after: {{expireTime}}",
|
|
31
|
+
"value_ttl-delete": "delete after: {{expireTime}}",
|
|
32
|
+
"value_ttl-unknown-action": "unknown action, after: {{expireTime}}",
|
|
29
33
|
"value_partitioning-by-size-enabled": "Enabled, split size: {{size}}",
|
|
30
34
|
"value_enabled": "Enabled",
|
|
31
35
|
"value_disabled": "Disabled",
|
|
@@ -42,7 +42,17 @@ export function prepareColumnTableGeneralInfo(columnTable: TColumnTableDescripti
|
|
|
42
42
|
if (columnTable.TtlSettings) {
|
|
43
43
|
const ttlInfo = prepareTTL(columnTable?.TtlSettings);
|
|
44
44
|
if (ttlInfo) {
|
|
45
|
-
left.push(
|
|
45
|
+
left.push({
|
|
46
|
+
...ttlInfo,
|
|
47
|
+
content: (
|
|
48
|
+
<span
|
|
49
|
+
style={{whiteSpace: 'break-spaces', wordBreak: 'break-word'}}
|
|
50
|
+
data-qa="table-ttl"
|
|
51
|
+
>
|
|
52
|
+
{ttlInfo.content}
|
|
53
|
+
</span>
|
|
54
|
+
),
|
|
55
|
+
});
|
|
46
56
|
}
|
|
47
57
|
}
|
|
48
58
|
|
|
@@ -66,7 +66,17 @@ export function prepareRowTableGeneralInfo(
|
|
|
66
66
|
if (TTLSettings) {
|
|
67
67
|
const ttlInfo = prepareTTL(TTLSettings);
|
|
68
68
|
if (ttlInfo) {
|
|
69
|
-
left.push(
|
|
69
|
+
left.push({
|
|
70
|
+
...ttlInfo,
|
|
71
|
+
content: (
|
|
72
|
+
<span
|
|
73
|
+
style={{whiteSpace: 'break-spaces', wordBreak: 'break-word'}}
|
|
74
|
+
data-qa="table-ttl"
|
|
75
|
+
>
|
|
76
|
+
{ttlInfo.content}
|
|
77
|
+
</span>
|
|
78
|
+
),
|
|
79
|
+
});
|
|
70
80
|
}
|
|
71
81
|
}
|
|
72
82
|
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type {TColumnDataLifeCycle, TTTLSettings} from '../../../../../../types/api/schema';
|
|
2
|
+
import {EMPTY_DATA_PLACEHOLDER} from '../../../../../../utils/constants';
|
|
2
3
|
import {formatDurationToShortTimeFormat} from '../../../../../../utils/timeParsers';
|
|
3
4
|
import i18n from '../i18n';
|
|
4
5
|
|
|
@@ -8,11 +9,52 @@ import i18n from '../i18n';
|
|
|
8
9
|
* @returns Definition list item with TTL info, or undefined if TTL is not configured
|
|
9
10
|
*/
|
|
10
11
|
export function prepareTTL(ttl: TTTLSettings | TColumnDataLifeCycle) {
|
|
12
|
+
const enabled = ttl.Enabled;
|
|
13
|
+
if (!enabled?.ColumnName) {
|
|
14
|
+
return undefined;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
if (enabled.Tiers?.length) {
|
|
18
|
+
const tiers = enabled.Tiers.flatMap((tier) => {
|
|
19
|
+
const seconds = tier.ApplyAfterSeconds;
|
|
20
|
+
if (seconds === undefined || !Number.isFinite(seconds) || seconds < 0) {
|
|
21
|
+
return [];
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
const expireTime = formatDurationToShortTimeFormat(seconds * 1000, 1);
|
|
25
|
+
if (tier.EvictToExternalStorage) {
|
|
26
|
+
return [
|
|
27
|
+
i18n('value_ttl-evict', {
|
|
28
|
+
storageName: tier.EvictToExternalStorage.Storage || EMPTY_DATA_PLACEHOLDER,
|
|
29
|
+
expireTime,
|
|
30
|
+
}),
|
|
31
|
+
];
|
|
32
|
+
}
|
|
33
|
+
if (tier.Delete) {
|
|
34
|
+
return [i18n('value_ttl-delete', {expireTime})];
|
|
35
|
+
}
|
|
36
|
+
return [i18n('value_ttl-unknown-action', {expireTime})];
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
// Nonempty tiers supersede the legacy expiry, even if all delays are invalid.
|
|
40
|
+
if (!tiers.length) {
|
|
41
|
+
return undefined;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
return {
|
|
45
|
+
name: i18n('field_ttl-for-rows'),
|
|
46
|
+
content: i18n('value_ttl-tiered-config', {
|
|
47
|
+
columnName: enabled.ColumnName,
|
|
48
|
+
tiers: tiers.join('\n'),
|
|
49
|
+
}),
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
|
|
11
53
|
// ExpireAfterSeconds could be 0
|
|
12
|
-
if (
|
|
54
|
+
if (enabled.ExpireAfterSeconds !== undefined) {
|
|
13
55
|
const value = i18n('value_ttl-config', {
|
|
14
|
-
columnName:
|
|
15
|
-
expireTime: formatDurationToShortTimeFormat(
|
|
56
|
+
columnName: enabled.ColumnName,
|
|
57
|
+
expireTime: formatDurationToShortTimeFormat(enabled.ExpireAfterSeconds * 1000, 1),
|
|
16
58
|
});
|
|
17
59
|
|
|
18
60
|
return {name: i18n('field_ttl-for-rows'), content: value};
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
|
|
3
|
+
import {Text, useThemeValue} from '@gravity-ui/uikit';
|
|
4
|
+
|
|
5
|
+
import {ResponseError} from '../../../../components/Errors/ResponseError';
|
|
6
|
+
import {Loader} from '../../../../components/Loader';
|
|
7
|
+
import {prepareStreamingQueryPlan} from '../../../../store/reducers/query/parsers/prepareStreamingQueryPlan';
|
|
8
|
+
import {streamingQueriesApi} from '../../../../store/reducers/streamingQuery/streamingQuery';
|
|
9
|
+
import {cn} from '../../../../utils/cn';
|
|
10
|
+
import {getStringifiedData} from '../../../../utils/dataFormatters/dataFormatters';
|
|
11
|
+
import {useAutoRefreshInterval} from '../../../../utils/hooks';
|
|
12
|
+
import {parseIssuesData} from '../../../../utils/query';
|
|
13
|
+
import {ResultIssues} from '../../Query/Issues/Issues';
|
|
14
|
+
import {Graph} from '../../Query/QueryResult/components/Graph/Graph';
|
|
15
|
+
|
|
16
|
+
import i18n from './i18n';
|
|
17
|
+
|
|
18
|
+
import './StreamingQueryGraph.scss';
|
|
19
|
+
|
|
20
|
+
interface StreamingQueryGraphProps {
|
|
21
|
+
database: string;
|
|
22
|
+
path: string;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
const RUNNING_STATUS = 'RUNNING';
|
|
26
|
+
|
|
27
|
+
const b = cn('ydb-streaming-query-graph');
|
|
28
|
+
|
|
29
|
+
const PLAN_STATE_MESSAGES = {
|
|
30
|
+
empty: 'description_no-plan',
|
|
31
|
+
unparsed: 'description_unparsed-plan',
|
|
32
|
+
unsupported: 'description_unsupported-plan',
|
|
33
|
+
} as const;
|
|
34
|
+
|
|
35
|
+
export function StreamingQueryGraph({database, path}: StreamingQueryGraphProps) {
|
|
36
|
+
const theme = useThemeValue();
|
|
37
|
+
const [autoRefreshInterval] = useAutoRefreshInterval();
|
|
38
|
+
|
|
39
|
+
const {
|
|
40
|
+
currentData: planData,
|
|
41
|
+
isFetching,
|
|
42
|
+
error,
|
|
43
|
+
} = streamingQueriesApi.useGetStreamingQueryPlanQuery(
|
|
44
|
+
{database, path},
|
|
45
|
+
{skip: !database || !path, pollingInterval: autoRefreshInterval},
|
|
46
|
+
);
|
|
47
|
+
|
|
48
|
+
const row = planData?.resultSets?.[0]?.result?.[0];
|
|
49
|
+
|
|
50
|
+
const {state, prepared} = React.useMemo(
|
|
51
|
+
() => prepareStreamingQueryPlan(getStringifiedData(row?.Plan)),
|
|
52
|
+
[row?.Plan],
|
|
53
|
+
);
|
|
54
|
+
|
|
55
|
+
if (isFetching && planData === undefined) {
|
|
56
|
+
return <Loader size="s" className={b('loader')} />;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
const status = getStringifiedData(row?.Status);
|
|
60
|
+
const issues = parseIssuesData(row?.Issues);
|
|
61
|
+
const showStatus = Boolean(issues) || Boolean(status && status !== RUNNING_STATUS);
|
|
62
|
+
|
|
63
|
+
return (
|
|
64
|
+
<div className={b()}>
|
|
65
|
+
{error ? <ResponseError error={error} /> : null}
|
|
66
|
+
{showStatus ? (
|
|
67
|
+
<div className={b('status')}>
|
|
68
|
+
{status ? <Text variant="subheader-2">{status}</Text> : null}
|
|
69
|
+
{issues ? <ResultIssues data={issues} /> : null}
|
|
70
|
+
</div>
|
|
71
|
+
) : null}
|
|
72
|
+
{state === 'ready' ? (
|
|
73
|
+
<Graph explain={prepared} theme={theme} />
|
|
74
|
+
) : (
|
|
75
|
+
<div>{i18n(PLAN_STATE_MESSAGES[state])}</div>
|
|
76
|
+
)}
|
|
77
|
+
</div>
|
|
78
|
+
);
|
|
79
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {StreamingQueryGraph} from './StreamingQueryGraph';
|
|
@@ -19,6 +19,7 @@ import {HotKeys} from './HotKeys/HotKeys';
|
|
|
19
19
|
import {NetworkWrapper} from './Network/NetworkWrapper';
|
|
20
20
|
import {Partitions} from './Partitions/Partitions';
|
|
21
21
|
import {StorageUsage} from './StorageUsage/StorageUsage';
|
|
22
|
+
import {StreamingQueryGraph} from './StreamingQueryGraph';
|
|
22
23
|
import {TenantOverview} from './TenantOverview/TenantOverview';
|
|
23
24
|
import {TopQueries} from './TopQueries/TopQueries';
|
|
24
25
|
import {TopShards} from './TopShards/TopShards';
|
|
@@ -182,6 +183,9 @@ const diagnosticsTabRenderers: Record<TenantDiagnosticsTab, DiagnosticsTabRender
|
|
|
182
183
|
database,
|
|
183
184
|
scrollContainerRef,
|
|
184
185
|
}),
|
|
186
|
+
[TENANT_DIAGNOSTICS_TABS_IDS.computationGraph]: ({database, path}) => (
|
|
187
|
+
<StreamingQueryGraph database={database} path={path} />
|
|
188
|
+
),
|
|
185
189
|
[TENANT_DIAGNOSTICS_TABS_IDS.monitoring]: ({database, databaseFullPath}) => {
|
|
186
190
|
const content = uiFactory.renderMonitoring?.({database, databaseFullPath});
|
|
187
191
|
|
|
@@ -119,6 +119,14 @@ export function YqlEditor({
|
|
|
119
119
|
const currentStatementCleanupRef = React.useRef<VoidFunction>();
|
|
120
120
|
const [isEditorMounted, setIsEditorMounted] = React.useState(false);
|
|
121
121
|
|
|
122
|
+
React.useEffect(() => {
|
|
123
|
+
// onEditorReady removes the parent's visibility:hidden loading state.
|
|
124
|
+
// Focus after that render commits; focusing during editorDidMount is too early.
|
|
125
|
+
if (isEditorMounted) {
|
|
126
|
+
editorRef.current?.focus();
|
|
127
|
+
}
|
|
128
|
+
}, [isEditorMounted]);
|
|
129
|
+
|
|
122
130
|
const isMultiTabQueryEditorEnabled = useMultiTabQueryEditorEnabled();
|
|
123
131
|
const isAutocompleteEnabled = useEventHandler(() => Boolean(enableAutocomplete));
|
|
124
132
|
|
|
@@ -330,7 +338,6 @@ export function YqlEditor({
|
|
|
330
338
|
if (!isMultiTabQueryEditorEnabled) {
|
|
331
339
|
initUserPrompt(editor, getLastQueryText);
|
|
332
340
|
}
|
|
333
|
-
editor.focus();
|
|
334
341
|
editor.addAction({
|
|
335
342
|
id: 'sendQuery',
|
|
336
343
|
label: i18n('action_send-query'),
|
|
@@ -106,6 +106,17 @@ WHERE Query NOT LIKE '%${QUERY_TECHNICAL_MARK}%'
|
|
|
106
106
|
AND QueryStartAt is not null`;
|
|
107
107
|
}
|
|
108
108
|
|
|
109
|
+
function getRunningQueriesByPoolText(poolName: string) {
|
|
110
|
+
const escapedPoolName = poolName.replace(/'/g, "''");
|
|
111
|
+
return `${QUERY_TECHNICAL_MARK}
|
|
112
|
+
SELECT
|
|
113
|
+
COUNT_IF(State = 'EXECUTING' AND (WmState IS NULL OR WmState NOT IN ('PENDING', 'DELAYED'))) as RunningQueriesCount,
|
|
114
|
+
COUNT_IF(State = 'QUEUED' OR WmState = 'PENDING' OR WmState = 'DELAYED') as QueuedQueriesCount
|
|
115
|
+
FROM \`.sys/query_sessions\`
|
|
116
|
+
WHERE Query NOT LIKE '%${QUERY_TECHNICAL_MARK}%'
|
|
117
|
+
AND WmPoolId = '${escapedPoolName}'`;
|
|
118
|
+
}
|
|
119
|
+
|
|
109
120
|
interface QueriesRequestParams {
|
|
110
121
|
database: string;
|
|
111
122
|
filters?: TopQueriesFilters;
|
|
@@ -233,6 +244,41 @@ export const topQueriesApi = api.injectEndpoints({
|
|
|
233
244
|
},
|
|
234
245
|
providesTags: ['All'],
|
|
235
246
|
}),
|
|
247
|
+
getRunningQueriesByPool: build.query({
|
|
248
|
+
queryFn: async (
|
|
249
|
+
{database, poolName}: {database: string; poolName: string},
|
|
250
|
+
{signal},
|
|
251
|
+
) => {
|
|
252
|
+
try {
|
|
253
|
+
const response = await window.api.viewer.sendQuery(
|
|
254
|
+
{
|
|
255
|
+
query: getRunningQueriesByPoolText(poolName),
|
|
256
|
+
database,
|
|
257
|
+
action: 'execute-query',
|
|
258
|
+
internal_call: true,
|
|
259
|
+
},
|
|
260
|
+
{signal, withRetries: true},
|
|
261
|
+
);
|
|
262
|
+
|
|
263
|
+
if (isQueryErrorResponse(response)) {
|
|
264
|
+
throw response;
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
const data = parseQueryAPIResponse(response);
|
|
268
|
+
const row = data?.resultSets?.[0]?.result?.[0];
|
|
269
|
+
|
|
270
|
+
return {
|
|
271
|
+
data: {
|
|
272
|
+
runningQueriesCount: Number(row?.RunningQueriesCount) || 0,
|
|
273
|
+
queuedQueriesCount: Number(row?.QueuedQueriesCount) || 0,
|
|
274
|
+
},
|
|
275
|
+
};
|
|
276
|
+
} catch (error) {
|
|
277
|
+
return {error};
|
|
278
|
+
}
|
|
279
|
+
},
|
|
280
|
+
providesTags: ['All'],
|
|
281
|
+
}),
|
|
236
282
|
}),
|
|
237
283
|
overrideExisting: 'throw',
|
|
238
284
|
});
|