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';