fix(graph): refresh pdv periodically in watch mode (#21218)
Co-authored-by: FrozenPandaz <jasonjean1993@gmail.com>
This commit is contained in:
parent
66929530b1
commit
b5ffb85874
@ -1,5 +1,4 @@
|
|||||||
import { useCallback, useEffect, useState } from 'react';
|
import { useCallback, useEffect, useState } from 'react';
|
||||||
import { useIntervalWhen } from '../hooks/use-interval-when';
|
|
||||||
import { getProjectGraphService } from '../machines/get-services';
|
import { getProjectGraphService } from '../machines/get-services';
|
||||||
import { ExperimentalFeature } from '../ui-components/experimental-feature';
|
import { ExperimentalFeature } from '../ui-components/experimental-feature';
|
||||||
import { FocusedPanel } from '../ui-components/focused-panel';
|
import { FocusedPanel } from '../ui-components/focused-panel';
|
||||||
@ -27,14 +26,19 @@ import { ProjectList } from './project-list';
|
|||||||
import { ProjectGraphClientResponse } from 'nx/src/command-line/graph/graph';
|
import { ProjectGraphClientResponse } from 'nx/src/command-line/graph/graph';
|
||||||
/* eslint-enable @nx/enforce-module-boundaries */
|
/* eslint-enable @nx/enforce-module-boundaries */
|
||||||
import { useFloating } from '@floating-ui/react';
|
import { useFloating } from '@floating-ui/react';
|
||||||
import { useEnvironmentConfig, useRouteConstructor } from '@nx/graph/shared';
|
import {
|
||||||
|
fetchProjectGraph,
|
||||||
|
getProjectGraphDataService,
|
||||||
|
useEnvironmentConfig,
|
||||||
|
useIntervalWhen,
|
||||||
|
useRouteConstructor,
|
||||||
|
} from '@nx/graph/shared';
|
||||||
import {
|
import {
|
||||||
useNavigate,
|
useNavigate,
|
||||||
useParams,
|
useParams,
|
||||||
useRouteLoaderData,
|
useRouteLoaderData,
|
||||||
useSearchParams,
|
useSearchParams,
|
||||||
} from 'react-router-dom';
|
} from 'react-router-dom';
|
||||||
import { getProjectGraphDataService } from '../hooks/get-project-graph-data-service';
|
|
||||||
import { useCurrentPath } from '../hooks/use-current-path';
|
import { useCurrentPath } from '../hooks/use-current-path';
|
||||||
import { ProjectDetailsModal } from '../ui-components/project-details-modal';
|
import { ProjectDetailsModal } from '../ui-components/project-details-modal';
|
||||||
|
|
||||||
@ -293,28 +297,18 @@ export function ProjectsSidebar(): JSX.Element {
|
|||||||
|
|
||||||
useIntervalWhen(
|
useIntervalWhen(
|
||||||
() => {
|
() => {
|
||||||
const selectedWorkspaceId =
|
fetchProjectGraph(
|
||||||
params.selectedWorkspaceId ??
|
projectGraphDataService,
|
||||||
environmentConfig.appConfig.defaultWorkspaceId;
|
params,
|
||||||
|
environmentConfig.appConfig
|
||||||
const projectInfo = environmentConfig.appConfig.workspaces.find(
|
).then((response: ProjectGraphClientResponse) => {
|
||||||
(graph) => graph.id === selectedWorkspaceId
|
|
||||||
);
|
|
||||||
|
|
||||||
const fetchProjectGraph = async () => {
|
|
||||||
const response: ProjectGraphClientResponse =
|
|
||||||
await projectGraphDataService.getProjectGraph(
|
|
||||||
projectInfo.projectGraphUrl
|
|
||||||
);
|
|
||||||
projectGraphService.send({
|
projectGraphService.send({
|
||||||
type: 'updateGraph',
|
type: 'updateGraph',
|
||||||
projects: response.projects,
|
projects: response.projects,
|
||||||
dependencies: response.dependencies,
|
dependencies: response.dependencies,
|
||||||
fileMap: response.fileMap,
|
fileMap: response.fileMap,
|
||||||
});
|
});
|
||||||
};
|
});
|
||||||
|
|
||||||
fetchProjectGraph();
|
|
||||||
},
|
},
|
||||||
5000,
|
5000,
|
||||||
environmentConfig.watch
|
environmentConfig.watch
|
||||||
|
|||||||
@ -1,27 +0,0 @@
|
|||||||
import { FetchProjectGraphService } from '../fetch-project-graph-service';
|
|
||||||
import { ProjectGraphService } from '../interfaces';
|
|
||||||
import { LocalProjectGraphService } from '../local-project-graph-service';
|
|
||||||
import { MockProjectGraphService } from '../mock-project-graph-service';
|
|
||||||
import { NxConsoleProjectGraphService } from '../nx-console-project-graph-service';
|
|
||||||
|
|
||||||
let projectGraphService: ProjectGraphService;
|
|
||||||
|
|
||||||
export function getProjectGraphDataService() {
|
|
||||||
if (projectGraphService === undefined) {
|
|
||||||
if (window.environment === 'dev') {
|
|
||||||
projectGraphService = new FetchProjectGraphService();
|
|
||||||
} else if (window.environment === 'watch') {
|
|
||||||
projectGraphService = new MockProjectGraphService();
|
|
||||||
} else if (window.environment === 'nx-console') {
|
|
||||||
projectGraphService = new NxConsoleProjectGraphService();
|
|
||||||
} else if (window.environment === 'release') {
|
|
||||||
if (window.localMode === 'build') {
|
|
||||||
projectGraphService = new LocalProjectGraphService();
|
|
||||||
} else {
|
|
||||||
projectGraphService = new FetchProjectGraphService();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return projectGraphService;
|
|
||||||
}
|
|
||||||
@ -1,6 +1,8 @@
|
|||||||
import { GraphService } from '@nx/graph/ui-graph';
|
import { GraphService } from '@nx/graph/ui-graph';
|
||||||
import { getProjectGraphDataService } from '../hooks/get-project-graph-data-service';
|
import {
|
||||||
import { getEnvironmentConfig } from '@nx/graph/shared';
|
getEnvironmentConfig,
|
||||||
|
getProjectGraphDataService,
|
||||||
|
} from '@nx/graph/shared';
|
||||||
import { selectValueByThemeStatic } from '@nx/graph/ui-theme';
|
import { selectValueByThemeStatic } from '@nx/graph/ui-theme';
|
||||||
|
|
||||||
let graphService: GraphService;
|
let graphService: GraphService;
|
||||||
|
|||||||
@ -7,9 +7,11 @@ import { Shell } from './shell';
|
|||||||
import { ProjectGraphClientResponse } from 'nx/src/command-line/graph/graph';
|
import { ProjectGraphClientResponse } from 'nx/src/command-line/graph/graph';
|
||||||
/* eslint-enable @nx/enforce-module-boundaries */
|
/* eslint-enable @nx/enforce-module-boundaries */
|
||||||
import { ProjectDetailsPage } from '@nx/graph/project-details';
|
import { ProjectDetailsPage } from '@nx/graph/project-details';
|
||||||
import { getEnvironmentConfig } from '@nx/graph/shared';
|
import {
|
||||||
|
getEnvironmentConfig,
|
||||||
|
getProjectGraphDataService,
|
||||||
|
} from '@nx/graph/shared';
|
||||||
import { TasksSidebarErrorBoundary } from './feature-tasks/tasks-sidebar-error-boundary';
|
import { TasksSidebarErrorBoundary } from './feature-tasks/tasks-sidebar-error-boundary';
|
||||||
import { getProjectGraphDataService } from './hooks/get-project-graph-data-service';
|
|
||||||
|
|
||||||
const { appConfig } = getEnvironmentConfig();
|
const { appConfig } = getEnvironmentConfig();
|
||||||
const projectGraphDataService = getProjectGraphDataService();
|
const projectGraphDataService = getProjectGraphDataService();
|
||||||
@ -78,6 +80,7 @@ const projectDetailsLoader = async (
|
|||||||
(project) => project.name === projectName
|
(project) => project.name === projectName
|
||||||
);
|
);
|
||||||
return {
|
return {
|
||||||
|
hash: workspaceData.hash,
|
||||||
project,
|
project,
|
||||||
sourceMap: sourceMaps[project.data.root],
|
sourceMap: sourceMaps[project.data.root],
|
||||||
};
|
};
|
||||||
|
|||||||
@ -1,25 +1,58 @@
|
|||||||
/* eslint-disable @nx/enforce-module-boundaries */
|
/* eslint-disable @nx/enforce-module-boundaries */
|
||||||
// nx-ignore-next-line
|
// nx-ignore-next-line
|
||||||
import { ProjectGraphProjectNode } from '@nx/devkit';
|
import { ProjectGraphProjectNode } from '@nx/devkit';
|
||||||
import { Link, useRouteLoaderData } from 'react-router-dom';
|
import {
|
||||||
|
Link,
|
||||||
|
ScrollRestoration,
|
||||||
|
useLocation,
|
||||||
|
useNavigate,
|
||||||
|
useParams,
|
||||||
|
useRouteLoaderData,
|
||||||
|
} from 'react-router-dom';
|
||||||
import ProjectDetails from './project-details';
|
import ProjectDetails from './project-details';
|
||||||
import { useEnvironmentConfig, useRouteConstructor } from '@nx/graph/shared';
|
import {
|
||||||
|
fetchProjectGraph,
|
||||||
|
getProjectGraphDataService,
|
||||||
|
useEnvironmentConfig,
|
||||||
|
useIntervalWhen,
|
||||||
|
useRouteConstructor,
|
||||||
|
} from '@nx/graph/shared';
|
||||||
import { ThemePanel } from '@nx/graph/ui-theme';
|
import { ThemePanel } from '@nx/graph/ui-theme';
|
||||||
|
|
||||||
export function ProjectDetailsPage() {
|
export function ProjectDetailsPage() {
|
||||||
const { project, sourceMap } = useRouteLoaderData(
|
const { project, sourceMap, hash } = useRouteLoaderData(
|
||||||
'selectedProjectDetails'
|
'selectedProjectDetails'
|
||||||
) as {
|
) as {
|
||||||
|
hash: string;
|
||||||
project: ProjectGraphProjectNode;
|
project: ProjectGraphProjectNode;
|
||||||
sourceMap: Record<string, string[]>;
|
sourceMap: Record<string, string[]>;
|
||||||
};
|
};
|
||||||
|
|
||||||
const environment = useEnvironmentConfig()?.environment;
|
const { environment, watch, appConfig } = useEnvironmentConfig();
|
||||||
|
|
||||||
|
const projectGraphDataService = getProjectGraphDataService();
|
||||||
|
const params = useParams();
|
||||||
|
|
||||||
|
useIntervalWhen(
|
||||||
|
async () => {
|
||||||
|
fetchProjectGraph(projectGraphDataService, params, appConfig).then(
|
||||||
|
(data) => {
|
||||||
|
if (data?.hash !== hash) {
|
||||||
|
window.location.reload();
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
},
|
||||||
|
1000,
|
||||||
|
watch
|
||||||
|
);
|
||||||
|
|
||||||
const routeConstructor = useRouteConstructor();
|
const routeConstructor = useRouteConstructor();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="flex flex-col justify-center w-full text-slate-700 dark:text-slate-400">
|
<div className="flex flex-col justify-center w-full text-slate-700 dark:text-slate-400">
|
||||||
|
<ScrollRestoration />
|
||||||
{environment !== 'nx-console' ? (
|
{environment !== 'nx-console' ? (
|
||||||
<header className="flex w-full justify-center items-center px-4 py-2 border-b-2 border-slate-900/10 mb-16 dark:border-slate-300/10">
|
<header className="flex w-full justify-center items-center px-4 py-2 border-b-2 border-slate-900/10 mb-16 dark:border-slate-300/10">
|
||||||
<div className="flex flex-grow items-center justify-between max-w-6xl">
|
<div className="flex flex-grow items-center justify-between max-w-6xl">
|
||||||
|
|||||||
@ -3,3 +3,6 @@ export * from './lib/external-api-service';
|
|||||||
export * from './lib/use-environment-config';
|
export * from './lib/use-environment-config';
|
||||||
export * from './lib/app-config';
|
export * from './lib/app-config';
|
||||||
export * from './lib/use-route-constructor';
|
export * from './lib/use-route-constructor';
|
||||||
|
export * from './lib/use-interval-when';
|
||||||
|
export * from './lib/project-graph-data-service/get-project-graph-data-service';
|
||||||
|
export * from './lib/fetch-project-graph';
|
||||||
|
|||||||
18
graph/shared/src/lib/fetch-project-graph.ts
Normal file
18
graph/shared/src/lib/fetch-project-graph.ts
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
import { Params } from 'react-router-dom';
|
||||||
|
import { ProjectGraphService } from './project-graph-data-service/get-project-graph-data-service';
|
||||||
|
import { AppConfig } from './app-config';
|
||||||
|
|
||||||
|
export async function fetchProjectGraph(
|
||||||
|
projectGraphService: ProjectGraphService,
|
||||||
|
params: Readonly<Params<string>>,
|
||||||
|
appConfig: AppConfig
|
||||||
|
) {
|
||||||
|
const selectedWorkspaceId =
|
||||||
|
params.selectedWorkspaceId ?? appConfig.defaultWorkspaceId;
|
||||||
|
|
||||||
|
const projectInfo = appConfig.workspaces.find(
|
||||||
|
(graph) => graph.id === selectedWorkspaceId
|
||||||
|
);
|
||||||
|
|
||||||
|
return await projectGraphService.getProjectGraph(projectInfo.projectGraphUrl);
|
||||||
|
}
|
||||||
@ -4,8 +4,8 @@ import type {
|
|||||||
ProjectGraphClientResponse,
|
ProjectGraphClientResponse,
|
||||||
TaskGraphClientResponse,
|
TaskGraphClientResponse,
|
||||||
} from 'nx/src/command-line/graph/graph';
|
} from 'nx/src/command-line/graph/graph';
|
||||||
|
import { ProjectGraphService } from './get-project-graph-data-service';
|
||||||
/* eslint-enable @nx/enforce-module-boundaries */
|
/* eslint-enable @nx/enforce-module-boundaries */
|
||||||
import { ProjectGraphService } from './interfaces';
|
|
||||||
|
|
||||||
export class FetchProjectGraphService implements ProjectGraphService {
|
export class FetchProjectGraphService implements ProjectGraphService {
|
||||||
private taskInputsUrl: string;
|
private taskInputsUrl: string;
|
||||||
@ -0,0 +1,44 @@
|
|||||||
|
import { FetchProjectGraphService } from './fetch-project-graph-service';
|
||||||
|
import { LocalProjectGraphService } from './local-project-graph-service';
|
||||||
|
import { MockProjectGraphService } from './mock-project-graph-service';
|
||||||
|
import { NxConsoleProjectGraphService } from './nx-console-project-graph-service';
|
||||||
|
|
||||||
|
/* eslint-disable @nx/enforce-module-boundaries */
|
||||||
|
// nx-ignore-next-line
|
||||||
|
import type {
|
||||||
|
ProjectGraphClientResponse,
|
||||||
|
TaskGraphClientResponse,
|
||||||
|
} from 'nx/src/command-line/graph/graph';
|
||||||
|
|
||||||
|
let projectGraphService: ProjectGraphService;
|
||||||
|
|
||||||
|
export interface ProjectGraphService {
|
||||||
|
getHash: () => Promise<string>;
|
||||||
|
getProjectGraph: (url: string) => Promise<ProjectGraphClientResponse>;
|
||||||
|
getTaskGraph: (url: string) => Promise<TaskGraphClientResponse>;
|
||||||
|
setTaskInputsUrl?: (url: string) => void;
|
||||||
|
getExpandedTaskInputs?: (taskId: string) => Promise<Record<string, string[]>>;
|
||||||
|
getSourceMaps?: (
|
||||||
|
url: string
|
||||||
|
) => Promise<Record<string, Record<string, string[]>>>;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getProjectGraphDataService() {
|
||||||
|
if (projectGraphService === undefined) {
|
||||||
|
if (window.environment === 'dev') {
|
||||||
|
projectGraphService = new FetchProjectGraphService();
|
||||||
|
} else if (window.environment === 'watch') {
|
||||||
|
projectGraphService = new MockProjectGraphService();
|
||||||
|
} else if (window.environment === 'nx-console') {
|
||||||
|
projectGraphService = new NxConsoleProjectGraphService();
|
||||||
|
} else if (window.environment === 'release') {
|
||||||
|
if (window.localMode === 'build') {
|
||||||
|
projectGraphService = new LocalProjectGraphService();
|
||||||
|
} else {
|
||||||
|
projectGraphService = new FetchProjectGraphService();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return projectGraphService;
|
||||||
|
}
|
||||||
@ -4,8 +4,8 @@ import type {
|
|||||||
ProjectGraphClientResponse,
|
ProjectGraphClientResponse,
|
||||||
TaskGraphClientResponse,
|
TaskGraphClientResponse,
|
||||||
} from 'nx/src/command-line/graph/graph';
|
} from 'nx/src/command-line/graph/graph';
|
||||||
|
import { ProjectGraphService } from './get-project-graph-data-service';
|
||||||
/* eslint-enable @nx/enforce-module-boundaries */
|
/* eslint-enable @nx/enforce-module-boundaries */
|
||||||
import { ProjectGraphService } from './interfaces';
|
|
||||||
|
|
||||||
export class LocalProjectGraphService implements ProjectGraphService {
|
export class LocalProjectGraphService implements ProjectGraphService {
|
||||||
async getHash(): Promise<string> {
|
async getHash(): Promise<string> {
|
||||||
@ -9,8 +9,8 @@ import type {
|
|||||||
ProjectGraphClientResponse,
|
ProjectGraphClientResponse,
|
||||||
TaskGraphClientResponse,
|
TaskGraphClientResponse,
|
||||||
} from 'nx/src/command-line/graph/graph';
|
} from 'nx/src/command-line/graph/graph';
|
||||||
|
import { ProjectGraphService } from './get-project-graph-data-service';
|
||||||
/* eslint-enable @nx/enforce-module-boundaries */
|
/* eslint-enable @nx/enforce-module-boundaries */
|
||||||
import { ProjectGraphService } from '../app/interfaces';
|
|
||||||
|
|
||||||
export class MockProjectGraphService implements ProjectGraphService {
|
export class MockProjectGraphService implements ProjectGraphService {
|
||||||
private projectGraphsResponse: ProjectGraphClientResponse = {
|
private projectGraphsResponse: ProjectGraphClientResponse = {
|
||||||
@ -84,6 +84,12 @@ export class MockProjectGraphService implements ProjectGraphService {
|
|||||||
return new Promise((resolve) => resolve(this.taskGraphsResponse));
|
return new Promise((resolve) => resolve(this.taskGraphsResponse));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getSourceMaps(
|
||||||
|
url: string
|
||||||
|
): Promise<Record<string, Record<string, string[]>>> {
|
||||||
|
return new Promise((resolve) => resolve({}));
|
||||||
|
}
|
||||||
|
|
||||||
private createNewProject(): ProjectGraphProjectNode {
|
private createNewProject(): ProjectGraphProjectNode {
|
||||||
const type = Math.random() > 0.25 ? 'lib' : 'app';
|
const type = Math.random() > 0.25 ? 'lib' : 'app';
|
||||||
const name = `${type}-${this.projectGraphsResponse.projects.length + 1}`;
|
const name = `${type}-${this.projectGraphsResponse.projects.length + 1}`;
|
||||||
@ -4,7 +4,7 @@ import type {
|
|||||||
ProjectGraphClientResponse,
|
ProjectGraphClientResponse,
|
||||||
TaskGraphClientResponse,
|
TaskGraphClientResponse,
|
||||||
} from 'nx/src/command-line/graph/graph';
|
} from 'nx/src/command-line/graph/graph';
|
||||||
import { ProjectGraphService } from './interfaces';
|
import { ProjectGraphService } from './get-project-graph-data-service';
|
||||||
|
|
||||||
export class NxConsoleProjectGraphService implements ProjectGraphService {
|
export class NxConsoleProjectGraphService implements ProjectGraphService {
|
||||||
async getHash(): Promise<string> {
|
async getHash(): Promise<string> {
|
||||||
@ -100,7 +100,7 @@ export async function showProjectHandler(
|
|||||||
{
|
{
|
||||||
view: 'project-details',
|
view: 'project-details',
|
||||||
focus: node.name,
|
focus: node.name,
|
||||||
watch: false,
|
watch: true,
|
||||||
open: true,
|
open: true,
|
||||||
},
|
},
|
||||||
[]
|
[]
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user