diff --git a/graph/shared/src/lib/use-environment-config.ts b/graph/shared/src/lib/use-environment-config.ts index 1991ed3bb3cef..602f2058d719c 100644 --- a/graph/shared/src/lib/use-environment-config.ts +++ b/graph/shared/src/lib/use-environment-config.ts @@ -10,7 +10,7 @@ export function useEnvironmentConfig(): { watch: boolean; localMode: 'serve' | 'build'; projectGraphResponse?: ProjectGraphClientResponse; - environment: 'dev' | 'watch' | 'release' | 'nx-console'; + environment: 'dev' | 'watch' | 'release' | 'nx-console' | 'docs'; appConfig: AppConfig; useXstateInspect: boolean; } { @@ -25,13 +25,14 @@ export function getEnvironmentConfig() { watch: window.watch, localMode: window.localMode, projectGraphResponse: window.projectGraphResponse, - environment: window.environment, + // If this was not built into JS or HTML, then it is rendered on docs (nx.dev). + environment: window.environment ?? ('docs' as const), appConfig: { ...window.appConfig, showExperimentalFeatures: localStorage.getItem('showExperimentalFeatures') === 'true' ? true - : window.appConfig.showExperimentalFeatures, + : window.appConfig?.showExperimentalFeatures, }, useXstateInspect: window.useXstateInspect, }; diff --git a/graph/ui-project-details/src/lib/show-all-options/show-options-help.tsx b/graph/ui-project-details/src/lib/show-all-options/show-options-help.tsx new file mode 100644 index 0000000000000..4ed41f668c0f1 --- /dev/null +++ b/graph/ui-project-details/src/lib/show-all-options/show-options-help.tsx @@ -0,0 +1,198 @@ +import { Fragment, ReactNode, useMemo, useState } from 'react'; +import { PlayIcon, XMarkIcon } from '@heroicons/react/24/outline'; +import { Transition } from '@headlessui/react'; +import { getExternalApiService, useEnvironmentConfig } from '@nx/graph/shared'; +/* eslint-disable @nx/enforce-module-boundaries */ +// nx-ignore-next-line +import type { TargetConfiguration } from '@nx/devkit'; +import { TerminalOutput } from '@nx/nx-dev/ui-fence'; +import { Tooltip } from '@nx/graph/ui-tooltips'; +import { TooltipTriggerText } from '../target-configuration-details/tooltip-trigger-text'; + +interface ShowOptionsHelpProps { + projectName: string; + targetName: string; + targetConfiguration: TargetConfiguration; +} + +const fallbackHelpExample = { + options: { + silent: true, + }, + args: ['foo'], +}; + +export function ShowOptionsHelp({ + projectName, + targetName, + targetConfiguration, +}: ShowOptionsHelpProps) { + const config = useEnvironmentConfig(); + const environment = config?.environment; + const localMode = config?.localMode; + const [result, setResult] = useState<{ + text: string; + success: boolean; + } | null>(null); + const [isPending, setPending] = useState(false); + const externalApiService = getExternalApiService(); + + const helpData = targetConfiguration.metadata?.help; + const helpCommand = helpData?.command; + const helpExampleOptions = helpData?.example?.options; + const helpExampleArgs = helpData?.example?.args; + + const helpExampleTest = useMemo(() => { + const targetExampleJson = + helpExampleOptions || helpExampleArgs + ? { + options: helpExampleOptions, + args: helpExampleArgs, + } + : fallbackHelpExample; + return JSON.stringify( + { + targets: { + [targetName]: targetExampleJson, + }, + }, + null, + 2 + ); + }, [helpExampleOptions, helpExampleArgs]); + + let runHelpActionElement: null | ReactNode; + if (environment === 'docs') { + // Cannot run help command when rendering in docs (e.g. nx.dev). + runHelpActionElement = null; + } else if (environment === 'release' && localMode === 'build') { + // Cannot run help command when statically built via `nx graph --file=graph.html`. + runHelpActionElement = null; + } else if (isPending || !result) { + runHelpActionElement = ( + + ); + } else { + runHelpActionElement = ( + + ); + } + + return ( + helpCommand && ( + <> +
+ Use
+ For example, you can use the following configuration for the{' '}
+
+ The
+ The --help
to see all options for this command, and set
+ them by{' '}
+
+ passing them
+ {' '}
+ to the "options"
property in{' '}
+ {targetName}
target in the{' '}
+ project.json
file for{' '}
+ {projectName}.
+
+ {helpExampleTest}
+
+ {helpExampleOptions && (
+ options
are CLI options prefixed by{' '}
+ --
, such as ls --color=never
,
+ where you would use {'"color": "never"'}
to
+ set it in the target configuration.
+ args
are CLI positional arguments, such
+ as ls somedir
, where you would use{' '}
+ {'"args": ["somedir"]'}
to set it in the
+ target configuration.
+
+
+
+ {result?.text} ++
{line}
+ {actionElement ? ( +