From e0ede972a1edc4b1f67f86c2a0416b763ced88ea Mon Sep 17 00:00:00 2001 From: Valentin Kirilov Date: Wed, 17 Sep 2025 11:17:28 +0300 Subject: [PATCH 1/3] feat(ui): rework the vector search onboarding screen - no longer silently mark the onboarding as seen, unless it's explicilty dismissed by the user re #RI-7479 --- .../VectorSearchOnboarding.spec.tsx | 7 ------ .../onboarding/VectorSearchOnboarding.tsx | 7 +----- .../onboarding/components/Header.tsx | 2 +- .../VectorSearchOnboardingContext.spec.tsx | 24 +------------------ .../context/VectorSearchOnboardingContext.tsx | 8 ------- 5 files changed, 3 insertions(+), 45 deletions(-) diff --git a/redisinsight/ui/src/pages/vector-search/components/onboarding/VectorSearchOnboarding.spec.tsx b/redisinsight/ui/src/pages/vector-search/components/onboarding/VectorSearchOnboarding.spec.tsx index 7a0ce2b71e..ab264e050a 100644 --- a/redisinsight/ui/src/pages/vector-search/components/onboarding/VectorSearchOnboarding.spec.tsx +++ b/redisinsight/ui/src/pages/vector-search/components/onboarding/VectorSearchOnboarding.spec.tsx @@ -20,7 +20,6 @@ const renderVectorSearchOnboardingComponent = ( const defaultContextValue: VectorSearchOnboardingContextType = { showOnboarding: false, setOnboardingSeen: jest.fn(), - setOnboardingSeenSilent: jest.fn(), ...contextValue, } @@ -37,11 +36,8 @@ describe('VectorSearchOnboarding', () => { }) it('should render onboarding content', () => { - const mockMarkOnboardingAsSeenSilent = jest.fn() - renderVectorSearchOnboardingComponent({ showOnboarding: true, - setOnboardingSeenSilent: mockMarkOnboardingAsSeenSilent, }) const container = screen.getByTestId('vector-search-onboarding') @@ -60,9 +56,6 @@ describe('VectorSearchOnboarding', () => { expect(actions).toBeInTheDocument() expect(footer).toBeInTheDocument() - // Verify the onboarding was marked as seen - expect(mockMarkOnboardingAsSeenSilent).toHaveBeenCalledTimes(1) - // Verify telemetry event was sent expect(sendEventTelemetry).toHaveBeenCalledWith({ event: TelemetryEvent.VECTOR_SEARCH_INITIAL_MESSAGE_DISPLAYED, diff --git a/redisinsight/ui/src/pages/vector-search/components/onboarding/VectorSearchOnboarding.tsx b/redisinsight/ui/src/pages/vector-search/components/onboarding/VectorSearchOnboarding.tsx index c787435fc6..8e494249cf 100644 --- a/redisinsight/ui/src/pages/vector-search/components/onboarding/VectorSearchOnboarding.tsx +++ b/redisinsight/ui/src/pages/vector-search/components/onboarding/VectorSearchOnboarding.tsx @@ -18,12 +18,7 @@ import { useVectorSearchOnboarding } from '../../context/VectorSearchOnboardingC export const VectorSearchOnboarding = () => { useTelemetryMountEvent(TelemetryEvent.VECTOR_SEARCH_INITIAL_MESSAGE_DISPLAYED) - const { setOnboardingSeen, setOnboardingSeenSilent } = - useVectorSearchOnboarding() - - useEffect(() => { - setOnboardingSeenSilent() - }, []) + const { setOnboardingSeen } = useVectorSearchOnboarding() return ( ( grow={false} data-testid="vector-search-onboarding--header" > - Get Started with vector search + Get started with vector search Launch a quick onboarding to learn how to build ultra-fast similarity search across massive datasets - in real time. diff --git a/redisinsight/ui/src/pages/vector-search/context/VectorSearchOnboardingContext.spec.tsx b/redisinsight/ui/src/pages/vector-search/context/VectorSearchOnboardingContext.spec.tsx index 431776df02..724a1e3013 100644 --- a/redisinsight/ui/src/pages/vector-search/context/VectorSearchOnboardingContext.spec.tsx +++ b/redisinsight/ui/src/pages/vector-search/context/VectorSearchOnboardingContext.spec.tsx @@ -7,8 +7,7 @@ import { import { BrowserStorageItem } from 'uiSrc/constants' const TestComponent: React.FC = () => { - const { showOnboarding, setOnboardingSeen, setOnboardingSeenSilent } = - useVectorSearchOnboarding() + const { showOnboarding, setOnboardingSeen } = useVectorSearchOnboarding() return (
@@ -19,9 +18,6 @@ const TestComponent: React.FC = () => { -
) } @@ -89,24 +85,6 @@ describe('VectorSearchOnboardingContext', () => { expect(showOnboardingStorage).toBe('true') }) - it('should update only localStorage when setOnboardingSeenSilent is called', () => { - renderTestComponent() - - // Update localStorage only, to not force re-render - const markAsSeenSilentBtn = screen.getByTestId('silent-btn') - fireEvent.click(markAsSeenSilentBtn) - - // localStorage should be updated - const showOnboardingStorage = localStorage.getItem( - BrowserStorageItem.vectorSearchOnboarding, - ) - expect(showOnboardingStorage).toBe('true') - - // State should remain intact - const showOnboardingState = screen.getByTestId('show-onboarding') - expect(showOnboardingState.textContent).toBe('true') - }) - it('should throw if used outside provider', () => { // Suppress error output for this test const spy = jest.spyOn(console, 'error').mockImplementation(() => {}) diff --git a/redisinsight/ui/src/pages/vector-search/context/VectorSearchOnboardingContext.tsx b/redisinsight/ui/src/pages/vector-search/context/VectorSearchOnboardingContext.tsx index 550702ae0c..b21176f4f6 100644 --- a/redisinsight/ui/src/pages/vector-search/context/VectorSearchOnboardingContext.tsx +++ b/redisinsight/ui/src/pages/vector-search/context/VectorSearchOnboardingContext.tsx @@ -4,7 +4,6 @@ import { BrowserStorageItem } from 'uiSrc/constants' export interface VectorSearchOnboardingContextType { showOnboarding: boolean setOnboardingSeen: () => void - setOnboardingSeenSilent: () => void } export const VectorSearchOnboardingContext = createContext< @@ -27,18 +26,11 @@ export const VectorSearchOnboardingProvider: React.FC<{ setShowOnboarding(false) }, []) - // Update only localStorage (no re-render) - const setOnboardingSeenSilent = useCallback(() => { - localStorage.setItem(BrowserStorageItem.vectorSearchOnboarding, 'true') - // Do not update state - }, []) - return ( {children} From a054433201b68eecd128a88427b32b2d18497b8d Mon Sep 17 00:00:00 2001 From: Valentin Kirilov Date: Wed, 17 Sep 2025 11:43:10 +0300 Subject: [PATCH 2/3] test(e2e): update the onboarding screen tests to reflect the new dismiss behavior - verify we keep showing the onboarding screen unless we dismiss it manually re #RI-7479 --- .../tests/vector-search/onboarding.spec.ts | 44 ++++++++++++++----- 1 file changed, 33 insertions(+), 11 deletions(-) diff --git a/tests/playwright/tests/vector-search/onboarding.spec.ts b/tests/playwright/tests/vector-search/onboarding.spec.ts index ec6d80c8d4..e7876daafd 100644 --- a/tests/playwright/tests/vector-search/onboarding.spec.ts +++ b/tests/playwright/tests/vector-search/onboarding.spec.ts @@ -6,18 +6,15 @@ import { } from '../../helpers/utils' import { CreateIndexPage } from '../../pageObjects/pages/vector-search/create-index-page' import { ossStandaloneV6Config } from '../../helpers/conf' -import { BrowserPage } from '../../pageObjects/browser-page' test.describe('Vector Search - Onboarding', () => { let searchPage: VectorSearchPage let createIndexPage: CreateIndexPage - let browserPage: BrowserPage let cleanupInstance: () => Promise test.beforeEach(async ({ page, api: { databaseService } }) => { searchPage = new VectorSearchPage(page) createIndexPage = new CreateIndexPage(page) - browserPage = new BrowserPage(page) cleanupInstance = await addStandaloneInstanceAndNavigateToIt( page, @@ -42,6 +39,13 @@ test.describe('Vector Search - Onboarding', () => { // Verify that "Create index" flow is opened await createIndexPage.verifyCreateIndexPageLoaded() + + // But it should not dismiss the onboarding screen yet + // Click on "Cancel" button to go back to Search page + await createIndexPage.cancelButton.click() + + // Verify that onboarding screen is still visible + await searchPage.waitForLocatorVisible(searchPage.onboardingContainer) }) test('should dismiss onboarding when clicking on "Skip for now" button', async () => { @@ -53,6 +57,15 @@ test.describe('Vector Search - Onboarding', () => { // Verify that onboarding screen is not visible await searchPage.waitForLocatorVisible(searchPage.vectorSearchPage) + + // Verify that onboarding screen is not visible after dismissing it + await searchPage.reload() + + // Verify that onboarding screen is not visible anymore + await searchPage.waitForLocatorNotVisible( + searchPage.onboardingContainer, + ) + await searchPage.waitForLocatorVisible(searchPage.vectorSearchPage) }) test('should dismiss onboarding when clicking on "X" button', async () => { @@ -61,19 +74,28 @@ test.describe('Vector Search - Onboarding', () => { // Click on "X" button await searchPage.onboardingDismissButton.click() + + // Verify that onboarding screen is not visible + await searchPage.waitForLocatorVisible(searchPage.vectorSearchPage) + + // Verify that onboarding screen is not visible after dismissing it + await searchPage.reload() + + // Verify that onboarding screen is not visible anymore + await searchPage.waitForLocatorNotVisible( + searchPage.onboardingContainer, + ) + await searchPage.waitForLocatorVisible(searchPage.vectorSearchPage) }) - test('should not open the onboarding screen when it is already dismissed', async () => { + test('should open the onboarding screen unless it is manuyally dismissed', async () => { // Verify that onboarding screen is visible await searchPage.waitForLocatorVisible(searchPage.onboardingContainer) - // Go to Browser page - await browserPage.navigateToBrowserPage() - - // Navigate back to vector search page - await searchPage.navigateToVectorSearchPage() + // Verify that onboarding screen is visible unless we dismiss it manually + await searchPage.reload() - // Verify that onboarding screen is not visible anymore - await searchPage.waitForLocatorVisible(searchPage.vectorSearchPage) + // Verify that onboarding screen is still visible + await searchPage.waitForLocatorVisible(searchPage.onboardingContainer) }) }) From 29c4d68568d94cb842878a340fd3f9d49739b558 Mon Sep 17 00:00:00 2001 From: Valentin Kirilov Date: Wed, 17 Sep 2025 12:19:22 +0300 Subject: [PATCH 3/3] fix(ui): update the onboarding spacings to match figma re #RI-7479 --- .../onboarding/VectorSearchOnboarding.styles.ts | 6 +++++- .../components/onboarding/VectorSearchOnboarding.tsx | 8 +------- .../components/onboarding/components/Features.styles.ts | 7 ++++--- .../components/onboarding/components/Header.tsx | 1 - 4 files changed, 10 insertions(+), 12 deletions(-) diff --git a/redisinsight/ui/src/pages/vector-search/components/onboarding/VectorSearchOnboarding.styles.ts b/redisinsight/ui/src/pages/vector-search/components/onboarding/VectorSearchOnboarding.styles.ts index f0611776af..bbdf46503d 100644 --- a/redisinsight/ui/src/pages/vector-search/components/onboarding/VectorSearchOnboarding.styles.ts +++ b/redisinsight/ui/src/pages/vector-search/components/onboarding/VectorSearchOnboarding.styles.ts @@ -29,6 +29,10 @@ export const Content = styled(FlexGroup)` export const HeaderContainer = styled(FlexGroup)` z-index: 1; + gap: 8px; + max-width: 508px; + text-align: center; + margin-bottom: 40px; ` export const MagnifierImage = styled.img` @@ -43,5 +47,5 @@ export const MagnifierImage = styled.img` export const StyledActions = styled(FlexGroup)` z-index: 1; - margin-top: ${({ theme }) => theme.core.space.space300}; + margin-top: 56px; // ${({ theme }) => theme.core.space.space300}; ` diff --git a/redisinsight/ui/src/pages/vector-search/components/onboarding/VectorSearchOnboarding.tsx b/redisinsight/ui/src/pages/vector-search/components/onboarding/VectorSearchOnboarding.tsx index 8e494249cf..ab85e2e42f 100644 --- a/redisinsight/ui/src/pages/vector-search/components/onboarding/VectorSearchOnboarding.tsx +++ b/redisinsight/ui/src/pages/vector-search/components/onboarding/VectorSearchOnboarding.tsx @@ -33,13 +33,7 @@ export const VectorSearchOnboarding = () => { /> - +
diff --git a/redisinsight/ui/src/pages/vector-search/components/onboarding/components/Features.styles.ts b/redisinsight/ui/src/pages/vector-search/components/onboarding/components/Features.styles.ts index 0f5623dbbd..dbd8e28708 100644 --- a/redisinsight/ui/src/pages/vector-search/components/onboarding/components/Features.styles.ts +++ b/redisinsight/ui/src/pages/vector-search/components/onboarding/components/Features.styles.ts @@ -10,20 +10,21 @@ export const StyledFeatures = styled.div` max-width: 90rem; margin: 0 auto; z-index: 1; + margin-bottom: 32px; ` export const FeatureCard = styled(FlexGroup)` max-width: 216px; text-align: center; gap: ${({ theme }) => theme.core.space.space100}; - padding: ${({ theme }) => theme.core.space.space150}; + padding: 16px; // ${({ theme }) => theme.core.space.space150}; background-color: ${({ theme }) => theme.semantic.color.background.neutral100}; border: 1px solid ${({ theme }) => theme.semantic.color.border.neutral600}; - border-radius: ${({ theme }) => theme.components.card.borderRadius}; + border-radius: 4px; // ${({ theme }) => theme.components.card.borderRadius}; ` export const FeatureTitleWrapper = styled(Row)` align-items: center; - gap: ${({ theme }) => theme.core.space.space100}; + gap: 4px; // ${({ theme }) => theme.core.space.space100}; ` diff --git a/redisinsight/ui/src/pages/vector-search/components/onboarding/components/Header.tsx b/redisinsight/ui/src/pages/vector-search/components/onboarding/components/Header.tsx index 94223ca829..c7821e9698 100644 --- a/redisinsight/ui/src/pages/vector-search/components/onboarding/components/Header.tsx +++ b/redisinsight/ui/src/pages/vector-search/components/onboarding/components/Header.tsx @@ -8,7 +8,6 @@ const Header: React.FC = () => ( direction="column" justify="center" align="center" - gap="s" grow={false} data-testid="vector-search-onboarding--header" >