/* eslint-disable @nx/enforce-module-boundaries */ // nx-ignore-next-line import { ChevronDownIcon, ChevronUpIcon, EyeIcon, PlayIcon, } from '@heroicons/react/24/outline'; // nx-ignore-next-line import { TargetConfiguration } from '@nx/devkit'; import { JsonCodeBlock } from '@nx/graph/ui-code-block'; import { ForwardedRef, forwardRef, useCallback, useEffect, useImperativeHandle, useMemo, useState, } from 'react'; import { SourceInfo } from './source-info'; import { FadingCollapsible } from './fading-collapsible'; import { TargetConfigurationProperty } from './target-configuration-property'; import { selectSourceInfo } from './target-configuration-details.util'; import { CopyToClipboard } from './copy-to-clipboard'; import { ExternalLink, PropertyInfoTooltip, Tooltip, } from '@nx/graph/ui-tooltips'; import { TooltipTriggerText } from './tooltip-trigger-text'; import { twMerge } from 'tailwind-merge'; /* eslint-disable-next-line */ export interface TargetProps { projectName: string; targetName: string; targetConfiguration: TargetConfiguration; sourceMap: Record; variant?: 'default' | 'compact'; onCollapse?: (targetName: string) => void; onExpand?: (targetName: string) => void; onRunTarget?: (data: { projectName: string; targetName: string }) => void; onViewInTaskGraph?: (data: { projectName: string; targetName: string; }) => void; } export interface TargetConfigurationDetailsHandle { collapse: () => void; expand: () => void; } export const TargetConfigurationDetails = forwardRef( ( { variant, projectName, targetName, targetConfiguration, sourceMap, onExpand, onCollapse, onViewInTaskGraph, onRunTarget, }: TargetProps, ref: ForwardedRef ) => { const isCompact = variant === 'compact'; const [collapsed, setCollapsed] = useState(true); const handleCopyClick = async (copyText: string) => { await window.navigator.clipboard.writeText(copyText); }; const handleCollapseToggle = useCallback( () => setCollapsed((collapsed) => !collapsed), [setCollapsed] ); useEffect(() => { if (collapsed) { onCollapse?.(targetName); } else { onExpand?.(targetName); } }, [collapsed, onCollapse, onExpand, projectName, targetName]); useImperativeHandle(ref, () => ({ collapse: () => { !collapsed && setCollapsed(true); }, expand: () => { collapsed && setCollapsed(false); }, })); let executorLink: string | null = null; // TODO: Handle this better because this will not work with labs if (targetConfiguration.executor?.startsWith('@nx/')) { const packageName = targetConfiguration.executor .split('/')[1] .split(':')[0]; const executorName = targetConfiguration.executor .split('/')[1] .split(':')[1]; executorLink = `https://nx.dev/nx-api/${packageName}/executors/${executorName}`; } else if (targetConfiguration.executor === 'nx:run-commands') { executorLink = `https://nx.dev/nx-api/nx/executors/run-commands`; } else if (targetConfiguration.executor === 'nx:run-script') { executorLink = `https://nx.dev/nx-api/nx/executors/run-script`; } const singleCommand = targetConfiguration.executor === 'nx:run-commands' ? targetConfiguration.command ?? targetConfiguration.options?.command : null; const options = useMemo(() => { if (singleCommand) { const { command, ...rest } = targetConfiguration.options; return rest; } else { return targetConfiguration.options; } }, [targetConfiguration.options, singleCommand]); const configurations = targetConfiguration.configurations; const shouldRenderOptions = options && (typeof options === 'object' ? Object.keys(options).length : true); const shouldRenderConfigurations = configurations && (typeof configurations === 'object' ? Object.keys(configurations).length : true); return (

{targetName}

{collapsed && (

{singleCommand ? singleCommand : targetConfiguration.executor}

)}
{onViewInTaskGraph && ( { e.stopPropagation(); onViewInTaskGraph({ projectName, targetName }); }} /> )} {targetConfiguration.cache && ( ) as any} > Cacheable )} {onRunTarget && ( { e.stopPropagation(); onRunTarget({ projectName, targetName }); }} /> )} {collapsed ? ( ) : ( )}
{!collapsed && (
nx run {projectName}:{targetName} handleCopyClick(`nx run ${projectName}:${targetName}`) } />
)}
{/* body */} {!collapsed && (

{singleCommand ? ( Command handleCopyClick(`"command": "${singleCommand}"`) } /> ) : ( ) as any} > Executor )}

{executorLink ? ( ) : singleCommand ? ( singleCommand ) : ( targetConfiguration.executor )}

{targetConfiguration.inputs && (

) as any} > Inputs handleCopyClick( `"inputs": ${JSON.stringify( targetConfiguration.inputs )}` ) } />

    {targetConfiguration.inputs.map((input, idx) => { const sourceInfo = selectSourceInfo( sourceMap, `targets.${targetName}.inputs` ); return (
  • {sourceInfo && ( )}
  • ); })}
)} {targetConfiguration.outputs && (

) as any} > Outputs handleCopyClick( `"outputs": ${JSON.stringify( targetConfiguration.outputs )}` ) } />

    {targetConfiguration.outputs?.map((output, idx) => { const sourceInfo = selectSourceInfo( sourceMap, `targets.${targetName}.outputs` ); return (
  • {sourceInfo && ( )}
  • ); }) ?? no outputs}
)} {targetConfiguration.dependsOn && (

) as any} > Depends On handleCopyClick( `"dependsOn": ${JSON.stringify( targetConfiguration.dependsOn )}` ) } />

    {targetConfiguration.dependsOn.map((dep, idx) => { const sourceInfo = selectSourceInfo( sourceMap, `targets.${targetName}.dependsOn` ); return (
  • {sourceInfo && ( )}
  • ); })}
)} {shouldRenderOptions ? ( <>

) as any} > Options

{ const sourceInfo = selectSourceInfo( sourceMap, `targets.${targetName}.options.${propertyName}` ); return sourceInfo ? ( ) : null; }} />
) : ( '' )} {shouldRenderConfigurations ? ( <>

) as any } > Configurations {' '} {targetConfiguration.defaultConfiguration && ( {targetConfiguration.defaultConfiguration} )}

{ const sourceInfo = selectSourceInfo( sourceMap, `targets.${targetName}.configurations.${propertyName}` ); return sourceInfo ? ( {' '} ) : null; }} /> ) : ( '' )}
)}
); } ); export default TargetConfigurationDetails;