Skip to content

Commit 4132867

Browse files
committed
feat: integrate translation for results components and improve user feedback messages
- Added translation support for various labels and messages in ResultsDialogViews, ResultsGraphs, ResultsGraphsSelection, ResultsGraphsSwitch, ResultsTabHyperparameters, ResultsTabInfo, ResultsTabInfoDescription, ResultsTabMetricsRuns, ResultsTabMetricsToggle, ResultsTabParametersDisplay, ResultsTabParametersToggle, ResultsTable, ResultsTableLayout. - Updated error messages and labels to enhance user experience and accessibility. - Implemented dynamic translations for display set names and metrics in ResultsTabMetricsRuns. - Improved consistency in user interface text across different components.
1 parent d7e4113 commit 4132867

26 files changed

Lines changed: 313 additions & 120 deletions

DashAI/front/src/components/experiments/SplitDatasetRows.jsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -408,7 +408,7 @@ function SplitDatasetRows({
408408
<Grid size={{ xs: 4 }}>
409409
<TextField
410410
id="train"
411-
label={t("common:trainSubject")}
411+
label={t("common:train")}
412412
autoComplete="off"
413413
size="small"
414414
error={manualSplitError}
@@ -428,7 +428,7 @@ function SplitDatasetRows({
428428
<Grid size={{ xs: 4 }}>
429429
<TextField
430430
id="test"
431-
label={t("common:testSubject")}
431+
label={t("common:test")}
432432
autoComplete="off"
433433
size="small"
434434
error={manualSplitError}

DashAI/front/src/components/experiments/metrics/MetricsSelector.jsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,7 @@ export default function MetricsSelector({
138138
onClick={() => selectAllForSplit("train")}
139139
variant="contained"
140140
>
141-
{t("common:trainSubject")}
141+
{t("common:train")}
142142
</Button>
143143
<Button
144144
onClick={() => selectAllForSplit("validation")}
@@ -147,7 +147,7 @@ export default function MetricsSelector({
147147
{t("common:validation")}
148148
</Button>
149149
<Button onClick={() => selectAllForSplit("test")} variant="contained">
150-
{t("common:testSubject")}
150+
{t("common:test")}
151151
</Button>
152152
</Stack>
153153

DashAI/front/src/components/models/SessionVisualization.jsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -234,17 +234,17 @@ export default function SessionVisualization({
234234
>
235235
{hasTrainMetrics && (
236236
<ToggleButton value="train">
237-
{t("models:label.train")}
237+
{t("common:train")}
238238
</ToggleButton>
239239
)}
240240
{hasValidationMetrics && (
241241
<ToggleButton value="validation">
242-
{t("models:label.validation")}
242+
{t("common:validation")}
243243
</ToggleButton>
244244
)}
245245
{hasTestMetrics && (
246246
<ToggleButton value="test">
247-
{t("models:label.test")}
247+
{t("common:test")}
248248
</ToggleButton>
249249
)}
250250
</ToggleButtonGroup>

DashAI/front/src/pages/results/components/LiveMetricsChart.jsx

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,10 @@ import {
2121
} from "recharts";
2222
import { useEffect, useRef, useState } from "react";
2323
import { getExperimentById } from "../../../api/experiment";
24+
import { useTranslation } from "react-i18next";
2425

2526
export function LiveMetricsChart({ run }) {
27+
const { t } = useTranslation(["models", "common"]);
2628
const [level, setLevel] = useState(null);
2729
const [split, setSplit] = useState("TRAIN");
2830
const [data, setData] = useState({});
@@ -301,7 +303,7 @@ export function LiveMetricsChart({ run }) {
301303
<Select
302304
multiple
303305
value={selectedMetrics}
304-
label="Metrics"
306+
label={t("common:metrics")}
305307
onChange={handleMetricChange}
306308
renderValue={(selected) => selected.join(", ")}
307309
>
@@ -315,9 +317,9 @@ export function LiveMetricsChart({ run }) {
315317
</Box>
316318

317319
<Tabs value={split} onChange={(_, v) => setSplit(v)} sx={{ mb: 2 }}>
318-
<Tab label="Train" value="TRAIN" />
319-
<Tab label="Validation" value="VALIDATION" />
320-
<Tab label="Test" value="TEST" />
320+
<Tab label={t("common:train")} value="TRAIN" />
321+
<Tab label={t("common:validation")} value="VALIDATION" />
322+
<Tab label={t("common:test")} value="TEST" />
321323
</Tabs>
322324

323325
{chartData.length === 0 || selectedMetrics.length === 0 ? (
@@ -329,7 +331,7 @@ export function LiveMetricsChart({ run }) {
329331
border="1px dashed grey"
330332
>
331333
<Typography color="textSecondary">
332-
No metrics available for this view
334+
{t("models:label.noMetricsAvailableForThisView")}
333335
</Typography>
334336
</Box>
335337
) : (
@@ -365,21 +367,21 @@ export function LiveMetricsChart({ run }) {
365367
onClick={() => handleLevelChange("TRIAL")}
366368
disabled={!hasTrialData}
367369
>
368-
Trial
370+
{t("models:label.trial")}
369371
</Button>
370372
<Button
371373
variant={level === "STEP" ? "contained" : "outlined"}
372374
onClick={() => handleLevelChange("STEP")}
373375
disabled={!hasStepData}
374376
>
375-
Step
377+
{t("models:label.step")}
376378
</Button>
377379
<Button
378380
variant={level === "EPOCH" ? "contained" : "outlined"}
379381
onClick={() => handleLevelChange("EPOCH")}
380382
disabled={!hasEpochData}
381383
>
382-
Epoch
384+
{t("models:label.epoch")}
383385
</Button>
384386
</ButtonGroup>
385387
</Box>

DashAI/front/src/pages/results/components/MetricsCard.jsx

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
11
import React from "react";
22
import { Box, Divider, Paper, Typography } from "@mui/material";
3+
import { useTranslation } from "react-i18next";
34

45
export default function MetricsCard({ title, metrics }) {
6+
const { t } = useTranslation(["models"]);
7+
58
return (
69
<Paper elevation={2} sx={{ p: 2, height: "100%" }}>
710
<Typography variant="subtitle1" fontWeight="bold" gutterBottom>
@@ -24,7 +27,7 @@ export default function MetricsCard({ title, metrics }) {
2427
))
2528
) : (
2629
<Typography variant="body2" color="text.secondary">
27-
No metrics available
30+
{t("models:label.noMetricsAvailable")}
2831
</Typography>
2932
)}
3033
</Paper>

DashAI/front/src/pages/results/components/ResultsDetailsLayout.jsx

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import ResultsTabMetrics from "./ResultsTabMetrics";
99
import ResultsTabHyperparameters from "./ResultsTabHyperparameters";
1010
import { tabsResultsDetails } from "../constants/tabsResultsDetails";
1111
import { checkIfHaveOptimazers } from "../../../utils/schema";
12+
import { useTranslation } from "react-i18next";
1213

1314
function ResultsDetailsLayout({
1415
runData,
@@ -17,6 +18,7 @@ function ResultsDetailsLayout({
1718
handleCloseCustomLayout,
1819
handleRun,
1920
}) {
21+
const { t } = useTranslation(["common"]);
2022
const optimizables = checkIfHaveOptimazers(runData.parameters);
2123
const updatedTabs = tabsResultsDetails.map((tab) => ({
2224
...tab,
@@ -28,7 +30,7 @@ function ResultsDetailsLayout({
2830
startIcon={<ArrowBackIosNewIcon />}
2931
onClick={handleCloseCustomLayout}
3032
>
31-
Close
33+
{t("common:close")}
3234
</Button>
3335

3436
<Paper sx={{ mt: 2 }}>
@@ -49,7 +51,7 @@ function ResultsDetailsLayout({
4951
{/* {currentTab === 1 && <ResultsTabParameters runData={runData} />}
5052
{currentTab === 2 && <ResultsTabMetrics runData={runData} />} */}
5153
{currentTab === 3 && <ResultsTabHyperparameters runData={runData} />}
52-
{currentTab === 4 && <Typography>TODO...</Typography>}
54+
{currentTab === 4 && <Typography>{t("common:todo")}</Typography>}
5355
</Box>
5456
</Paper>
5557
</CustomLayout>

DashAI/front/src/pages/results/components/ResultsDialogLayout.jsx

Lines changed: 68 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ import { LoadingButton } from "@mui/lab";
3131
import { useTourContext } from "../../../components/tour/TourProvider";
3232
import { deleteRun } from "../../../api/run";
3333
import DeleteConfirmationModal from "../../../components/threeSectionLayout/DeleteConfirmationModal";
34+
import { useTranslation } from "react-i18next";
3435

3536
function ResultsDialogLayout({
3637
experiment,
@@ -57,6 +58,7 @@ function ResultsDialogLayout({
5758
const tourContext = useTourContext();
5859
const hasNotifiedRef = useRef(false);
5960
const { enqueueSnackbar } = useSnackbar();
61+
const { t } = useTranslation(["models", "common"]);
6062

6163
const hasActiveRuns = runs.some(
6264
(r) => r.status === "Delivered" || r.status === "Started",
@@ -95,9 +97,12 @@ function ResultsDialogLayout({
9597
if (allRunsFinished && !hasNotifiedRef.current) {
9698
hasNotifiedRef.current = true;
9799

98-
enqueueSnackbar(`${experiment.name} has completed all runs`, {
99-
variant: "success",
100-
});
100+
enqueueSnackbar(
101+
t("models:message.allRunsCompleted", { experiment: experiment.name }),
102+
{
103+
variant: "success",
104+
},
105+
);
101106

102107
setFinishedRunning(true);
103108

@@ -106,9 +111,13 @@ function ResultsDialogLayout({
106111
}
107112
}
108113
} catch (error) {
109-
enqueueSnackbar(`Error retrieving runs for ${experiment.name}`, {
110-
variant: "error",
111-
});
114+
enqueueSnackbar(
115+
t("models:message.errorFetchingRuns"),
116+
{ experiment: experiment.name },
117+
{
118+
variant: "error",
119+
},
120+
);
112121
console.error("Error fetching runs:", error);
113122
} finally {
114123
if (showLoading) {
@@ -131,19 +140,28 @@ function ResultsDialogLayout({
131140
},
132141
(result) => {
133142
console.error(`Run job ${response.id} failed:`, result);
134-
enqueueSnackbar(`Run failed: ${result.error || "Unknown error"}`, {
135-
variant: "error",
136-
});
143+
enqueueSnackbar(
144+
t("models:message.runFailed", {
145+
error: result.error || t("common:unknownError"),
146+
}),
147+
{
148+
variant: "error",
149+
},
150+
);
137151
getRuns({ showLoading: false });
138152
},
139153
);
140154
}
141155

142156
return false;
143157
} catch (error) {
144-
enqueueSnackbar(`Error enqueueing run with ID ${runId}`, {
145-
variant: "error",
146-
});
158+
enqueueSnackbar(
159+
t("models:message.errorEnqueueingRun"),
160+
{ runId },
161+
{
162+
variant: "error",
163+
},
164+
);
147165
console.error("Error enqueueing run:", error);
148166
return true;
149167
}
@@ -168,10 +186,7 @@ function ResultsDialogLayout({
168186
});
169187

170188
if (runsToExecute.length === 0) {
171-
enqueueSnackbar(
172-
"No runs available to execute. Selected runs may already be running or completed.",
173-
{ variant: "info" },
174-
);
189+
enqueueSnackbar(t("models:message.noRunsToExecute"), { variant: "info" });
175190
return;
176191
}
177192

@@ -194,15 +209,19 @@ function ResultsDialogLayout({
194209

195210
if (enqueueErrors < runsToExecute.length) {
196211
enqueueSnackbar(
197-
`${runsToExecute.length - enqueueErrors} run(s) started successfully`,
212+
t("models:message.runsStartedSuccessfully", {
213+
count: runsToExecute.length - enqueueErrors,
214+
}),
198215
{ variant: "success" },
199216
);
200217
} else {
201218
getRuns({ showLoading: false });
202219
}
203220
} catch (error) {
204221
console.error("Error executing runs:", error);
205-
enqueueSnackbar("Error executing runs", { variant: "error" });
222+
enqueueSnackbar(t("models:error.errorExecutingRuns"), {
223+
variant: "error",
224+
});
206225

207226
getRuns({ showLoading: false });
208227
}
@@ -218,17 +237,25 @@ function ResultsDialogLayout({
218237
const response = await enqueueRunnerJobRequest(run.id);
219238

220239
if (!response || !response.id) {
221-
enqueueSnackbar(`Error starting run ${run.id}`, {
222-
variant: "error",
223-
});
240+
enqueueSnackbar(
241+
t("models:error.errorEnqueueingRun"),
242+
{ runId: run.id },
243+
{
244+
variant: "error",
245+
},
246+
);
224247
return;
225248
}
226249

227250
// Update run to "Delivered" status
228251
initialUpdatedRun.status = 1;
229-
enqueueSnackbar(`Run ${run.id} started successfully`, {
230-
variant: "success",
231-
});
252+
enqueueSnackbar(
253+
t("models:message.runStartedSuccessfully"),
254+
{ runId: run.id },
255+
{
256+
variant: "success",
257+
},
258+
);
232259

233260
// Track job ID
234261
setTrackedJobIds((prev) => new Set(prev).add(response.id));
@@ -265,7 +292,10 @@ function ResultsDialogLayout({
265292
async (result) => {
266293
// Job failed, still fetch only this run
267294
enqueueSnackbar(
268-
`Run ${run.id} failed: ${result.error || "Unknown error"}`,
295+
t("models:error.runFailedId", {
296+
runId: run.id,
297+
error: result.error || t("common:unknownError"),
298+
}),
269299
{ variant: "error" },
270300
);
271301

@@ -286,9 +316,13 @@ function ResultsDialogLayout({
286316
} catch (error) {
287317
console.error("Error enqueueing run:", error);
288318

289-
enqueueSnackbar(`Error starting run ${run.id}`, {
290-
variant: "error",
291-
});
319+
enqueueSnackbar(
320+
t("models:error.errorEnqueueingRun"),
321+
{ runId: run.id },
322+
{
323+
variant: "error",
324+
},
325+
);
292326

293327
// Fetch only the affected run to restore its real status
294328
const updated = await getRunById(run.id);
@@ -355,7 +389,7 @@ function ResultsDialogLayout({
355389
justifyContent: "space-between",
356390
}}
357391
>
358-
{`Experiment ${experiment.name} results`}
392+
{t("models:label.experimentResults", { name: experiment.name })}
359393
<IconButton
360394
onClick={handleOnClose}
361395
sx={{
@@ -390,18 +424,20 @@ function ResultsDialogLayout({
390424
} else {
391425
await deleteRun(runToDelete);
392426
}
393-
enqueueSnackbar("Run deleted successfully", {
427+
enqueueSnackbar(t("models:message.runDeletedSuccessfully"), {
394428
variant: "success",
395429
});
396430
} catch (error) {
397431
console.error("Error deleting run:", error);
398-
enqueueSnackbar("Error deleting run", { variant: "error" });
432+
enqueueSnackbar(t("models:error.errorDeletingRun"), {
433+
variant: "error",
434+
});
399435
} finally {
400436
setOpenDeleteModal(false);
401437
setRunToDelete(null);
402438
}
403439
}}
404-
content="Are you sure you want to delete this run? This action cannot be undone."
440+
content={t("models:message.confirmDeleteRun")}
405441
/>
406442
)}
407443

0 commit comments

Comments
 (0)