fix(graph): update atomizer metadata & pdv hint (#26733)

<!-- Please make sure you have read the submission guidelines before
posting an PR -->
<!--
https://github.com/nrwl/nx/blob/master/CONTRIBUTING.md#-submitting-a-pr
-->

<!-- Please make sure that your commit message follows our format -->
<!-- Example: `fix(nx): must begin with lowercase` -->

<!-- If this is a particularly complex change or feature addition, you
can request a dedicated Nx release for this pull request branch. Mention
someone from the Nx team or the `@nrwl/nx-pipelines-reviewers` and they
will confirm if the PR warrants its own release for testing purposes,
and generate it for you if appropriate. -->

## Current Behavior
<!-- This is the behavior we have today -->

## Expected Behavior
<!-- This is the behavior we should expect with the changes in this PR
-->

## Related Issue(s)
<!-- Please link the issue being fixed so it gets closed when this is
merged. -->

Fixes #
This commit is contained in:
MaxKless 2024-06-27 20:28:21 +02:00 committed by GitHub
parent c75e7ef683
commit 7f1e351cbb
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
10 changed files with 83 additions and 93 deletions

View File

@ -173,9 +173,7 @@ export function ProjectDetailsWrapper({
environment === 'nx-console' ? 'bottom' : 'top' environment === 'nx-console' ? 'bottom' : 'top'
} }
connectedToCloud={connectedToCloud} connectedToCloud={connectedToCloud}
nxConnectCallback={ onNxConnect={environment === 'nx-console' ? handleNxConnect : undefined}
environment === 'nx-console' ? handleNxConnect : undefined
}
/> />
<ErrorToast errors={errors} /> <ErrorToast errors={errors} />
</> </>

View File

@ -26,7 +26,7 @@ export interface ProjectDetailsProps {
targetName: string; targetName: string;
}) => void; }) => void;
onRunTarget?: (data: { projectName: string; targetName: string }) => void; onRunTarget?: (data: { projectName: string; targetName: string }) => void;
nxConnectCallback?: () => void; onNxConnect?: () => void;
viewInProjectGraphPosition?: 'top' | 'bottom'; viewInProjectGraphPosition?: 'top' | 'bottom';
} }
@ -43,7 +43,7 @@ export const ProjectDetails = ({
onViewInProjectGraph, onViewInProjectGraph,
onViewInTaskGraph, onViewInTaskGraph,
onRunTarget, onRunTarget,
nxConnectCallback, onNxConnect,
viewInProjectGraphPosition = 'top', viewInProjectGraphPosition = 'top',
connectedToCloud, connectedToCloud,
}: ProjectDetailsProps) => { }: ProjectDetailsProps) => {
@ -166,7 +166,7 @@ export const ProjectDetails = ({
onRunTarget={onRunTarget} onRunTarget={onRunTarget}
onViewInTaskGraph={onViewInTaskGraph} onViewInTaskGraph={onViewInTaskGraph}
connectedToCloud={connectedToCloud} connectedToCloud={connectedToCloud}
nxConnectCallback={nxConnectCallback} onNxConnect={onNxConnect}
/> />
</div> </div>
</> </>

View File

@ -3,18 +3,12 @@ import { TargetConfigurationGroupHeader } from '../target-configuration-details-
export interface TargetConfigurationGroupContainerProps { export interface TargetConfigurationGroupContainerProps {
targetGroupName: string; targetGroupName: string;
targetsNumber: number; targetsNumber: number;
nonAtomizedTarget?: string;
connectedToCloud?: boolean;
nxConnectCallback?: () => void;
children: React.ReactNode; children: React.ReactNode;
} }
export function TargetConfigurationGroupContainer({ export function TargetConfigurationGroupContainer({
targetGroupName, targetGroupName,
targetsNumber, targetsNumber,
nonAtomizedTarget,
connectedToCloud,
nxConnectCallback,
children, children,
}: TargetConfigurationGroupContainerProps) { }: TargetConfigurationGroupContainerProps) {
if (targetsNumber === 0) { if (targetsNumber === 0) {
@ -25,9 +19,6 @@ export function TargetConfigurationGroupContainer({
<TargetConfigurationGroupHeader <TargetConfigurationGroupHeader
targetGroupName={targetGroupName} targetGroupName={targetGroupName}
targetsNumber={targetsNumber} targetsNumber={targetsNumber}
nonAtomizedTarget={nonAtomizedTarget}
connectedToCloud={connectedToCloud}
nxConnectCallback={nxConnectCallback}
className="sticky top-0 z-10 bg-white dark:bg-slate-900" className="sticky top-0 z-10 bg-white dark:bg-slate-900"
/> />
<div className="rounded-md border border-slate-200 p-2 dark:border-slate-700"> <div className="rounded-md border border-slate-200 p-2 dark:border-slate-700">

View File

@ -1,4 +1,3 @@
import { AtomizerTooltip, Tooltip } from '@nx/graph/ui-tooltips';
import { Pill } from '../pill'; import { Pill } from '../pill';
import { Square3Stack3DIcon } from '@heroicons/react/24/outline'; import { Square3Stack3DIcon } from '@heroicons/react/24/outline';
@ -6,18 +5,13 @@ export interface TargetConfigurationGroupHeaderProps {
targetGroupName: string; targetGroupName: string;
targetsNumber: number; targetsNumber: number;
className?: string; className?: string;
nonAtomizedTarget?: string;
connectedToCloud?: boolean;
nxConnectCallback?: () => void;
showIcon?: boolean; showIcon?: boolean;
} }
export const TargetConfigurationGroupHeader = ({ export const TargetConfigurationGroupHeader = ({
targetGroupName, targetGroupName,
targetsNumber, targetsNumber,
nonAtomizedTarget,
connectedToCloud = true,
nxConnectCallback,
className = '', className = '',
}: TargetConfigurationGroupHeaderProps) => { }: TargetConfigurationGroupHeaderProps) => {
return ( return (
@ -25,36 +19,15 @@ export const TargetConfigurationGroupHeader = ({
className={`flex items-center gap-2 px-4 py-2 text-lg capitalize ${className}`} className={`flex items-center gap-2 px-4 py-2 text-lg capitalize ${className}`}
> >
{targetGroupName}{' '} {targetGroupName}{' '}
{nonAtomizedTarget && <Square3Stack3DIcon className="h-5 w-5" />} {targetGroupName !== 'Others' && (
<Square3Stack3DIcon className="h-5 w-5" />
)}
<Pill <Pill
text={ text={
targetsNumber.toString() + targetsNumber.toString() +
(targetsNumber === 1 ? ' target' : ' targets') (targetsNumber === 1 ? ' target' : ' targets')
} }
/> />
{nonAtomizedTarget && (
<Tooltip
openAction="hover"
strategy="fixed"
usePortal={true}
content={
(
<AtomizerTooltip
connectedToCloud={connectedToCloud}
nonAtomizedTarget={nonAtomizedTarget}
nxConnectCallback={nxConnectCallback}
/>
) as any
}
>
<span className="inline-flex">
<Pill
color={connectedToCloud ? 'grey' : 'yellow'}
text={'Atomizer'}
/>
</span>
</Tooltip>
)}
</header> </header>
); );
}; };

View File

@ -4,10 +4,7 @@ import type { ProjectGraphProjectNode } from '@nx/devkit';
import { TargetConfigurationDetailsListItem } from '../target-configuration-details-list-item/target-configuration-details-list-item'; 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 { TargetConfigurationGroupContainer } from '../target-configuration-details-group-container/target-configuration-details-group-container';
import { import { groupTargets } from '../utils/group-targets';
getNonAtomizedTargetForGroup,
groupTargets,
} from '../utils/group-targets';
import { useMemo } from 'react'; import { useMemo } from 'react';
export interface TargetConfigurationGroupListProps { export interface TargetConfigurationGroupListProps {
@ -19,7 +16,7 @@ export interface TargetConfigurationGroupListProps {
projectName: string; projectName: string;
targetName: string; targetName: string;
}) => void; }) => void;
nxConnectCallback?: () => void; onNxConnect?: () => void;
connectedToCloud?: boolean; connectedToCloud?: boolean;
className?: string; className?: string;
} }
@ -30,7 +27,7 @@ export function TargetConfigurationGroupList({
sourceMap, sourceMap,
onRunTarget, onRunTarget,
onViewInTaskGraph, onViewInTaskGraph,
nxConnectCallback, onNxConnect,
className = '', className = '',
connectedToCloud, connectedToCloud,
}: TargetConfigurationGroupListProps) { }: TargetConfigurationGroupListProps) {
@ -51,12 +48,6 @@ export function TargetConfigurationGroupList({
<TargetConfigurationGroupContainer <TargetConfigurationGroupContainer
targetGroupName={targetGroupName} targetGroupName={targetGroupName}
targetsNumber={targets.length} targetsNumber={targets.length}
nonAtomizedTarget={getNonAtomizedTargetForGroup(
project,
targetGroupName
)}
connectedToCloud={connectedToCloud}
nxConnectCallback={nxConnectCallback}
key={targetGroupName} key={targetGroupName}
> >
<ul className={className}> <ul className={className}>
@ -64,9 +55,11 @@ export function TargetConfigurationGroupList({
<TargetConfigurationDetailsListItem <TargetConfigurationDetailsListItem
project={project} project={project}
sourceMap={sourceMap} sourceMap={sourceMap}
connectedToCloud={connectedToCloud}
variant={variant} variant={variant}
onRunTarget={onRunTarget} onRunTarget={onRunTarget}
onViewInTaskGraph={onViewInTaskGraph} onViewInTaskGraph={onViewInTaskGraph}
onNxConnect={onNxConnect}
targetName={targetName} targetName={targetName}
collapsable={true} collapsable={true}
key={targetName} key={targetName}
@ -88,9 +81,11 @@ export function TargetConfigurationGroupList({
<TargetConfigurationDetailsListItem <TargetConfigurationDetailsListItem
project={project} project={project}
sourceMap={sourceMap} sourceMap={sourceMap}
connectedToCloud={connectedToCloud}
variant={variant} variant={variant}
onRunTarget={onRunTarget} onRunTarget={onRunTarget}
onViewInTaskGraph={onViewInTaskGraph} onViewInTaskGraph={onViewInTaskGraph}
onNxConnect={onNxConnect}
targetName={targetName} targetName={targetName}
collapsable={true} collapsable={true}
key={targetName} key={targetName}
@ -109,9 +104,11 @@ export function TargetConfigurationGroupList({
<TargetConfigurationDetailsListItem <TargetConfigurationDetailsListItem
project={project} project={project}
sourceMap={sourceMap} sourceMap={sourceMap}
connectedToCloud={connectedToCloud}
variant={variant} variant={variant}
onRunTarget={onRunTarget} onRunTarget={onRunTarget}
onViewInTaskGraph={onViewInTaskGraph} onViewInTaskGraph={onViewInTaskGraph}
onNxConnect={onNxConnect}
targetName={targetName} targetName={targetName}
collapsable={true} collapsable={true}
key={targetName} key={targetName}

View File

@ -8,7 +8,11 @@ import {
PlayIcon, PlayIcon,
} from '@heroicons/react/24/outline'; } from '@heroicons/react/24/outline';
import { PropertyInfoTooltip, Tooltip } from '@nx/graph/ui-tooltips'; import {
AtomizerTooltip,
PropertyInfoTooltip,
Tooltip,
} from '@nx/graph/ui-tooltips';
import { twMerge } from 'tailwind-merge'; import { twMerge } from 'tailwind-merge';
import { Pill } from '../pill'; import { Pill } from '../pill';
import { TargetTechnologies } from '../target-technologies/target-technologies'; import { TargetTechnologies } from '../target-technologies/target-technologies';
@ -26,11 +30,13 @@ export interface TargetConfigurationDetailsHeaderProps {
projectName: string; projectName: string;
targetName: string; targetName: string;
sourceMap: Record<string, string[]>; sourceMap: Record<string, string[]>;
connectedToCloud?: boolean;
onRunTarget?: (data: { projectName: string; targetName: string }) => void; onRunTarget?: (data: { projectName: string; targetName: string }) => void;
onViewInTaskGraph?: (data: { onViewInTaskGraph?: (data: {
projectName: string; projectName: string;
targetName: string; targetName: string;
}) => void; }) => void;
onNxConnect?: () => void;
} }
export const TargetConfigurationDetailsHeader = ({ export const TargetConfigurationDetailsHeader = ({
@ -41,9 +47,11 @@ export const TargetConfigurationDetailsHeader = ({
targetConfiguration, targetConfiguration,
projectName, projectName,
targetName, targetName,
connectedToCloud = true,
sourceMap, sourceMap,
onRunTarget, onRunTarget,
onViewInTaskGraph, onViewInTaskGraph,
onNxConnect,
}: TargetConfigurationDetailsHeaderProps) => { }: TargetConfigurationDetailsHeaderProps) => {
const handleCopyClick = async (copyText: string) => { const handleCopyClick = async (copyText: string) => {
await window.navigator.clipboard.writeText(copyText); await window.navigator.clipboard.writeText(copyText);
@ -97,7 +105,7 @@ export const TargetConfigurationDetailsHeader = ({
</p> </p>
)} )}
</div> </div>
<div> <div className="flex items-center gap-2">
{targetName === 'nx-release-publish' && ( {targetName === 'nx-release-publish' && (
<Tooltip <Tooltip
openAction="hover" openAction="hover"
@ -109,6 +117,31 @@ export const TargetConfigurationDetailsHeader = ({
</span> </span>
</Tooltip> </Tooltip>
)} )}
{targetConfiguration.metadata?.nonAtomizedTarget && (
<Tooltip
openAction="hover"
strategy="fixed"
usePortal={true}
content={
(
<AtomizerTooltip
connectedToCloud={connectedToCloud}
nonAtomizedTarget={
targetConfiguration.metadata.nonAtomizedTarget
}
onNxConnect={onNxConnect}
/>
) as any
}
>
<span className="inline-flex">
<Pill
color={connectedToCloud ? 'grey' : 'yellow'}
text={'Atomizer'}
/>
</span>
</Tooltip>
)}
{targetConfiguration.cache && ( {targetConfiguration.cache && (
<Tooltip <Tooltip
openAction="hover" openAction="hover"

View File

@ -6,12 +6,14 @@ import TargetConfigurationDetails from '../target-configuration-details/target-c
export interface TargetConfigurationDetailsListItemProps { export interface TargetConfigurationDetailsListItemProps {
project: ProjectGraphProjectNode; project: ProjectGraphProjectNode;
sourceMap: Record<string, string[]>; sourceMap: Record<string, string[]>;
connectedToCloud?: boolean;
variant?: 'default' | 'compact'; variant?: 'default' | 'compact';
onRunTarget?: (data: { projectName: string; targetName: string }) => void; onRunTarget?: (data: { projectName: string; targetName: string }) => void;
onViewInTaskGraph?: (data: { onViewInTaskGraph?: (data: {
projectName: string; projectName: string;
targetName: string; targetName: string;
}) => void; }) => void;
onNxConnect?: () => void;
targetName: string; targetName: string;
collapsable: boolean; collapsable: boolean;
} }
@ -20,8 +22,10 @@ export function TargetConfigurationDetailsListItem({
project, project,
variant, variant,
sourceMap, sourceMap,
connectedToCloud,
onRunTarget, onRunTarget,
onViewInTaskGraph, onViewInTaskGraph,
onNxConnect,
targetName, targetName,
collapsable, collapsable,
}: TargetConfigurationDetailsListItemProps) { }: TargetConfigurationDetailsListItemProps) {
@ -37,8 +41,10 @@ export function TargetConfigurationDetailsListItem({
targetName={targetName} targetName={targetName}
targetConfiguration={target} targetConfiguration={target}
sourceMap={sourceMap} sourceMap={sourceMap}
connectedToCloud={connectedToCloud}
onRunTarget={onRunTarget} onRunTarget={onRunTarget}
onViewInTaskGraph={onViewInTaskGraph} onViewInTaskGraph={onViewInTaskGraph}
onNxConnect={onNxConnect}
collapsable={collapsable} collapsable={collapsable}
/> />
</li> </li>

View File

@ -24,6 +24,7 @@ interface TargetConfigurationDetailsProps {
targetName: string; targetName: string;
targetConfiguration: TargetConfiguration; targetConfiguration: TargetConfiguration;
sourceMap: Record<string, string[]>; sourceMap: Record<string, string[]>;
connectedToCloud?: boolean;
variant?: 'default' | 'compact'; variant?: 'default' | 'compact';
onCollapse?: (targetName: string) => void; onCollapse?: (targetName: string) => void;
onExpand?: (targetName: string) => void; onExpand?: (targetName: string) => void;
@ -32,6 +33,7 @@ interface TargetConfigurationDetailsProps {
projectName: string; projectName: string;
targetName: string; targetName: string;
}) => void; }) => void;
onNxConnect?: () => void;
collapsable: boolean; collapsable: boolean;
} }
@ -41,8 +43,10 @@ export default function TargetConfigurationDetails({
targetName, targetName,
targetConfiguration, targetConfiguration,
sourceMap, sourceMap,
connectedToCloud,
onViewInTaskGraph, onViewInTaskGraph,
onRunTarget, onRunTarget,
onNxConnect,
collapsable, collapsable,
}: TargetConfigurationDetailsProps) { }: TargetConfigurationDetailsProps) {
const isCompact = variant === 'compact'; const isCompact = variant === 'compact';
@ -95,9 +99,11 @@ export default function TargetConfigurationDetails({
targetConfiguration={targetConfiguration} targetConfiguration={targetConfiguration}
projectName={projectName} projectName={projectName}
targetName={targetName} targetName={targetName}
connectedToCloud={connectedToCloud}
sourceMap={sourceMap} sourceMap={sourceMap}
onRunTarget={onRunTarget} onRunTarget={onRunTarget}
onViewInTaskGraph={onViewInTaskGraph} onViewInTaskGraph={onViewInTaskGraph}
onNxConnect={onNxConnect}
/> />
{/* body */} {/* body */}
{!collapsed && ( {!collapsed && (

View File

@ -33,18 +33,3 @@ function sortNxReleasePublishLast(a: string, b: string) {
if (b === 'nx-release-publish') return -1; if (b === 'nx-release-publish') return -1;
return a.localeCompare(b); return a.localeCompare(b);
} }
export function getNonAtomizedTargetForGroup(
project: ProjectGraphProjectNode,
targetGroupName: string
): string | undefined {
const targetWithNonAtomizedEquivalent = project.data.metadata?.targetGroups?.[
targetGroupName
]?.find(
(target) => project.data.targets?.[target]?.metadata?.nonAtomizedTarget
);
return targetWithNonAtomizedEquivalent
? project.data.targets?.[targetWithNonAtomizedEquivalent]?.metadata
?.nonAtomizedTarget
: undefined;
}

View File

@ -4,7 +4,7 @@ import { twMerge } from 'tailwind-merge';
export interface AtomizerTooltipProps { export interface AtomizerTooltipProps {
connectedToCloud: boolean; connectedToCloud: boolean;
nonAtomizedTarget: string; nonAtomizedTarget: string;
nxConnectCallback?: () => void; onNxConnect?: () => void;
} }
export function AtomizerTooltip(props: AtomizerTooltipProps) { export function AtomizerTooltip(props: AtomizerTooltipProps) {
return ( return (
@ -26,19 +26,19 @@ export function AtomizerTooltip(props: AtomizerTooltipProps) {
href="https://nx.dev/ci/features/split-e2e-tasks" href="https://nx.dev/ci/features/split-e2e-tasks"
text="automatically split" text="automatically split"
/> />
{ {' the potentially slow'}
' this potentially slow task into separate tasks for each file. We recommend enabling ' <code className="mx-2 rounded bg-gray-100 px-1 font-mono text-gray-800 dark:bg-gray-700 dark:text-gray-300">
} {props.nonAtomizedTarget}
{!props.connectedToCloud && ( </code>
<> {'task into separate tasks for each file. Enable '}
<Link href="https://nx.app/" text="Nx Cloud" /> {!props.connectedToCloud ? (
{' and '} <Link href="https://nx.app/" text="Nx Cloud" />
</> ) : (
<Link
href="https://nx.dev/ci/features/distribute-task-execution"
text="Nx Agents"
/>
)} )}
<Link
href="https://nx.dev/ci/features/distribute-task-execution"
text="Nx Agents"
/>
{' to benefit from '} {' to benefit from '}
<Link <Link
href="https://nx.dev/ci/features/distribute-task-execution" href="https://nx.dev/ci/features/distribute-task-execution"
@ -59,19 +59,20 @@ export function AtomizerTooltip(props: AtomizerTooltipProps) {
text="flaky task re-runs" text="flaky task re-runs"
/> />
. Use . Use
<code className="mx-2 inline rounded bg-gray-100 px-1 font-mono text-gray-800 dark:bg-gray-700 dark:text-gray-300"> <code className="mx-2 rounded bg-gray-100 px-1 font-mono text-gray-800 dark:bg-gray-700 dark:text-gray-300">
{props.nonAtomizedTarget} {props.nonAtomizedTarget}
</code> </code>
when running without Nx Agents. when running without{' '}
{!props.connectedToCloud ? 'Nx Cloud' : 'Nx Agents'}.
</p> </p>
</div> </div>
{!props.connectedToCloud && ( {!props.connectedToCloud && (
<div className="flex py-2"> <div className="flex py-2">
<p className="pr-4 normal-case"> <p className="pr-4 normal-case">
{props.nxConnectCallback ? ( {props.onNxConnect ? (
<button <button
className="inline-flex cursor-pointer items-center gap-2 rounded-md px-2 py-1 text-base text-slate-600 ring-2 ring-inset ring-slate-400/40 hover:bg-slate-50 dark:text-slate-300 dark:ring-slate-400/30 dark:hover:bg-slate-800/60" className="inline-flex cursor-pointer items-center gap-2 rounded-md px-2 py-1 text-base text-slate-600 ring-2 ring-inset ring-slate-400/40 hover:bg-slate-50 dark:text-slate-300 dark:ring-slate-400/30 dark:hover:bg-slate-800/60"
onClick={() => props.nxConnectCallback!()} onClick={() => props.onNxConnect!()}
> >
<NxCloudIcon className="h-5 w-5 "></NxCloudIcon> <NxCloudIcon className="h-5 w-5 "></NxCloudIcon>
<span>Connect to Nx Cloud</span> <span>Connect to Nx Cloud</span>
@ -79,7 +80,7 @@ export function AtomizerTooltip(props: AtomizerTooltipProps) {
) : ( ) : (
<span className="font-mono"> <span className="font-mono">
{'Run'} {'Run'}
<code className="mx-2 inline rounded bg-gray-100 px-1 font-mono text-gray-800 dark:bg-gray-700 dark:text-gray-300"> <code className="mx-2 rounded bg-gray-100 px-1 font-mono text-gray-800 dark:bg-gray-700 dark:text-gray-300">
nx connect nx connect
</code> </code>
{'to connect to Nx Cloud'} {'to connect to Nx Cloud'}