From c37f2e3609d97ba35caa9010d8b8a8be1881a661 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=90=D1=80=D1=82=D1=91=D0=BC=20=D0=9C=D1=83=D1=84=D0=B0?= =?UTF-8?q?=D0=B7=D0=B0=D0=BB=D0=BE=D0=B2?= <67755036+artemmufazalov@users.noreply.github.com> Date: Wed, 2 Jul 2025 11:09:47 +0300 Subject: [PATCH 1/5] fix: remove viewer from balancer (#2523) --- src/utils/__test__/parseBalancer.test.ts | 13 ++++++++++++- src/utils/parseBalancer.ts | 2 +- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/src/utils/__test__/parseBalancer.test.ts b/src/utils/__test__/parseBalancer.test.ts index 91cf528461..221a7761d6 100644 --- a/src/utils/__test__/parseBalancer.test.ts +++ b/src/utils/__test__/parseBalancer.test.ts @@ -61,12 +61,23 @@ describe('parseBalancer', () => { }); describe('removeViewerPathname', () => { - test('should remove pathname', () => { + test('should remove /viewer/json pathname', () => { const initialValue = 'https://ydb-testing-0000.search.net:8765/viewer/json'; const result = 'https://ydb-testing-0000.search.net:8765'; expect(removeViewerPathname(initialValue)).toBe(result); }); + test('should remove /viewer pathname', () => { + const initialValue = 'https://ydb-testing-0000.search.net:8765/viewer'; + const result = 'https://ydb-testing-0000.search.net:8765'; + + expect(removeViewerPathname(initialValue)).toBe(result); + }); + test('should not change input if there is no /viewer or /viewer/json', () => { + const initialValue = 'https://ydb-testing-0000.search.net:8765'; + + expect(removeViewerPathname(initialValue)).toBe(initialValue); + }); }); describe('removeProtocol', () => { test('should remove protocol from start', () => { diff --git a/src/utils/parseBalancer.ts b/src/utils/parseBalancer.ts index 37d3e6d712..1c64f1e886 100644 --- a/src/utils/parseBalancer.ts +++ b/src/utils/parseBalancer.ts @@ -1,7 +1,7 @@ import {normalizePathSlashes} from '.'; const protocolRegex = /^http[s]?:\/\//; -const viewerPathnameRegex = /\/viewer\/json$/; +const viewerPathnameRegex = /\/viewer(\/json)?$/; export const removeViewerPathname = (value: string) => { return value.replace(viewerPathnameRegex, ''); From 5ff0120730a5de0941e4351cc01b615899b3ee7e Mon Sep 17 00:00:00 2001 From: Hellen Date: Wed, 2 Jul 2025 12:04:50 +0300 Subject: [PATCH 2/5] chore: fix some types (#2525) --- src/store/reducers/api.ts | 1 + src/types/api/common.ts | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/store/reducers/api.ts b/src/store/reducers/api.ts index f185fa1cde..441d28f22f 100644 --- a/src/store/reducers/api.ts +++ b/src/store/reducers/api.ts @@ -20,6 +20,7 @@ export const api = createApi({ 'VDiskData', 'AccessRights', 'Backups', + 'BackupsSchedule', ], }); diff --git a/src/types/api/common.ts b/src/types/api/common.ts index 3f247a084e..97e6c662e8 100644 --- a/src/types/api/common.ts +++ b/src/types/api/common.ts @@ -1,6 +1,6 @@ export interface IProtobufTimeObject { /** int64 */ - seconds?: string; + seconds?: string | number; nanos?: number; } From 512cf159374b0fa416910540ed437ef4fa840946 Mon Sep 17 00:00:00 2001 From: Anton Standrik Date: Wed, 2 Jul 2025 15:20:55 +0300 Subject: [PATCH 3/5] fix: make operations page_size to 20 (#2498) --- .../Operations/useOperationsInfiniteQuery.ts | 12 +++++++++--- src/store/reducers/operations.ts | 2 +- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/src/containers/Operations/useOperationsInfiniteQuery.ts b/src/containers/Operations/useOperationsInfiniteQuery.ts index d6d0f6aa66..d6d5ed9526 100644 --- a/src/containers/Operations/useOperationsInfiniteQuery.ts +++ b/src/containers/Operations/useOperationsInfiniteQuery.ts @@ -2,7 +2,7 @@ import React from 'react'; import {throttle} from 'lodash'; -import {operationsApi} from '../../store/reducers/operations'; +import {DEFAULT_PAGE_SIZE, operationsApi} from '../../store/reducers/operations'; import type {OperationKind} from '../../types/api/operations'; interface UseOperationsInfiniteQueryProps { @@ -18,7 +18,7 @@ const DEFAULT_SCROLL_MARGIN = 100; export function useOperationsInfiniteQuery({ database, kind, - pageSize = 10, + pageSize = DEFAULT_PAGE_SIZE, searchValue, scrollContainerRef, }: UseOperationsInfiniteQueryProps) { @@ -63,8 +63,14 @@ export function useOperationsInfiniteQuery({ // Check after data updates React.useLayoutEffect(() => { if (!isFetchingNextPage) { - checkAndLoadMorePages(); + // RAF to ensure browser has completed layout and paint + const raf = requestAnimationFrame(() => { + checkAndLoadMorePages(); + }); + return () => cancelAnimationFrame(raf); } + + return undefined; }, [data, isFetchingNextPage, checkAndLoadMorePages]); // Scroll handler for infinite scrolling diff --git a/src/store/reducers/operations.ts b/src/store/reducers/operations.ts index 2d19b1683f..dd65e13fee 100644 --- a/src/store/reducers/operations.ts +++ b/src/store/reducers/operations.ts @@ -8,7 +8,7 @@ import type { import {api} from './api'; -const DEFAULT_PAGE_SIZE = 20; +export const DEFAULT_PAGE_SIZE = 20; // Validate and normalize the response to ensure it has proper structure function validateOperationListResponse(data: TOperationList): TOperationList { From 2511059fc05ef035a4b44f71434f20f462b96c21 Mon Sep 17 00:00:00 2001 From: Anton Standrik Date: Thu, 3 Jul 2025 09:43:18 +0300 Subject: [PATCH 4/5] feat!: remove ai assistant button (#2535) --- .../ComponentsProvider/componentsRegistry.ts | 1 - .../AsideNavigation/hooks/useHotkeysPanel.tsx | 30 +++++++++++++++---- src/containers/Header/Header.tsx | 6 ---- 3 files changed, 24 insertions(+), 13 deletions(-) diff --git a/src/components/ComponentsProvider/componentsRegistry.ts b/src/components/ComponentsProvider/componentsRegistry.ts index abaa28d5ba..d1bc723863 100644 --- a/src/components/ComponentsProvider/componentsRegistry.ts +++ b/src/components/ComponentsProvider/componentsRegistry.ts @@ -13,7 +13,6 @@ const componentsRegistryInner = new Registry() .register('AsideNavigation', AsideNavigation) .register('ErrorBoundary', ErrorBoundaryInner) .register('ShardsTable', ShardsTable) - .register('AIAssistantButton', EmptyPlaceholder) .register('ChatPanel', EmptyPlaceholder); export type ComponentsRegistry = ComponentsRegistryTemplate; diff --git a/src/containers/AsideNavigation/hooks/useHotkeysPanel.tsx b/src/containers/AsideNavigation/hooks/useHotkeysPanel.tsx index c2e4fa58b6..dd91f85822 100644 --- a/src/containers/AsideNavigation/hooks/useHotkeysPanel.tsx +++ b/src/containers/AsideNavigation/hooks/useHotkeysPanel.tsx @@ -1,5 +1,6 @@ import React from 'react'; +import type {HotkeysGroup} from '@gravity-ui/navigation'; import {HotkeysPanel as UIKitHotkeysPanel} from '@gravity-ui/navigation'; import {Hotkey} from '@gravity-ui/uikit'; import hotkeys from 'hotkeys-js'; @@ -13,7 +14,7 @@ export const isMac = () => navigator.platform.toUpperCase().includes('MAC'); export const SHORTCUTS_HOTKEY = isMac() ? 'cmd+K' : 'ctrl+K'; -export const HOTKEYS = [ +export const DEFAULT_HOTKEY_GROUPS: HotkeysGroup[] = [ { title: 'Query Editor', items: [ @@ -48,6 +49,7 @@ export const HOTKEYS = [ export interface HotkeysPanelProps { visible: boolean; closePanel: () => void; + hotkeyGroups?: HotkeysGroup[]; } /** @@ -60,7 +62,11 @@ export interface HotkeysPanelProps { * This wrapper ensures the component mounts first, then sets visible=true in a subsequent render cycle * to make transition actually happen. */ -export const HotkeysPanelWrapper = ({visible: propsVisible, closePanel}: HotkeysPanelProps) => { +export const HotkeysPanelWrapper = ({ + visible: propsVisible, + closePanel, + hotkeyGroups = DEFAULT_HOTKEY_GROUPS, +}: HotkeysPanelProps) => { const [visible, setVisible] = React.useState(false); React.useEffect(() => { @@ -70,7 +76,7 @@ export const HotkeysPanelWrapper = ({visible: propsVisible, closePanel}: Hotkeys return ( @@ -87,9 +93,15 @@ interface UseHotkeysPanel { isPanelVisible: boolean; openPanel: () => void; closePanel: () => void; + hotkeyGroups?: HotkeysGroup[]; } -export const useHotkeysPanel = ({isPanelVisible, openPanel, closePanel}: UseHotkeysPanel) => { +export const useHotkeysPanel = ({ + isPanelVisible, + openPanel, + closePanel, + hotkeyGroups = DEFAULT_HOTKEY_GROUPS, +}: UseHotkeysPanel) => { React.useEffect(() => { hotkeys(SHORTCUTS_HOTKEY, openPanel); @@ -102,8 +114,14 @@ export const useHotkeysPanel = ({isPanelVisible, openPanel, closePanel}: UseHotk }, [openPanel]); const renderPanel = React.useCallback( - () => , - [isPanelVisible, closePanel], + () => ( + + ), + [isPanelVisible, closePanel, hotkeyGroups], ); return { diff --git a/src/containers/Header/Header.tsx b/src/containers/Header/Header.tsx index 09c3f0b68f..af0e3ef46d 100644 --- a/src/containers/Header/Header.tsx +++ b/src/containers/Header/Header.tsx @@ -4,7 +4,6 @@ import {ArrowUpRightFromSquare, CirclePlus, PlugConnection} from '@gravity-ui/ic import {Breadcrumbs, Button, Divider, Flex, Icon} from '@gravity-ui/uikit'; import {useLocation} from 'react-router-dom'; -import {componentsRegistry} from '../../components/ComponentsProvider/componentsRegistry'; import {getConnectToDBDialog} from '../../components/ConnectToDB/ConnectToDBDialog'; import {InternalLink} from '../../components/InternalLink'; import {useAddClusterFeatureAvailable} from '../../store/reducers/capabilities/hooks'; @@ -77,11 +76,6 @@ function Header() { ); } - if (componentsRegistry.has('AIAssistantButton')) { - const AIAssistantButton = componentsRegistry.get('AIAssistantButton'); - elements.push(); - } - if (!isClustersPage && isUserAllowedToMakeChanges) { elements.push(