diff --git a/dep-graph/client/project.json b/dep-graph/client/project.json index 50f77e5fbbfff9..59f69ad9c34f0a 100644 --- a/dep-graph/client/project.json +++ b/dep-graph/client/project.json @@ -43,6 +43,21 @@ } ] }, + "nx-console": { + "assets": [ + "dep-graph/client/src/favicon.ico", + { + "input": "dep-graph/client/src/assets/graphs", + "output": "/assets/graphs", + "glob": "nx-examples.json" + }, + { + "input": "dep-graph/client/src/assets/nx-console", + "output": "/", + "glob": "environment.js" + } + ] + }, "release": { "assets": [ "dep-graph/client/src/favicon.ico", @@ -91,6 +106,9 @@ "dev": { "buildTarget": "dep-graph-client:build-base:dev" }, + "nx-console": { + "buildTarget": "dep-graph-client:build-base:nx-console" + }, "release": { "buildTarget": "dep-graph-client:build-base:release" }, diff --git a/dep-graph/client/src/app/hooks/use-environment-config.ts b/dep-graph/client/src/app/hooks/use-environment-config.ts index d1dd91b43169c0..677c7f63e3c0db 100644 --- a/dep-graph/client/src/app/hooks/use-environment-config.ts +++ b/dep-graph/client/src/app/hooks/use-environment-config.ts @@ -8,7 +8,7 @@ export function useEnvironmentConfig(): { watch: boolean; localMode: 'serve' | 'build'; projectGraphResponse?: DepGraphClientResponse; - environment: 'dev' | 'watch' | 'release'; + environment: 'dev' | 'watch' | 'release' | 'nx-console'; appConfig: AppConfig; useXstateInspect: boolean; } { diff --git a/dep-graph/client/src/app/hooks/use-project-graph-data-service.ts b/dep-graph/client/src/app/hooks/use-project-graph-data-service.ts index 7848357dd137ea..60225449da7b22 100644 --- a/dep-graph/client/src/app/hooks/use-project-graph-data-service.ts +++ b/dep-graph/client/src/app/hooks/use-project-graph-data-service.ts @@ -7,7 +7,7 @@ let projectGraphService: ProjectGraphService; export function useProjectGraphDataService() { if (projectGraphService === undefined) { - if (window.environment === 'dev') { + if (window.environment === 'dev' || window.environment === 'nx-console') { projectGraphService = new FetchProjectGraphService(); } else if (window.environment === 'watch') { projectGraphService = new MockProjectGraphService(); diff --git a/dep-graph/client/src/app/machines/dep-graph.service.ts b/dep-graph/client/src/app/machines/dep-graph.service.ts index d91fc00280a9c6..3b2dbf9a1637c7 100644 --- a/dep-graph/client/src/app/machines/dep-graph.service.ts +++ b/dep-graph/client/src/app/machines/dep-graph.service.ts @@ -1,23 +1,13 @@ -import { interpret, Interpreter, Typestate } from 'xstate'; +import { interpret, InterpreterStatus } from 'xstate'; import { depGraphMachine } from './dep-graph.machine'; -import { - DepGraphContext, - DepGraphSchema, - DepGraphUIEvents, -} from './interfaces'; -let depGraphService: Interpreter< - DepGraphContext, - DepGraphSchema, - DepGraphUIEvents, - Typestate ->; +// TODO: figure out what happened to make the interprett return type get so weird +let depGraphService = interpret(depGraphMachine, { + devTools: !!window.useXstateInspect, +}); export function getDepGraphService() { - if (!depGraphService) { - depGraphService = interpret(depGraphMachine, { - devTools: !!window.useXstateInspect, - }); + if (depGraphService.status === InterpreterStatus.NotStarted) { depGraphService.start(); } diff --git a/dep-graph/client/src/app/machines/externalApi.ts b/dep-graph/client/src/app/machines/externalApi.ts new file mode 100644 index 00000000000000..16b39b22f3db16 --- /dev/null +++ b/dep-graph/client/src/app/machines/externalApi.ts @@ -0,0 +1,9 @@ +import { getDepGraphService } from './dep-graph.service'; + +export class ExternalApi { + depGraphService = getDepGraphService(); + + focusProject(projectName: string) { + this.depGraphService.send({ type: 'focusProject', projectName }); + } +} diff --git a/dep-graph/client/src/app/machines/graph.ts b/dep-graph/client/src/app/machines/graph.ts index 51b7fb89703083..777fcccc7dbaca 100644 --- a/dep-graph/client/src/app/machines/graph.ts +++ b/dep-graph/client/src/app/machines/graph.ts @@ -17,6 +17,7 @@ import { ProjectNode, } from '../util-cytoscape'; import { GraphPerfReport, GraphRenderEvents } from './interfaces'; +import { getEnvironmentConfig } from '../hooks/use-environment-config'; export class GraphService { private traversalGraph: cy.Core; @@ -212,7 +213,19 @@ export class GraphService { }); } - this.renderGraph.fit().center().resize(); + const environmentConfig = getEnvironmentConfig(); + + if (environmentConfig.environment === 'nx-console') { + // when in the nx-console environment, adjust graph width and position to be to right of floating panel + // 175 is a magic number that represents the width of the floating panels divided in half plus some padding + this.renderGraph + .fit(this.renderGraph.elements(), 175) + .center() + .resize() + .panBy({ x: 150, y: 0 }); + } else { + this.renderGraph.fit(this.renderGraph.elements(), 25).center().resize(); + } selectedProjectNames = this.renderGraph .nodes('[type!="dir"]') diff --git a/dep-graph/client/src/app/sidebar/sidebar.tsx b/dep-graph/client/src/app/sidebar/sidebar.tsx index 3166ae513556b0..b718f01d043acb 100644 --- a/dep-graph/client/src/app/sidebar/sidebar.tsx +++ b/dep-graph/client/src/app/sidebar/sidebar.tsx @@ -23,8 +23,10 @@ import TextFilterPanel from './text-filter-panel'; import ThemePanel from './theme-panel'; import TracingPanel from './tracing-panel'; import { TracingAlgorithmType } from '../machines/interfaces'; +import { useEnvironmentConfig } from '../hooks/use-environment-config'; export function Sidebar() { + const environmentConfig = useEnvironmentConfig(); const depGraphService = useDepGraphService(); const focusedProject = useDepGraphSelector(focusedProjectNameSelector); const searchDepthInfo = useDepGraphSelector(searchDepthSelector); @@ -110,31 +112,37 @@ export function Sidebar() { return ( - + {environmentConfig.environment !== 'nx-console' ? ( + + ) : null} ); } diff --git a/dep-graph/client/src/assets/nx-console/environment.js b/dep-graph/client/src/assets/nx-console/environment.js new file mode 100644 index 00000000000000..652af724c0d497 --- /dev/null +++ b/dep-graph/client/src/assets/nx-console/environment.js @@ -0,0 +1,17 @@ +window.exclude = []; +window.watch = false; +window.environment = 'nx-console'; +window.useXstateInspect = false; + +window.appConfig = { + showDebugger: false, + showExperimentalFeatures: false, + projectGraphs: [ + { + id: 'local', + label: 'local', + url: 'assets/graphs/nx-examples.json', + }, + ], + defaultProjectGraph: 'local', +}; diff --git a/dep-graph/client/src/globals.d.ts b/dep-graph/client/src/globals.d.ts index 685115161cec5a..e478b89dfb70ef 100644 --- a/dep-graph/client/src/globals.d.ts +++ b/dep-graph/client/src/globals.d.ts @@ -1,6 +1,7 @@ // nx-ignore-next-line import type { DepGraphClientResponse } from 'nx/src/command-line/dep-graph'; import { AppConfig } from './app/interfaces'; +import { ExternalApi } from './app/machines/externalApi'; export declare global { export interface Window { @@ -8,9 +9,10 @@ export declare global { watch: boolean; localMode: 'serve' | 'build'; projectGraphResponse?: DepGraphClientResponse; - environment: 'dev' | 'watch' | 'release'; + environment: 'dev' | 'watch' | 'release' | 'nx-console'; appConfig: AppConfig; useXstateInspect: boolean; + externalApi?: ExternalApi; } } diff --git a/dep-graph/client/src/main.tsx b/dep-graph/client/src/main.tsx index 829b92689d47fc..5da159f5c17e36 100644 --- a/dep-graph/client/src/main.tsx +++ b/dep-graph/client/src/main.tsx @@ -2,6 +2,7 @@ import { StrictMode } from 'react'; import * as ReactDOM from 'react-dom'; import { inspect } from '@xstate/inspect'; import App from './app/app'; +import { ExternalApi } from './app/machines/externalApi'; if (window.useXstateInspect === true) { inspect({ @@ -10,6 +11,8 @@ if (window.useXstateInspect === true) { }); } +window.externalApi = new ExternalApi(); + ReactDOM.render(