Skip to content

Commit

Permalink
feat(graph): toggle visibility of all projects in a folder
Browse files Browse the repository at this point in the history
Adds a button next to the folder label to quickly show/hide all projects of that folder

ISSUES CLOSED: 12640
  • Loading branch information
alexciesielski committed Oct 19, 2022
1 parent 204c5cb commit 0ffea24
Show file tree
Hide file tree
Showing 3 changed files with 55 additions and 7 deletions.
18 changes: 17 additions & 1 deletion graph/client-e2e/src/integration/app.spec.ts
Expand Up @@ -12,12 +12,13 @@ import {
getSelectProjectsMessage,
getTextFilterInput,
getTextFilterReset,
getToggleAllButtonForFolder,
getUncheckedProjectItems,
getUnfocusProjectButton,
} from '../support/app.po';

import * as nxExamplesJson from '../fixtures/nx-examples.json';
import * as affectedJson from '../fixtures/affected.json';
import * as nxExamplesJson from '../fixtures/nx-examples.json';

describe('graph-client', () => {
before(() => {
Expand Down Expand Up @@ -229,6 +230,21 @@ describe('graph-client', () => {
});
});

describe('toggle all projects in folder button', () => {
it('should uncheck all projects in folder if at least one project checked', () => {
cy.contains('shared-product-state').scrollIntoView().should('be.visible');
cy.get('[data-project="shared-product-state"]').should('be.visible');
cy.get('[data-project="shared-product-state"]').click({ force: true });
getToggleAllButtonForFolder('shared/product').click({ force: true });
getCheckedProjectItems().should('have.length', 0);
});

it('should check all projects in folder if no projects checked yet', () => {
getToggleAllButtonForFolder('shared').click({ force: true });
getCheckedProjectItems().should('have.length', 5);
});
});

describe('image download button', () => {
it('should be hidden initally', () => {
getImageDownloadButton().should('have.class', 'opacity-0');
Expand Down
3 changes: 3 additions & 0 deletions graph/client-e2e/src/support/app.po.ts
Expand Up @@ -32,3 +32,6 @@ export const getImageDownloadButton = () =>

export const getFocusButtonForProject = (projectName: string) =>
cy.get(`[data-cy="focus-button-${projectName}"]`);

export const getToggleAllButtonForFolder = (folderName: string) =>
cy.get(`[data-cy="toggle-folder-visibility-button-${folderName}"]`);
41 changes: 35 additions & 6 deletions graph/client/src/app/sidebar/project-list.tsx
Expand Up @@ -4,19 +4,19 @@ import {
MapPinIcon,
} from '@heroicons/react/24/outline';
// nx-ignore-next-line
import { EyeIcon } from '@heroicons/react/24/outline';
import type { ProjectGraphNode } from '@nrwl/devkit';
import ExperimentalFeature from '../experimental-feature';
import { useDepGraphService } from '../hooks/use-dep-graph';
import { useDepGraphSelector } from '../hooks/use-dep-graph-selector';
import { TracingAlgorithmType } from '../machines/interfaces';
import {
allProjectsSelector,
getTracingInfo,
selectedProjectNamesSelector,
workspaceLayoutSelector,
} from '../machines/selectors';
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
Expand Down Expand Up @@ -187,12 +187,41 @@ function SubProjectList({
}
}

function toggleAllProjects(currentlySelected: boolean) {
if (currentlySelected) {
projects.forEach((project) =>
deselectProject(project.projectGraphNode.name)
);
} else {
projects.forEach((project) =>
selectProject(project.projectGraphNode.name)
);
}
}

const someProjectsSelected = projects.some((project) => project.isSelected);

return (
<>
{headerText !== '' ? (
<h3 className="mt-4 cursor-text py-2 text-sm font-semibold uppercase tracking-wide text-slate-800 dark:text-slate-200 lg:text-xs">
{headerText}
</h3>
<div className="relative mt-4 flex justify-between py-2 text-slate-800 dark:text-slate-200">
<h3 className="cursor-text text-sm font-semibold uppercase tracking-wide lg:text-xs">
{headerText}
</h3>

<span
title={
someProjectsSelected
? `Hide all ${headerText} projects`
: `Show all ${headerText} projects`
}
className="absolute inset-y-0 right-0 flex cursor-pointer items-center text-sm font-semibold uppercase tracking-wide lg:text-xs"
data-cy={`toggle-folder-visibility-button-${headerText}`}
onClick={() => toggleAllProjects(someProjectsSelected)}
>
<EyeIcon className="h-5 w-5"></EyeIcon>
</span>
</div>
) : null}
<ul className="mt-2 -ml-3">
{sortedProjects.map((project) => {
Expand Down

0 comments on commit 0ffea24

Please sign in to comment.