/* eslint-disable @nx/enforce-module-boundaries */
// nx-ignore-next-line
import type { ProjectGraphProjectNode } from '@nx/devkit';
/* eslint-enable @nx/enforce-module-boundaries */
import {
createTaskName,
getProjectsByType,
groupProjectsByDirectory,
} from '../util';
import { WorkspaceLayout } from '../interfaces';
import { ExclamationCircleIcon, EyeIcon } from '@heroicons/react/24/outline';
import { ReactNode } from 'react';
import { Tooltip } from '@nx/graph/ui-tooltips';
import { TaskGraphErrorTooltip } from './task-graph-error-tooltip';
interface SidebarProject {
projectGraphNode: ProjectGraphProjectNode;
isSelected: boolean;
error: string | null;
}
function ProjectListItem({
project,
toggleTask,
}: {
project: SidebarProject;
toggleTask: (taskId: string) => void;
}) {
return (
{project.error ? (
}
openAction="click"
strategy="fixed"
>
) : null}
{project.isSelected ? (
toggleTask(project.projectGraphNode.name)}
>
) : null}
);
}
function SubProjectList({
headerText = '',
projects,
toggleTask,
}: {
headerText: string;
projects: SidebarProject[];
toggleTask: (taskId: string) => void;
}) {
let sortedProjects = [...projects];
sortedProjects.sort((a, b) => {
return a.projectGraphNode.name.localeCompare(b.projectGraphNode.name);
});
return (
<>
{headerText !== '' ? (
{headerText}
) : null}
{sortedProjects.map((project) => {
return (
);
})}
>
);
}
function mapToSidebarProjectWithTasks(
project: ProjectGraphProjectNode,
selectedProjects: string[],
selectedTarget: string,
errors: Record
): SidebarProject {
const taskId = createTaskName(project.name, selectedTarget);
return {
projectGraphNode: project,
isSelected: selectedProjects.includes(project.name),
error: errors?.[taskId] ?? null,
};
}
export interface TaskListProps {
projects: ProjectGraphProjectNode[];
workspaceLayout: WorkspaceLayout;
selectedTarget: string;
selectedProjects: string[];
toggleProject: (projectName: string) => void;
children: ReactNode | ReactNode[];
errors: Record;
}
export function TaskList({
projects,
workspaceLayout,
selectedTarget,
selectedProjects,
toggleProject,
children,
errors,
}: TaskListProps) {
const filteredProjects = projects
.filter((project) =>
(project.data as any).targets?.hasOwnProperty(selectedTarget)
)
.sort((a, b) => a.name.localeCompare(b.name));
const appProjects = getProjectsByType('app', filteredProjects);
const libProjects = getProjectsByType('lib', filteredProjects);
const e2eProjects = getProjectsByType('e2e', filteredProjects);
const appDirectoryGroups = groupProjectsByDirectory(
appProjects,
workspaceLayout
);
const libDirectoryGroups = groupProjectsByDirectory(
libProjects,
workspaceLayout
);
const e2eDirectoryGroups = groupProjectsByDirectory(
e2eProjects,
workspaceLayout
);
const sortedAppDirectories = Object.keys(appDirectoryGroups).sort();
const sortedLibDirectories = Object.keys(libDirectoryGroups).sort();
const sortedE2EDirectories = Object.keys(e2eDirectoryGroups).sort();
return (
{children}
app projects
{sortedAppDirectories.map((directoryName) => {
return (
mapToSidebarProjectWithTasks(
project,
selectedProjects,
selectedTarget,
errors
)
)}
toggleTask={toggleProject}
>
);
})}
e2e projects
{sortedE2EDirectories.map((directoryName) => {
return (
mapToSidebarProjectWithTasks(
project,
selectedProjects,
selectedTarget,
errors
)
)}
toggleTask={toggleProject}
>
);
})}
lib projects
{sortedLibDirectories.map((directoryName) => {
return (
mapToSidebarProjectWithTasks(
project,
selectedProjects,
selectedTarget,
errors
)
)}
toggleTask={toggleProject}
>
);
})}
);
}