From ca3ffbb61a316351e32aa9deb71e857adb7bb117 Mon Sep 17 00:00:00 2001 From: Anton Standrik Date: Thu, 3 Jul 2025 14:28:22 +0300 Subject: [PATCH] fix: remove operations counter --- src/containers/Operations/Operations.tsx | 18 ++- .../Operations/OperationsControls.tsx | 13 -- src/containers/Operations/i18n/en.json | 3 - .../Operations/useOperationsInfiniteQuery.ts | 1 - .../diagnostics/tabs/OperationsModel.ts | 49 +------- .../diagnostics/tabs/operations.test.ts | 115 ++++++++++-------- 6 files changed, 74 insertions(+), 125 deletions(-) diff --git a/src/containers/Operations/Operations.tsx b/src/containers/Operations/Operations.tsx index 5749621bf..8b68855cf 100644 --- a/src/containers/Operations/Operations.tsx +++ b/src/containers/Operations/Operations.tsx @@ -23,14 +23,13 @@ export function Operations({database, scrollContainerRef}: OperationsProps) { const {kind, searchValue, pageSize, handleKindChange, handleSearchChange} = useOperationsQueryParams(); - const {operations, isLoading, isLoadingMore, error, refreshTable, totalCount} = - useOperationsInfiniteQuery({ - database, - kind, - pageSize, - searchValue, - scrollContainerRef, - }); + const {operations, isLoading, isLoadingMore, error, refreshTable} = useOperationsInfiniteQuery({ + database, + kind, + pageSize, + searchValue, + scrollContainerRef, + }); const settings = React.useMemo(() => { return { @@ -49,9 +48,6 @@ export function Operations({database, scrollContainerRef}: OperationsProps) { diff --git a/src/containers/Operations/OperationsControls.tsx b/src/containers/Operations/OperationsControls.tsx index 1508054c2..fce9b0df6 100644 --- a/src/containers/Operations/OperationsControls.tsx +++ b/src/containers/Operations/OperationsControls.tsx @@ -2,7 +2,6 @@ import React from 'react'; import {Select} from '@gravity-ui/uikit'; -import {EntitiesCount} from '../../components/EntitiesCount'; import {Search} from '../../components/Search'; import type {OperationKind} from '../../types/api/operations'; @@ -15,9 +14,6 @@ import './Operations.scss'; interface OperationsControlsProps { kind: OperationKind; searchValue: string; - entitiesCountCurrent: number; - entitiesCountTotal?: number; - entitiesLoading: boolean; handleKindChange: (kind: OperationKind) => void; handleSearchChange: (value: string) => void; } @@ -25,9 +21,6 @@ interface OperationsControlsProps { export function OperationsControls({ kind, searchValue, - entitiesCountCurrent, - entitiesCountTotal, - entitiesLoading, handleKindChange, handleSearchChange, }: OperationsControlsProps) { @@ -45,12 +38,6 @@ export function OperationsControls({ options={OPERATION_KINDS} onUpdate={(value) => handleKindChange(value[0] as OperationKind)} /> - ); } diff --git a/src/containers/Operations/i18n/en.json b/src/containers/Operations/i18n/en.json index d32cc3587..791d01f9d 100644 --- a/src/containers/Operations/i18n/en.json +++ b/src/containers/Operations/i18n/en.json @@ -1,5 +1,4 @@ { - "label_operations": "Operations", "title_empty": "No operations data", "pleaceholder_search": "Search operations", "placeholder_kind": "Select operation kind", @@ -8,7 +7,6 @@ "kind_export_yt": "Export/YT", "kind_import_s3": "Import/S3", "kind_buildIndex": "Build Index", - "column_operationId": "Operation ID", "column_status": "Status", "column_createdBy": "Created By", @@ -18,7 +16,6 @@ "column_state": "State", "column_progress": "Progress", "label_duration-ongoing": "{{value}} (ongoing)", - "header_cancel": "Cancel operation", "header_forget": "Forget operation", "text_cancel": "The operation will be cancelled. Do you want to proceed?", diff --git a/src/containers/Operations/useOperationsInfiniteQuery.ts b/src/containers/Operations/useOperationsInfiniteQuery.ts index d6d5ed952..a8a4a4c38 100644 --- a/src/containers/Operations/useOperationsInfiniteQuery.ts +++ b/src/containers/Operations/useOperationsInfiniteQuery.ts @@ -116,6 +116,5 @@ export function useOperationsInfiniteQuery({ isLoadingMore: isFetchingNextPage, error, refreshTable: refetch, - totalCount: allOperations.length, }; } diff --git a/tests/suites/tenant/diagnostics/tabs/OperationsModel.ts b/tests/suites/tenant/diagnostics/tabs/OperationsModel.ts index c6bbd1f62..eb8dd4b7d 100644 --- a/tests/suites/tenant/diagnostics/tabs/OperationsModel.ts +++ b/tests/suites/tenant/diagnostics/tabs/OperationsModel.ts @@ -150,56 +150,19 @@ export class OperationsTable extends BaseModel { return await this.accessDeniedTitle.innerText(); } - async getOperationsCount(): Promise { - // The EntitiesCount component renders a Label with the count - const countLabel = await this.page - .locator('.ydb-entities-count .g-label__content') - .textContent(); - if (!countLabel) { - return 0; - } - const match = countLabel.match(/(\d+)/); - return match ? parseInt(match[1], 10) : 0; - } - - async waitForOperationsCount(expectedCount: number, timeout = 5000): Promise { - await this.page.waitForFunction( - (expected) => { - const countElement = document.querySelector( - '.ydb-entities-count .g-label__content', - ); - if (!countElement) { - return false; - } - const text = countElement.textContent || ''; - const match = text.match(/(\d+)/); - const currentCount = match ? parseInt(match[1], 10) : 0; - return currentCount === expected; - }, - expectedCount, - {timeout}, - ); - } - - async waitForOperationsCountToChange(previousCount: number, timeout = 5000): Promise { + async waitForRowCountToChange(previousCount: number, timeout = 5000): Promise { await this.page.waitForFunction( (prev) => { - const countElement = document.querySelector( - '.ydb-entities-count .g-label__content', + const rows = document.querySelectorAll( + '.data-table__row:not(.data-table__row_header)', ); - if (!countElement) { - return false; - } - const text = countElement.textContent || ''; - const match = text.match(/(\d+)/); - const currentCount = match ? parseInt(match[1], 10) : 0; - return currentCount !== prev; + return rows.length !== prev; }, previousCount, {timeout}, ); - // Now get the actual new count - return await this.getOperationsCount(); + // Return the new row count + return await this.getRowCount(); } async isPageErrorVisible(): Promise { diff --git a/tests/suites/tenant/diagnostics/tabs/operations.test.ts b/tests/suites/tenant/diagnostics/tabs/operations.test.ts index 4928c2dac..4a42aa4e5 100644 --- a/tests/suites/tenant/diagnostics/tabs/operations.test.ts +++ b/tests/suites/tenant/diagnostics/tabs/operations.test.ts @@ -34,13 +34,13 @@ test.describe('Operations Tab - Infinite Query', () => { await diagnostics.operations.waitForTableVisible(); await diagnostics.operations.waitForDataLoad(); - // Wait a bit for the counter to stabilize after initial load + // Wait a bit for the table to stabilize after initial load await page.waitForTimeout(1000); - // Verify initial page loaded (should show count in badge) - const operationsCount = await diagnostics.operations.getOperationsCount(); - expect(operationsCount).toBeGreaterThan(0); - expect(operationsCount).toBeLessThanOrEqual(20); // Should have up to DEFAULT_PAGE_SIZE operations loaded initially + // Verify initial page loaded (should have up to DEFAULT_PAGE_SIZE operations) + const rowCount = await diagnostics.operations.getRowCount(); + expect(rowCount).toBeGreaterThan(0); + expect(rowCount).toBeLessThanOrEqual(20); // Should have up to DEFAULT_PAGE_SIZE operations loaded initially // Verify first row data structure const firstRowData = await diagnostics.operations.getRowData(0); @@ -78,32 +78,32 @@ test.describe('Operations Tab - Infinite Query', () => { await diagnostics.operations.waitForTableVisible(); await diagnostics.operations.waitForDataLoad(); - // Get initial operations count - const initialOperationsCount = await diagnostics.operations.getOperationsCount(); - expect(initialOperationsCount).toBeGreaterThan(0); + // Get initial row count + const initialRowCount = await diagnostics.operations.getRowCount(); + expect(initialRowCount).toBeGreaterThan(0); // Scroll to bottom await diagnostics.operations.scrollToBottom(); - // Wait for operations count to potentially change - let finalOperationsCount: number; + // Wait for row count to potentially change + let finalRowCount: number; try { - finalOperationsCount = await diagnostics.operations.waitForOperationsCountToChange( - initialOperationsCount, + finalRowCount = await diagnostics.operations.waitForRowCountToChange( + initialRowCount, 3000, ); } catch (_e) { // If timeout, the count didn't change - finalOperationsCount = await diagnostics.operations.getOperationsCount(); + finalRowCount = await diagnostics.operations.getRowCount(); } // Check if more operations were loaded - if (finalOperationsCount > initialOperationsCount) { + if (finalRowCount > initialRowCount) { // Infinite scroll worked - more operations were loaded - expect(finalOperationsCount).toBeGreaterThan(initialOperationsCount); + expect(finalRowCount).toBeGreaterThan(initialRowCount); } else { - // No more data to load - operations count should stay the same - expect(finalOperationsCount).toBe(initialOperationsCount); + // No more data to load - row count should stay the same + expect(finalRowCount).toBe(initialRowCount); } }); @@ -222,16 +222,12 @@ test.describe('Operations Tab - Infinite Query', () => { const rowCount = await diagnostics.operations.getRowCount(); expect(rowCount).toBeLessThanOrEqual(1); - // Verify operations count is 0 - const operationsCount = await diagnostics.operations.getOperationsCount(); - expect(operationsCount).toBe(0); - // Wait to ensure no infinite refetching occurs await page.waitForTimeout(3000); - // Verify the count is still 0 (no infinite refetching) - const finalOperationsCount = await diagnostics.operations.getOperationsCount(); - expect(finalOperationsCount).toBe(0); + // Verify the count is still the same (no infinite refetching) + const finalRowCount = await diagnostics.operations.getRowCount(); + expect(finalRowCount).toBe(rowCount); }); test('stops pagination when receiving malformed response after valid data', async ({page}) => { @@ -254,9 +250,10 @@ test.describe('Operations Tab - Infinite Query', () => { await diagnostics.operations.waitForTableVisible(); await diagnostics.operations.waitForDataLoad(); - // Verify initial page loaded (should have 20 operations) - const initialOperationsCount = await diagnostics.operations.getOperationsCount(); - expect(initialOperationsCount).toBe(20); + // Verify initial page loaded (virtualized table may not show all 20 rows) + const initialRowCount = await diagnostics.operations.getRowCount(); + expect(initialRowCount).toBeGreaterThan(0); + expect(initialRowCount).toBeLessThanOrEqual(20); // Verify first row data const firstRowData = await diagnostics.operations.getRowData(0); @@ -274,16 +271,18 @@ test.describe('Operations Tab - Infinite Query', () => { await diagnostics.operations.waitForLoadingMoreToDisappear(); } - // Verify the count remains at 20 (malformed response didn't add more) - const finalOperationsCount = await diagnostics.operations.getOperationsCount(); - expect(finalOperationsCount).toBe(20); + // Verify the count didn't significantly increase (malformed response didn't add more) + const finalRowCount = await diagnostics.operations.getRowCount(); + // With virtualization, row count might vary slightly but shouldn't exceed initial data + expect(finalRowCount).toBeLessThanOrEqual(20); // Wait to ensure no infinite refetching occurs await page.waitForTimeout(3000); - // Verify the count is still 20 - const stillFinalCount = await diagnostics.operations.getOperationsCount(); - expect(stillFinalCount).toBe(20); + // Verify the count remains stable (no infinite refetching) + const stillFinalRowCount = await diagnostics.operations.getRowCount(); + // Allow for minor virtualization differences + expect(Math.abs(stillFinalRowCount - finalRowCount)).toBeLessThanOrEqual(5); }); test('loads all operations when scrolling to the bottom multiple times', async ({page}) => { @@ -306,21 +305,24 @@ test.describe('Operations Tab - Infinite Query', () => { await diagnostics.operations.waitForTableVisible(); await diagnostics.operations.waitForDataLoad(); - // Wait a bit for the counter to stabilize after initial load + // Wait a bit for the table to stabilize after initial load await page.waitForTimeout(2000); - // Get initial operations count (should be around 20) - const initialOperationsCount = await diagnostics.operations.getOperationsCount(); - expect(initialOperationsCount).toBeGreaterThan(0); - expect(initialOperationsCount).toBeLessThanOrEqual(20); + // Get initial row count (should be around 20) + const initialRowCount = await diagnostics.operations.getRowCount(); + expect(initialRowCount).toBeGreaterThan(0); + expect(initialRowCount).toBeLessThanOrEqual(20); // Keep scrolling until all operations are loaded - let previousOperationsCount = initialOperationsCount; - let currentOperationsCount = initialOperationsCount; + let previousRowCount = initialRowCount; + let currentRowCount = initialRowCount; const maxScrollAttempts = 10; // Safety limit to prevent infinite loop let scrollAttempts = 0; - while (currentOperationsCount < 80 && scrollAttempts < maxScrollAttempts) { + // Keep track of whether we're still loading more data + let hasMoreData = true; + + while (hasMoreData && scrollAttempts < maxScrollAttempts) { // Scroll to bottom await diagnostics.operations.scrollToBottom(); @@ -333,28 +335,33 @@ test.describe('Operations Tab - Infinite Query', () => { await diagnostics.operations.waitForLoadingMoreToDisappear(); } - // Wait for operations count to change or timeout + // Wait for row count to change or timeout try { - currentOperationsCount = - await diagnostics.operations.waitForOperationsCountToChange( - previousOperationsCount, - 3000, - ); + currentRowCount = await diagnostics.operations.waitForRowCountToChange( + previousRowCount, + 3000, + ); + // If row count changed, we still have more data + hasMoreData = true; } catch (_e) { // If timeout, the count didn't change - we might have reached the end - currentOperationsCount = await diagnostics.operations.getOperationsCount(); + currentRowCount = await diagnostics.operations.getRowCount(); + hasMoreData = false; } - previousOperationsCount = currentOperationsCount; + previousRowCount = currentRowCount; scrollAttempts++; } - // Verify all 80 operations were loaded - expect(currentOperationsCount).toBe(80); + // With virtualization, we can't verify exact count via DOM + // But we should have more rows than initially + expect(currentRowCount).toBeGreaterThan(initialRowCount); const rowCount = await diagnostics.operations.getRowCount(); - // Verify the last operation has the expected ID pattern - const lastRowData = await diagnostics.operations.getRowData(rowCount - 1); - expect(lastRowData['Operation ID']).toContain('ydb://'); + // Verify we can read data from the last visible row + if (rowCount > 0) { + const lastRowData = await diagnostics.operations.getRowData(rowCount - 1); + expect(lastRowData['Operation ID']).toContain('ydb://'); + } }); });