From 0e87c2f9caaaaf417560f051aa3e245a067c4241 Mon Sep 17 00:00:00 2001 From: Anis Date: Thu, 23 Jan 2025 11:00:04 +0100 Subject: [PATCH 1/4] feat(ui-studies): sort study tree folders (#2300) Co-authored-by: Anis SMAIL Co-authored-by: Samir Kamal <1954121+skamril@users.noreply.github.com> --- .../components/App/Studies/StudyTree/StudyTreeNode.tsx | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/webapp/src/components/App/Studies/StudyTree/StudyTreeNode.tsx b/webapp/src/components/App/Studies/StudyTree/StudyTreeNode.tsx index e84b9592c9..7d3644f06f 100644 --- a/webapp/src/components/App/Studies/StudyTree/StudyTreeNode.tsx +++ b/webapp/src/components/App/Studies/StudyTree/StudyTreeNode.tsx @@ -12,7 +12,8 @@ * This file is part of the Antares project. */ -import { memo } from "react"; +import { memo, useMemo } from "react"; +import * as R from "ramda"; import type { StudyTreeNodeProps } from "./types"; import TreeItemEnhanced from "@/components/common/TreeItemEnhanced"; import { t } from "i18next"; @@ -25,6 +26,11 @@ export default memo(function StudyTreeNode({ const isLoadingFolder = studyTreeNode.hasChildren && studyTreeNode.children.length === 0; const id = parentId ? `${parentId}/${studyTreeNode.name}` : studyTreeNode.name; + const sortedChildren = useMemo( + () => R.sortBy(R.prop("name"), studyTreeNode.children), + [studyTreeNode.children], + ); + if (isLoadingFolder) { return ( onNodeClick(id, studyTreeNode)} > - {studyTreeNode.children.map((child) => ( + {sortedChildren.map((child) => ( Date: Thu, 23 Jan 2025 11:03:51 +0100 Subject: [PATCH 2/4] fix(ui): resolve sonar complexity warning (#2311) --- .../components/App/Singlestudy/NavHeader/Details.tsx | 4 ++-- webapp/src/services/utils/index.ts | 10 ++++------ 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/webapp/src/components/App/Singlestudy/NavHeader/Details.tsx b/webapp/src/components/App/Singlestudy/NavHeader/Details.tsx index 3a557db208..4ea99b62fb 100644 --- a/webapp/src/components/App/Singlestudy/NavHeader/Details.tsx +++ b/webapp/src/components/App/Singlestudy/NavHeader/Details.tsx @@ -24,7 +24,7 @@ import { Link } from "react-router-dom"; import { buildModificationDate, convertUTCToLocalTime, - countAllChildrens, + countDescendants, displayVersionName, } from "../../../../services/utils"; import type { StudyMetadata, VariantTree } from "../../../../common/types"; @@ -105,7 +105,7 @@ function Details({ study, parent, childrenTree }: Props) { {childrenTree && ( - {countAllChildrens(childrenTree)} + {countDescendants(childrenTree)} )} diff --git a/webapp/src/services/utils/index.ts b/webapp/src/services/utils/index.ts index 4c73f86c13..0e28479055 100644 --- a/webapp/src/services/utils/index.ts +++ b/webapp/src/services/utils/index.ts @@ -201,12 +201,10 @@ export const buildModificationDate = ( return duration.locale(language.substring(0, 2) === "fr" ? "fr" : "en").humanize(); }; -export const countAllChildrens = (tree: VariantTree): number => { - if (tree.children.length > 0) { - return tree.children.map((elm) => 1 + countAllChildrens(elm)).reduce((acc, curr) => acc + curr); - } - return 0; -}; +export const countDescendants = (tree: VariantTree): number => + tree.children.length + ? tree.children.reduce((sum, child) => sum + 1 + countDescendants(child), 0) + : 0; export const findNodeInTree = (studyId: string, tree: VariantTree): VariantTree | undefined => { if (studyId === tree.node.id) { From e300c9446731e0e2d314aa44f8e2e30b56ed1037 Mon Sep 17 00:00:00 2001 From: Anis Date: Fri, 24 Jan 2025 10:29:29 +0100 Subject: [PATCH 3/4] fix(ui-studies): display 'default' workspace even if empty (#2301) Co-authored-by: Anis SMAIL --- .../App/Studies/StudyTree/__test__/fixtures.ts | 10 ++++++++++ webapp/src/components/App/Studies/StudyTree/utils.ts | 11 ++++++++++- 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/webapp/src/components/App/Studies/StudyTree/__test__/fixtures.ts b/webapp/src/components/App/Studies/StudyTree/__test__/fixtures.ts index 5ac08ebfb2..616d018500 100644 --- a/webapp/src/components/App/Studies/StudyTree/__test__/fixtures.ts +++ b/webapp/src/components/App/Studies/StudyTree/__test__/fixtures.ts @@ -238,6 +238,11 @@ export const FIXTURES_BUILD_STUDY_TREE = { name: "root", path: "", children: [ + { + name: "default", + path: "/default", + children: [], + }, { name: "workspace", path: "/workspace", @@ -270,6 +275,11 @@ export const FIXTURES_BUILD_STUDY_TREE = { name: "root", path: "", children: [ + { + name: "default", + path: "/default", + children: [], + }, { name: "workspace", path: "/workspace", diff --git a/webapp/src/components/App/Studies/StudyTree/utils.ts b/webapp/src/components/App/Studies/StudyTree/utils.ts index 87670d03e6..405ecb6ceb 100644 --- a/webapp/src/components/App/Studies/StudyTree/utils.ts +++ b/webapp/src/components/App/Studies/StudyTree/utils.ts @@ -23,9 +23,18 @@ import type { StudyTreeNode, NonStudyFolderDTO } from "./types"; * @returns A tree structure representing the studies. */ export function buildStudyTree(studies: StudyMetadata[]) { + // It is important to initialize the root node with the default workspace as a child + // Otherwise we won't see the default workspace if no study has a path (which only + // happens when a user moves a study to another folder) const tree: StudyTreeNode = { name: "root", - children: [], + children: [ + { + name: "default", + children: [], + path: "/default", + }, + ], path: "", }; From a31f9c14fe5f1617210cab30fe45d89a33ceb417 Mon Sep 17 00:00:00 2001 From: Anis Date: Fri, 24 Jan 2025 10:45:04 +0100 Subject: [PATCH 4/4] fix(ui-studies): 615 minor fixes (#2314) Co-authored-by: Anis SMAIL --- webapp/src/components/App/Studies/StudiesList/index.tsx | 2 +- webapp/src/redux/ducks/studies.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/webapp/src/components/App/Studies/StudiesList/index.tsx b/webapp/src/components/App/Studies/StudiesList/index.tsx index 82587d0e12..dba3866d98 100644 --- a/webapp/src/components/App/Studies/StudiesList/index.tsx +++ b/webapp/src/components/App/Studies/StudiesList/index.tsx @@ -285,7 +285,7 @@ function StudiesList(props: StudiesListProps) { > {`${t("studies.scanFolder")} ${folder}?`} diff --git a/webapp/src/redux/ducks/studies.ts b/webapp/src/redux/ducks/studies.ts index 177ed2992d..951f5fc199 100644 --- a/webapp/src/redux/ducks/studies.ts +++ b/webapp/src/redux/ducks/studies.ts @@ -84,7 +84,7 @@ const initialState = studiesAdapter.getInitialState({ filters: { inputValue: "", folder: "root", - strictFolder: true, + strictFolder: false, managed: false, archived: false, variant: false,