Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(graph): add atomizer label to target groups #26622

Merged
merged 11 commits into from
Jun 26, 2024
38 changes: 4 additions & 34 deletions graph/client/src/app/external-api-impl.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,40 +25,10 @@ export class ExternalApiImpl extends ExternalApi {
console.log('graphInteractionEventListener not registered.');
return;
}
if (type === 'file-click') {
const url = `${payload.sourceRoot}/${payload.file}`;
this.graphInteractionEventListener({
type: 'file-click',
payload: { url },
});
} else if (type === 'open-project-config') {
this.graphInteractionEventListener({
type: 'open-project-config',
payload,
});
} else if (type === 'run-task') {
this.graphInteractionEventListener({
type: 'run-task',
payload,
});
} else if (type === 'open-project-graph') {
this.graphInteractionEventListener({
type: 'open-project-graph',
payload,
});
} else if (type === 'open-task-graph') {
this.graphInteractionEventListener({
type: 'open-task-graph',
payload,
});
} else if (type === 'override-target') {
this.graphInteractionEventListener({
type: 'override-target',
payload,
});
} else {
console.log('unhandled event', type, payload);
}
this.graphInteractionEventListener({
type,
payload,
});
}
);

Expand Down
2 changes: 2 additions & 0 deletions graph/client/src/app/routes.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ const projectDetailsLoader = async (
project: ProjectGraphProjectNode;
sourceMap: Record<string, string[]>;
errors?: GraphError[];
connectedToCloud?: boolean;
}> => {
const workspaceData = await workspaceDataLoader(selectedWorkspaceId);
const sourceMaps = await sourceMapsLoader(selectedWorkspaceId);
Expand All @@ -102,6 +103,7 @@ const projectDetailsLoader = async (
project,
sourceMap: sourceMaps[project.data.root],
errors: workspaceData.errors,
connectedToCloud: workspaceData.connectedToCloud,
};
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,8 +69,7 @@ export function TooltipDisplay() {
externalApiService.postEvent({
type: 'file-click',
payload: {
sourceRoot: currentTooltip.props.sourceRoot,
file: url,
url: `${currentTooltip.props.sourceRoot}/${url}`,
},
})
: undefined;
Expand Down
17 changes: 9 additions & 8 deletions graph/project-details/src/lib/project-details-page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,14 +21,14 @@ import {
import { ProjectDetailsHeader } from './project-details-header';

export function ProjectDetailsPage() {
const { project, sourceMap, hash, errors } = useRouteLoaderData(
'selectedProjectDetails'
) as {
hash: string;
project: ProjectGraphProjectNode;
sourceMap: Record<string, string[]>;
errors?: GraphError[];
};
const { project, sourceMap, hash, errors, connectedToCloud } =
useRouteLoaderData('selectedProjectDetails') as {
hash: string;
project: ProjectGraphProjectNode;
sourceMap: Record<string, string[]>;
errors?: GraphError[];
connectedToCloud?: boolean;
};

const { environment, watch, appConfig } = useEnvironmentConfig();

Expand Down Expand Up @@ -64,6 +64,7 @@ export function ProjectDetailsPage() {
project={project}
sourceMap={sourceMap}
errors={errors}
connectedToCloud={connectedToCloud}
></ProjectDetailsWrapper>
</div>
</div>
Expand Down
14 changes: 14 additions & 0 deletions graph/project-details/src/lib/project-details-wrapper.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,14 @@ interface ProjectDetailsProps {
project: ProjectGraphProjectNode;
sourceMap: Record<string, string[]>;
errors?: GraphError[];
connectedToCloud?: boolean;
}

export function ProjectDetailsWrapper({
project,
sourceMap,
errors,
connectedToCloud,
}: ProjectDetailsProps) {
const environment = useEnvironmentConfig()?.environment;
const externalApiService = getExternalApiService();
Expand Down Expand Up @@ -93,6 +95,14 @@ export function ProjectDetailsWrapper({
[externalApiService]
);

const handleNxConnect = useCallback(
() =>
externalApiService.postEvent({
type: 'nx-connect',
}),
[externalApiService]
);

const updateSearchParams = (
params: URLSearchParams,
targetNames: string[]
Expand Down Expand Up @@ -167,6 +177,10 @@ export function ProjectDetailsWrapper({
viewInProjectGraphPosition={
environment === 'nx-console' ? 'bottom' : 'top'
}
connectedToCloud={connectedToCloud}
nxConnectCallback={
environment === 'nx-console' ? handleNxConnect : undefined
}
/>
<ErrorToast errors={errors} />
</>
Expand Down
4 changes: 2 additions & 2 deletions graph/shared/src/lib/external-api-service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,10 @@ export function getExternalApiService() {
}

export class ExternalApiService {
private subscribers: Set<(event: { type: string; payload: any }) => void> =
private subscribers: Set<(event: { type: string; payload?: any }) => void> =
new Set();

postEvent(event: { type: string; payload: any }) {
postEvent(event: { type: string; payload?: any }) {
this.subscribers.forEach((subscriber) => {
subscriber(event);
});
Expand Down
1 change: 1 addition & 0 deletions graph/ui-icons/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
export * from './lib/technology-icon';
export * from './lib/framework-icons';
export * from './lib/ nx-cloud-icon';
17 changes: 17 additions & 0 deletions graph/ui-icons/src/lib/ nx-cloud-icon.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { FC, SVGProps } from 'react';

export const NxCloudIcon: FC<SVGProps<SVGSVGElement>> = (props) => (
<svg
role="img"
xmlns="http://www.w3.org/2000/svg"
stroke="currentColor"
fill="transparent"
viewBox="0 0 24 24"
{...props}
>
<path
d="M22.167 7.167v-2.5a2.5 2.5 0 0 0-2.5-2.5h-15a2.5 2.5 0 0 0-2.5 2.5v15a2.5 2.5 0 0 0 2.5 2.5h2.5m15-15c-2.76 0-5 2.24-5 5s-2.24 5-5 5-5 2.24-5 5m15-15V19.59a2.577 2.577 0 0 1-2.576 2.576H7.167"
strokeWidth="2"
/>
</svg>
);
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,14 @@ export interface ProjectDetailsProps {
sourceMap: Record<string, string[]>;
errors?: GraphError[];
variant?: 'default' | 'compact';
connectedToCloud?: boolean;
onViewInProjectGraph?: (data: { projectName: string }) => void;
onViewInTaskGraph?: (data: {
projectName: string;
targetName: string;
}) => void;
onRunTarget?: (data: { projectName: string; targetName: string }) => void;
nxConnectCallback?: () => void;
viewInProjectGraphPosition?: 'top' | 'bottom';
}

Expand All @@ -41,7 +43,9 @@ export const ProjectDetails = ({
onViewInProjectGraph,
onViewInTaskGraph,
onRunTarget,
nxConnectCallback,
viewInProjectGraphPosition = 'top',
connectedToCloud,
}: ProjectDetailsProps) => {
const projectData = project.data;
const isCompact = variant === 'compact';
Expand Down Expand Up @@ -161,6 +165,8 @@ export const ProjectDetails = ({
variant={variant}
onRunTarget={onRunTarget}
onViewInTaskGraph={onViewInTaskGraph}
connectedToCloud={connectedToCloud}
nxConnectCallback={nxConnectCallback}
/>
</div>
</>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,28 @@ import { TargetConfigurationGroupHeader } from '../target-configuration-details-
export interface TargetConfigurationGroupContainerProps {
targetGroupName: string;
targetsNumber: number;
nonAtomizedTarget?: string;
connectedToCloud?: boolean;
nxConnectCallback?: () => void;
children: React.ReactNode;
}

export function TargetConfigurationGroupContainer({
targetGroupName,
targetsNumber,
nonAtomizedTarget,
connectedToCloud,
nxConnectCallback,
children,
}: TargetConfigurationGroupContainerProps) {
return (
<div className="mb-4 w-full">
<TargetConfigurationGroupHeader
targetGroupName={targetGroupName}
targetsNumber={targetsNumber}
nonAtomizedTarget={nonAtomizedTarget}
connectedToCloud={connectedToCloud}
nxConnectCallback={nxConnectCallback}
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">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,21 @@ export const Simple: Story = {
targetsNumber: 5,
},
};

export const AtomizerCloud: Story = {
args: {
targetGroupName: 'Target Group Name',
targetsNumber: 5,
nonAtomizedTarget: 'e2e',
connectedToCloud: true,
},
};

export const AtomizerNoCloud: Story = {
args: {
targetGroupName: 'Target Group Name',
targetsNumber: 5,
nonAtomizedTarget: 'e2e',
connectedToCloud: false,
},
};
Original file line number Diff line number Diff line change
@@ -1,25 +1,60 @@
import { AtomizerTooltip, Tooltip } from '@nx/graph/ui-tooltips';
import { Pill } from '../pill';
import { Square3Stack3DIcon } from '@heroicons/react/24/outline';

export interface TargetConfigurationGroupHeaderProps {
targetGroupName: string;
targetsNumber: number;
className?: string;
nonAtomizedTarget?: string;
connectedToCloud?: boolean;
nxConnectCallback?: () => void;
showIcon?: boolean;
}

export const TargetConfigurationGroupHeader = ({
targetGroupName,
targetsNumber,
nonAtomizedTarget,
connectedToCloud = true,
nxConnectCallback,
className = '',
}: TargetConfigurationGroupHeaderProps) => {
return (
<header className={`px-4 py-2 text-lg capitalize ${className}`}>
<header
className={`flex items-center gap-2 px-4 py-2 text-lg capitalize ${className}`}
>
{targetGroupName}{' '}
{nonAtomizedTarget && <Square3Stack3DIcon className="h-5 w-5" />}
<Pill
text={
targetsNumber.toString() +
(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>
);
};
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,10 @@ 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 {
getNonAtomizedTargetForGroup,
groupTargets,
} from '../utils/group-targets';
import { useMemo } from 'react';

export interface TargetConfigurationGroupListProps {
Expand All @@ -16,6 +19,8 @@ export interface TargetConfigurationGroupListProps {
projectName: string;
targetName: string;
}) => void;
nxConnectCallback?: () => void;
connectedToCloud?: boolean;
className?: string;
}

Expand All @@ -25,7 +30,9 @@ export function TargetConfigurationGroupList({
sourceMap,
onRunTarget,
onViewInTaskGraph,
nxConnectCallback,
className = '',
connectedToCloud,
}: TargetConfigurationGroupListProps) {
const targetsGroup = useMemo(() => groupTargets(project), [project]);
const hasGroups = useMemo(() => {
Expand All @@ -47,6 +54,12 @@ export function TargetConfigurationGroupList({
<TargetConfigurationGroupContainer
targetGroupName={targetGroupName}
targetsNumber={targets.length}
nonAtomizedTarget={getNonAtomizedTargetForGroup(
project,
targetGroupName
)}
connectedToCloud={connectedToCloud}
nxConnectCallback={nxConnectCallback}
key={targetGroupName}
>
<ul className={className}>
Expand Down
15 changes: 15 additions & 0 deletions graph/ui-project-details/src/lib/utils/group-targets.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,3 +33,18 @@ function sortNxReleasePublishLast(a: string, b: string) {
if (b === 'nx-release-publish') return -1;
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;
}
1 change: 1 addition & 0 deletions graph/ui-tooltips/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,4 @@ export * from './lib/tooltip-button';
export * from './lib/property-info-tooltip';
export * from './lib/sourcemap-info-tooltip';
export * from './lib/external-link';
export * from './lib/atomizer-tooltip';
Loading