[] = [
+ {
+ value: VectorIndexTab.BuildNewIndex,
+ label: ,
+ content: null,
+ disabled: true,
+ },
+ {
+ value: VectorIndexTab.UsePresetIndex,
+ label: 'Use preset index',
+ content: (
+
+ TODO: Add content later
+
+ ),
+ },
+]
+
+export const CreateIndexStepWrapper = (props: Partial) => {
+ const { tabs, defaultValue, ...rest } = props
+
+ return (
+
+ )
+}
diff --git a/redisinsight/ui/src/components/new-index/create-index-step/build-new-index-tab/BuildNewIndexTabTrigger.styles.ts b/redisinsight/ui/src/components/new-index/create-index-step/build-new-index-tab/BuildNewIndexTabTrigger.styles.ts
new file mode 100644
index 0000000000..5715bf56bf
--- /dev/null
+++ b/redisinsight/ui/src/components/new-index/create-index-step/build-new-index-tab/BuildNewIndexTabTrigger.styles.ts
@@ -0,0 +1,7 @@
+import styled from 'styled-components'
+
+export const StyledBuildNewIndexTabTrigger = styled.div`
+ display: flex;
+ align-items: center;
+ gap: ${({ theme }) => theme.core.space.space050};
+`
diff --git a/redisinsight/ui/src/components/new-index/create-index-step/build-new-index-tab/BuildNewIndexTabTrigger.tsx b/redisinsight/ui/src/components/new-index/create-index-step/build-new-index-tab/BuildNewIndexTabTrigger.tsx
new file mode 100644
index 0000000000..4c9eba37e8
--- /dev/null
+++ b/redisinsight/ui/src/components/new-index/create-index-step/build-new-index-tab/BuildNewIndexTabTrigger.tsx
@@ -0,0 +1,9 @@
+import React from 'react'
+import { Badge } from '@redis-ui/components'
+import { StyledBuildNewIndexTabTrigger } from './BuildNewIndexTabTrigger.styles'
+
+export const BuildNewIndexTabTrigger = () => (
+
+ Build new index
+
+)
diff --git a/redisinsight/ui/src/components/new-index/create-index-step/field-box/FieldBox.spec.tsx b/redisinsight/ui/src/components/new-index/create-index-step/field-box/FieldBox.spec.tsx
new file mode 100644
index 0000000000..48aa8d50d8
--- /dev/null
+++ b/redisinsight/ui/src/components/new-index/create-index-step/field-box/FieldBox.spec.tsx
@@ -0,0 +1,84 @@
+import React from 'react'
+import { BoxSelectionGroup } from '@redis-ui/components'
+
+import { FieldTypes } from 'uiSrc/pages/browser/components/create-redisearch-index/constants'
+import { MOCK_VECTOR_SEARCH_BOX } from 'uiSrc/constants/mocks/mock-vector-index-search'
+import { cleanup, fireEvent, render, screen } from 'uiSrc/utils/test-utils'
+
+import { FieldBox, FieldBoxProps } from './FieldBox'
+import { VectorSearchBox } from './types'
+
+const renderFieldBoxComponent = (props?: FieldBoxProps) => {
+ const defaultProps: FieldBoxProps = {
+ box: MOCK_VECTOR_SEARCH_BOX,
+ }
+
+ return render(
+
+
+ ,
+ )
+}
+
+describe('CreateIndexStepWrapper', () => {
+ beforeEach(() => {
+ cleanup()
+ })
+
+ it('should render', () => {
+ const props: FieldBoxProps = {
+ box: {
+ ...MOCK_VECTOR_SEARCH_BOX,
+ value: 'id',
+ label: 'id',
+ text: 'Unique product identifier',
+ tag: FieldTypes.TAG,
+ disabled: false,
+ },
+ }
+
+ const { container } = renderFieldBoxComponent(props)
+
+ expect(container).toBeTruthy()
+
+ // Check if the box is rendered with the correct visual elements
+ const label = screen.getByText(props.box.label!)
+ const description = screen.getByText(props.box.text!)
+ const tag = screen.getByText(props.box.tag.toUpperCase()!)
+ const checkbox = screen.getByRole('checkbox')
+
+ expect(label).toBeInTheDocument()
+ expect(description).toBeInTheDocument()
+ expect(tag).toBeInTheDocument()
+ expect(checkbox).toBeInTheDocument()
+ })
+
+ it('should select the box when clicked', () => {
+ renderFieldBoxComponent()
+
+ const checkbox = screen.getByRole('checkbox')
+ expect(checkbox).not.toBeChecked()
+
+ const box = screen.getByTestId(`field-box-${MOCK_VECTOR_SEARCH_BOX.value}`)
+ fireEvent.click(box)
+
+ expect(checkbox).toBeChecked()
+ })
+
+ it('should not select the box when clicked if disabled', () => {
+ const disabledBox: VectorSearchBox = {
+ ...MOCK_VECTOR_SEARCH_BOX,
+ disabled: true,
+ }
+
+ renderFieldBoxComponent({ box: disabledBox })
+
+ const checkbox = screen.getByRole('checkbox')
+ expect(checkbox).not.toBeChecked()
+
+ const box = screen.getByTestId(`field-box-${disabledBox.value}`)
+ fireEvent.click(box)
+
+ expect(checkbox).not.toBeChecked()
+ })
+})
diff --git a/redisinsight/ui/src/components/new-index/create-index-step/field-box/FieldBox.styles.ts b/redisinsight/ui/src/components/new-index/create-index-step/field-box/FieldBox.styles.ts
new file mode 100644
index 0000000000..5028b0511f
--- /dev/null
+++ b/redisinsight/ui/src/components/new-index/create-index-step/field-box/FieldBox.styles.ts
@@ -0,0 +1,25 @@
+import { BoxSelectionGroup } from '@redis-ui/components'
+import styled from 'styled-components'
+
+export const StyledFieldBox = styled(BoxSelectionGroup.Item.Compose)`
+ display: flex;
+ flex-direction: column;
+ justify-content: space-between;
+ width: 100%;
+ padding: ${({ theme }) => theme.core.space.space100};
+ gap: ${({ theme }) => theme.components.boxSelectionGroup.defaultItem.gap};
+`
+
+export const BoxHeader = styled.div`
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+`
+
+export const BoxHeaderActions = styled.div`
+ display: flex;
+ align-items: center;
+ gap: ${({ theme }) => theme.components.boxSelectionGroup.defaultItem.gap};
+`
+
+export const BoxContent = styled.div``
diff --git a/redisinsight/ui/src/components/new-index/create-index-step/field-box/FieldBox.tsx b/redisinsight/ui/src/components/new-index/create-index-step/field-box/FieldBox.tsx
new file mode 100644
index 0000000000..08c016229e
--- /dev/null
+++ b/redisinsight/ui/src/components/new-index/create-index-step/field-box/FieldBox.tsx
@@ -0,0 +1,53 @@
+import React from 'react'
+import {
+ BoxSelectionGroup,
+ BoxSelectionGroupItemComposeProps,
+ Checkbox,
+} from '@redis-ui/components'
+
+import { EditIcon } from 'uiSrc/components/base/icons'
+import { IconButton } from 'uiSrc/components/base/forms/buttons/IconButton'
+import { Text } from 'uiSrc/components/base/text'
+
+import {
+ BoxContent,
+ BoxHeader,
+ BoxHeaderActions,
+ StyledFieldBox,
+} from './FieldBox.styles'
+import { FieldTag } from './FieldTag'
+import { VectorSearchBox } from './types'
+
+export interface FieldBoxProps extends BoxSelectionGroupItemComposeProps {
+ box: VectorSearchBox
+}
+
+export const FieldBox = ({ box, ...rest }: FieldBoxProps) => {
+ const { label, text, tag, disabled } = box
+
+ return (
+
+
+
+ {(props) => }
+
+
+
+
+
+
+
+
+
+ {label}
+
+
+ {text && (
+
+ {text}
+
+ )}
+
+
+ )
+}
diff --git a/redisinsight/ui/src/components/new-index/create-index-step/field-box/FieldTag.tsx b/redisinsight/ui/src/components/new-index/create-index-step/field-box/FieldTag.tsx
new file mode 100644
index 0000000000..b35f48ad8c
--- /dev/null
+++ b/redisinsight/ui/src/components/new-index/create-index-step/field-box/FieldTag.tsx
@@ -0,0 +1,15 @@
+import React from 'react'
+import { Badge } from '@redis-ui/components'
+import {
+ FIELD_TYPE_OPTIONS,
+ FieldTypes,
+} from 'uiSrc/pages/browser/components/create-redisearch-index/constants'
+
+// TODO: Add colors mapping for tags when @redis-ui/components v38.6.0 is released
+export const FieldTag = ({ tag }: { tag: FieldTypes }) => {
+ const tagLabel = FIELD_TYPE_OPTIONS.find(
+ (option) => option.value === tag,
+ )?.text
+
+ return tagLabel ? : null
+}
diff --git a/redisinsight/ui/src/components/new-index/create-index-step/field-box/types.ts b/redisinsight/ui/src/components/new-index/create-index-step/field-box/types.ts
new file mode 100644
index 0000000000..db9a8111ad
--- /dev/null
+++ b/redisinsight/ui/src/components/new-index/create-index-step/field-box/types.ts
@@ -0,0 +1,7 @@
+import { BoxSelectionGroupBox } from '@redis-ui/components'
+import { FieldTypes } from 'uiSrc/pages/browser/components/create-redisearch-index/constants'
+
+export interface VectorSearchBox extends BoxSelectionGroupBox {
+ text: string
+ tag: FieldTypes
+}
diff --git a/redisinsight/ui/src/components/new-index/create-index-step/field-boxes-group/FieldBoxesGroup.spec.tsx b/redisinsight/ui/src/components/new-index/create-index-step/field-boxes-group/FieldBoxesGroup.spec.tsx
new file mode 100644
index 0000000000..20671839e6
--- /dev/null
+++ b/redisinsight/ui/src/components/new-index/create-index-step/field-boxes-group/FieldBoxesGroup.spec.tsx
@@ -0,0 +1,55 @@
+import React from 'react'
+
+import { fireEvent, render, screen } from 'uiSrc/utils/test-utils'
+import { MOCK_VECTOR_SEARCH_BOX } from 'uiSrc/constants/mocks/mock-vector-index-search'
+import { FieldBoxesGroup, FieldBoxesGroupProps } from './FieldBoxesGroup'
+
+const renderFieldBoxesGroupComponent = (
+ props?: Partial,
+) => {
+ const defaultProps: FieldBoxesGroupProps = {
+ boxes: [MOCK_VECTOR_SEARCH_BOX],
+ value: [MOCK_VECTOR_SEARCH_BOX.value],
+ onChange: jest.fn(),
+ }
+
+ return render()
+}
+
+describe('FieldBoxesGroup', () => {
+ it('should render', () => {
+ const { container } = renderFieldBoxesGroupComponent()
+
+ expect(container).toBeTruthy()
+
+ const fieldBoxesGroup = screen.getByTestId('field-boxes-group')
+ expect(fieldBoxesGroup).toBeInTheDocument()
+
+ const fieldBoxes = screen.getAllByTestId(/field-box-/)
+ expect(fieldBoxes).toHaveLength(1)
+ })
+
+ it('should call onChange when clicking on a box to select it', () => {
+ const onChangeMock = jest.fn()
+ const value: string[] = []
+
+ renderFieldBoxesGroupComponent({ value, onChange: onChangeMock })
+
+ const box = screen.getByTestId(`field-box-${MOCK_VECTOR_SEARCH_BOX.value}`)
+
+ fireEvent.click(box)
+ expect(onChangeMock).toHaveBeenCalledWith([MOCK_VECTOR_SEARCH_BOX.value])
+ })
+
+ it('should call onChange when clicking on a box to deselect it', () => {
+ const onChangeMock = jest.fn()
+ const value: string[] = [MOCK_VECTOR_SEARCH_BOX.value]
+
+ renderFieldBoxesGroupComponent({ value, onChange: onChangeMock })
+
+ const box = screen.getByTestId(`field-box-${MOCK_VECTOR_SEARCH_BOX.value}`)
+
+ fireEvent.click(box)
+ expect(onChangeMock).toHaveBeenCalledWith([])
+ })
+})
diff --git a/redisinsight/ui/src/components/new-index/create-index-step/field-boxes-group/FieldBoxesGroup.styles.ts b/redisinsight/ui/src/components/new-index/create-index-step/field-boxes-group/FieldBoxesGroup.styles.ts
new file mode 100644
index 0000000000..b535d1369c
--- /dev/null
+++ b/redisinsight/ui/src/components/new-index/create-index-step/field-boxes-group/FieldBoxesGroup.styles.ts
@@ -0,0 +1,10 @@
+import styled from 'styled-components'
+import { MultiBoxSelectionGroup } from '@redis-ui/components'
+
+export const StyledFieldBoxesGroup = styled(MultiBoxSelectionGroup.Compose)`
+ display: grid;
+ grid-template-columns: repeat(auto-fit, minmax(210px, 1fr));
+ gap: ${({ theme }) => theme.core.space.space150};
+ align-items: flex-start;
+ align-self: stretch;
+`
diff --git a/redisinsight/ui/src/components/new-index/create-index-step/field-boxes-group/FieldBoxesGroup.tsx b/redisinsight/ui/src/components/new-index/create-index-step/field-boxes-group/FieldBoxesGroup.tsx
new file mode 100644
index 0000000000..75305c70cb
--- /dev/null
+++ b/redisinsight/ui/src/components/new-index/create-index-step/field-boxes-group/FieldBoxesGroup.tsx
@@ -0,0 +1,29 @@
+import React from 'react'
+import { MultiBoxSelectionGroupProps } from '@redis-ui/components'
+import { StyledFieldBoxesGroup } from './FieldBoxesGroup.styles'
+import { VectorSearchBox } from '../field-box/types'
+import { FieldBox } from '../field-box/FieldBox'
+
+export interface FieldBoxesGroupProps extends MultiBoxSelectionGroupProps {
+ boxes: VectorSearchBox[]
+ value: string[]
+ onChange: (value: string[] | undefined) => void
+}
+
+export const FieldBoxesGroup = ({
+ boxes,
+ value,
+ onChange,
+ ...rest
+}: FieldBoxesGroupProps) => (
+
+ {boxes.map((box) => (
+
+ ))}
+
+)
diff --git a/redisinsight/ui/src/components/new-index/create-index-step/index.ts b/redisinsight/ui/src/components/new-index/create-index-step/index.ts
new file mode 100644
index 0000000000..b342bcebad
--- /dev/null
+++ b/redisinsight/ui/src/components/new-index/create-index-step/index.ts
@@ -0,0 +1,3 @@
+import { CreateIndexStepWrapper } from './CreateIndexStepWrapper'
+
+export default CreateIndexStepWrapper
diff --git a/redisinsight/ui/src/constants/mocks/mock-vector-index-search.ts b/redisinsight/ui/src/constants/mocks/mock-vector-index-search.ts
new file mode 100644
index 0000000000..994eff57c9
--- /dev/null
+++ b/redisinsight/ui/src/constants/mocks/mock-vector-index-search.ts
@@ -0,0 +1,12 @@
+import { VectorSearchBox } from 'uiSrc/components/new-index/create-index-step/field-box/types'
+import { FieldTypes } from 'uiSrc/pages/browser/components/create-redisearch-index/constants'
+
+// TODO: Maybe transform this to a factory function, so it can be reused more easily
+// TODO: Maybe make the values more dynamic with faker, so we can test more cases
+export const MOCK_VECTOR_SEARCH_BOX: VectorSearchBox = {
+ value: 'field_mock',
+ label: 'Field Label Mock',
+ text: 'Field description mock',
+ tag: FieldTypes.TEXT,
+ disabled: false,
+}