diff --git a/src/components/ProjectSelector.tsx b/src/components/ProjectSelector.tsx index c20aa554..7f285740 100644 --- a/src/components/ProjectSelector.tsx +++ b/src/components/ProjectSelector.tsx @@ -1,4 +1,4 @@ -import { Select } from 'antd' +import { TreeSelect } from 'antd' import React from 'react' import ProjectDefinition from '../models/ProjectDefinition' import { localize } from '../utils/Language' @@ -10,39 +10,97 @@ interface ProjectSelectorProps { excludeProjectId?: string } +interface ProjectSelectorTreeNode { + title: string + key: string + value: string + disabled?: boolean + parentProjectId?: string + children?: ProjectSelectorTreeNode[] +} + class ProjectSelector extends React.Component { render() { const { allProjects, selectedProjectId, onChange, excludeProjectId } = this.props - const projectOptions = [ + const projectsMap: { + [key: string]: ProjectSelectorTreeNode + } = {} + let root: ProjectSelectorTreeNode[] = [] + // Create a map of all projects + allProjects.forEach((item) => { + projectsMap[item.id] = { + title: item.name, + parentProjectId: item.parentProjectId, + key: item.id, + value: item.id, + } + }) + + // Function to check if a project or its ancestors are excluded + const isProjectOrAncestorExcluded = (projectId: string): boolean => { + let current: string | undefined = projectId + while (current) { + if (current === excludeProjectId) { + return true + } + // eslint-disable-next-line no-loop-func + current = projectsMap[current].parentProjectId + } + return false + } + + // Distribute projects and apps to their respective parents or to the root + allProjects.forEach((item) => { + const project = projectsMap[item.id] + if (isProjectOrAncestorExcluded(item.id)) { + project.disabled = true + } + if (item.parentProjectId && projectsMap[item.parentProjectId]) { + const children = + projectsMap[item.parentProjectId].children || [] + children.push(project) + projectsMap[item.parentProjectId].children = children + } else { + root.push(project) + } + }) + + root.forEach((project) => { + if (project.children) + project.children = + project.children.length > 0 ? project.children : undefined + }) + root = [ { - value: '', - label: localize( + title: localize( 'projects.parent_project_selector_default', 'root ' ), + key: '', + value: '', + children: root, }, - ...allProjects - .filter((project) => project.id !== excludeProjectId) - .map((project) => ({ - value: project.id, - label: project.name, - })), ] + const handleChange = (value: string) => { + onChange(value ?? '') + } + return ( -