-
Notifications
You must be signed in to change notification settings - Fork 384
[RI-7194] Add "Create vector search" wizard #4718
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -15,6 +15,7 @@ export interface IRoute { | |
|
||
export enum PageNames { | ||
workbench = 'workbench', | ||
vectorSearch = 'vector-search', | ||
browser = 'browser', | ||
search = 'search', | ||
slowLog = 'slowlog', | ||
|
@@ -49,6 +50,8 @@ export const Pages = { | |
sentinelDatabases: `${sentinel}/databases`, | ||
sentinelDatabasesResult: `${sentinel}/databases-result`, | ||
browser: (instanceId: string) => `/${instanceId}/${PageNames.browser}`, | ||
vectorSearch: (instanceId: string) => | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why not just There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. because that's the name of the epic and the target branch |
||
`/${instanceId}/${PageNames.vectorSearch}`, | ||
workbench: (instanceId: string) => `/${instanceId}/${PageNames.workbench}`, | ||
search: (instanceId: string) => `/${instanceId}/${PageNames.search}`, | ||
pubSub: (instanceId: string) => `/${instanceId}/${PageNames.pubSub}`, | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
import React from 'react' | ||
|
||
import { VectorSearchCreateIndex } from './create-index/VectorSearchCreateIndex' | ||
import { VectorSearchQuery } from './query/VectorSearchQuery' | ||
|
||
export const VectorSearchPage = () => { | ||
const hasIndexes = false | ||
|
||
if (!hasIndexes) { | ||
return <VectorSearchCreateIndex /> | ||
} | ||
Check warning on line 11 in redisinsight/ui/src/pages/vector-search/VectorSearchPage.tsx
|
||
|
||
// TODO: QueryScreen | ||
|
||
return <VectorSearchQuery /> | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,98 @@ | ||
import React, { useState } from 'react' | ||
import { useParams } from 'react-router-dom' | ||
|
||
import { Stepper } from '@redis-ui/components' | ||
import { Title } from 'uiSrc/components/base/text' | ||
import { Button, SecondaryButton } from 'uiSrc/components/base/forms/buttons' | ||
import { ChevronLeftIcon } from 'uiSrc/components/base/icons' | ||
|
||
import { stepContents } from './steps' | ||
import { | ||
CreateIndexContent, | ||
CreateIndexFooter, | ||
CreateIndexHeader, | ||
CreateIndexWrapper, | ||
} from './styles' | ||
import { | ||
CreateSearchIndexParameters, | ||
SampleDataType, | ||
SearchIndexType, | ||
} from './types' | ||
|
||
const stepNextButtonTexts = [ | ||
'Proceed to adding data', | ||
'Proceed to index', | ||
'Create index', | ||
] | ||
|
||
type VectorSearchCreateIndexProps = { | ||
initialStep?: number | ||
} | ||
|
||
export const VectorSearchCreateIndex = ({ | ||
initialStep = 1, | ||
}: VectorSearchCreateIndexProps) => { | ||
const { instanceId } = useParams<{ instanceId: string }>() | ||
const [step, setStep] = useState(initialStep) | ||
const [createSearchIndexParameters, setCreateSearchIndexParameters] = | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Tip: It's ok for now, since it's the first PR in a series, so I'll leave a note only to think about it. I like the idea you went for a state variable to control this (instead of Redux), but we'll need to prop drill it to every component, in order to access some useful information. Instead of deep prop drilling, we may use React Context, and let it be a "central state storage" for the family of components related to the Vector Search setup. But we may change this in the next PRs, once we have the other components in place and more vision on the data model itself. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. yes, context will be the way to go if deep sharing of state is needed |
||
useState<CreateSearchIndexParameters>({ | ||
instanceId, | ||
searchIndexType: SearchIndexType.REDIS_QUERY_ENGINE, | ||
sampleDataType: SampleDataType.PRESET_DATA, | ||
dataContent: '', | ||
usePresetVectorIndex: false, | ||
presetVectorIndexName: '', | ||
tags: [], | ||
}) | ||
|
||
const setParameters = (params: Partial<CreateSearchIndexParameters>) => { | ||
setCreateSearchIndexParameters((prev) => ({ ...prev, ...params })) | ||
Check warning on line 49 in redisinsight/ui/src/pages/vector-search/create-index/VectorSearchCreateIndex.tsx
|
||
} | ||
const showBackButton = step > initialStep | ||
const StepContent = stepContents[step] | ||
const onNextClick = () => { | ||
const isFinalStep = step === stepContents.length - 1 | ||
if (isFinalStep) { | ||
alert( | ||
`TODO: trigger index creation for params: ${JSON.stringify(createSearchIndexParameters)}`, | ||
) | ||
return | ||
} | ||
Check warning on line 60 in redisinsight/ui/src/pages/vector-search/create-index/VectorSearchCreateIndex.tsx
|
||
|
||
setStep(step + 1) | ||
} | ||
const onBackClick = () => { | ||
setStep(step - 1) | ||
} | ||
|
||
return ( | ||
<CreateIndexWrapper direction="column" justify="between"> | ||
<CreateIndexHeader direction="row"> | ||
<Title size="M" data-testid="title"> | ||
New vector search | ||
</Title> | ||
<Stepper currentStep={step} title="test"> | ||
<Stepper.Step>Select a database</Stepper.Step> | ||
<Stepper.Step>Adding data</Stepper.Step> | ||
<Stepper.Step>Create Index</Stepper.Step> | ||
</Stepper> | ||
</CreateIndexHeader> | ||
<CreateIndexContent direction="column" grow={1}> | ||
<StepContent setParameters={setParameters} /> | ||
</CreateIndexContent> | ||
<CreateIndexFooter direction="row"> | ||
{showBackButton && ( | ||
<SecondaryButton | ||
iconSide="left" | ||
icon={ChevronLeftIcon} | ||
onClick={onBackClick} | ||
> | ||
Back | ||
</SecondaryButton> | ||
)} | ||
<div /> | ||
<Button onClick={onNextClick}>{stepNextButtonTexts[step]}</Button> | ||
</CreateIndexFooter> | ||
</CreateIndexWrapper> | ||
) | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
import React from 'react' | ||
|
||
import { FlexItem } from 'uiSrc/components/base/layout/flex' | ||
import { Text } from 'uiSrc/components/base/text' | ||
import { IStepComponent } from '../types' | ||
|
||
export const AddDataStep: IStepComponent = ({ setParameters }) => ( | ||
<> | ||
<FlexItem direction="column" $gap="m"> | ||
<FlexItem direction="row" $gap="m"> | ||
<div>Box1</div> | ||
<div>Box2</div> | ||
</FlexItem> | ||
</FlexItem> | ||
<FlexItem direction="column" $gap="m"> | ||
<Text>Select sample dataset</Text> | ||
</FlexItem> | ||
<FlexItem direction="column" $gap="m"> | ||
<Text>Data content</Text> | ||
<FlexItem direction="row" $gap="m"> | ||
<div>Box1</div> | ||
<div>Box2</div> | ||
<div>Box3</div> | ||
</FlexItem> | ||
</FlexItem> | ||
</> | ||
) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
import React from 'react' | ||
|
||
import { FlexItem } from 'uiSrc/components/base/layout/flex' | ||
import { Text } from 'uiSrc/components/base/text' | ||
import { IStepComponent } from '../types' | ||
|
||
export const CreateIndexStep: IStepComponent = ({ setParameters }) => ( | ||
<> | ||
<FlexItem direction="column" $gap="m"> | ||
<Text>Vector index</Text> | ||
<Text size="S"> | ||
Indexes tell Redis how to search your data. Creating an index enables | ||
fast, accurate retrieval across your dataset. | ||
</Text> | ||
</FlexItem> | ||
<FlexItem direction="column" $gap="m"> | ||
<Text>Index name</Text> | ||
<Text>Bikes</Text> | ||
</FlexItem> | ||
<FlexItem direction="column" $gap="m"> | ||
<FlexItem direction="row" $gap="m"> | ||
<div>Box1</div> | ||
<div>Box2</div> | ||
<div>Box3</div> | ||
</FlexItem> | ||
</FlexItem> | ||
</> | ||
) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
import { IStepComponent } from '../types' | ||
|
||
export const SelectDatabaseStep: IStepComponent = () => null | ||
Check warning on line 3 in redisinsight/ui/src/pages/vector-search/create-index/steps/SelectDatabaseStep.tsx
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
import { SelectDatabaseStep } from './SelectDatabaseStep' | ||
import { AddDataStep } from './AddDataStep' | ||
import { CreateIndexStep } from './CreateIndexStep' | ||
|
||
export const stepContents = [SelectDatabaseStep, AddDataStep, CreateIndexStep] |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
import styled, { css } from 'styled-components' | ||
import { useTheme } from '@redis-ui/styles' | ||
import { FlexGroup, FlexItem } from 'uiSrc/components/base/layout/flex' | ||
|
||
export const CreateIndexWrapper = styled(FlexGroup)` | ||
valkirilov marked this conversation as resolved.
Show resolved
Hide resolved
|
||
${() => css` | ||
margin-top: ${useTheme().core.space.space250}; | ||
margin-bottom: ${useTheme().core.space.space250}; | ||
background-color: ${useTheme().semantic.color.background.neutral100}; | ||
border-radius: 8px; | ||
`} | ||
|
||
width: 95%; | ||
margin-left: auto; | ||
margin-right: auto; | ||
` | ||
|
||
export const CreateIndexHeader = styled(FlexItem)` | ||
${() => css` | ||
padding: ${useTheme().core.space.space300}; | ||
border-color: ${useTheme().color.dusk200}; | ||
`} | ||
|
||
justify-content: space-between; | ||
border: 1px solid; | ||
border-top-left-radius: 8px; | ||
border-top-right-radius: 8px; | ||
` | ||
|
||
export const CreateIndexContent = styled(FlexItem)` | ||
${() => css` | ||
gap: ${useTheme().core.space.space550}; | ||
padding: ${useTheme().core.space.space300}; | ||
border-color: ${useTheme().color.dusk200}; | ||
`} | ||
|
||
border-left: 1px solid; | ||
border-right: 1px solid; | ||
` | ||
|
||
export const CreateIndexFooter = styled(FlexItem)` | ||
${() => css` | ||
padding: ${useTheme().core.space.space300}; | ||
border-color: ${useTheme().color.dusk200}; | ||
`} | ||
|
||
border: 1px solid; | ||
justify-content: space-between; | ||
border-bottom-left-radius: 8px; | ||
border-bottom-right-radius: 8px; | ||
` |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
export enum SearchIndexType { | ||
REDIS_QUERY_ENGINE = 'redis_query_engine', | ||
VECTOR_SET = 'vector_set', | ||
} | ||
|
||
export enum SampleDataType { | ||
PRESET_DATA = 'preset_data', | ||
CUSTOM_DATA = 'custom_data', | ||
} | ||
|
||
export type CreateSearchIndexParameters = { | ||
// Select a database step | ||
instanceId: string | ||
|
||
// Adding data step | ||
searchIndexType: SearchIndexType | ||
sampleDataType: SampleDataType | ||
dataContent: string | ||
|
||
// Create index step | ||
usePresetVectorIndex: boolean | ||
presetVectorIndexName: string | ||
tags: string[] | ||
} | ||
|
||
export type StepComponentProps = { | ||
setParameters: (params: Partial<CreateSearchIndexParameters>) => void | ||
} | ||
|
||
export interface IStepComponent { | ||
(props: StepComponentProps): JSX.Element | null | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
import { VectorSearchPage } from './VectorSearchPage' | ||
|
||
export { VectorSearchPage } | ||
export default VectorSearchPage |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
import React from 'react' | ||
|
||
export const VectorSearchQuery = () => { | ||
// TODO: implement this component | ||
// https://www.figma.com/design/oO2eYRuuLmfzUYLkvCkFhM/Search-page?node-id=645-37412&t=TSwcttCYa4Ld9WzC-4 | ||
; | ||
return <h4>TODO</h4> | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
turned off so we can we can add theme related css inside styled components without an extra wrapper function