diff --git a/graph/client/src/app/machines/dep-graph.machine.ts b/graph/client/src/app/machines/dep-graph.machine.ts
index 7ff221b1c2088..3a680b5fa4dd5 100644
--- a/graph/client/src/app/machines/dep-graph.machine.ts
+++ b/graph/client/src/app/machines/dep-graph.machine.ts
@@ -92,7 +92,11 @@ export const depGraphMachine = Machine<
},
selectProject: {
target: 'customSelected',
- actions: ['notifyGraphShowProject'],
+ actions: ['notifyGraphShowProjects'],
+ },
+ selectProjects: {
+ target: 'customSelected',
+ actions: ['notifyGraphShowProjects'],
},
selectAll: {
target: 'customSelected',
@@ -112,7 +116,17 @@ export const depGraphMachine = Machine<
},
{
target: 'customSelected',
- actions: ['notifyGraphHideProject'],
+ actions: ['notifyGraphHideProjects'],
+ },
+ ],
+ deselectProjects: [
+ {
+ target: 'unselected',
+ cond: 'deselectLastProject',
+ },
+ {
+ target: 'customSelected',
+ actions: ['notifyGraphHideProjects'],
},
],
deselectAll: {
@@ -298,27 +312,46 @@ export const depGraphMachine = Machine<
}
),
- notifyGraphShowProject: send(
+ notifyGraphShowProjects: send(
(context, event) => {
- if (event.type !== 'selectProject') return;
+ if (event.type !== 'selectProject' && event.type !== 'selectProjects')
+ return;
- return {
- type: 'notifyGraphShowProject',
- projectName: event.projectName,
- };
+ if (event.type === 'selectProject') {
+ return {
+ type: 'notifyGraphShowProjects',
+ projectNames: [event.projectName],
+ };
+ } else {
+ return {
+ type: 'notifyGraphShowProjects',
+ projectNames: event.projectNames,
+ };
+ }
},
{
to: (context) => context.graphActor,
}
),
- notifyGraphHideProject: send(
+ notifyGraphHideProjects: send(
(context, event) => {
- if (event.type !== 'deselectProject') return;
+ if (
+ event.type !== 'deselectProject' &&
+ event.type !== 'deselectProjects'
+ )
+ return;
- return {
- type: 'notifyGraphHideProject',
- projectName: event.projectName,
- };
+ if (event.type === 'deselectProject') {
+ return {
+ type: 'notifyGraphHideProjects',
+ projectNames: [event.projectName],
+ };
+ } else {
+ return {
+ type: 'notifyGraphHideProjects',
+ projectNames: event.projectNames,
+ };
+ }
},
{
to: (context) => context.graphActor,
diff --git a/graph/client/src/app/machines/interfaces.ts b/graph/client/src/app/machines/interfaces.ts
index a8ba471192570..588835d5bcf78 100644
--- a/graph/client/src/app/machines/interfaces.ts
+++ b/graph/client/src/app/machines/interfaces.ts
@@ -34,6 +34,8 @@ export type DepGraphUIEvents =
}
| { type: 'selectProject'; projectName: string }
| { type: 'deselectProject'; projectName: string }
+ | { type: 'selectProjects'; projectNames: string[] }
+ | { type: 'deselectProjects'; projectNames: string[] }
| { type: 'selectAll' }
| { type: 'deselectAll' }
| { type: 'selectAffected' }
diff --git a/graph/client/src/app/sidebar/project-list.tsx b/graph/client/src/app/sidebar/project-list.tsx
index b2327727673c6..6b6fe5d861f13 100644
--- a/graph/client/src/app/sidebar/project-list.tsx
+++ b/graph/client/src/app/sidebar/project-list.tsx
@@ -1,5 +1,6 @@
import {
DocumentMagnifyingGlassIcon,
+ EyeIcon,
FlagIcon,
MapPinIcon,
} from '@heroicons/react/24/outline';
@@ -16,7 +17,6 @@ import {
import { parseParentDirectoriesFromFilePath } from '../util';
import { TracingAlgorithmType } from '../machines/interfaces';
import ExperimentalFeature from '../experimental-feature';
-import { EyeIcon } from '@heroicons/react/24/outline';
function getProjectsByType(type: string, projects: ProjectGraphNode[]) {
return projects
@@ -70,19 +70,33 @@ function groupProjectsByDirectory(
function ProjectListItem({
project,
- toggleProject,
- focusProject,
- startTrace,
- endTrace,
tracingInfo,
}: {
project: SidebarProject;
- toggleProject: (projectId: string, currentlySelected: boolean) => void;
- focusProject: (projectId: string) => void;
- startTrace: (projectId: string) => void;
- endTrace: (projectId: string) => void;
tracingInfo: TracingInfo;
}) {
+ const depGraphService = useDepGraphService();
+
+ function startTrace(projectName: string) {
+ depGraphService.send({ type: 'setTracingStart', projectName });
+ }
+
+ function endTrace(projectName: string) {
+ depGraphService.send({ type: 'setTracingEnd', projectName });
+ }
+
+ function toggleProject(projectName: string, currentlySelected: boolean) {
+ if (currentlySelected) {
+ depGraphService.send({ type: 'deselectProject', projectName });
+ } else {
+ depGraphService.send({ type: 'selectProject', projectName });
+ }
+ }
+
+ function focusProject(projectName: string) {
+ depGraphService.send({ type: 'focusProject', projectName });
+ }
+
return (
@@ -158,44 +172,27 @@ function ProjectListItem({
function SubProjectList({
headerText = '',
projects,
- selectProject,
- deselectProject,
- focusProject,
- startTrace,
- endTrace,
tracingInfo,
}: {
headerText: string;
projects: SidebarProject[];
- selectProject: (projectName: string) => void;
- deselectProject: (projectName: string) => void;
- focusProject: (projectName: string) => void;
- startTrace: (projectId: string) => void;
- endTrace: (projectId: string) => void;
tracingInfo: TracingInfo;
}) {
+ const depGraphService = useDepGraphService();
+
let sortedProjects = [...projects];
sortedProjects.sort((a, b) => {
return a.projectGraphNode.name.localeCompare(b.projectGraphNode.name);
});
- function toggleProject(projectName: string, currentlySelected: boolean) {
- if (currentlySelected) {
- deselectProject(projectName);
- } else {
- selectProject(projectName);
- }
- }
-
function toggleAllProjects(currentlySelected: boolean) {
+ const projectNames = projects.map(
+ (project) => project.projectGraphNode.name
+ );
if (currentlySelected) {
- projects.forEach((project) =>
- deselectProject(project.projectGraphNode.name)
- );
+ depGraphService.send({ type: 'deselectProjects', projectNames });
} else {
- projects.forEach((project) =>
- selectProject(project.projectGraphNode.name)
- );
+ depGraphService.send({ type: 'selectProjects', projectNames });
}
}
@@ -229,10 +226,6 @@ function SubProjectList({
);
@@ -243,29 +236,8 @@ function SubProjectList({
}
export function ProjectList() {
- const depGraphService = useDepGraphService();
const tracingInfo = useDepGraphSelector(getTracingInfo);
- function deselectProject(projectName: string) {
- depGraphService.send({ type: 'deselectProject', projectName });
- }
-
- function selectProject(projectName: string) {
- depGraphService.send({ type: 'selectProject', projectName });
- }
-
- function focusProject(projectName: string) {
- depGraphService.send({ type: 'focusProject', projectName });
- }
-
- function startTrace(projectName: string) {
- depGraphService.send({ type: 'setTracingStart', projectName });
- }
-
- function endTrace(projectName: string) {
- depGraphService.send({ type: 'setTracingEnd', projectName });
- }
-
const projects = useDepGraphSelector(allProjectsSelector);
const workspaceLayout = useDepGraphSelector(workspaceLayoutSelector);
const selectedProjects = useDepGraphSelector(selectedProjectNamesSelector);
@@ -306,11 +278,6 @@ export function ProjectList() {
key={'app-' + directoryName}
headerText={directoryName}
projects={appDirectoryGroups[directoryName]}
- deselectProject={deselectProject}
- selectProject={selectProject}
- focusProject={focusProject}
- startTrace={startTrace}
- endTrace={endTrace}
tracingInfo={tracingInfo}
>
);
@@ -326,11 +293,6 @@ export function ProjectList() {
key={'e2e-' + directoryName}
headerText={directoryName}
projects={e2eDirectoryGroups[directoryName]}
- deselectProject={deselectProject}
- selectProject={selectProject}
- focusProject={focusProject}
- startTrace={startTrace}
- endTrace={endTrace}
tracingInfo={tracingInfo}
>
);
@@ -346,11 +308,6 @@ export function ProjectList() {
key={'lib-' + directoryName}
headerText={directoryName}
projects={libDirectoryGroups[directoryName]}
- deselectProject={deselectProject}
- selectProject={selectProject}
- focusProject={focusProject}
- startTrace={startTrace}
- endTrace={endTrace}
tracingInfo={tracingInfo}
>
);
diff --git a/graph/ui-graph/src/lib/graph.ts b/graph/ui-graph/src/lib/graph.ts
index a789b1c929db8..d2447b0f3da71 100644
--- a/graph/ui-graph/src/lib/graph.ts
+++ b/graph/ui-graph/src/lib/graph.ts
@@ -157,12 +157,12 @@ export class GraphService {
);
break;
- case 'notifyGraphShowProject':
- this.showProjects([event.projectName]);
+ case 'notifyGraphShowProjects':
+ this.showProjects(event.projectNames);
break;
- case 'notifyGraphHideProject':
- this.hideProject(event.projectName);
+ case 'notifyGraphHideProjects':
+ this.hideProjects(event.projectNames);
break;
case 'notifyGraphShowAllProjects':
@@ -349,14 +349,18 @@ export class GraphService {
this.transferToRenderGraph(nodesToRender.union(edgesToRender));
}
- hideProject(projectName: string) {
+ hideProjects(projectNames: string[]) {
const currentNodes =
this.renderGraph?.nodes() ?? this.traversalGraph.collection();
- const nodeToHide = this.renderGraph.$id(projectName);
+ let nodesToHide = this.renderGraph.collection();
+
+ projectNames.forEach((projectName) => {
+ nodesToHide = nodesToHide.union(this.renderGraph.$id(projectName));
+ });
const nodesToAdd = currentNodes
- .difference(nodeToHide)
- .difference(nodeToHide.ancestors());
+ .difference(nodesToHide)
+ .difference(nodesToHide.ancestors());
const ancestorsToAdd = nodesToAdd.ancestors();
let nodesToRender = nodesToAdd.union(ancestorsToAdd);
diff --git a/graph/ui-graph/src/lib/interfaces.ts b/graph/ui-graph/src/lib/interfaces.ts
index a8ba471192570..d44c325f588d4 100644
--- a/graph/ui-graph/src/lib/interfaces.ts
+++ b/graph/ui-graph/src/lib/interfaces.ts
@@ -34,6 +34,8 @@ export type DepGraphUIEvents =
}
| { type: 'selectProject'; projectName: string }
| { type: 'deselectProject'; projectName: string }
+ | { type: 'selectProjects'; projectNames: string[] }
+ | { type: 'deselectProjects'; projectNames: string[] }
| { type: 'selectAll' }
| { type: 'deselectAll' }
| { type: 'selectAffected' }
@@ -103,12 +105,12 @@ export type GraphRenderEvents =
searchDepth: number;
}
| {
- type: 'notifyGraphShowProject';
- projectName: string;
+ type: 'notifyGraphShowProjects';
+ projectNames: string[];
}
| {
- type: 'notifyGraphHideProject';
- projectName: string;
+ type: 'notifyGraphHideProjects';
+ projectNames: string[];
}
| {
type: 'notifyGraphShowAllProjects';