diff --git a/src/store/reducers/node/node.ts b/src/store/reducers/node/node.ts
index 316a245b07..0ba5a55c28 100644
--- a/src/store/reducers/node/node.ts
+++ b/src/store/reducers/node/node.ts
@@ -26,25 +26,6 @@ export const nodeApi = api.injectEndpoints({
},
providesTags: ['All'],
}),
- getNodeThreads: build.query({
- queryFn: async ({nodeId}: {nodeId: string}, {signal}) => {
- try {
- const data = await window.api.viewer.getNodeInfo(nodeId, {signal});
-
- // Extract thread information from the response
- return {
- data: {
- Threads: data.Threads || [],
- ResponseTime: data.ResponseTime,
- ResponseDuration: data.ResponseDuration,
- },
- };
- } catch (error) {
- return {error};
- }
- },
- providesTags: ['All'],
- }),
}),
overrideExisting: 'throw',
});
diff --git a/src/types/api/nodes.ts b/src/types/api/nodes.ts
index 2afee29df1..b42b7a31d3 100644
--- a/src/types/api/nodes.ts
+++ b/src/types/api/nodes.ts
@@ -2,6 +2,7 @@ import type {BackendSortParam} from './common';
import type {EFlag} from './enums';
import type {TPDiskStateInfo} from './pdisk';
import type {TTabletStateInfo} from './tablet';
+import type {TThreadPoolInfo} from './threads';
import type {TVDiskStateInfo} from './vdisk';
/**
@@ -152,6 +153,8 @@ export interface TSystemStateInfo {
SharedCacheStats?: TNodeSharedCache;
TotalSessions?: number;
NodeName?: string;
+ /** Detailed thread information when fields_required=-1 is used */
+ Threads?: TThreadPoolInfo[];
}
interface TNodeStateInfo {
From c13b1d0fa763d1b3e9a70b3eaeeeab96d0b7c49e Mon Sep 17 00:00:00 2001
From: Elena Makarova
Date: Fri, 25 Jul 2025 16:04:44 +0300
Subject: [PATCH 8/9] fix: review fixes
---
THREADS_IMPLEMENTATION.md | 140 ------------------
.../TitleWithHelpmark/TitleWithHelpmark.tsx | 15 ++
.../Node/Threads/CpuUsageBar/CpuUsageBar.scss | 24 +--
.../Node/Threads/CpuUsageBar/CpuUsageBar.tsx | 38 ++---
.../ThreadStatesBar/ThreadStatesBar.scss | 45 +-----
.../ThreadStatesBar/ThreadStatesBar.tsx | 101 ++++++++-----
src/containers/Node/Threads/Threads.tsx | 112 ++------------
src/containers/Node/Threads/columns.tsx | 60 ++++++++
src/containers/Node/Threads/i18n/en.json | 3 +-
.../AccessRights/AccessRights.scss | 6 -
.../components/RightsTable/columns.tsx | 23 +--
11 files changed, 177 insertions(+), 390 deletions(-)
delete mode 100644 THREADS_IMPLEMENTATION.md
create mode 100644 src/components/TitleWithHelpmark/TitleWithHelpmark.tsx
create mode 100644 src/containers/Node/Threads/columns.tsx
diff --git a/THREADS_IMPLEMENTATION.md b/THREADS_IMPLEMENTATION.md
deleted file mode 100644
index e0018861f4..0000000000
--- a/THREADS_IMPLEMENTATION.md
+++ /dev/null
@@ -1,140 +0,0 @@
-# Threads Tab Implementation Documentation
-
-## Overview
-
-This document describes the implementation of the Threads tab for the Node page in YDB Embedded UI, which displays detailed thread pool information as requested in issue #2051.
-
-## Features Implemented
-
-- **Complete UI Components**: Thread pools table with all required columns
-- **CPU Usage Visualization**: Progress bars showing system + user CPU usage with color coding
-- **Thread State Visualization**: Horizontal bar chart showing distribution of thread states (R, S, etc.)
-- **Real API Integration**: Connected to RTK Query with auto-refresh and error handling
-- **TypeScript Types**: Complete type definitions for thread pool information
-- **Internationalization**: Full i18n support following project conventions
-
-## Component Structure
-
-```
-src/containers/Node/Threads/
-├── Threads.tsx # Main component
-├── Threads.scss # Styling
-├── CpuUsageBar/ # CPU usage visualization
-│ ├── CpuUsageBar.tsx
-│ └── CpuUsageBar.scss
-├── ThreadStatesBar/ # Thread states visualization
-│ ├── ThreadStatesBar.tsx
-│ └── ThreadStatesBar.scss
-└── i18n/ # Internationalization
- ├── en.json
- └── index.ts
-```
-
-## Data Structure
-
-The component expects thread pool information in the following format:
-
-```typescript
-interface TThreadPoolInfo {
- Name?: string; // Thread pool name (e.g., "AwsEventLoop", "klktmr.IC")
- Threads?: number; // Number of threads in the pool
- SystemUsage?: number; // System CPU usage (0-1 range)
- UserUsage?: number; // User CPU usage (0-1 range)
- MinorPageFaults?: number; // Number of minor page faults
- MajorPageFaults?: number; // Number of major page faults
- States?: Record; // Thread states with counts (e.g., {R: 2, S: 1})
-}
-```
-
-## Backend Integration Required
-
-Currently, the implementation uses mock data. To connect real data, the YDB backend needs to provide detailed thread information through one of these approaches:
-
-### Option 1: New Dedicated Endpoint (Recommended)
-
-```
-GET /viewer/json/threads?node_id={nodeId}
-```
-
-Response format:
-
-```json
-{
- "Threads": [
- {
- "Name": "AwsEventLoop",
- "Threads": 64,
- "SystemUsage": 0.0,
- "UserUsage": 0.0,
- "MinorPageFaults": 0,
- "MajorPageFaults": 0,
- "States": {
- "S": 64
- }
- }
- ],
- "ResponseTime": "1234567890",
- "ResponseDuration": 123
-}
-```
-
-### Option 2: Extend Existing Endpoint
-
-Extend `/viewer/json/sysinfo` to include detailed thread information in addition to the current `PoolStats`.
-
-## API Implementation
-
-The frontend API integration is already implemented:
-
-1. **Viewer API**: `getNodeThreads()` method in `src/services/api/viewer.ts`
-2. **Node Store**: RTK Query endpoint in `src/store/reducers/node/node.ts`
-3. **Component**: Connected with auto-refresh in `src/containers/Node/Threads/Threads.tsx`
-
-## Data Mapping
-
-The backend should provide:
-
-- **Thread Pool Name**: From the actual thread pool name
-- **Thread Count**: Number of threads in each pool
-- **CPU Usage**: System and user CPU usage percentages (0-1 range)
-- **Page Faults**: Minor and major page fault counts
-- **Thread States**: Distribution of thread states using Linux process state codes:
- - `R`: Running
- - `S`: Sleeping (interruptible)
- - `D`: Disk sleep (uninterruptible)
- - `Z`: Zombie
- - `T`: Stopped
- - etc.
-
-## Screenshots
-
-The implementation provides a complete table view matching the requirements in the issue:
-
-- Pool name column
-- Thread count column
-- CPU usage with visual progress bar
-- Page fault counts
-- Thread state distribution visualization
-
-## Testing
-
-To test the implementation:
-
-1. Navigate to `/node/{nodeId}/threads` in the YDB Embedded UI
-2. The tab will be available in the node page tabs
-3. Currently shows mock data until backend integration is complete
-
-## Next Steps
-
-1. **Backend Development**: Implement the threads endpoint in YDB backend
-2. **Real Data Integration**: Replace mock data with actual thread information
-3. **Testing**: Verify with real YDB instances
-4. **Performance**: Ensure efficient data collection for thread statistics
-
-## Related Files
-
-- Node page tabs: `src/containers/Node/NodePages.ts`
-- Node page component: `src/containers/Node/Node.tsx`
-- Thread types: `src/types/api/threads.ts`
-- API viewer: `src/services/api/viewer.ts`
-- Node store: `src/store/reducers/node/node.ts`
diff --git a/src/components/TitleWithHelpmark/TitleWithHelpmark.tsx b/src/components/TitleWithHelpmark/TitleWithHelpmark.tsx
new file mode 100644
index 0000000000..583abd1de6
--- /dev/null
+++ b/src/components/TitleWithHelpmark/TitleWithHelpmark.tsx
@@ -0,0 +1,15 @@
+import {Flex, HelpMark} from '@gravity-ui/uikit';
+
+interface TitleWithHelpMarkProps {
+ header: string;
+ note: string;
+}
+
+export function TitleWithHelpMark({header, note}: TitleWithHelpMarkProps) {
+ return (
+
+ {header}
+ {note}
+
+ );
+}
diff --git a/src/containers/Node/Threads/CpuUsageBar/CpuUsageBar.scss b/src/containers/Node/Threads/CpuUsageBar/CpuUsageBar.scss
index 5b136950bb..724e167354 100644
--- a/src/containers/Node/Threads/CpuUsageBar/CpuUsageBar.scss
+++ b/src/containers/Node/Threads/CpuUsageBar/CpuUsageBar.scss
@@ -1,28 +1,6 @@
.cpu-usage-bar {
- display: flex;
- align-items: center;
- gap: 8px;
-
- min-width: 120px;
-
&__progress {
- flex: 1;
-
+ width: 60px;
min-width: 60px;
}
-
- &__text {
- font-size: 12px;
- white-space: nowrap;
- }
-
- &__total {
- font-weight: 500;
- }
-
- &__breakdown {
- margin-left: 4px;
-
- color: var(--g-color-text-secondary);
- }
}
diff --git a/src/containers/Node/Threads/CpuUsageBar/CpuUsageBar.tsx b/src/containers/Node/Threads/CpuUsageBar/CpuUsageBar.tsx
index 0b41a37305..15755ef585 100644
--- a/src/containers/Node/Threads/CpuUsageBar/CpuUsageBar.tsx
+++ b/src/containers/Node/Threads/CpuUsageBar/CpuUsageBar.tsx
@@ -1,5 +1,6 @@
-import {Progress} from '@gravity-ui/uikit';
+import {Flex, Text} from '@gravity-ui/uikit';
+import {ProgressViewer} from '../../../../components/ProgressViewer/ProgressViewer';
import {cn} from '../../../../utils/cn';
import './CpuUsageBar.scss';
@@ -12,37 +13,26 @@ interface CpuUsageBarProps {
className?: string;
}
-/**
- * Component to display CPU usage as a progress bar showing both system and user usage
- */
export function CpuUsageBar({systemUsage = 0, userUsage = 0, className}: CpuUsageBarProps) {
const totalUsage = systemUsage + userUsage;
const systemPercent = Math.round(systemUsage * 100);
const userPercent = Math.round(userUsage * 100);
const totalPercent = Math.round(totalUsage * 100);
- // Determine color based on total load
- const getProgressTheme = (): 'success' | 'warning' | 'danger' => {
- if (totalUsage >= 1.0) {
- return 'danger';
- } // 100% or more load
- if (totalUsage >= 0.8) {
- return 'warning';
- } // 80% or more load
- return 'success';
- };
-
return (
-
+
-
-
{totalPercent}%
-
- (S: {systemPercent}%, U: {userPercent}%)
-
+
-
+
+ (Sys: {systemPercent}%, U: {userPercent}%)
+
+
);
}
diff --git a/src/containers/Node/Threads/ThreadStatesBar/ThreadStatesBar.scss b/src/containers/Node/Threads/ThreadStatesBar/ThreadStatesBar.scss
index 7ae7932ac7..249de46045 100644
--- a/src/containers/Node/Threads/ThreadStatesBar/ThreadStatesBar.scss
+++ b/src/containers/Node/Threads/ThreadStatesBar/ThreadStatesBar.scss
@@ -1,49 +1,10 @@
-.thread-states-bar {
- &__bar {
- display: flex;
- overflow: hidden;
-
- min-width: 80px;
- height: 16px;
- margin-bottom: 4px;
-
- border: 1px solid var(--g-color-line-generic);
- border-radius: 4px;
- background-color: var(--g-color-base-generic);
- }
-
- &__segment {
- transition: opacity 0.2s ease;
-
- &:hover {
- opacity: 0.8;
- }
- }
-
- &__legend {
- display: flex;
- flex-wrap: wrap;
- gap: 8px;
-
- font-size: 11px;
-
- color: var(--g-color-text-secondary);
- }
-
- &__legend-item {
- display: flex;
- align-items: center;
- gap: 4px;
-
- white-space: nowrap;
- }
-
+.ydb-thread-states-bar {
&__legend-color {
flex-shrink: 0;
width: 8px;
- height: 8px;
+ aspect-ratio: 1;
- border-radius: 2px;
+ border-radius: var(--g-border-radius-xs);
}
}
diff --git a/src/containers/Node/Threads/ThreadStatesBar/ThreadStatesBar.tsx b/src/containers/Node/Threads/ThreadStatesBar/ThreadStatesBar.tsx
index e40b11b9b7..3f9792319b 100644
--- a/src/containers/Node/Threads/ThreadStatesBar/ThreadStatesBar.tsx
+++ b/src/containers/Node/Threads/ThreadStatesBar/ThreadStatesBar.tsx
@@ -1,8 +1,12 @@
+import type {ProgressTheme} from '@gravity-ui/uikit';
+import {ActionTooltip, Flex, Progress, Text} from '@gravity-ui/uikit';
+
import {cn} from '../../../../utils/cn';
+import {EMPTY_DATA_PLACEHOLDER} from '../../../../utils/constants';
import './ThreadStatesBar.scss';
-const b = cn('thread-states-bar');
+const b = cn('ydb-thread-states-bar');
interface ThreadStatesBarProps {
states?: Record;
@@ -13,64 +17,89 @@ interface ThreadStatesBarProps {
/**
* Thread state colors based on the state type
*/
-const getStateColor = (state: string): string => {
+const getProgressBackgroundColor = (state: string): string => {
+ switch (state.toUpperCase()) {
+ case 'R': // Running
+ return 'var(--g-color-base-positive-medium)';
+ case 'S': // Sleeping
+ return 'var(--g-color-base-info-medium)';
+ case 'D': // Uninterruptible sleep
+ return 'var(--g-color-base-warning-medium)';
+ case 'Z': // Zombie
+ case 'T': // Stopped
+ case 'X': // Dead
+ return 'var(--g-color-base-danger-medium)';
+ default:
+ return 'var(--g-color-base-misc-medium)';
+ }
+};
+const getStackThemeColor = (state: string): ProgressTheme => {
+ switch (state.toUpperCase()) {
+ case 'R': // Running
+ return 'success';
+ case 'S': // Sleeping
+ return 'info';
+ case 'D': // Uninterruptible sleep
+ return 'warning';
+ case 'Z': // Zombie
+ case 'T': // Stopped
+ case 'X': // Dead
+ return 'danger';
+ default:
+ return 'misc';
+ }
+};
+const getStateTitle = (state: string): string => {
switch (state.toUpperCase()) {
case 'R': // Running
- return 'var(--g-color-text-positive)';
+ return 'Running';
case 'S': // Sleeping
- return 'var(--g-color-text-secondary)';
+ return 'Sleeping';
case 'D': // Uninterruptible sleep
- return 'var(--g-color-text-warning)';
+ return 'Uninterruptible sleep';
case 'Z': // Zombie
+ return 'Zombie';
case 'T': // Stopped
+ return 'Stopped';
case 'X': // Dead
- return 'var(--g-color-text-danger)';
+ return 'Dead';
default:
- return 'var(--g-color-text-misc)';
+ return 'Unknown';
}
};
-/**
- * Component to display thread states as a horizontal bar chart
- */
export function ThreadStatesBar({states = {}, totalThreads, className}: ThreadStatesBarProps) {
const total = totalThreads || Object.values(states).reduce((sum, count) => sum + count, 0);
if (total === 0) {
- return No threads
;
+ return EMPTY_DATA_PLACEHOLDER;
}
const stateEntries = Object.entries(states).filter(([, count]) => count > 0);
+ const stack = Object.entries(states).map(([state, count]) => ({
+ theme: getStackThemeColor(state),
+ value: (count / total) * 100,
+ }));
+
return (
-
- {stateEntries.map(([state, count]) => {
- const percentage = (count / total) * 100;
- return (
-
- );
- })}
-
-
+
+
{stateEntries.map(([state, count]) => (
-
-
- {state}: {count}
-
+
+
+
+
+ {state}: {count}
+
+
+
))}
-
+
);
}
diff --git a/src/containers/Node/Threads/Threads.tsx b/src/containers/Node/Threads/Threads.tsx
index 03c34c2fd1..ad62176db7 100644
--- a/src/containers/Node/Threads/Threads.tsx
+++ b/src/containers/Node/Threads/Threads.tsx
@@ -1,17 +1,12 @@
-import type {Column} from '@gravity-ui/react-data-table';
-import DataTable from '@gravity-ui/react-data-table';
-
import {ResponseError} from '../../../components/Errors/ResponseError';
-import {Loader} from '../../../components/Loader';
+import {LoaderWrapper} from '../../../components/LoaderWrapper/LoaderWrapper';
import {ResizeableDataTable} from '../../../components/ResizeableDataTable/ResizeableDataTable';
import {nodeApi} from '../../../store/reducers/node/node';
-import type {TThreadPoolInfo} from '../../../types/api/threads';
import {cn} from '../../../utils/cn';
-import {formatNumber} from '../../../utils/dataFormatters/dataFormatters';
+import {DEFAULT_TABLE_SETTINGS} from '../../../utils/constants';
import {useAutoRefreshInterval} from '../../../utils/hooks';
-import {CpuUsageBar} from './CpuUsageBar/CpuUsageBar';
-import {ThreadStatesBar} from './ThreadStatesBar/ThreadStatesBar';
+import {columns} from './columns';
import i18n from './i18n';
import './Threads.scss';
@@ -23,94 +18,8 @@ interface ThreadsProps {
className?: string;
}
-interface ThreadsTableProps {
- data: TThreadPoolInfo[];
- loading?: boolean;
-}
-
const THREADS_COLUMNS_WIDTH_LS_KEY = 'threadsTableColumnsWidth';
-function ThreadsTable({data, loading}: ThreadsTableProps) {
- const columns: Column[] = [
- {
- name: 'Name',
- header: i18n('field_pool-name'),
- render: ({row}: {row: TThreadPoolInfo}) => row.Name || i18n('value_unknown'),
- sortable: false,
- width: 200,
- },
- {
- name: 'Threads',
- header: i18n('field_thread-count'),
- render: ({row}: {row: TThreadPoolInfo}) => formatNumber(row.Threads),
- sortable: false,
- align: DataTable.RIGHT,
- width: 100,
- },
- {
- name: 'CpuUsage',
- header: i18n('field_cpu-usage'),
- render: ({row}: {row: TThreadPoolInfo}) => (
-
- ),
- sortable: false,
- width: 200,
- },
- {
- name: 'MinorPageFaults',
- header: i18n('field_minor-page-faults'),
- render: ({row}: {row: TThreadPoolInfo}) => formatNumber(row.MinorPageFaults),
- sortable: false,
- align: DataTable.RIGHT,
- width: 120,
- },
- {
- name: 'MajorPageFaults',
- header: i18n('field_major-page-faults'),
- render: ({row}: {row: TThreadPoolInfo}) => formatNumber(row.MajorPageFaults),
- sortable: false,
- align: DataTable.RIGHT,
- width: 120,
- },
- {
- name: 'States',
- header: i18n('field_thread-states'),
- render: ({row}: {row: TThreadPoolInfo}) => (
-
- ),
- sortable: false,
- width: 250,
- },
- ];
-
- if (loading) {
- return ;
- }
-
- if (!data.length) {
- return {i18n('alert_no-thread-data')}
;
- }
-
- return (
-
-
-
- );
-}
-
-/**
- * Main threads component for displaying thread pool information
- */
export function Threads({nodeId, className}: ThreadsProps) {
const [autoRefreshInterval] = useAutoRefreshInterval();
@@ -120,13 +29,18 @@ export function Threads({nodeId, className}: ThreadsProps) {
error,
} = nodeApi.useGetNodeInfoQuery({nodeId}, {pollingInterval: autoRefreshInterval});
- // Extract threads data from the node data
const data = nodeData?.Threads || [];
return (
-
- {error ? : null}
-
-
+
+ {error ? : null}
+
+
);
}
diff --git a/src/containers/Node/Threads/columns.tsx b/src/containers/Node/Threads/columns.tsx
new file mode 100644
index 0000000000..1646f40b12
--- /dev/null
+++ b/src/containers/Node/Threads/columns.tsx
@@ -0,0 +1,60 @@
+import type {Column} from '@gravity-ui/react-data-table';
+import DataTable from '@gravity-ui/react-data-table';
+
+import {TitleWithHelpMark} from '../../../components/TitleWithHelpmark/TitleWithHelpmark';
+import type {TThreadPoolInfo} from '../../../types/api/threads';
+import {formatNumber} from '../../../utils/dataFormatters/dataFormatters';
+import {safeParseNumber} from '../../../utils/utils';
+
+import {CpuUsageBar} from './CpuUsageBar/CpuUsageBar';
+import {ThreadStatesBar} from './ThreadStatesBar/ThreadStatesBar';
+import i18n from './i18n';
+
+export const columns: Column[] = [
+ {
+ name: 'Name',
+ header: i18n('field_pool-name'),
+ render: ({row}) => row.Name || i18n('value_unknown'),
+ width: 200,
+ },
+ {
+ name: 'Threads',
+ header: i18n('field_thread-count'),
+ render: ({row}) => formatNumber(row.Threads),
+ align: DataTable.RIGHT,
+ width: 100,
+ },
+ {
+ name: 'CpuUsage',
+ header: (
+
+ ),
+ render: ({row}) => ,
+ sortAccessor: (row) => safeParseNumber(row.SystemUsage) + safeParseNumber(row.UserUsage),
+ width: 200,
+ },
+ {
+ name: 'MinorPageFaults',
+ header: i18n('field_minor-page-faults'),
+ render: ({row}) => formatNumber(row.MinorPageFaults),
+ align: DataTable.RIGHT,
+ width: 145,
+ },
+ {
+ name: 'MajorPageFaults',
+ header: i18n('field_major-page-faults'),
+ render: ({row}) => formatNumber(row.MajorPageFaults),
+ align: DataTable.RIGHT,
+ width: 145,
+ },
+ {
+ name: 'States',
+ header: i18n('field_thread-states'),
+ render: ({row}) => ,
+ sortable: false,
+ width: 250,
+ },
+];
diff --git a/src/containers/Node/Threads/i18n/en.json b/src/containers/Node/Threads/i18n/en.json
index af2e7a27d4..a589c515fd 100644
--- a/src/containers/Node/Threads/i18n/en.json
+++ b/src/containers/Node/Threads/i18n/en.json
@@ -6,5 +6,6 @@
"field_major-page-faults": "Major Page Faults",
"field_thread-states": "Thread States",
"value_unknown": "Unknown",
- "alert_no-thread-data": "No thread pool information available"
+ "alert_no-thread-data": "No thread pool information available",
+ "description_cpu-usage": "System usage + user usage"
}
diff --git a/src/containers/Tenant/Diagnostics/AccessRights/AccessRights.scss b/src/containers/Tenant/Diagnostics/AccessRights/AccessRights.scss
index f8c86111ae..74e4179a75 100644
--- a/src/containers/Tenant/Diagnostics/AccessRights/AccessRights.scss
+++ b/src/containers/Tenant/Diagnostics/AccessRights/AccessRights.scss
@@ -47,12 +47,6 @@
text-overflow: ellipsis;
}
- &__note {
- display: flex;
- .g-help-mark__button {
- display: flex;
- }
- }
&__rights-wrapper {
position: relative;
diff --git a/src/containers/Tenant/Diagnostics/AccessRights/components/RightsTable/columns.tsx b/src/containers/Tenant/Diagnostics/AccessRights/components/RightsTable/columns.tsx
index 84c4f38197..2462b3d6fb 100644
--- a/src/containers/Tenant/Diagnostics/AccessRights/components/RightsTable/columns.tsx
+++ b/src/containers/Tenant/Diagnostics/AccessRights/components/RightsTable/columns.tsx
@@ -1,7 +1,8 @@
import type {Column} from '@gravity-ui/react-data-table';
-import {Flex, HelpMark, Label} from '@gravity-ui/uikit';
+import {Flex, Label} from '@gravity-ui/uikit';
import {SubjectWithAvatar} from '../../../../../../components/SubjectWithAvatar/SubjectWithAvatar';
+import {TitleWithHelpMark} from '../../../../../../components/TitleWithHelpmark/TitleWithHelpmark';
import type {PreparedAccessRights} from '../../../../../../types/api/acl';
import i18n from '../../i18n';
import {block} from '../../shared';
@@ -24,7 +25,7 @@ export const columns: Column[] = [
width: 400,
get header() {
return (
-
@@ -55,7 +56,7 @@ export const columns: Column[] = [
width: 400,
get header() {
return (
-
@@ -75,19 +76,3 @@ export const columns: Column[] = [
sortable: false,
},
];
-
-interface HeaderWithHelpMarkProps {
- header: string;
- note: string;
-}
-
-function HeaderWithHelpMark({header, note}: HeaderWithHelpMarkProps) {
- return (
-
- {header}
-
- {note}
-
-
- );
-}
From 127d839521f9b989e8a486c1e264eae777724c49 Mon Sep 17 00:00:00 2001
From: Elena Makarova
Date: Fri, 25 Jul 2025 16:07:34 +0300
Subject: [PATCH 9/9] fix
---
src/containers/Node/Threads/Threads.scss | 20 --------------------
src/containers/Node/Threads/Threads.tsx | 7 +------
2 files changed, 1 insertion(+), 26 deletions(-)
delete mode 100644 src/containers/Node/Threads/Threads.scss
diff --git a/src/containers/Node/Threads/Threads.scss b/src/containers/Node/Threads/Threads.scss
deleted file mode 100644
index ce7a19764b..0000000000
--- a/src/containers/Node/Threads/Threads.scss
+++ /dev/null
@@ -1,20 +0,0 @@
-.threads {
- &__error {
- margin-bottom: 16px;
- }
-
- &__table {
- .g-table {
- --g-table-row-height: 56px;
- }
- }
-
- &__empty {
- padding: 24px;
-
- font-size: 14px;
- text-align: center;
-
- color: var(--g-color-text-secondary);
- }
-}
diff --git a/src/containers/Node/Threads/Threads.tsx b/src/containers/Node/Threads/Threads.tsx
index ad62176db7..2328ada020 100644
--- a/src/containers/Node/Threads/Threads.tsx
+++ b/src/containers/Node/Threads/Threads.tsx
@@ -2,17 +2,12 @@ import {ResponseError} from '../../../components/Errors/ResponseError';
import {LoaderWrapper} from '../../../components/LoaderWrapper/LoaderWrapper';
import {ResizeableDataTable} from '../../../components/ResizeableDataTable/ResizeableDataTable';
import {nodeApi} from '../../../store/reducers/node/node';
-import {cn} from '../../../utils/cn';
import {DEFAULT_TABLE_SETTINGS} from '../../../utils/constants';
import {useAutoRefreshInterval} from '../../../utils/hooks';
import {columns} from './columns';
import i18n from './i18n';
-import './Threads.scss';
-
-const b = cn('threads');
-
interface ThreadsProps {
nodeId: string;
className?: string;
@@ -32,7 +27,7 @@ export function Threads({nodeId, className}: ThreadsProps) {
const data = nodeData?.Threads || [];
return (
-
+
{error ? : null}