fix(graph): improve layout when target groups are empty or there are no groups (#26555)

This PR fixes empty target groups and adds consistency between grouped
and ungrouped targets.

## Before

Empty groups have bad empty state -- we should not show it. The
ungrouped targets being on their own without a group is also
inconsistent.

<img width="1153" alt="Screenshot 2024-06-14 at 9 46 11 AM"
src="https://github.com/nrwl/nx/assets/53559/b6e96187-fc6f-4c3f-9b45-39744d02b0ec">

## After

If group is empty, don't render it. Also, if there are no groups then
don't nest the ungrouped targets.

<img width="1190" alt="Screenshot 2024-06-14 at 9 46 29 AM"
src="https://github.com/nrwl/nx/assets/53559/76cd0b32-532b-470d-ad2f-85fc3aaf3997">

If there are groups, put the ungrouped targets into `Others`.

<img width="1152" alt="Screenshot 2024-06-14 at 9 45 55 AM"
src="https://github.com/nrwl/nx/assets/53559/465e64c7-e376-4555-b580-d6ecaafb61f5">
This commit is contained in:
Jack Hsu 2024-06-17 09:28:58 -07:00 committed by GitHub
parent 59ab43ab79
commit 09a08c6cef
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

View File

@ -5,6 +5,7 @@ import type { ProjectGraphProjectNode } from '@nx/devkit';
import { TargetConfigurationDetailsListItem } from '../target-configuration-details-list-item/target-configuration-details-list-item';
import { TargetConfigurationGroupContainer } from '../target-configuration-details-group-container/target-configuration-details-group-container';
import { groupTargets } from '../utils/group-targets';
import { useMemo } from 'react';
export interface TargetConfigurationGroupListProps {
project: ProjectGraphProjectNode;
@ -26,11 +27,19 @@ export function TargetConfigurationGroupList({
onViewInTaskGraph,
className = '',
}: TargetConfigurationGroupListProps) {
const targetsGroup = groupTargets(project);
const targetsGroup = useMemo(() => groupTargets(project), [project]);
const hasGroups = useMemo(() => {
for (const group of Object.entries(targetsGroup.groups)) {
if (group[1]?.length > 0) return true;
}
return false;
}, [targetsGroup]);
if (hasGroups) {
return (
<>
{Object.entries(targetsGroup.groups).map(([targetGroupName, targets]) => {
{Object.entries(targetsGroup.groups).map(
([targetGroupName, targets]) => {
if (targets.length === 0) {
return null;
}
@ -56,8 +65,14 @@ export function TargetConfigurationGroupList({
</ul>
</TargetConfigurationGroupContainer>
);
})}
<ul className={`mt-8 p-2 ${className}`}>
}
)}
<TargetConfigurationGroupContainer
targetGroupName="Others"
targetsNumber={targetsGroup.targets.length}
key="others-group"
>
<ul className={`p-2 ${className}`}>
{targetsGroup.targets.map((targetName) => {
return (
<TargetConfigurationDetailsListItem
@ -73,6 +88,27 @@ export function TargetConfigurationGroupList({
);
})}
</ul>
</TargetConfigurationGroupContainer>
</>
);
} else {
return (
<ul className={className}>
{targetsGroup.targets.map((targetName) => {
return (
<TargetConfigurationDetailsListItem
project={project}
sourceMap={sourceMap}
variant={variant}
onRunTarget={onRunTarget}
onViewInTaskGraph={onViewInTaskGraph}
targetName={targetName}
collapsable={true}
key={targetName}
/>
);
})}
</ul>
);
}
}