Skip to content

Commit 56cfab4

Browse files
committed
Merge branch 'origin/develop' into feat/multilingual-front
2 parents bdc590e + e77c3ea commit 56cfab4

20 files changed

Lines changed: 1314 additions & 292 deletions

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

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -347,7 +347,11 @@ function PrepareDatasetStep({ newExp, setNewExp, setNextEnabled }) {
347347

348348
return (
349349
<React.Fragment>
350-
<Alert severity={columnsAreValid ? "success" : "error"} sx={{ mb: 1 }}>
350+
<Alert
351+
severity={columnsAreValid ? "success" : "error"}
352+
sx={{ mb: 1 }}
353+
data-tour="models-validation-alert"
354+
>
351355
<AlertTitle>
352356
{taskRequirements
353357
? t(

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

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -258,9 +258,9 @@ function AddModelDialog({
258258
const isStep1Valid = Boolean(selectedModel && name.trim() !== "");
259259
const isStep2Valid = Boolean(
260260
selectedOptimizer &&
261-
optimizerParameters &&
262-
Object.keys(optimizerParameters).length > 0 &&
263-
goalMetric,
261+
optimizerParameters &&
262+
Object.keys(optimizerParameters).length > 0 &&
263+
goalMetric,
264264
);
265265

266266
return (
@@ -317,7 +317,7 @@ function AddModelDialog({
317317
/>
318318

319319
{selectedModel && (
320-
<Box>
320+
<Box data-tour="model-config">
321321
<Typography variant="subtitle2" sx={{ mb: 2 }}>
322322
{t("common:modelParameters")}
323323
</Typography>
@@ -391,6 +391,7 @@ function AddModelDialog({
391391
</Button>
392392
)}
393393
<Button
394+
data-tour="add-model-button"
394395
onClick={handleNext}
395396
variant="contained"
396397
disabled={

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

Lines changed: 53 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
1-
import { useState, useMemo, useEffect } from "react";
1+
import { useState, useMemo, useEffect, useRef } from "react";
22
import PropTypes from "prop-types";
33
import { Box, Stepper, Step, StepLabel } from "@mui/material";
44
import { useSnackbar } from "notistack";
55
import { useFormik } from "formik";
6+
import { useTourContext } from "../tour/TourProvider";
67
import SetNameAndDatasetStep from "./SetNameAndDatasetStep";
78
import PrepareDatasetStep from "../experiments/PrepareDatasetStep";
89
import FormSchemaButtonGroup from "../shared/FormSchemaButtonGroup";
@@ -23,13 +24,40 @@ function CreateSessionSteps({
2324
const [activeStep, setActiveStep] = useState(0);
2425
const { enqueueSnackbar } = useSnackbar();
2526
const { t } = useTranslation(["models", "common"]);
27+
const tourContext = useTourContext();
28+
const hasAdvancedTourRef = useRef(false);
2629

2730
const [selectedDataset, setSelectedDataset] = useState(
2831
preselectedDatasetId
2932
? datasets.find((d) => d.id === preselectedDatasetId) || null
3033
: null,
3134
);
3235

36+
const handleDatasetChange = (newDataset) => {
37+
setSelectedDataset(newDataset);
38+
if (
39+
tourContext?.run &&
40+
tourContext?.stepIndex === 5 &&
41+
newDataset &&
42+
!hasAdvancedTourRef.current
43+
) {
44+
hasAdvancedTourRef.current = true;
45+
const waitForElement = () => {
46+
const element = document.querySelector(
47+
'[data-tour="models-next-button"]',
48+
);
49+
if (element) {
50+
setTimeout(() => {
51+
tourContext.nextStep();
52+
}, 100);
53+
} else {
54+
setTimeout(waitForElement, 100);
55+
}
56+
};
57+
setTimeout(waitForElement, 200);
58+
}
59+
};
60+
3361
const [newExp, setNewExp] = useState({
3462
name: "",
3563
dataset: null,
@@ -84,6 +112,22 @@ function CreateSessionSteps({
84112
}));
85113
setActiveStep(1);
86114
setNextEnabled(false);
115+
116+
if (tourContext?.run && tourContext?.stepIndex === 6) {
117+
const waitForElement = () => {
118+
const element = document.querySelector(
119+
'[data-tour="models-validation-alert"]',
120+
);
121+
if (element) {
122+
setTimeout(() => {
123+
tourContext.nextStep();
124+
}, 100);
125+
} else {
126+
setTimeout(waitForElement, 100);
127+
}
128+
};
129+
setTimeout(waitForElement, 300);
130+
}
87131
} else if (activeStep === 1) {
88132
await createSession();
89133
}
@@ -180,6 +224,11 @@ function CreateSessionSteps({
180224
variant: "success",
181225
});
182226

227+
if (tourContext?.run) {
228+
tourContext.stopTour();
229+
sessionStorage.setItem("startModelsSessionTour", "true");
230+
}
231+
183232
if (handleSessionCreated) {
184233
handleSessionCreated(response);
185234
}
@@ -196,7 +245,6 @@ function CreateSessionSteps({
196245
return (
197246
<>
198247
<Box sx={{ height: "100%", display: "flex", flexDirection: "column" }}>
199-
{/* Stepper */}
200248
<Box sx={{ p: 2 }}>
201249
<Stepper activeStep={activeStep}>
202250
{steps.map((label) => (
@@ -207,16 +255,16 @@ function CreateSessionSteps({
207255
</Stepper>
208256
</Box>
209257

210-
{/* Step content */}
211258
<Box sx={{ flexGrow: 1, overflow: "auto", p: 2 }}>
212259
{activeStep === 0 && (
213260
<SetNameAndDatasetStep
214261
formik={formik}
215262
selectedDataset={selectedDataset}
216-
setSelectedDataset={setSelectedDataset}
263+
setSelectedDataset={handleDatasetChange}
217264
datasets={datasets}
218265
nameError={nameError}
219266
selectedTask={selectedTask}
267+
onDatasetChange={handleDatasetChange}
220268
/>
221269
)}
222270
{activeStep === 1 && (
@@ -228,11 +276,11 @@ function CreateSessionSteps({
228276
)}
229277
</Box>
230278

231-
{/* Footer with navigation buttons */}
232279
<Box sx={{ display: "flex", justifyContent: "flex-end", p: 2 }}>
233280
<FormSchemaButtonGroup
234281
onCancel={handleBack}
235282
onFormSubmit={formik.handleSubmit}
283+
dataTour="models-next-button"
236284
formik={{
237285
errors: {
238286
...(nameError ? { name: nameError } : {}),
@@ -254,7 +302,6 @@ function CreateSessionSteps({
254302
</Box>
255303
</Box>
256304

257-
{/* Job Queue Widget */}
258305
<Box
259306
sx={{
260307
position: "fixed",

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -179,11 +179,12 @@ export default function ModelsRightBar({ session, onToggle, onModelClick }) {
179179
</Box>
180180
) : (
181181
<Box sx={{ display: "flex", flexDirection: "column", gap: 1 }}>
182-
{filteredModels.map((model) => (
182+
{filteredModels.map((model, index) => (
183183
<ModelListItem
184184
key={model.name}
185185
model={model}
186186
onClick={() => handleModelClick(model)}
187+
data-tour={index === 0 ? "first-model" : undefined}
187188
/>
188189
))}
189190
</Box>

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

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ function RunCard({
4747
onDelete,
4848
onOperationsRefresh,
4949
explainerRefreshTrigger,
50+
isLastRun = false,
5051
}) {
5152
const [expanded, setExpanded] = useState(false);
5253
const { t } = useTranslation(["models", "common"]);
@@ -113,10 +114,10 @@ function RunCard({
113114
statusText === "Finished"
114115
? "success.main"
115116
: statusText === "Error"
116-
? "error.main"
117-
: isRunning
118-
? "info.main"
119-
: "grey.500",
117+
? "error.main"
118+
: isRunning
119+
? "info.main"
120+
: "grey.500",
120121
}}
121122
>
122123
<CardContent>
@@ -300,6 +301,7 @@ function RunCard({
300301
)}
301302
{canTrain && (
302303
<Button
304+
data-tour={isLastRun ? "train-button" : undefined}
303305
size="small"
304306
startIcon={<PlayArrow />}
305307
onClick={() => onTrain(run)}

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

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -200,6 +200,7 @@ export default function SessionVisualization({
200200
>
201201
{/* Sticky Comparison Table */}
202202
<Paper
203+
data-tour="model-comparison-panel"
203204
sx={{
204205
height: `${tableHeight}px`,
205206
flexShrink: 0,
@@ -260,6 +261,7 @@ export default function SessionVisualization({
260261
{t("common:table")}
261262
</Button>
262263
<Button
264+
data-tour="graphs-button"
263265
variant={!showTable ? "contained" : "outlined"}
264266
onClick={() => handleToggleView(false)}
265267
startIcon={<BarChart />}
@@ -354,6 +356,7 @@ export default function SessionVisualization({
354356

355357
{/* Scrollable Run Cards */}
356358
<Box
359+
data-tour="run-cards-section"
357360
sx={{
358361
flex: 1,
359362
overflow: "auto",
@@ -375,10 +378,15 @@ export default function SessionVisualization({
375378
</Box>
376379
) : (
377380
<Stack spacing={2}>
378-
{sortedRuns.map((run) => (
381+
{sortedRuns.map((run, index) => (
379382
<Box
380383
key={run.id}
381384
id={`run-card-${run.id}`}
385+
data-tour={
386+
index === sortedRuns.length - 1
387+
? "first-run-card"
388+
: undefined
389+
}
382390
sx={{
383391
scrollMarginTop: "20px",
384392
transition: "all 0.3s ease",
@@ -397,6 +405,7 @@ export default function SessionVisualization({
397405
onExplainer={handleExplainer}
398406
onDelete={onDeleteRun}
399407
explainerRefreshTrigger={explainerRefreshTrigger}
408+
isLastRun={index === sortedRuns.length - 1}
400409
/>
401410
</Box>
402411
))}

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

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,15 @@ function SetNameAndDatasetStep({
1010
datasets,
1111
nameError,
1212
selectedTask,
13+
onDatasetChange,
1314
}) {
1415
const { t } = useTranslation(["models"]);
16+
const handleDatasetChange = (newDataset) => {
17+
setSelectedDataset(newDataset);
18+
if (onDatasetChange) {
19+
onDatasetChange(newDataset);
20+
}
21+
};
1522

1623
return (
1724
<Grid
@@ -38,7 +45,7 @@ function SetNameAndDatasetStep({
3845
<DatasetAutocomplete
3946
datasets={datasets}
4047
selectedDataset={selectedDataset}
41-
setSelectedDataset={setSelectedDataset}
48+
setSelectedDataset={handleDatasetChange}
4249
/>
4350
</Grid>
4451

@@ -79,6 +86,7 @@ SetNameAndDatasetStep.propTypes = {
7986
datasets: PropTypes.array.isRequired,
8087
nameError: PropTypes.string,
8188
selectedTask: PropTypes.object,
89+
onDatasetChange: PropTypes.func,
8290
};
8391

8492
export default SetNameAndDatasetStep;

DashAI/front/src/components/models/model/ModelListItem.jsx

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,12 @@ import { Box, Typography, Tooltip } from "@mui/material";
33
import HoverModelInfo from "./HoverModelInfo";
44
import { ModelIcon } from "./ModelIcon";
55

6-
export default function ModelListItem({ model, disabled = false, onClick }) {
6+
export default function ModelListItem({
7+
model,
8+
disabled = false,
9+
onClick,
10+
...props
11+
}) {
712
const [anchorEl, setAnchorEl] = useState(null);
813
const [hoveredModel, setHoveredModel] = useState(null);
914

@@ -53,6 +58,7 @@ export default function ModelListItem({ model, disabled = false, onClick }) {
5358
onMouseEnter={(e) => handleMouseEnter(e, model)}
5459
onMouseLeave={handleMouseLeave}
5560
onClick={disabled ? null : onClick}
61+
{...props}
5662
sx={{
5763
display: "flex",
5864
alignItems: "center",

DashAI/front/src/components/notebooks/notebookCreation/DatasetAutocomplete.jsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ export default function DatasetAutocomplete({
7171
<Box width="100%">
7272
<Box sx={{ width: "100%", mx: "auto" }}>
7373
<Autocomplete
74+
data-tour="models-dataset-selection"
7475
options={datasets}
7576
getOptionLabel={(option) => option.name}
7677
isOptionEqualToValue={(opt, val) => opt.id === val.id}

DashAI/front/src/components/threeSectionLayout/OptionBox.jsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ export default function OptionBox({
1919

2020
return (
2121
<Button
22+
data-tour="models-task-selection"
2223
onClick={onClick}
2324
sx={{
2425
p: 0,

0 commit comments

Comments
 (0)