diff --git a/redisinsight/ui/src/pages/rdi/pipeline-management/components/dry-run-job-transformations/DryRunJobTransformations.tsx b/redisinsight/ui/src/pages/rdi/pipeline-management/components/dry-run-job-transformations/DryRunJobTransformations.tsx
index bbe23cb55f..3b503bea3c 100644
--- a/redisinsight/ui/src/pages/rdi/pipeline-management/components/dry-run-job-transformations/DryRunJobTransformations.tsx
+++ b/redisinsight/ui/src/pages/rdi/pipeline-management/components/dry-run-job-transformations/DryRunJobTransformations.tsx
@@ -3,11 +3,10 @@ import { useAppSelector } from 'uiSrc/slices/hooks'
import { rdiDryRunJobSelector } from 'uiSrc/slices/rdi/dryRun'
import MonacoJson from 'uiSrc/components/monaco-editor/components/monaco-json'
-
-const NO_TRANSFORMATION_MESSAGE =
- 'No transformation results provided by the server.'
+import { useTranslation } from 'uiSrc/i18n'
const DryRunJobTransformations = () => {
+ const { t } = useTranslation()
const { results } = useAppSelector(rdiDryRunJobSelector)
const [transformations, setTransformations] = useState('')
@@ -17,13 +16,15 @@ const DryRunJobTransformations = () => {
return
}
+ const noTransformationMessage = t('rdi.pipeline.dryRun.noTransformation')
+
try {
const transformations = JSON.stringify(results?.transformation, null, 2)
- setTransformations(transformations || NO_TRANSFORMATION_MESSAGE)
+ setTransformations(transformations || noTransformationMessage)
} catch (e) {
- setTransformations(NO_TRANSFORMATION_MESSAGE)
+ setTransformations(noTransformationMessage)
}
- }, [results])
+ }, [results, t])
return (
<>
diff --git a/redisinsight/ui/src/pages/rdi/pipeline-management/components/jobs-panel/Panel.tsx b/redisinsight/ui/src/pages/rdi/pipeline-management/components/jobs-panel/Panel.tsx
index 1a8c1ec07f..50e9d56ba8 100644
--- a/redisinsight/ui/src/pages/rdi/pipeline-management/components/jobs-panel/Panel.tsx
+++ b/redisinsight/ui/src/pages/rdi/pipeline-management/components/jobs-panel/Panel.tsx
@@ -36,6 +36,7 @@ import {
} from 'uiSrc/components/base/forms/select/RiSelect'
import { DryRunPanelContainer } from 'uiSrc/pages/rdi/pipeline-management/components/jobs-panel/styles'
import { Button, TextButton } from '@redis-ui/components'
+import { Trans, useTranslation } from 'uiSrc/i18n'
export interface Props {
job: string
@@ -55,6 +56,7 @@ const getTargetOption = (value: string) => {
}
const DryRunJobPanel = (props: Props) => {
+ const { t } = useTranslation()
const { job, name, onClose } = props
const { loading: isDryRunning, results } =
useAppSelector(rdiDryRunJobSelector)
@@ -129,7 +131,11 @@ const DryRunJobPanel = (props: Props) => {
createAxiosError({
message: (
<>
-
{`${upperFirst(name)} has an invalid structure.`}
+
+ {t('rdi.pipeline.invalidStructure', {
+ name: upperFirst(name),
+ })}
+
{msg}
>
),
@@ -159,15 +165,15 @@ const DryRunJobPanel = (props: Props) => {
- Displays the results of the transformations you defined. The data
- is presented in JSON format.
-
- No data is written to the target database.
+ }}
+ />
}
data-testid="transformation-output-tooltip"
>
- Transformation output
+ {t('rdi.pipeline.dryRun.transformationOutput')}
),
content: null,
@@ -178,15 +184,15 @@ const DryRunJobPanel = (props: Props) => {
- Displays the list of Redis commands that will be generated based
- on your job details.
-
- No data is written to the target database.
+ }}
+ />
}
data-testid="job-output-tooltip"
>
- Job output
+ {t('rdi.pipeline.dryRun.jobOutput')}
),
content: null,
@@ -209,32 +215,32 @@ const DryRunJobPanel = (props: Props) => {
- Test transformation logic
+ {t('rdi.pipeline.dryRun.title')}
- Add input data to test the transformation logic.
+ {t('rdi.pipeline.dryRun.inputHelp')}
{/* Input section */}
- Input
+ {t('rdi.pipeline.dryRun.inputTitle')}
{
{
data-testid="dry-run-btn"
>
- Dry run
+ {t('rdi.pipeline.dryRun.runButton')}
diff --git a/redisinsight/ui/src/pages/rdi/pipeline-management/components/navigation/Navigation.tsx b/redisinsight/ui/src/pages/rdi/pipeline-management/components/navigation/Navigation.tsx
index 2b36913086..d56f4b05ca 100644
--- a/redisinsight/ui/src/pages/rdi/pipeline-management/components/navigation/Navigation.tsx
+++ b/redisinsight/ui/src/pages/rdi/pipeline-management/components/navigation/Navigation.tsx
@@ -9,6 +9,7 @@ import { Col } from 'uiSrc/components/base/layout/flex'
import { LoadingContent } from 'uiSrc/components/base'
import { RdiPipelineTabs } from 'uiSrc/slices/interfaces/rdi'
import { rdiPipelineSelector } from 'uiSrc/slices/rdi/pipeline'
+import { useTranslation } from 'uiSrc/i18n'
import { ConfigurationCard, JobsCard } from './cards'
@@ -27,6 +28,7 @@ const getSelectedTab = (path: string, rdiInstanceId: string) => {
}
const Navigation = () => {
+ const { t } = useTranslation()
const [selectedTab, setSelectedTab] =
useState>(null)
@@ -52,7 +54,7 @@ const Navigation = () => {
return (
- Pipeline management
+ {t('rdi.pipeline.nav.title')}
{loading && }
diff --git a/redisinsight/ui/src/pages/rdi/pipeline-management/components/navigation/cards/ConfigurationCard.tsx b/redisinsight/ui/src/pages/rdi/pipeline-management/components/navigation/cards/ConfigurationCard.tsx
index 633c86548c..838fe63094 100644
--- a/redisinsight/ui/src/pages/rdi/pipeline-management/components/navigation/cards/ConfigurationCard.tsx
+++ b/redisinsight/ui/src/pages/rdi/pipeline-management/components/navigation/cards/ConfigurationCard.tsx
@@ -6,6 +6,7 @@ import { Indicator } from 'uiSrc/components/base/text/text.styles'
import { Row } from 'uiSrc/components/base/layout/flex'
import { Text } from 'uiSrc/components/base/text'
import { Icon, ToastNotificationIcon } from 'uiSrc/components/base/icons'
+import { useTranslation } from 'uiSrc/i18n'
import { useConfigurationState } from './hooks'
import BaseCard, { BaseCardProps } from './BaseCard'
@@ -22,6 +23,7 @@ const ConfigurationCard = ({
onSelect,
isSelected,
}: ConfigurationCardProps) => {
+ const { t } = useTranslation()
const { hasChanges, isValid, configValidationErrors } =
useConfigurationState()
@@ -31,7 +33,7 @@ const ConfigurationCard = ({
return (
)}
- Configuration file
+ {t('rdi.pipeline.nav.configFile')}
{!isValid && (
{
if (!jobName) {
- return buildValidationMessage('Job name is required')
+ return buildValidationMessage(i18n.t('rdi.pipeline.jobName.required'))
}
if (jobName === currentJobName) return undefined
if (jobs.some((job) => job.name === jobName)) {
- return buildValidationMessage('Job name is already in use')
+ return buildValidationMessage(i18n.t('rdi.pipeline.jobName.inUse'))
}
return undefined
@@ -71,7 +72,7 @@ const JobNameForm = ({
isLoading={isLoading}
declineOnUnmount={false}
initialValue={currentJobName || ''}
- placeholder="Enter job name"
+ placeholder={i18n.t('rdi.pipeline.jobName.placeholder')}
maxLength={250}
viewChildrenMode={false}
disableEmpty
diff --git a/redisinsight/ui/src/pages/rdi/pipeline-management/components/navigation/cards/jobs/JobsCard.tsx b/redisinsight/ui/src/pages/rdi/pipeline-management/components/navigation/cards/jobs/JobsCard.tsx
index 181722c05d..199b9deff0 100644
--- a/redisinsight/ui/src/pages/rdi/pipeline-management/components/navigation/cards/jobs/JobsCard.tsx
+++ b/redisinsight/ui/src/pages/rdi/pipeline-management/components/navigation/cards/jobs/JobsCard.tsx
@@ -19,6 +19,7 @@ import { Row } from 'uiSrc/components/base/layout/flex'
import { RiTooltip } from 'uiSrc/components'
import { IconButton } from 'uiSrc/components/base/forms/buttons'
import { PlusIcon } from 'uiSrc/components/base/icons'
+import { useTranslation } from 'uiSrc/i18n'
import BaseCard, { BaseCardProps } from '../BaseCard'
import JobNameForm from './JobNameForm'
@@ -32,6 +33,7 @@ export type JobsCardProps = Omit<
}
const JobsCard = (props: JobsCardProps) => {
+ const { t } = useTranslation()
const { onSelect, isSelected } = props
const [currentJobName, setCurrentJobName] = useState>(null)
@@ -132,10 +134,10 @@ const JobsCard = (props: JobsCardProps) => {
return (
@@ -151,7 +153,7 @@ const JobsCard = (props: JobsCardProps) => {
setHideTooltip(true)
}}
disabled={isNewJob}
- aria-label="add new job file"
+ aria-label={t('rdi.pipeline.nav.addJobAria')}
data-testid="add-new-job"
/>
diff --git a/redisinsight/ui/src/pages/rdi/pipeline-management/components/navigation/cards/jobs/JobsItem.tsx b/redisinsight/ui/src/pages/rdi/pipeline-management/components/navigation/cards/jobs/JobsItem.tsx
index d9a930a8c1..97cb35ce43 100644
--- a/redisinsight/ui/src/pages/rdi/pipeline-management/components/navigation/cards/jobs/JobsItem.tsx
+++ b/redisinsight/ui/src/pages/rdi/pipeline-management/components/navigation/cards/jobs/JobsItem.tsx
@@ -13,6 +13,7 @@ import ValidationErrorsList from 'uiSrc/pages/rdi/pipeline-management/components
import { Indicator } from 'uiSrc/components/base/text/text.styles'
import { ToastNotificationIcon } from '@redis-ui/icons'
import { truncateText } from 'uiSrc/utils'
+import { useTranslation } from 'uiSrc/i18n'
type JobItemProps = {
name: string
@@ -34,102 +35,105 @@ const JobItem = ({
onSelect,
onEdit,
onDelete,
-}: JobItemProps) => (
-
-
- {!hasChanges && }
+}: JobItemProps) => {
+ const { t } = useTranslation()
- {hasChanges && (
-
-
-
- )}
-
+ return (
+
+
+ {!hasChanges && }
- onSelect(name)}
- data-testid={`rdi-nav-job-${name}`}
- grow
- >
-
-
-
- {truncateText(name, 20)}
-
-
-
- {!isValid && (
+ {hasChanges && (
- }
+ content={t('rdi.pipeline.nav.undeployedChanges')}
+ position="top"
>
-
)}
-
-
+
-
-
-
- onEdit(name)}
- aria-label="edit job file name"
- data-testid={`edit-job-name-${name}`}
- />
-
+ onSelect(name)}
+ data-testid={`rdi-nav-job-${name}`}
+ grow
+ >
+
+
+
+ {truncateText(name, 20)}
+
+
-
-
- Changes will not be applied until the pipeline is deployed.
-
- }
- submitBtn={
-
- Delete
-
- }
- onConfirm={() => onDelete(name)}
- button={
-
+ }
+ >
+
- }
- />
-
-
-
-
-)
+
+ )}
+
+
+
+
+
+
+ onEdit(name)}
+ aria-label={t('rdi.pipeline.nav.editJobAria')}
+ data-testid={`edit-job-name-${name}`}
+ />
+
+
+
+ {t('rdi.pipeline.nav.deleteJobBody')}}
+ submitBtn={
+
+ {t('rdi.pipeline.nav.deleteConfirm')}
+
+ }
+ onConfirm={() => onDelete(name)}
+ button={
+
+ }
+ />
+
+
+
+
+ )
+}
export default JobItem
diff --git a/redisinsight/ui/src/pages/rdi/pipeline-management/components/source-pipeline-dialog/SourcePipelineModal.tsx b/redisinsight/ui/src/pages/rdi/pipeline-management/components/source-pipeline-dialog/SourcePipelineModal.tsx
index 6d4b6819fd..493a6885ae 100644
--- a/redisinsight/ui/src/pages/rdi/pipeline-management/components/source-pipeline-dialog/SourcePipelineModal.tsx
+++ b/redisinsight/ui/src/pages/rdi/pipeline-management/components/source-pipeline-dialog/SourcePipelineModal.tsx
@@ -16,6 +16,7 @@ import { ContractsIcon, UploadIcon } from 'uiSrc/components/base/icons'
import { FileChangeType } from 'uiSrc/slices/interfaces'
import { Modal } from 'uiSrc/components/base/display'
import { Spacer } from 'uiSrc/components/base/layout'
+import { useTranslation } from 'uiSrc/i18n'
import { ButtonWrapper } from './SourcePipelineModal.styles'
@@ -30,6 +31,7 @@ export enum PipelineSourceOptions {
}
const SourcePipelineDialog = () => {
+ const { t } = useTranslation()
const [isShowDownloadDialog, setIsShowDownloadDialog] = useState(false)
const { rdiInstanceId } = useParams<{ rdiInstanceId: string }>()
@@ -102,10 +104,10 @@ const SourcePipelineDialog = () => {
- Select an option
+ {t('rdi.pipeline.source.title')}
- to start with your pipeline
+ {t('rdi.pipeline.source.subtitle')}
@@ -119,7 +121,7 @@ const SourcePipelineDialog = () => {
>
- Import pipeline from ZIP file
+ {t('rdi.pipeline.source.importZip')}
{
>
- Create new pipeline
+ {t('rdi.pipeline.source.createNew')}
diff --git a/redisinsight/ui/src/pages/rdi/pipeline-management/components/template-button/TemplateButton.tsx b/redisinsight/ui/src/pages/rdi/pipeline-management/components/template-button/TemplateButton.tsx
index 0bf164957b..3552c5aa7d 100644
--- a/redisinsight/ui/src/pages/rdi/pipeline-management/components/template-button/TemplateButton.tsx
+++ b/redisinsight/ui/src/pages/rdi/pipeline-management/components/template-button/TemplateButton.tsx
@@ -10,6 +10,7 @@ import {
import { RiTooltip } from 'uiSrc/components'
import { RdiPipelineTabs } from 'uiSrc/slices/interfaces'
import { SecondaryButton } from 'uiSrc/components/base/forms/buttons'
+import { useTranslation } from 'uiSrc/i18n'
import { getTooltipContent } from '../template-form/TemplateForm'
import { INGEST_OPTION } from '../template-form/constants'
@@ -19,6 +20,7 @@ export interface TemplateButtonProps {
}
const TemplateButton = ({ setFieldValue, value }: TemplateButtonProps) => {
+ const { t } = useTranslation()
const dispatch = useAppDispatch()
const { rdiInstanceId } = useParams<{ rdiInstanceId: string }>()
const { loading, data } = useAppSelector(rdiPipelineStrategiesSelector)
@@ -53,13 +55,13 @@ const TemplateButton = ({ setFieldValue, value }: TemplateButtonProps) => {
- Insert template
+ {t('rdi.pipeline.template.insertButton')}
)
diff --git a/redisinsight/ui/src/pages/rdi/pipeline-management/components/template-form/TemplateForm.spec.tsx b/redisinsight/ui/src/pages/rdi/pipeline-management/components/template-form/TemplateForm.spec.tsx
index d0b6d3ce06..2eddd133ea 100644
--- a/redisinsight/ui/src/pages/rdi/pipeline-management/components/template-form/TemplateForm.spec.tsx
+++ b/redisinsight/ui/src/pages/rdi/pipeline-management/components/template-form/TemplateForm.spec.tsx
@@ -16,7 +16,7 @@ import {
rdiPipelineStrategiesSelector,
} from 'uiSrc/slices/rdi/pipeline'
import { RdiPipelineTabs } from 'uiSrc/slices/interfaces'
-import { INGEST_OPTION, NO_TEMPLATE_LABEL } from './constants'
+import { INGEST_OPTION } from './constants'
import TemplateForm, { Props } from './TemplateForm'
const mockedProps = mock
()
@@ -114,7 +114,7 @@ describe('TemplateForm', () => {
)
expect(screen.getByTestId('db-type-select')).toHaveTextContent(
- NO_TEMPLATE_LABEL,
+ 'No template',
)
})
diff --git a/redisinsight/ui/src/pages/rdi/pipeline-management/components/template-form/TemplateForm.tsx b/redisinsight/ui/src/pages/rdi/pipeline-management/components/template-form/TemplateForm.tsx
index b8ad880ca1..649c9c90a4 100644
--- a/redisinsight/ui/src/pages/rdi/pipeline-management/components/template-form/TemplateForm.tsx
+++ b/redisinsight/ui/src/pages/rdi/pipeline-management/components/template-form/TemplateForm.tsx
@@ -1,4 +1,4 @@
-import React, { useEffect, useState } from 'react'
+import React, { useEffect, useMemo, useState } from 'react'
import { useAppDispatch, useAppSelector } from 'uiSrc/slices/hooks'
import { useParams } from 'react-router-dom'
@@ -23,7 +23,8 @@ import {
RiSelect,
defaultValueRender,
} from 'uiSrc/components/base/forms/select/RiSelect'
-import { NO_TEMPLATE_VALUE, NO_OPTIONS, INGEST_OPTION } from './constants'
+import { NO_TEMPLATE_VALUE, INGEST_OPTION } from './constants'
+import i18n, { useTranslation } from 'uiSrc/i18n'
import { Col, Row } from 'uiSrc/components/base/layout/flex'
@@ -41,32 +42,44 @@ export const getTooltipContent = (
if (isNoTemplateOptions) {
return (
<>
- No template is available.
+ {i18n.t('rdi.pipeline.template.noneAvailableLine1')}
- Close the form and try again.
+ {i18n.t('rdi.pipeline.template.noneAvailableLine2')}
>
)
}
if (value) {
- return 'Templates can be accessed only with the empty Editor to prevent potential data loss.'
+ return i18n.t('rdi.pipeline.template.editorOnly')
}
return null
}
const TemplateForm = (props: Props) => {
+ const { t } = useTranslation()
const { closePopover, setTemplate, source, value } = props
const { loading, data } = useAppSelector(rdiPipelineStrategiesSelector)
const { rdiInstanceId } = useParams<{ rdiInstanceId: string }>()
+ // Built at render (not module load) so the label follows the active language.
+ const noOptions: RiSelectOption[] = useMemo(
+ () => [
+ {
+ value: NO_TEMPLATE_VALUE,
+ label: t('rdi.pipeline.template.noTemplateLabel'),
+ },
+ ],
+ [t],
+ )
+
const [pipelineTypeOptions, setPipelineTypeOptions] = useState<
RiSelectOption[]
>([])
const [dbTypeOptions, setDbTypeOptions] =
- useState(NO_OPTIONS)
+ useState(noOptions)
const [selectedDbType, setSelectedDbType] = useState('')
const [selectedPipelineType, setSelectedPipelineType] = useState('')
@@ -113,8 +126,8 @@ const TemplateForm = (props: Props) => {
useEffect(() => {
if (!selectedPipelineType || !data.length) {
- setDbTypeOptions(NO_OPTIONS)
- setSelectedDbType(NO_OPTIONS[0].value)
+ setDbTypeOptions(noOptions)
+ setSelectedDbType(NO_TEMPLATE_VALUE)
return
}
@@ -132,10 +145,10 @@ const TemplateForm = (props: Props) => {
setDbTypeOptions(newDbTypeOptions)
setSelectedDbType(newDbTypeOptions[0].value)
} else {
- setDbTypeOptions(NO_OPTIONS)
- setSelectedDbType(NO_OPTIONS[0].value)
+ setDbTypeOptions(noOptions)
+ setSelectedDbType(NO_TEMPLATE_VALUE)
}
- }, [data, selectedPipelineType])
+ }, [data, selectedPipelineType, noOptions])
useEffect(() => {
const newPipelineTypeOptions = data.map((strategy) => ({
@@ -144,7 +157,7 @@ const TemplateForm = (props: Props) => {
}))
setPipelineTypeOptions(
- newPipelineTypeOptions.length ? newPipelineTypeOptions : NO_OPTIONS,
+ newPipelineTypeOptions.length ? newPipelineTypeOptions : noOptions,
)
if (data?.length) {
@@ -154,9 +167,9 @@ const TemplateForm = (props: Props) => {
) || newPipelineTypeOptions[0]
setSelectedPipelineType(initialSelectedOption.value)
} else {
- setSelectedPipelineType(NO_OPTIONS[0].value)
+ setSelectedPipelineType(NO_TEMPLATE_VALUE)
}
- }, [data])
+ }, [data, noOptions])
useEffect(() => {
dispatch(fetchPipelineStrategies(rdiInstanceId))
@@ -165,12 +178,12 @@ const TemplateForm = (props: Props) => {
return (
- Select a template
+ {t('rdi.pipeline.template.title')}