Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
281 changes: 280 additions & 1 deletion redisinsight/ui/src/i18n/locales/bg.json

Large diffs are not rendered by default.

281 changes: 280 additions & 1 deletion redisinsight/ui/src/i18n/locales/en.json

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -30,26 +30,26 @@ export const FIELD_TYPE_OPTIONS = [
{
text: 'TEXT',
value: FieldTypes.TEXT,
description: 'Use TEXT for full-text search and indexing free-form text.',
descriptionKey: 'vectorSearch.fieldType.desc.text',
},
{
text: 'TAG',
value: FieldTypes.TAG,
description: 'Use TAG for filtering by exact match values.',
descriptionKey: 'vectorSearch.fieldType.desc.tag',
},
{
text: 'NUMERIC',
value: FieldTypes.NUMERIC,
description: 'Use NUMERIC for storing and querying numbers.',
descriptionKey: 'vectorSearch.fieldType.desc.numeric',
},
{
text: 'GEO',
value: FieldTypes.GEO,
description: 'Use GEO for geographic coordinates (latitude and longitude).',
descriptionKey: 'vectorSearch.fieldType.desc.geo',
},
{
text: 'VECTOR',
value: FieldTypes.VECTOR,
description: 'Use VECTOR for semantic search using vector embeddings.',
descriptionKey: 'vectorSearch.fieldType.desc.vector',
},
]
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import React, { useMemo } from 'react'
import { merge } from 'lodash'

import { useTranslation } from 'uiSrc/i18n'
import { MonacoLanguage } from 'uiSrc/constants'
import { defaultMonacoOptions } from 'uiSrc/constants/monaco/monaco'
import { CopyButton } from 'uiSrc/components/copy-button'
Expand All @@ -18,6 +19,7 @@ export const CommandView = ({
onCopy,
showLineNumbers = false,
}: CommandViewProps) => {
const { t } = useTranslation()
const editorOptions = useMemo(
() =>
merge({}, defaultMonacoOptions, COMMAND_VIEW_EDITOR_OPTIONS, {
Expand All @@ -37,10 +39,10 @@ export const CommandView = ({
<S.CopyButtonWrapper>
<CopyButton
copy={command}
successLabel="Copied"
successLabel={t('vectorSearch.commandView.copied')}
onCopy={onCopy}
data-testid={`${dataTestId ?? 'command-view'}--copy-button`}
aria-label="Copy command"
aria-label={t('vectorSearch.commandView.copyAria')}
/>
</S.CopyButtonWrapper>
</S.EditorWrapper>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import React from 'react'

import i18n, { Trans } from 'uiSrc/i18n'
import { Text } from 'uiSrc/components/base/text'
import { IndexingTypeContent } from '../field-type-list'

Expand Down Expand Up @@ -28,70 +29,70 @@ export interface StepContent {
body: React.ReactNode
}

export const STEP_CONTENT: Record<CreateIndexOnboardingStep, StepContent> = {
// Built at call time (not module scope) so titles/bodies resolve in the active
// language when the popover renders.
export const getStepContent = (): Record<
CreateIndexOnboardingStep,
StepContent
> => ({
[CreateIndexOnboardingStep.DefineIndex]: {
title: 'Review and adjust the indexing schema',
title: i18n.t('vectorSearch.onboarding.defineIndex.title'),
body: (
<>
<Text size="m" color="secondary">
An index defines how Redis searches and queries your data. The schema
controls which fields are indexed, their types, and other
configuration options.
{i18n.t('vectorSearch.onboarding.defineIndex.body1')}
</Text>
<Text size="m" color="secondary">
Review the suggested index name. You{'\u2019'}ll use it when building
queries.
{i18n.t('vectorSearch.onboarding.defineIndex.body2')}
</Text>
<Text size="m" color="secondary">
Tip: Index only fields you plan to search or filter on.
{i18n.t('vectorSearch.onboarding.defineIndex.body3')}
</Text>
</>
),
},
[CreateIndexOnboardingStep.IndexPrefix]: {
title: 'Index prefix',
title: i18n.t('vectorSearch.onboarding.indexPrefix.title'),
body: (
<>
<Text size="m" color="secondary">
Controls which keys are included in the index. All keys starting with
this prefix will be indexed.
{i18n.t('vectorSearch.onboarding.indexPrefix.body1')}
</Text>
<Text size="m" color="secondary">
Example: <strong>bike:</strong> will index <strong>bike:1</strong>,{' '}
<strong>bike:road:3</strong>.
<Trans
i18nKey="vectorSearch.onboarding.indexPrefix.body2"
components={{ bold: <strong /> }}
/>
</Text>
</>
),
},
[CreateIndexOnboardingStep.FieldName]: {
title: 'Field name',
title: i18n.t('vectorSearch.onboarding.fieldName.title'),
body: (
<Text size="m" color="secondary">
Represents a searchable attribute in your data. Only selected fields
will be searchable.
{i18n.t('vectorSearch.onboarding.fieldName.body')}
</Text>
),
},
[CreateIndexOnboardingStep.SampleValue]: {
title: 'Sample value',
title: i18n.t('vectorSearch.onboarding.sampleValue.title'),
body: (
<Text size="m" color="secondary">
A sample value from the data to be indexed. Use it to verify the field
type and indexing choice.
{i18n.t('vectorSearch.onboarding.sampleValue.body')}
</Text>
),
},
[CreateIndexOnboardingStep.IndexingType]: {
title: 'Indexing type & options',
title: i18n.t('vectorSearch.onboarding.indexingType.title'),
body: <IndexingTypeContent />,
},
[CreateIndexOnboardingStep.CommandView]: {
title: 'Create index command',
title: i18n.t('vectorSearch.onboarding.commandView.title'),
body: (
<Text size="m" color="secondary">
This is the FT.CREATE command Redis will run. Once executed, your data
becomes searchable.
{i18n.t('vectorSearch.onboarding.commandView.body')}
</Text>
),
},
}
})
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import React from 'react'

import { useTranslation } from 'uiSrc/i18n'
import { AnchorPosition, RiPopover } from 'uiSrc/components/base'
import {
Button,
Expand All @@ -15,7 +16,7 @@ import { useCreateIndexOnboarding } from '../../context/create-index-onboarding'
import {
CreateIndexOnboardingStep,
ONBOARDING_STEPS,
STEP_CONTENT,
getStepContent,
TOTAL_STEPS,
} from './CreateIndexOnboarding.constants'
import * as S from './CreateIndexOnboardingPopover.styles'
Expand All @@ -31,6 +32,7 @@ export const CreateIndexOnboardingPopover = ({
children,
anchorPosition = 'rightCenter',
}: CreateIndexOnboardingPopoverProps) => {
const { t } = useTranslation()
const { currentStep, isActive, nextStep, prevStep, skipOnboarding } =
useCreateIndexOnboarding()

Expand All @@ -40,7 +42,7 @@ export const CreateIndexOnboardingPopover = ({
return <>{children}</>
}

const content = STEP_CONTENT[step]
const content = getStepContent()[step]

if (!content) {
return <>{children}</>
Expand All @@ -54,7 +56,9 @@ export const CreateIndexOnboardingPopover = ({
const stepNumber = stepIndex + 1

const handleAction = isLastStep ? skipOnboarding : nextStep
const actionLabel = isLastStep ? 'Got it' : 'Next'
const actionLabel = isLastStep
? t('vectorSearch.onboarding.gotIt')
: t('vectorSearch.onboarding.next')

return (
<div onClick={(e) => e.stopPropagation()} role="presentation">
Expand All @@ -75,7 +79,7 @@ export const CreateIndexOnboardingPopover = ({
icon={CancelSlimIcon}
onClick={skipOnboarding}
size="S"
aria-label="close-onboarding"
aria-label={t('vectorSearch.onboarding.close')}
data-testid="create-index-onboarding-close"
/>
) : (
Expand All @@ -84,7 +88,7 @@ export const CreateIndexOnboardingPopover = ({
data-testid="create-index-onboarding-skip"
>
<Text size="m" color="primary">
Skip tour
{t('vectorSearch.onboarding.skipTour')}
</Text>
</EmptyButton>
)}
Expand All @@ -99,7 +103,10 @@ export const CreateIndexOnboardingPopover = ({
<Row justify="between" align="center">
<S.StepCounter>
<Text size="s" color="secondary">
{stepNumber}/{TOTAL_STEPS}
{t('vectorSearch.onboarding.stepCounter', {
current: stepNumber,
total: TOTAL_STEPS,
})}
</Text>
</S.StepCounter>

Expand All @@ -110,7 +117,7 @@ export const CreateIndexOnboardingPopover = ({
onClick={prevStep}
data-testid="create-index-onboarding-back"
>
Back
{t('vectorSearch.onboarding.back')}
</SecondaryButton>
)}
<Button
Expand Down
Original file line number Diff line number Diff line change
@@ -1,42 +1,49 @@
import React from 'react'

import { useTranslation } from 'uiSrc/i18n'
import { Text } from 'uiSrc/components/base/text'
import { Col } from 'uiSrc/components/base/layout/flex'
import { FieldTag } from 'uiSrc/pages/vector-search/components/field-tag/FieldTag'
import { FieldTypes } from 'uiSrc/pages/browser/components/create-redisearch-index/constants'

import * as S from './FieldTypeList.styles'

const FIELD_TYPE_DESCRIPTIONS: { type: FieldTypes; description: string }[] = [
const FIELD_TYPE_DESCRIPTION_KEYS: {
type: FieldTypes
descriptionKey: string
}[] = [
{ type: FieldTypes.TEXT, descriptionKey: 'vectorSearch.fieldType.list.text' },
{ type: FieldTypes.TAG, descriptionKey: 'vectorSearch.fieldType.list.tag' },
{
type: FieldTypes.TEXT,
description: 'Full-text search and relevance scoring',
type: FieldTypes.NUMERIC,
descriptionKey: 'vectorSearch.fieldType.list.numeric',
},
{ type: FieldTypes.TAG, description: 'Exact matching and filtering' },
{ type: FieldTypes.NUMERIC, description: 'Range queries and sorting' },
{ type: FieldTypes.GEO, descriptionKey: 'vectorSearch.fieldType.list.geo' },
{
type: FieldTypes.GEO,
description: 'Geographic distance and radius queries',
type: FieldTypes.VECTOR,
descriptionKey: 'vectorSearch.fieldType.list.vector',
},
{ type: FieldTypes.VECTOR, description: 'Similarity and semantic search' },
]

export const IndexingTypeContent = () => (
<Col gap="m" data-testid="create-index-onboarding-indexing-types">
<Text size="m" color="secondary">
Defines how Redis searches this field and how it behaves at query time.
Available indexing types:
</Text>
export const IndexingTypeContent = () => {
const { t } = useTranslation()

{FIELD_TYPE_DESCRIPTIONS.map(({ type, description }) => (
<S.FieldTypeRow key={type} gap="s">
<FieldTag tag={type} />
<Text>{description}</Text>
</S.FieldTypeRow>
))}
return (
<Col gap="m" data-testid="create-index-onboarding-indexing-types">
<Text size="m" color="secondary">
{t('vectorSearch.fieldType.list.intro')}
</Text>

<Text size="m" color="secondary">
Optional settings may affect performance, storage, or ranking.
</Text>
</Col>
)
{FIELD_TYPE_DESCRIPTION_KEYS.map(({ type, descriptionKey }) => (
<S.FieldTypeRow key={type} gap="s">
<FieldTag tag={type} />
<Text>{t(descriptionKey as never)}</Text>
</S.FieldTypeRow>
))}

<Text size="m" color="secondary">
{t('vectorSearch.fieldType.list.optionalSettings')}
</Text>
</Col>
)
}
Loading
Loading