Skip to content

Commit 1704719

Browse files
committed
Further component translation
1 parent 258cf9b commit 1704719

31 files changed

+484
-164
lines changed

airflow-core/src/airflow/ui/src/components/ConfigForm.tsx

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
*/
1919
import { Accordion, Box, Field } from "@chakra-ui/react";
2020
import { type Control, type FieldValues, type Path, Controller } from "react-hook-form";
21+
import { useTranslation } from "react-i18next";
2122

2223
import type { ParamsSpec } from "src/queries/useDagParams";
2324
import { useParamStore } from "src/queries/useParamStore";
@@ -50,6 +51,7 @@ const ConfigForm = <T extends FieldValues = FieldValues>({
5051
setErrors,
5152
setFormError,
5253
}: ConfigFormProps<T>) => {
54+
const { t: translate } = useTranslation("components");
5355
const { conf, setConf } = useParamStore();
5456

5557
const validateAndPrettifyJson = (value: string) => {
@@ -66,11 +68,11 @@ const ConfigForm = <T extends FieldValues = FieldValues>({
6668

6769
return formattedJson;
6870
} catch (error) {
69-
const errorMessage = error instanceof Error ? error.message : "Unknown error occurred.";
71+
const errorMessage = error instanceof Error ? error.message : translate("configForm.unkownError");
7072

7173
setErrors((prev) => ({
7274
...prev,
73-
conf: `Invalid JSON format: ${errorMessage}`,
75+
conf: translate("configForm.invalidJson", { errorMessage }),
7476
}));
7577

7678
return value;
@@ -91,7 +93,9 @@ const ConfigForm = <T extends FieldValues = FieldValues>({
9193
setError={setFormError}
9294
/>
9395
<Accordion.Item key="advancedOptions" value="advancedOptions">
94-
<Accordion.ItemTrigger cursor="button">Advanced Options</Accordion.ItemTrigger>
96+
<Accordion.ItemTrigger cursor="button">
97+
{translate("configForm.advancedOptions")}
98+
</Accordion.ItemTrigger>
9599
<Accordion.ItemContent>
96100
<Box p={4}>
97101
{children}
@@ -100,7 +104,7 @@ const ConfigForm = <T extends FieldValues = FieldValues>({
100104
name={"conf" as Path<T>}
101105
render={({ field }) => (
102106
<Field.Root invalid={Boolean(errors.conf)} mt={6}>
103-
<Field.Label fontSize="md">Configuration JSON</Field.Label>
107+
<Field.Label fontSize="md">{translate("configForm.configJson")}</Field.Label>
104108
<JsonEditor
105109
{...field}
106110
onBlur={() => {

airflow-core/src/airflow/ui/src/components/DagActions/RunBackfillForm.tsx

Lines changed: 3 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
* specific language governing permissions and limitations
1717
* under the License.
1818
*/
19-
import { Input, Box, Spacer, HStack, Field, VStack, Flex, Text, Skeleton } from "@chakra-ui/react";
19+
import { Input, Box, Spacer, HStack, Field, VStack, Flex, Text } from "@chakra-ui/react";
2020
import dayjs from "dayjs";
2121
import { useEffect, useState } from "react";
2222
import { useForm, Controller, useWatch } from "react-hook-form";
@@ -37,6 +37,7 @@ import { ErrorAlert } from "../ErrorAlert";
3737
import type { DagRunTriggerParams } from "../TriggerDag/TriggerDAGForm";
3838
import { Checkbox } from "../ui/Checkbox";
3939
import { RadioCardItem, RadioCardLabel, RadioCardRoot } from "../ui/RadioCard";
40+
import { getInlineMessage } from "./inlineMessage";
4041

4142
type RunBackfillFormProps = {
4243
readonly dag: DAGResponse | DAGWithLatestDagRunsResponse;
@@ -137,21 +138,7 @@ const RunBackfillForm = ({ dag, onClose }: RunBackfillFormProps) => {
137138
total_entries: 0,
138139
};
139140

140-
const inlineMessage = isPendingDryRun ? (
141-
<Skeleton height="20px" width="100px" />
142-
) : affectedTasks.total_entries > 1 ? (
143-
<Text color="fg.success" fontSize="sm">
144-
{translate("backfill.affectedOne")}
145-
</Text>
146-
) : affectedTasks.total_entries > 0 ? (
147-
<Text color="fg.success" fontSize="sm">
148-
{translate("backfill.affectedMultiple", { count: affectedTasks.total_entries })}
149-
</Text>
150-
) : (
151-
<Text color="fg.error" fontSize="sm" fontWeight="medium">
152-
{translate("backfill.affectedNone")}
153-
</Text>
154-
);
141+
const inlineMessage = getInlineMessage(isPendingDryRun, affectedTasks.total_entries, translate);
155142

156143
return (
157144
<>
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
/*!
2+
* Licensed to the Apache Software Foundation (ASF) under one
3+
* or more contributor license agreements. See the NOTICE file
4+
* distributed with this work for additional information
5+
* regarding copyright ownership. The ASF licenses this file
6+
* to you under the Apache License, Version 2.0 (the
7+
* "License"); you may not use this file except in compliance
8+
* with the License. You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing,
13+
* software distributed under the License is distributed on an
14+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
* KIND, either express or implied. See the License for the
16+
* specific language governing permissions and limitations
17+
* under the License.
18+
*/
19+
import { Text, Skeleton } from "@chakra-ui/react";
20+
import type { TFunction } from "i18next";
21+
22+
export const getInlineMessage = (isPendingDryRun: boolean, totalEntries: number, translate: TFunction) =>
23+
isPendingDryRun ? (
24+
<Skeleton height="20px" width="100px" />
25+
) : totalEntries > 1 ? (
26+
<Text color="fg.success" fontSize="sm">
27+
{translate("backfill.affectedOne")}
28+
</Text>
29+
) : totalEntries > 0 ? (
30+
<Text color="fg.success" fontSize="sm">
31+
{translate("backfill.affectedMultiple", { count: totalEntries })}
32+
</Text>
33+
) : (
34+
<Text color="fg.error" fontSize="sm" fontWeight="medium">
35+
{translate("backfill.affectedNone")}
36+
</Text>
37+
);

airflow-core/src/airflow/ui/src/components/DagRunInfo.tsx

Lines changed: 43 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
* under the License.
1818
*/
1919
import { VStack, Text, Box } from "@chakra-ui/react";
20+
import { useTranslation } from "react-i18next";
2021

2122
import type { DAGRunResponse } from "openapi/requests/types.gen";
2223
import { StateBadge } from "src/components/StateBadge";
@@ -32,35 +33,47 @@ type Props = {
3233
readonly state?: DAGRunResponse["state"];
3334
};
3435

35-
const DagRunInfo = ({ endDate, logicalDate, runAfter, startDate, state }: Props) => (
36-
<Tooltip
37-
content={
38-
<VStack align="left" gap={0}>
39-
{state === undefined ? undefined : <Text>State: {state}</Text>}
40-
{Boolean(logicalDate) ? (
41-
<Text>
42-
Logical Date: <Time datetime={logicalDate} />
43-
</Text>
44-
) : undefined}
45-
{Boolean(startDate) ? (
46-
<Text>
47-
Start Date: <Time datetime={startDate} />
48-
</Text>
49-
) : undefined}
50-
{Boolean(endDate) ? (
51-
<Text>
52-
End Date: <Time datetime={endDate} />
53-
</Text>
54-
) : undefined}
55-
{Boolean(startDate) ? <Text>Duration: {getDuration(startDate, endDate)}</Text> : undefined}
56-
</VStack>
57-
}
58-
>
59-
<Box>
60-
<Time datetime={runAfter} mr={2} showTooltip={false} />
61-
{state === undefined ? undefined : <StateBadge state={state} />}
62-
</Box>
63-
</Tooltip>
64-
);
36+
const DagRunInfo = ({ endDate, logicalDate, runAfter, startDate, state }: Props) => {
37+
const { t: translate } = useTranslation("common");
38+
39+
return (
40+
<Tooltip
41+
content={
42+
<VStack align="left" gap={0}>
43+
{state === undefined ? undefined : (
44+
<Text>
45+
{translate("state")}: {state}
46+
</Text>
47+
)}
48+
{Boolean(logicalDate) ? (
49+
<Text>
50+
{translate("logicalDate")}: <Time datetime={logicalDate} />
51+
</Text>
52+
) : undefined}
53+
{Boolean(startDate) ? (
54+
<Text>
55+
{translate("startDate")}: <Time datetime={startDate} />
56+
</Text>
57+
) : undefined}
58+
{Boolean(endDate) ? (
59+
<Text>
60+
{translate("endDate")}: <Time datetime={endDate} />
61+
</Text>
62+
) : undefined}
63+
{Boolean(startDate) ? (
64+
<Text>
65+
{translate("duration")}: {getDuration(startDate, endDate)}
66+
</Text>
67+
) : undefined}
68+
</VStack>
69+
}
70+
>
71+
<Box>
72+
<Time datetime={runAfter} mr={2} showTooltip={false} />
73+
{state === undefined ? undefined : <StateBadge state={state} />}
74+
</Box>
75+
</Tooltip>
76+
);
77+
};
6578

6679
export default DagRunInfo;

airflow-core/src/airflow/ui/src/components/DagVersionDetails.tsx

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,14 @@
1717
* under the License.
1818
*/
1919
import { Link, Table } from "@chakra-ui/react";
20+
import { useTranslation } from "react-i18next";
2021

2122
import type { DagVersionResponse } from "openapi/requests/types.gen";
2223
import Time from "src/components/Time";
2324

2425
export const DagVersionDetails = ({ dagVersion }: { readonly dagVersion?: DagVersionResponse | null }) => {
26+
const { t: translate } = useTranslation("components");
27+
2528
if (dagVersion === null || dagVersion === undefined) {
2629
return undefined;
2730
}
@@ -30,29 +33,29 @@ export const DagVersionDetails = ({ dagVersion }: { readonly dagVersion?: DagVer
3033
<Table.Root striped>
3134
<Table.Body>
3235
<Table.Row>
33-
<Table.Cell>Version ID</Table.Cell>
36+
<Table.Cell>{translate("versionDetails.versionId")}</Table.Cell>
3437
<Table.Cell>{dagVersion.id}</Table.Cell>
3538
</Table.Row>
3639
<Table.Row>
37-
<Table.Cell>Bundle Name</Table.Cell>
40+
<Table.Cell>{translate("versionDetails.bundleName")}</Table.Cell>
3841
<Table.Cell>{dagVersion.bundle_name}</Table.Cell>
3942
</Table.Row>
4043
{dagVersion.bundle_version === null ? undefined : (
4144
<Table.Row>
42-
<Table.Cell>Bundle Version</Table.Cell>
45+
<Table.Cell>{translate("versionDetails.bundleVersion")}</Table.Cell>
4346
<Table.Cell>{dagVersion.bundle_version}</Table.Cell>
4447
</Table.Row>
4548
)}
4649
{dagVersion.bundle_url === null ? undefined : (
4750
<Table.Row>
48-
<Table.Cell>Bundle Link</Table.Cell>
51+
<Table.Cell>{translate("versionDetails.bundleLink")}</Table.Cell>
4952
<Table.Cell>
5053
<Link href={dagVersion.bundle_url}>{dagVersion.bundle_url}</Link>
5154
</Table.Cell>
5255
</Table.Row>
5356
)}
5457
<Table.Row>
55-
<Table.Cell>Created At</Table.Cell>
58+
<Table.Cell>{translate("versionDetails.createdAt")}</Table.Cell>
5659
<Table.Cell>
5760
<Time datetime={dagVersion.created_at} />
5861
</Table.Cell>

airflow-core/src/airflow/ui/src/components/DagVersionSelect.tsx

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
*/
1919
import { createListCollection, Flex, Select, type SelectValueChangeDetails, Text } from "@chakra-ui/react";
2020
import { useCallback, useMemo } from "react";
21+
import { useTranslation } from "react-i18next";
2122
import { useParams, useSearchParams } from "react-router-dom";
2223

2324
import { useDagVersionServiceGetDagVersions } from "openapi/queries";
@@ -33,24 +34,19 @@ type VersionSelected = {
3334
};
3435

3536
export const DagVersionSelect = ({ showLabel = true }: { readonly showLabel?: boolean }) => {
37+
const { t: translate } = useTranslation("components");
3638
const { dagId = "" } = useParams();
37-
3839
const { data, isLoading } = useDagVersionServiceGetDagVersions({ dagId, orderBy: "-version_number" });
39-
4040
const [searchParams, setSearchParams] = useSearchParams();
41-
4241
const selectedVersionNumber = useSelectedVersion();
43-
4442
const selectedVersion = data?.dag_versions.find((dv) => dv.version_number === selectedVersionNumber);
45-
4643
const versionOptions = useMemo(
4744
() =>
4845
createListCollection({
4946
items: (data?.dag_versions ?? []).map((dv) => ({ value: dv.version_number, version: dv })),
5047
}),
5148
[data],
5249
);
53-
5450
const handleStateChange = useCallback(
5551
({ items }: SelectValueChangeDetails<VersionSelected>) => {
5652
if (items[0]) {
@@ -71,13 +67,17 @@ export const DagVersionSelect = ({ showLabel = true }: { readonly showLabel?: bo
7167
value={selectedVersionNumber === undefined ? [] : [selectedVersionNumber.toString()]}
7268
width="250px"
7369
>
74-
{showLabel ? <Select.Label fontSize="xs">Dag Version</Select.Label> : undefined}
70+
{showLabel ? (
71+
<Select.Label fontSize="xs">{translate("versionSelect.dagVersion")}</Select.Label>
72+
) : undefined}
7573
<Select.Control>
7674
<Select.Trigger>
7775
<Select.ValueText placeholder="All Versions">
7876
{selectedVersion === undefined ? undefined : (
7977
<Flex justifyContent="space-between" width="175px">
80-
<Text>v{selectedVersion.version_number}</Text>
78+
<Text>
79+
{translate("versionSelect.versionCode", { versionCode: selectedVersion.version_number })}
80+
</Text>
8181
<Time datetime={selectedVersion.created_at} />
8282
</Flex>
8383
)}

airflow-core/src/airflow/ui/src/components/DurationChart.tsx

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -31,11 +31,11 @@ import type { PartialEventContext } from "chartjs-plugin-annotation";
3131
import annotationPlugin from "chartjs-plugin-annotation";
3232
import dayjs from "dayjs";
3333
import { Bar } from "react-chartjs-2";
34+
import { useTranslation } from "react-i18next";
3435
import { useNavigate } from "react-router-dom";
3536

3637
import type { TaskInstanceResponse, DAGRunResponse } from "openapi/requests/types.gen";
3738
import { system } from "src/theme";
38-
import { pluralize } from "src/utils";
3939

4040
ChartJS.register(
4141
CategoryScale,
@@ -65,6 +65,7 @@ export const DurationChart = ({
6565
readonly entries: Array<RunResponse> | undefined;
6666
readonly kind: "Dag Run" | "Task Instance";
6767
}) => {
68+
const { t: translate } = useTranslation("components");
6869
const navigate = useNavigate();
6970

7071
if (!entries) {
@@ -98,7 +99,13 @@ export const DurationChart = ({
9899
return (
99100
<Box>
100101
<Heading pb={2} size="sm" textAlign="center">
101-
Last {pluralize(kind, entries.length)}
102+
{entries.length > 1
103+
? kind === "Dag Run"
104+
? translate("durationChart.lastDagRun_other", { count: entries.length })
105+
: translate("durationChart.lasttaskInstance_other", { count: entries.length })
106+
: kind === "Dag Run"
107+
? translate("durationChart.lastDagRun_one")
108+
: translate("durationChart.lasttaskInstance_one")}
102109
</Heading>
103110
<Bar
104111
data={{
@@ -127,7 +134,7 @@ export const DurationChart = ({
127134
return 0;
128135
}
129136
}),
130-
label: "Queued duration",
137+
label: translate("durationChart.queuedDuration"),
131138
},
132139
{
133140
backgroundColor: entries.map(
@@ -137,7 +144,7 @@ export const DurationChart = ({
137144
data: entries.map((entry: RunResponse) =>
138145
entry.start_date === null ? 0 : Number(getDuration(entry.start_date, entry.end_date)),
139146
),
140-
label: "Run duration",
147+
label: translate("durationChart.runDuration"),
141148
},
142149
],
143150
labels: entries.map((entry: RunResponse) => dayjs(entry.run_after).format("YYYY-MM-DD, hh:mm:ss")),
@@ -186,10 +193,10 @@ export const DurationChart = ({
186193
ticks: {
187194
maxTicksLimit: 3,
188195
},
189-
title: { align: "end", display: true, text: "Run After" },
196+
title: { align: "end", display: true, text: translate("durationChart.runAfter") },
190197
},
191198
y: {
192-
title: { align: "end", display: true, text: "Duration (seconds)" },
199+
title: { align: "end", display: true, text: translate("durationChart.duration") },
193200
},
194201
},
195202
}}

0 commit comments

Comments
 (0)