diff --git a/DashAI/front/src/App.jsx b/DashAI/front/src/App.jsx
index f11648abd..43915a4c6 100644
--- a/DashAI/front/src/App.jsx
+++ b/DashAI/front/src/App.jsx
@@ -29,6 +29,8 @@ import RAGPromptsPage from "./pages/generative/RAG/RAGPromptsPage";
import RAGSessionPage from "./pages/generative/RAGSession/RAGSessionPage";
import SessionRouter from "./pages/generative/SessionRouter";
import { DatasetsAndNotebooksProvider } from "./components/custom/contexts/DatasetsAndNotebooksContext";
+import { DatasetsProvider } from "./contexts/DatasetsContext";
+import { ModelsProvider } from "./components/models/ModelsContext";
function DataSectionLayout() {
return (
@@ -44,83 +46,103 @@ function App() {
-
-
- } />
- } />
- }>
- } />
- } />
- }
- />
- } />
- } />
- } />
- } />
- }
- />
- } />
-
- } />
- } />
- } />
- }
- />
- }
- />
- } />
- }
- />
-
-
-
- }
- />
-
-
-
- }
- />
- } />
- }
- />
- }
- />
- } />
- } />
- }
- />
-
- } />
-
- } />
- } />
-
-
-
-
+
+
+
+
+
+ } />
+ } />
+ }>
+ } />
+ } />
+ }
+ />
+ } />
+ } />
+ } />
+ } />
+ }
+ />
+ } />
+
+ } />
+ }
+ />
+ }
+ />
+ }
+ />
+ }
+ />
+ } />
+
+ }
+ />
+
+
+
+ }
+ />
+
+
+
+ }
+ />
+ }
+ />
+ }
+ />
+ }
+ />
+ } />
+ }
+ />
+ }
+ />
+
+ } />
+
+ } />
+ } />
+
+
+
+
+
+
+
);
diff --git a/DashAI/front/src/components/custom/contexts/DatasetsAndNotebooksContext.jsx b/DashAI/front/src/components/custom/contexts/DatasetsAndNotebooksContext.jsx
index 3201fe7e8..fe9ef95ff 100644
--- a/DashAI/front/src/components/custom/contexts/DatasetsAndNotebooksContext.jsx
+++ b/DashAI/front/src/components/custom/contexts/DatasetsAndNotebooksContext.jsx
@@ -1,8 +1,7 @@
import { createContext, useContext, useEffect, useState } from "react";
import { useTranslation } from "react-i18next";
-import { useDatasets } from "../../../hooks/datasets/useDatasets";
-import { useFolders } from "../../../hooks/datasets/useFolders";
+import { useSharedDatasets } from "../../../contexts/DatasetsContext";
import { useNotebooks } from "../../../hooks/datasets/useNotebooks";
import { useDownloads } from "../../../hooks/datasets/useDownloads";
@@ -34,29 +33,14 @@ export const DatasetsAndNotebooksProvider = ({ children }) => {
addDatasetOptimistically,
replaceDatasets,
startDatasetPolling,
- } = useDatasets({ t });
-
- const {
folders,
fetchFolders,
createFolder,
renameFolder,
- deleteFolderById: deleteFolderByIdRaw,
- } = useFolders({ t });
-
- // Deleting a folder moves its datasets to "no folder" server-side
- // (folder_id set to null via the FK's ON DELETE SET NULL), but the local
- // `datasets` state still holds the old folder_id until this clears it —
- // otherwise those datasets vanish from the list until a full refetch.
- const deleteFolderById = async (id) => {
- const success = await deleteFolderByIdRaw(id);
- if (success) {
- replaceDatasets((prev) =>
- prev.map((d) => (d.folder_id === id ? { ...d, folder_id: null } : d)),
- );
- }
- return success;
- };
+ deleteFolderById,
+ openFolderIds,
+ setOpenFolderIds,
+ } = useSharedDatasets();
const {
downloads,
@@ -158,6 +142,8 @@ export const DatasetsAndNotebooksProvider = ({ children }) => {
setScrollToColumn,
uploadDataloader,
setUploadDataloader,
+ openFolderIds,
+ setOpenFolderIds,
};
return (
diff --git a/DashAI/front/src/components/generative/GenerativeContext.jsx b/DashAI/front/src/components/generative/GenerativeContext.jsx
index 21cc4536e..b280c3f49 100644
--- a/DashAI/front/src/components/generative/GenerativeContext.jsx
+++ b/DashAI/front/src/components/generative/GenerativeContext.jsx
@@ -28,6 +28,7 @@ export function GenerativeProvider({ children }) {
editSession,
} = useSessions({ t });
const [stepIndex, setStepIndex] = useState(0);
+ const [openSections, setOpenSections] = useState({});
useEffect(() => {
fetchSessions();
@@ -54,6 +55,8 @@ export function GenerativeProvider({ children }) {
fetchTasks,
stepIndex,
setStepIndex,
+ openSections,
+ setOpenSections,
deleteSessionById,
deleteSessionsByIds,
editSession,
diff --git a/DashAI/front/src/components/generative/SessionBar.jsx b/DashAI/front/src/components/generative/SessionBar.jsx
index 9aebd1480..a68745c30 100644
--- a/DashAI/front/src/components/generative/SessionBar.jsx
+++ b/DashAI/front/src/components/generative/SessionBar.jsx
@@ -4,7 +4,7 @@ import { useNavigate } from "react-router-dom";
import FolderIcon from "@mui/icons-material/Folder";
import ViewModuleIcon from "@mui/icons-material/ViewModule";
import SearchBar from "../threeSectionLayout/SearchBar";
-import { useEffect, useState } from "react";
+import { useEffect, useMemo, useState } from "react";
import InfoSessionModal from "./InfoSessionModal";
import GroupedCollapsibleList from "../threeSectionLayout/GroupedCollapsibleList";
import Footer from "../threeSectionLayout/Footer";
@@ -31,6 +31,8 @@ export default function SessionBar({
deleteSessionById,
deleteSessionsByIds,
editSession,
+ openSections,
+ setOpenSections,
} = useGenerative();
const sessions = sessionsProp ?? sessionsCtx ?? [];
@@ -38,7 +40,6 @@ export default function SessionBar({
const [searchQuery, setSearchQuery] = useState("");
const [filteredSessions, setFilteredSessions] = useState(sessions);
const [selectedInfoSession, setSelectedInfoSession] = useState(null);
- const [openSections, setOpenSections] = useState({});
const { t } = useTranslation(["generative", "common"]);
const SEARCH_THRESHOLD = 10;
@@ -48,11 +49,14 @@ export default function SessionBar({
}, [sessions.length]);
// Create a map of task_name to display_name for quick lookup
- const taskDisplayNameMap =
- tasks?.reduce((map, task) => {
- map[task.name] = task.display_name;
- return map;
- }, {}) || {};
+ const taskDisplayNameMap = useMemo(
+ () =>
+ tasks?.reduce((map, task) => {
+ map[task.name] = task.display_name;
+ return map;
+ }, {}) || {},
+ [tasks],
+ );
useEffect(() => {
// Initialize all sections as closed based on unique task display names
@@ -158,28 +162,32 @@ export default function SessionBar({
return ok;
};
- // Group sessions by task display_name
- const groupedSessions = filteredSessions?.reduce((groups, session) => {
- // Get the display name from the task using the session's task_name
- const displayName =
- taskDisplayNameMap[session.task_name] || t("common:other");
+ // Group sessions by task display_name, sorted to maintain a consistent order.
+ // Memoized so the object identity stays stable across renders that don't
+ // change the underlying data — GroupedCollapsibleList uses `groups` as an
+ // effect dependency, so a fresh literal every render would re-run it.
+ const sortedGroupedSessions = useMemo(() => {
+ const groupedSessions = filteredSessions?.reduce((groups, session) => {
+ // Get the display name from the task using the session's task_name
+ const displayName =
+ taskDisplayNameMap[session.task_name] || t("common:other");
- if (!groups[displayName]) {
- groups[displayName] = [];
- }
- groups[displayName].push(session);
- return groups;
- }, {});
+ if (!groups[displayName]) {
+ groups[displayName] = [];
+ }
+ groups[displayName].push(session);
+ return groups;
+ }, {});
- // Sort grouped sessions to maintain consistent order
- const sortedGroupedSessions = groupedSessions
- ? Object.keys(groupedSessions)
- .sort()
- .reduce((sorted, key) => {
- sorted[key] = groupedSessions[key];
- return sorted;
- }, {})
- : {};
+ return groupedSessions
+ ? Object.keys(groupedSessions)
+ .sort()
+ .reduce((sorted, key) => {
+ sorted[key] = groupedSessions[key];
+ return sorted;
+ }, {})
+ : {};
+ }, [filteredSessions, taskDisplayNameMap, t]);
return (
@@ -231,7 +239,8 @@ export default function SessionBar({
onItemInfo={handleSessionInfo}
title={t("common:generative")}
Icon={FolderIcon}
- initialOpenGroups={openSections}
+ openGroups={openSections}
+ onOpenGroupsChange={setOpenSections}
getItemDescription={(session) => session.model_name}
getDeleteConfirmationContent={getSessionDeleteConfirmationContent}
onBulkDelete={handleBulkSessionDelete}
diff --git a/DashAI/front/src/components/models/ModelsContext.jsx b/DashAI/front/src/components/models/ModelsContext.jsx
index fa46dd498..3c0578a7d 100644
--- a/DashAI/front/src/components/models/ModelsContext.jsx
+++ b/DashAI/front/src/components/models/ModelsContext.jsx
@@ -7,8 +7,7 @@ import {
useMemo,
} from "react";
import { useTranslation } from "react-i18next";
-import { useDatasets } from "../../hooks/datasets/useDatasets";
-import { useFolders } from "../../hooks/datasets/useFolders";
+import { useSharedDatasets } from "../../contexts/DatasetsContext";
import { useSessions } from "../../hooks/models/useSessions";
import { useModelComponents } from "../../hooks/models/useModelComponents";
const ModelsContext = createContext(null);
@@ -39,31 +38,14 @@ export function ModelsProvider({ children }) {
replaceDatasets,
startDatasetPolling,
moveDatasetToFolder,
- datasetRowCount,
- setDatasetRowCount,
- } = useDatasets({ t });
-
- const {
folders,
fetchFolders,
createFolder,
renameFolder,
- deleteFolderById: deleteFolderByIdRaw,
- } = useFolders({ t });
-
- // Deleting a folder moves its datasets to "no folder" server-side
- // (folder_id set to null via the FK's ON DELETE SET NULL), but the local
- // `datasets` state still holds the old folder_id until this clears it —
- // otherwise those datasets vanish from the list until a full refetch.
- const deleteFolderById = async (id) => {
- const success = await deleteFolderByIdRaw(id);
- if (success) {
- replaceDatasets((prev) =>
- prev.map((d) => (d.folder_id === id ? { ...d, folder_id: null } : d)),
- );
- }
- return success;
- };
+ deleteFolderById,
+ openFolderIds,
+ setOpenFolderIds,
+ } = useSharedDatasets();
const {
tasks,
@@ -116,6 +98,8 @@ export function ModelsProvider({ children }) {
const [runDetailTab, setRunDetailTab] = useState(null);
const [explainerRefreshTrigger, setExplainerRefreshTrigger] = useState(0);
const [explainerToCreate, setExplainerToCreate] = useState(null);
+ const [openSections, setOpenSections] = useState({});
+ const [datasetRowCount, setDatasetRowCount] = useState(null);
const [selectedStatisticalTest, setSelectedStatisticalTest] = useState(null);
const [statisticalTestsModalOpen, setStatisticalTestsModalOpen] =
useState(false);
@@ -156,7 +140,8 @@ export function ModelsProvider({ children }) {
}, []);
useEffect(() => {
- fetchDatasets();
+ // Datasets are fetched by the shared DatasetsProvider on its own mount;
+ // fetching them here too would duplicate GET /datasets on every app boot.
fetchSessions();
}, []);
@@ -250,6 +235,10 @@ export function ModelsProvider({ children }) {
explainerToCreate,
openExplainerCreator,
closeExplainerCreator,
+ openSections,
+ setOpenSections,
+ openFolderIds,
+ setOpenFolderIds,
selectedStatisticalTest,
statisticalTestsModalOpen,
openStatisticalTest,
@@ -319,6 +308,8 @@ export function ModelsProvider({ children }) {
explainerToCreate,
openExplainerCreator,
closeExplainerCreator,
+ openSections,
+ openFolderIds,
selectedStatisticalTest,
statisticalTestsModalOpen,
openStatisticalTest,
diff --git a/DashAI/front/src/components/models/ModelsLeftBar.jsx b/DashAI/front/src/components/models/ModelsLeftBar.jsx
index 683934593..65a0fdf76 100644
--- a/DashAI/front/src/components/models/ModelsLeftBar.jsx
+++ b/DashAI/front/src/components/models/ModelsLeftBar.jsx
@@ -1,4 +1,4 @@
-import React, { useState, useEffect } from "react";
+import React, { useState, useEffect, useMemo } from "react";
import { useNavigate } from "react-router-dom";
import { Box, Divider, Typography } from "@mui/material";
import { useTheme } from "@mui/material/styles";
@@ -39,6 +39,10 @@ export default function ModelsLeftBar({ onToggle }) {
renameFolder,
deleteFolderById,
moveDatasetToFolder,
+ openSections,
+ setOpenSections,
+ openFolderIds,
+ setOpenFolderIds,
} = useModels();
const navigate = useNavigate();
@@ -46,7 +50,6 @@ export default function ModelsLeftBar({ onToggle }) {
const [searchQuery, setSearchQuery] = useState("");
const [filteredDatasets, setFilteredDatasets] = useState(datasets);
const [filteredSessions, setFilteredSessions] = useState(sessions);
- const [openSections, setOpenSections] = useState({});
const [selectedInfoSession, setSelectedInfoSession] = useState(null);
const { t } = useTranslation(["models", "datasets", "common"]);
@@ -73,22 +76,23 @@ export default function ModelsLeftBar({ onToggle }) {
);
useEffect(() => {
- // Initialize all task sections as closed
+ // Sync the section map with the current task display names
const displayNames = [
...new Set(
sessions.map((session) => getTaskDisplayName(session.task_name)),
),
];
- const initialOpenState = {};
- displayNames.forEach((displayName) => {
- initialOpenState[displayName] = false;
- });
setOpenSections((prev) => {
// Only update if display names have changed
const prevKeys = Object.keys(prev).sort().join(",");
- const newKeys = Object.keys(initialOpenState).sort().join(",");
+ const newKeys = displayNames.slice().sort().join(",");
if (prevKeys === newKeys) return prev;
- return initialOpenState;
+ // Preserve existing open/close state; initialize new keys as closed
+ const merged = {};
+ displayNames.forEach((displayName) => {
+ merged[displayName] = displayName in prev ? prev[displayName] : false;
+ });
+ return merged;
});
}, [sessions, tasks]);
@@ -190,25 +194,29 @@ export default function ModelsLeftBar({ onToggle }) {
return session.description || "";
};
- // Group sessions by task
- const groupedSessions = filteredSessions?.reduce((groups, session) => {
- const displayName = getTaskDisplayName(session.task_name);
- if (!groups[displayName]) {
- groups[displayName] = [];
- }
- groups[displayName].push(session);
- return groups;
- }, {});
-
- // Sort grouped sessions to maintain consistent order
- const sortedGroupedSessions = groupedSessions
- ? Object.keys(groupedSessions)
- .sort()
- .reduce((sorted, key) => {
- sorted[key] = groupedSessions[key];
- return sorted;
- }, {})
- : {};
+ // Group sessions by task, sorted to maintain a consistent order.
+ // Memoized so the object identity stays stable across renders that don't
+ // change the underlying data — GroupedCollapsibleList uses `groups` as an
+ // effect dependency, so a fresh literal every render would re-run it.
+ const sortedGroupedSessions = useMemo(() => {
+ const groupedSessions = filteredSessions?.reduce((groups, session) => {
+ const displayName = getTaskDisplayName(session.task_name);
+ if (!groups[displayName]) {
+ groups[displayName] = [];
+ }
+ groups[displayName].push(session);
+ return groups;
+ }, {});
+
+ return groupedSessions
+ ? Object.keys(groupedSessions)
+ .sort()
+ .reduce((sorted, key) => {
+ sorted[key] = groupedSessions[key];
+ return sorted;
+ }, {})
+ : {};
+ }, [filteredSessions, getTaskDisplayName]);
const onDatasetClick = (datasetId) => {
navigate(`/app/models/datasets/${datasetId}`);
@@ -329,6 +337,8 @@ export default function ModelsLeftBar({ onToggle }) {
{
+ const next = typeof updater === "function" ? updater(open) : updater;
+ if (isControlled) {
+ onToggleOpen?.(next);
+ } else {
+ setInternalOpen(next);
+ }
+ };
const [isRenaming, setIsRenaming] = useState(false);
const [renameValue, setRenameValue] = useState(folderName);
const [deleteDialogOpen, setDeleteDialogOpen] = useState(false);
@@ -120,10 +132,6 @@ function FolderSection({
}
}, [isRenaming]);
- useEffect(() => {
- if (selectionMode) setOpen(true);
- }, [selectionMode]);
-
const handleRenameKeyDown = async (e) => {
if (e.key === "Enter") {
if (renameValue.trim() && renameValue.trim() !== folderName) {
@@ -384,6 +392,8 @@ export default function DatasetFolderList({
getDeleteConfirmationContent,
getDeleteConfirmationWarning,
title,
+ openFolderIds = {},
+ setOpenFolderIds,
}) {
const theme = useTheme();
const [activeId, setActiveId] = useState(null);
@@ -681,7 +691,13 @@ export default function DatasetFolderList({
folderName={folder.name}
items={folderDatasets}
isOver={overId === String(folder.id)}
- defaultOpen={true}
+ open={selectionMode || (openFolderIds[folder.id] ?? true)}
+ onToggleOpen={(next) =>
+ setOpenFolderIds?.((prev) => ({
+ ...prev,
+ [folder.id]: next,
+ }))
+ }
selectedItemId={selectedItemId}
onItemClick={onItemClick}
onItemDelete={onItemDelete}
diff --git a/DashAI/front/src/components/threeSectionLayout/GroupedCollapsibleList.jsx b/DashAI/front/src/components/threeSectionLayout/GroupedCollapsibleList.jsx
index e0c5fae80..8197d062b 100644
--- a/DashAI/front/src/components/threeSectionLayout/GroupedCollapsibleList.jsx
+++ b/DashAI/front/src/components/threeSectionLayout/GroupedCollapsibleList.jsx
@@ -31,6 +31,8 @@ export default function GroupedCollapsibleList({
getDeleteConfirmationContent,
getDeleteConfirmationWarning,
initialOpenGroups = {},
+ openGroups: controlledOpenGroups,
+ onOpenGroupsChange,
onBulkDelete,
selectItemsTooltip = t(
"common:selectItemsToDelete",
@@ -45,7 +47,30 @@ export default function GroupedCollapsibleList({
bulkDeleteConfirmationWarning,
}) {
const theme = useTheme();
- const [openGroups, setOpenGroups] = useState(initialOpenGroups);
+ const isControlled = controlledOpenGroups !== undefined;
+ const [internalOpenGroups, setInternalOpenGroups] =
+ useState(initialOpenGroups);
+ const openGroups = isControlled ? controlledOpenGroups : internalOpenGroups;
+ const setOpenGroups = (updater) => {
+ const next = typeof updater === "function" ? updater(openGroups) : updater;
+ // Bail out on no-op updates. These are flat {groupName: boolean} maps, so a
+ // shallow key/value comparison is enough. Without this, a "set group X open"
+ // call for an already-open group would still notify the controlled parent,
+ // which re-renders the caller, which rebuilds `groups`, which re-triggers
+ // the auto-open effect below -> infinite render loop.
+ const isSame =
+ next === openGroups ||
+ (!!next &&
+ !!openGroups &&
+ Object.keys(next).length === Object.keys(openGroups).length &&
+ Object.keys(next).every((key) => next[key] === openGroups[key]));
+ if (isSame) return;
+ if (isControlled) {
+ onOpenGroupsChange?.(next);
+ } else {
+ setInternalOpenGroups(next);
+ }
+ };
const selectedItemRef = useRef(null);
const [selectionMode, setSelectionMode] = useState(false);
const [selectedIds, setSelectedIds] = useState(() => new Set());
diff --git a/DashAI/front/src/contexts/DatasetsContext.jsx b/DashAI/front/src/contexts/DatasetsContext.jsx
new file mode 100644
index 000000000..164b5c2bb
--- /dev/null
+++ b/DashAI/front/src/contexts/DatasetsContext.jsx
@@ -0,0 +1,126 @@
+import {
+ createContext,
+ useContext,
+ useCallback,
+ useMemo,
+ useState,
+} from "react";
+import { useTranslation } from "react-i18next";
+import { useDatasets } from "../hooks/datasets/useDatasets";
+import { useFolders } from "../hooks/datasets/useFolders";
+
+const DatasetsContext = createContext(null);
+
+export const useSharedDatasets = () => useContext(DatasetsContext);
+
+export function DatasetsProvider({ children }) {
+ const { t } = useTranslation(["datasets", "common"]);
+
+ const {
+ datasets,
+ createDataset,
+ selectedDatasetId,
+ fetchDatasets,
+ selectDataset,
+ clearSelectedDataset,
+ deleteDataset,
+ deleteDatasetById,
+ deleteDatasetsByIds,
+ editDataset,
+ addDatasetOptimistically,
+ replaceDatasets,
+ startDatasetPolling,
+ moveDatasetToFolder,
+ } = useDatasets({ t });
+
+ const {
+ folders,
+ fetchFolders,
+ createFolder,
+ renameFolder,
+ deleteFolderById: deleteFolderByIdRaw,
+ } = useFolders({ t });
+
+ // Which named folders are open/closed in the sidebar. Shared here (not in
+ // ModelsContext/DatasetsAndNotebooksContext individually) so the Datasets
+ // and Models modules — which each render their own DatasetFolderList
+ // instance — show the same open/closed state instead of two independent
+ // copies. A folder id with no entry here defaults to open (see
+ // DatasetFolderList's read side).
+ const [openFolderIds, setOpenFolderIds] = useState({});
+
+ // Deleting a folder moves its datasets to "no folder" server-side
+ // (folder_id set to null via the FK's ON DELETE SET NULL), but the local
+ // `datasets` state still holds the old folder_id until this clears it —
+ // otherwise those datasets vanish from the list until a full refetch.
+ const deleteFolderById = useCallback(
+ async (id) => {
+ const success = await deleteFolderByIdRaw(id);
+ if (success) {
+ replaceDatasets((prev) =>
+ prev.map((d) => (d.folder_id === id ? { ...d, folder_id: null } : d)),
+ );
+ setOpenFolderIds((prev) => {
+ const { [id]: _removed, ...rest } = prev;
+ return rest;
+ });
+ }
+ return success;
+ },
+ [deleteFolderByIdRaw, replaceDatasets],
+ );
+
+ const value = useMemo(
+ () => ({
+ datasets,
+ createDataset,
+ selectedDatasetId,
+ fetchDatasets,
+ selectDataset,
+ clearSelectedDataset,
+ deleteDataset,
+ deleteDatasetById,
+ deleteDatasetsByIds,
+ editDataset,
+ addDatasetOptimistically,
+ replaceDatasets,
+ startDatasetPolling,
+ moveDatasetToFolder,
+ folders,
+ fetchFolders,
+ createFolder,
+ renameFolder,
+ deleteFolderById,
+ openFolderIds,
+ setOpenFolderIds,
+ }),
+ [
+ datasets,
+ createDataset,
+ selectedDatasetId,
+ fetchDatasets,
+ selectDataset,
+ clearSelectedDataset,
+ deleteDataset,
+ deleteDatasetById,
+ deleteDatasetsByIds,
+ editDataset,
+ addDatasetOptimistically,
+ replaceDatasets,
+ startDatasetPolling,
+ moveDatasetToFolder,
+ folders,
+ fetchFolders,
+ createFolder,
+ renameFolder,
+ deleteFolderById,
+ openFolderIds,
+ ],
+ );
+
+ return (
+
+ {children}
+
+ );
+}
diff --git a/DashAI/front/src/pages/generative/Generative.jsx b/DashAI/front/src/pages/generative/Generative.jsx
index 3b8c0a706..83f10a4f2 100644
--- a/DashAI/front/src/pages/generative/Generative.jsx
+++ b/DashAI/front/src/pages/generative/Generative.jsx
@@ -1,14 +1,11 @@
import { TourProvider } from "../../components/tour/TourProvider";
import { TOUR_KEYS } from "../../constants/tours";
-import { GenerativeProvider } from "../../components/generative/GenerativeContext";
import GenerativeContent from "./GenerativeContent";
export default function Generative() {
return (
-
-
-
+
);
}
diff --git a/DashAI/front/src/pages/models/Models.jsx b/DashAI/front/src/pages/models/Models.jsx
index 462021863..774bba43d 100644
--- a/DashAI/front/src/pages/models/Models.jsx
+++ b/DashAI/front/src/pages/models/Models.jsx
@@ -1,10 +1,5 @@
import ModelsContent from "./ModelsContent";
-import { ModelsProvider } from "../../components/models/ModelsContext";
export default function Models() {
- return (
-
-
-
- );
+ return ;
}
diff --git a/tests/back/api/test_model_session_api.py b/tests/back/api/test_model_session_api.py
index d9efcadfb..23624d537 100644
--- a/tests/back/api/test_model_session_api.py
+++ b/tests/back/api/test_model_session_api.py
@@ -16,7 +16,7 @@
"train_metrics": [],
"validation_metrics": [],
"test_metrics": [],
- "evaluation_strategy": "holdout",
+ "evaluation_strategy": "HoldoutEvaluationStrategy",
"splits": json.dumps(
{
"train": 0.5,