From 578ecb67856613304cd39811b8a74897b8feb236 Mon Sep 17 00:00:00 2001 From: Philip Fulcher Date: Thu, 15 Dec 2022 18:54:34 -0700 Subject: [PATCH] feat(graph): add tooltips to docs graph (#13832) --- docs/shared/core-features/explore-graph.md | 3 +- graph/.storybook/main.js | 11 +++ graph/.storybook/preview.js | 0 .../.storybook}/tsconfig.json | 2 +- graph/client/.storybook/main.js | 2 +- graph/client/.storybook/preview.js | 10 +-- graph/client/.storybook/tailwind-imports.css | 3 + graph/client/src/app/app.tsx | 8 +- .../panels/collapse-edges-panel.tsx | 2 - .../panels/group-by-folder-panel.tsx | 5 +- .../feature-projects/panels/rankdir-panel.tsx | 2 +- .../feature-projects/panels/search-depth.tsx | 2 - .../panels/text-filter-panel.tsx | 4 +- .../feature-projects/panels/theme-panel.tsx | 2 +- .../feature-projects/panels/tracing-panel.tsx | 2 - .../src/app/feature-projects/project-list.tsx | 4 +- .../app/feature-projects/projects-sidebar.tsx | 24 +++-- .../src/app/feature-tasks/task-list.tsx | 2 - .../src/app/feature-tasks/tasks-sidebar.tsx | 11 +-- graph/client/src/app/machines/get-services.ts | 13 +++ graph/client/src/app/routes.tsx | 4 +- graph/client/src/app/shell.tsx | 17 ++-- .../ui-components/checkbox-panel.stories.tsx | 2 +- .../src/app/ui-components/checkbox-panel.tsx | 2 - .../src/app/ui-components/debugger-panel.tsx | 4 +- .../ui-components/experimental-feature.tsx | 4 +- .../src/app/ui-components/focused-panel.tsx | 2 - .../src/app/ui-components/show-hide-all.tsx | 2 - .../app/ui-tooltips/graph-tooltip-display.tsx | 21 +++-- .../app/ui-tooltips/project-node-actions.tsx | 65 ++++++++++++++ .../app/ui-tooltips/project-node-tooltip.tsx | 90 ------------------- .../src/app/ui-tooltips/task-node-tooltip.tsx | 26 ------ graph/client/src/main.tsx | 8 +- graph/client/tailwind.config.js | 5 +- graph/ui-components/.babelrc | 12 +++ graph/ui-components/.eslintrc.json | 18 ++++ graph/ui-components/.storybook/main.js | 24 +++++ graph/ui-components/.storybook/preview.js | 8 ++ .../.storybook/tailwind-imports.css | 3 + graph/ui-components/.storybook/tsconfig.json | 26 ++++++ graph/ui-components/README.md | 7 ++ graph/ui-components/jest.config.ts | 10 +++ graph/ui-components/postcss.config.js | 8 ++ graph/ui-components/project.json | 55 ++++++++++++ graph/ui-components/src/index.ts | 3 + .../src/lib}/debounced-text-input.stories.tsx | 2 +- .../src/lib}/debounced-text-input.tsx | 4 +- .../src/lib}/dropdown.stories.tsx | 0 .../src/lib}/dropdown.tsx | 2 - .../src/lib}/tag.stories.tsx | 0 .../src/lib}/tag.tsx | 2 - .../src/lib}/use-debounce.ts | 0 graph/ui-components/tailwind.config.js | 40 +++++++++ graph/ui-components/tsconfig.json | 23 +++++ graph/ui-components/tsconfig.lib.json | 28 ++++++ graph/ui-components/tsconfig.spec.json | 20 +++++ graph/ui-graph/.storybook/main.js | 2 +- graph/ui-graph/.storybook/preview-head.html | 26 ++++++ graph/ui-graph/.storybook/preview.js | 5 ++ .../ui-graph/.storybook/tailwind-imports.css | 3 + graph/ui-graph/postcss.config.js | 10 +++ graph/ui-graph/src/index.ts | 1 + .../src/lib/graph-interaction-events.ts | 15 ++-- graph/ui-graph/src/lib/graph.ts | 1 + graph/ui-graph/src/lib/interfaces.ts | 19 ++++ ...s.tsx => nx-project-graph-viz.stories.tsx} | 11 ++- .../ui-graph/src/lib/nx-project-graph-viz.tsx | 62 +++++++++++-- .../src/lib/nx-task-graph-viz.stories.tsx | 3 + graph/ui-graph/src/lib/nx-task-graph-viz.tsx | 52 +++++++++-- .../src/lib}/tooltip-service.ts | 41 +++------ .../src/lib/util-cytoscape/parent-node.ts | 2 +- .../src/lib/util-cytoscape/project-edge.ts | 4 +- .../src/lib/util-cytoscape/project-node.ts | 11 ++- .../util-cytoscape/project-traversal-graph.ts | 9 +- .../src/lib/util-cytoscape/render-graph.ts | 46 ++++++---- .../src/lib/util-cytoscape/task-node.ts | 6 +- graph/ui-graph/tailwind.config.js | 40 +++++++++ graph/ui-tooltips/.babelrc | 12 +++ graph/ui-tooltips/.eslintrc.json | 18 ++++ graph/ui-tooltips/.storybook/main.js | 22 +++++ graph/ui-tooltips/.storybook/preview.js | 1 + .../.storybook/tailwind-imports.css | 3 + graph/ui-tooltips/.storybook/tsconfig.json | 26 ++++++ graph/ui-tooltips/README.md | 7 ++ graph/ui-tooltips/jest.config.ts | 10 +++ graph/ui-tooltips/postcss.config.js | 10 +++ graph/ui-tooltips/project.json | 55 ++++++++++++ graph/ui-tooltips/src/index.ts | 5 ++ .../src/lib}/project-edge-tooltip.stories.tsx | 0 .../src/lib}/project-edge-tooltip.tsx | 9 +- .../src/lib}/project-node-tooltip.stories.tsx | 0 .../src/lib/project-node-tooltip.tsx | 37 ++++++++ .../src/lib}/task-node-tooltip.stories.tsx | 0 .../ui-tooltips/src/lib/task-node-tooltip.tsx | 23 +++++ .../src/lib}/tooltip-button.tsx | 0 .../src/lib}/tooltip.tsx | 13 +-- graph/ui-tooltips/tailwind.config.js | 40 +++++++++ graph/ui-tooltips/tsconfig.json | 23 +++++ graph/ui-tooltips/tsconfig.lib.json | 27 ++++++ graph/ui-tooltips/tsconfig.spec.json | 20 +++++ .../src/lib/tags/graph.component.tsx | 2 + package.json | 3 +- packages/nx/src/config/project-graph.ts | 2 + tsconfig.base.json | 2 + yarn.lock | 30 ++----- 105 files changed, 1093 insertions(+), 335 deletions(-) create mode 100644 graph/.storybook/main.js create mode 100644 graph/.storybook/preview.js rename {.storybook => graph/.storybook}/tsconfig.json (85%) create mode 100644 graph/client/.storybook/tailwind-imports.css create mode 100644 graph/client/src/app/ui-tooltips/project-node-actions.tsx delete mode 100644 graph/client/src/app/ui-tooltips/project-node-tooltip.tsx delete mode 100644 graph/client/src/app/ui-tooltips/task-node-tooltip.tsx create mode 100644 graph/ui-components/.babelrc create mode 100644 graph/ui-components/.eslintrc.json create mode 100644 graph/ui-components/.storybook/main.js create mode 100644 graph/ui-components/.storybook/preview.js create mode 100644 graph/ui-components/.storybook/tailwind-imports.css create mode 100644 graph/ui-components/.storybook/tsconfig.json create mode 100644 graph/ui-components/README.md create mode 100644 graph/ui-components/jest.config.ts create mode 100644 graph/ui-components/postcss.config.js create mode 100644 graph/ui-components/project.json create mode 100644 graph/ui-components/src/index.ts rename graph/{client/src/app/ui-components => ui-components/src/lib}/debounced-text-input.stories.tsx (97%) rename graph/{client/src/app/ui-components => ui-components/src/lib}/debounced-text-input.tsx (96%) rename graph/{client/src/app/ui-components => ui-components/src/lib}/dropdown.stories.tsx (100%) rename graph/{client/src/app/ui-components => ui-components/src/lib}/dropdown.tsx (96%) rename graph/{client/src/app/ui-components => ui-components/src/lib}/tag.stories.tsx (100%) rename graph/{client/src/app/ui-components => ui-components/src/lib}/tag.tsx (96%) rename graph/{client/src/app/hooks => ui-components/src/lib}/use-debounce.ts (100%) create mode 100644 graph/ui-components/tailwind.config.js create mode 100644 graph/ui-components/tsconfig.json create mode 100644 graph/ui-components/tsconfig.lib.json create mode 100644 graph/ui-components/tsconfig.spec.json create mode 100644 graph/ui-graph/.storybook/preview-head.html create mode 100644 graph/ui-graph/.storybook/tailwind-imports.css create mode 100644 graph/ui-graph/postcss.config.js rename graph/ui-graph/src/lib/{nx-graph-viz.stories.tsx => nx-project-graph-viz.stories.tsx} (81%) rename graph/{client/src/app/ui-tooltips => ui-graph/src/lib}/tooltip-service.ts (67%) create mode 100644 graph/ui-graph/tailwind.config.js create mode 100644 graph/ui-tooltips/.babelrc create mode 100644 graph/ui-tooltips/.eslintrc.json create mode 100644 graph/ui-tooltips/.storybook/main.js create mode 100644 graph/ui-tooltips/.storybook/preview.js create mode 100644 graph/ui-tooltips/.storybook/tailwind-imports.css create mode 100644 graph/ui-tooltips/.storybook/tsconfig.json create mode 100644 graph/ui-tooltips/README.md create mode 100644 graph/ui-tooltips/jest.config.ts create mode 100644 graph/ui-tooltips/postcss.config.js create mode 100644 graph/ui-tooltips/project.json create mode 100644 graph/ui-tooltips/src/index.ts rename graph/{client/src/app/ui-tooltips => ui-tooltips/src/lib}/project-edge-tooltip.stories.tsx (100%) rename graph/{client/src/app/ui-tooltips => ui-tooltips/src/lib}/project-edge-tooltip.tsx (87%) rename graph/{client/src/app/ui-tooltips => ui-tooltips/src/lib}/project-node-tooltip.stories.tsx (100%) create mode 100644 graph/ui-tooltips/src/lib/project-node-tooltip.tsx rename graph/{client/src/app/ui-tooltips => ui-tooltips/src/lib}/task-node-tooltip.stories.tsx (100%) create mode 100644 graph/ui-tooltips/src/lib/task-node-tooltip.tsx rename graph/{client/src/app/ui-tooltips => ui-tooltips/src/lib}/tooltip-button.tsx (100%) rename graph/{client/src/app/ui-tooltips => ui-tooltips/src/lib}/tooltip.tsx (93%) create mode 100644 graph/ui-tooltips/tailwind.config.js create mode 100644 graph/ui-tooltips/tsconfig.json create mode 100644 graph/ui-tooltips/tsconfig.lib.json create mode 100644 graph/ui-tooltips/tsconfig.spec.json diff --git a/docs/shared/core-features/explore-graph.md b/docs/shared/core-features/explore-graph.md index 57082bdf50623..3165ccc3628e0 100644 --- a/docs/shared/core-features/explore-graph.md +++ b/docs/shared/core-features/explore-graph.md @@ -126,7 +126,8 @@ Try playing around with a [fully interactive graph on a sample repo](https://nrw "affectedProjectIds": [], "focus": null, "groupByFolder": false, - "exclude": [] + "exclude": [], + "enableTooltips": true } ``` diff --git a/graph/.storybook/main.js b/graph/.storybook/main.js new file mode 100644 index 0000000000000..1492ac61f6fd0 --- /dev/null +++ b/graph/.storybook/main.js @@ -0,0 +1,11 @@ +module.exports = { + stories: [], + addons: ['@storybook/addon-essentials'], + // uncomment the property below if you want to apply some webpack config globally + // webpackFinal: async (config, { configType }) => { + // // Make whatever fine-grained changes you need that should apply to all storybook configs + + // // Return the altered config + // return config; + // }, +}; diff --git a/graph/.storybook/preview.js b/graph/.storybook/preview.js new file mode 100644 index 0000000000000..e69de29bb2d1d diff --git a/.storybook/tsconfig.json b/graph/.storybook/tsconfig.json similarity index 85% rename from .storybook/tsconfig.json rename to graph/.storybook/tsconfig.json index 7dd91521d33ee..e81ef225b3c65 100644 --- a/.storybook/tsconfig.json +++ b/graph/.storybook/tsconfig.json @@ -1,5 +1,5 @@ { - "extends": "../tsconfig.base.json", + "extends": "../../tsconfig.base.json", "exclude": [ "../**/*.spec.js", "../**/*.test.js", diff --git a/graph/client/.storybook/main.js b/graph/client/.storybook/main.js index d6adb0a4b87e5..52ee9e27b94a1 100644 --- a/graph/client/.storybook/main.js +++ b/graph/client/.storybook/main.js @@ -1,4 +1,4 @@ -const rootMain = require('../../../.storybook/main'); +const rootMain = require('../../.storybook/main'); module.exports = { ...rootMain, diff --git a/graph/client/.storybook/preview.js b/graph/client/.storybook/preview.js index 4a62262ba7560..7ecdbaf4b9b62 100644 --- a/graph/client/.storybook/preview.js +++ b/graph/client/.storybook/preview.js @@ -3,16 +3,10 @@ import '../src/styles.scss'; import React from 'react'; import { MemoryRouter } from 'react-router-dom'; -import { themes } from '@storybook/theming'; +import { rootParameters } from '../../.storybook/preview'; export const parameters = { - darkMode: { - // Override the default dark theme - dark: { ...themes.dark, appContentBg: 'rgb(15, 23, 42, 1)' }, - // Override the default light theme - light: themes.normal, - stylePreview: true, - }, + ...rootParameters, }; export const decorators = [ (Story, context) => { diff --git a/graph/client/.storybook/tailwind-imports.css b/graph/client/.storybook/tailwind-imports.css new file mode 100644 index 0000000000000..b5c61c956711f --- /dev/null +++ b/graph/client/.storybook/tailwind-imports.css @@ -0,0 +1,3 @@ +@tailwind base; +@tailwind components; +@tailwind utilities; diff --git a/graph/client/src/app/app.tsx b/graph/client/src/app/app.tsx index 57c1ba8d05a04..176498dc88515 100644 --- a/graph/client/src/app/app.tsx +++ b/graph/client/src/app/app.tsx @@ -1,10 +1,6 @@ import { themeInit } from './theme-resolver'; import { rankDirInit } from './rankdir-resolver'; -import { - createBrowserRouter, - createHashRouter, - RouterProvider, -} from 'react-router-dom'; +import { RouterProvider } from 'react-router-dom'; import { getRouter } from './get-router'; themeInit(); @@ -13,5 +9,3 @@ rankDirInit(); export function App() { return ; } - -export default App; diff --git a/graph/client/src/app/feature-projects/panels/collapse-edges-panel.tsx b/graph/client/src/app/feature-projects/panels/collapse-edges-panel.tsx index 46a7ce9511df5..50126a2f9e275 100644 --- a/graph/client/src/app/feature-projects/panels/collapse-edges-panel.tsx +++ b/graph/client/src/app/feature-projects/panels/collapse-edges-panel.tsx @@ -37,5 +37,3 @@ export const CollapseEdgesPanel = memo( ); } ); - -export default CollapseEdgesPanel; diff --git a/graph/client/src/app/feature-projects/panels/group-by-folder-panel.tsx b/graph/client/src/app/feature-projects/panels/group-by-folder-panel.tsx index 13da542ad7631..34e5ef3fc964d 100644 --- a/graph/client/src/app/feature-projects/panels/group-by-folder-panel.tsx +++ b/graph/client/src/app/feature-projects/panels/group-by-folder-panel.tsx @@ -1,5 +1,4 @@ -import { memo } from 'react'; -import CheckboxPanel from '../../ui-components/checkbox-panel'; +import { CheckboxPanel } from '../../ui-components/checkbox-panel'; export interface DisplayOptionsPanelProps { groupByFolder: boolean; @@ -20,5 +19,3 @@ export const GroupByFolderPanel = ({ /> ); }; - -export default GroupByFolderPanel; diff --git a/graph/client/src/app/feature-projects/panels/rankdir-panel.tsx b/graph/client/src/app/feature-projects/panels/rankdir-panel.tsx index 3d0a1c68b1627..98f83ebf05c89 100644 --- a/graph/client/src/app/feature-projects/panels/rankdir-panel.tsx +++ b/graph/client/src/app/feature-projects/panels/rankdir-panel.tsx @@ -9,7 +9,7 @@ import { rankDirResolver, } from '../../rankdir-resolver'; -export default function RankdirPanel(): JSX.Element { +export function RankdirPanel(): JSX.Element { const [rankDir, setRankDir] = useState( (localStorage.getItem(localStorageRankDirKey) as RankDir) || 'TB' ); diff --git a/graph/client/src/app/feature-projects/panels/search-depth.tsx b/graph/client/src/app/feature-projects/panels/search-depth.tsx index a63b644d44fca..d1762110f325d 100644 --- a/graph/client/src/app/feature-projects/panels/search-depth.tsx +++ b/graph/client/src/app/feature-projects/panels/search-depth.tsx @@ -76,5 +76,3 @@ export const SearchDepth = memo( ); } ); - -export default SearchDepth; diff --git a/graph/client/src/app/feature-projects/panels/text-filter-panel.tsx b/graph/client/src/app/feature-projects/panels/text-filter-panel.tsx index 02ef7c0adbba3..9dccce0d1e50f 100644 --- a/graph/client/src/app/feature-projects/panels/text-filter-panel.tsx +++ b/graph/client/src/app/feature-projects/panels/text-filter-panel.tsx @@ -1,4 +1,4 @@ -import DebouncedTextInput from '../../ui-components/debounced-text-input'; +import { DebouncedTextInput } from '@nrwl/graph/ui-components'; export interface TextFilterPanelProps { textFilter: string; @@ -56,5 +56,3 @@ export function TextFilterPanel({ ); } - -export default TextFilterPanel; diff --git a/graph/client/src/app/feature-projects/panels/theme-panel.tsx b/graph/client/src/app/feature-projects/panels/theme-panel.tsx index 4500d19d0abce..588fadce2ace0 100644 --- a/graph/client/src/app/feature-projects/panels/theme-panel.tsx +++ b/graph/client/src/app/feature-projects/panels/theme-panel.tsx @@ -12,7 +12,7 @@ import { themeResolver, } from '../../theme-resolver'; -export default function ThemePanel(): JSX.Element { +export function ThemePanel(): JSX.Element { const [theme, setTheme] = useState( (localStorage.getItem(localStorageThemeKey) as Theme) || 'system' ); diff --git a/graph/client/src/app/feature-projects/panels/tracing-panel.tsx b/graph/client/src/app/feature-projects/panels/tracing-panel.tsx index 88a13833dc0ac..26be6711f31fb 100644 --- a/graph/client/src/app/feature-projects/panels/tracing-panel.tsx +++ b/graph/client/src/app/feature-projects/panels/tracing-panel.tsx @@ -111,5 +111,3 @@ export const TracingPanel = memo( ); } ); - -export default TracingPanel; diff --git a/graph/client/src/app/feature-projects/project-list.tsx b/graph/client/src/app/feature-projects/project-list.tsx index ddb41da31922f..e7c326b6089cd 100644 --- a/graph/client/src/app/feature-projects/project-list.tsx +++ b/graph/client/src/app/feature-projects/project-list.tsx @@ -18,7 +18,7 @@ import { parseParentDirectoriesFromFilePath, useRouteConstructor, } from '../util'; -import ExperimentalFeature from '../ui-components/experimental-feature'; +import { ExperimentalFeature } from '../ui-components/experimental-feature'; import { TracingAlgorithmType } from './machines/interfaces'; import { getProjectGraphService } from '../machines/get-services'; import { Link, useNavigate } from 'react-router-dom'; @@ -317,5 +317,3 @@ export function ProjectList() { ); } - -export default ProjectList; diff --git a/graph/client/src/app/feature-projects/projects-sidebar.tsx b/graph/client/src/app/feature-projects/projects-sidebar.tsx index ecb2929bc6e38..a65e331dcb229 100644 --- a/graph/client/src/app/feature-projects/projects-sidebar.tsx +++ b/graph/client/src/app/feature-projects/projects-sidebar.tsx @@ -1,5 +1,5 @@ import { useCallback, useEffect } from 'react'; -import ExperimentalFeature from '../ui-components/experimental-feature'; +import { ExperimentalFeature } from '../ui-components/experimental-feature'; import { useProjectGraphSelector } from './hooks/use-project-graph-selector'; import { collapseEdgesSelector, @@ -11,14 +11,14 @@ import { searchDepthSelector, textFilterSelector, } from './machines/selectors'; -import CollapseEdgesPanel from './panels/collapse-edges-panel'; -import FocusedPanel from '../ui-components/focused-panel'; -import GroupByFolderPanel from './panels/group-by-folder-panel'; -import ProjectList from './project-list'; -import SearchDepth from './panels/search-depth'; -import ShowHideProjects from '../ui-components/show-hide-all'; -import TextFilterPanel from './panels/text-filter-panel'; -import TracingPanel from './panels/tracing-panel'; +import { CollapseEdgesPanel } from './panels/collapse-edges-panel'; +import { FocusedPanel } from '../ui-components/focused-panel'; +import { GroupByFolderPanel } from './panels/group-by-folder-panel'; +import { ProjectList } from './project-list'; +import { SearchDepth } from './panels/search-depth'; +import { ShowHideAll } from '../ui-components/show-hide-all'; +import { TextFilterPanel } from './panels/text-filter-panel'; +import { TracingPanel } from './panels/tracing-panel'; import { useEnvironmentConfig } from '../hooks/use-environment-config'; import { TracingAlgorithmType } from './machines/interfaces'; import { getProjectGraphService } from '../machines/get-services'; @@ -352,13 +352,13 @@ export function ProjectsSidebar(): JSX.Element { >
- + > ); } - -export default ProjectsSidebar; diff --git a/graph/client/src/app/feature-tasks/task-list.tsx b/graph/client/src/app/feature-tasks/task-list.tsx index 6a257d09063ed..c41006cc5dd01 100644 --- a/graph/client/src/app/feature-tasks/task-list.tsx +++ b/graph/client/src/app/feature-tasks/task-list.tsx @@ -187,5 +187,3 @@ export function TaskList({
); } - -export default TaskList; diff --git a/graph/client/src/app/feature-tasks/tasks-sidebar.tsx b/graph/client/src/app/feature-tasks/tasks-sidebar.tsx index 69731ec16e64b..b3acb65de817b 100644 --- a/graph/client/src/app/feature-tasks/tasks-sidebar.tsx +++ b/graph/client/src/app/feature-tasks/tasks-sidebar.tsx @@ -1,4 +1,4 @@ -import TaskList from './task-list'; +import { TaskList } from './task-list'; import { useNavigate, useParams, @@ -12,11 +12,10 @@ import type { } from 'nx/src/command-line/dep-graph'; import { getGraphService } from '../machines/graph.service'; import { useEffect, useState } from 'react'; -import CheckboxPanel from '../ui-components/checkbox-panel'; +import { CheckboxPanel } from '../ui-components/checkbox-panel'; -// nx-ignore-next-line -import Dropdown from '../ui-components/dropdown'; -import ShowHideAll from '../ui-components/show-hide-all'; +import { Dropdown } from '@nrwl/graph/ui-components'; +import { ShowHideAll } from '../ui-components/show-hide-all'; function createTaskName( project: string, @@ -217,5 +216,3 @@ export function TasksSidebar() { ); } - -export default TasksSidebar; diff --git a/graph/client/src/app/machines/get-services.ts b/graph/client/src/app/machines/get-services.ts index 3793d9176a98b..b810c7e5bf4b6 100644 --- a/graph/client/src/app/machines/get-services.ts +++ b/graph/client/src/app/machines/get-services.ts @@ -1,5 +1,7 @@ import { interpret, InterpreterStatus } from 'xstate'; import { projectGraphMachine } from '../feature-projects/machines/project-graph.machine'; +import { getGraphService } from './graph.service'; +import { GraphTooltipService } from '@nrwl/graph/ui-graph'; let projectGraphService = interpret(projectGraphMachine, { devTools: !!window.useXstateInspect, @@ -12,3 +14,14 @@ export function getProjectGraphService() { return projectGraphService; } + +let tooltipService: GraphTooltipService; + +export function getTooltipService(): GraphTooltipService { + if (!tooltipService) { + const graph = getGraphService(); + tooltipService = new GraphTooltipService(graph); + } + + return tooltipService; +} diff --git a/graph/client/src/app/routes.tsx b/graph/client/src/app/routes.tsx index 8c6ea9fed4041..11367f12e169b 100644 --- a/graph/client/src/app/routes.tsx +++ b/graph/client/src/app/routes.tsx @@ -1,7 +1,7 @@ import { Shell } from './shell'; import { redirect, RouteObject } from 'react-router-dom'; -import ProjectsSidebar from './feature-projects/projects-sidebar'; -import TasksSidebar from './feature-tasks/tasks-sidebar'; +import { ProjectsSidebar } from './feature-projects/projects-sidebar'; +import { TasksSidebar } from './feature-tasks/tasks-sidebar'; import { getEnvironmentConfig } from './hooks/use-environment-config'; // nx-ignore-next-line import { ProjectGraphClientResponse } from 'nx/src/command-line/dep-graph'; diff --git a/graph/client/src/app/shell.tsx b/graph/client/src/app/shell.tsx index b61ce729bb696..c6ac4c818bf75 100644 --- a/graph/client/src/app/shell.tsx +++ b/graph/client/src/app/shell.tsx @@ -4,22 +4,19 @@ import { InformationCircleIcon, } from '@heroicons/react/24/outline'; import classNames from 'classnames'; -// nx-ignore-next-line - -import DebuggerPanel from './ui-components/debugger-panel'; +import { DebuggerPanel } from './ui-components/debugger-panel'; import { useEnvironmentConfig } from './hooks/use-environment-config'; import { getGraphService } from './machines/graph.service'; -import { selectValueByThemeStatic } from './theme-resolver'; import { Outlet, useNavigate, useParams } from 'react-router-dom'; -import ThemePanel from './feature-projects/panels/theme-panel'; -import Dropdown from './ui-components/dropdown'; +import { ThemePanel } from './feature-projects/panels/theme-panel'; +import { Dropdown } from '@nrwl/graph/ui-components'; import { useCurrentPath } from './hooks/use-current-path'; -import ExperimentalFeature from './ui-components/experimental-feature'; -import RankdirPanel from './feature-projects/panels/rankdir-panel'; +import { ExperimentalFeature } from './ui-components/experimental-feature'; +import { RankdirPanel } from './feature-projects/panels/rankdir-panel'; import { getProjectGraphService } from './machines/get-services'; -import TooltipDisplay from './ui-tooltips/graph-tooltip-display'; import { useSyncExternalStore } from 'use-sync-external-store/shim'; -import { Tooltip } from './ui-tooltips/tooltip'; +import { Tooltip } from '@nrwl/graph/ui-tooltips'; +import { TooltipDisplay } from './ui-tooltips/graph-tooltip-display'; export function Shell(): JSX.Element { const projectGraphService = getProjectGraphService(); diff --git a/graph/client/src/app/ui-components/checkbox-panel.stories.tsx b/graph/client/src/app/ui-components/checkbox-panel.stories.tsx index af6dc5bf2fe31..9b89dd16c6aff 100644 --- a/graph/client/src/app/ui-components/checkbox-panel.stories.tsx +++ b/graph/client/src/app/ui-components/checkbox-panel.stories.tsx @@ -1,5 +1,5 @@ import { ComponentMeta, ComponentStory } from '@storybook/react'; -import CheckboxPanel from './checkbox-panel'; +import { CheckboxPanel } from './checkbox-panel'; export default { component: CheckboxPanel, diff --git a/graph/client/src/app/ui-components/checkbox-panel.tsx b/graph/client/src/app/ui-components/checkbox-panel.tsx index 1248c9616c2a8..9fea965cac1d8 100644 --- a/graph/client/src/app/ui-components/checkbox-panel.tsx +++ b/graph/client/src/app/ui-components/checkbox-panel.tsx @@ -38,5 +38,3 @@ export const CheckboxPanel = memo( ); } ); - -export default CheckboxPanel; diff --git a/graph/client/src/app/ui-components/debugger-panel.tsx b/graph/client/src/app/ui-components/debugger-panel.tsx index 1f32fb7276666..9001bda584595 100644 --- a/graph/client/src/app/ui-components/debugger-panel.tsx +++ b/graph/client/src/app/ui-components/debugger-panel.tsx @@ -1,6 +1,6 @@ import { memo } from 'react'; import { WorkspaceData, GraphPerfReport } from '../interfaces'; -import Dropdown from './dropdown'; +import { Dropdown } from '@nrwl/graph/ui-components'; export interface DebuggerPanelProps { projects: WorkspaceData[]; @@ -49,5 +49,3 @@ export const DebuggerPanel = memo(function ({ ); }); - -export default DebuggerPanel; diff --git a/graph/client/src/app/ui-components/experimental-feature.tsx b/graph/client/src/app/ui-components/experimental-feature.tsx index a798c5bcae3fc..89574c0428424 100644 --- a/graph/client/src/app/ui-components/experimental-feature.tsx +++ b/graph/client/src/app/ui-components/experimental-feature.tsx @@ -1,7 +1,7 @@ import { useEnvironmentConfig } from '../hooks/use-environment-config'; import { Children, cloneElement } from 'react'; -function ExperimentalFeature(props) { +export function ExperimentalFeature(props) { const environment = useEnvironmentConfig(); const showExperimentalFeatures = environment.appConfig.showExperimentalFeatures; @@ -11,5 +11,3 @@ function ExperimentalFeature(props) { ) : null; } - -export default ExperimentalFeature; diff --git a/graph/client/src/app/ui-components/focused-panel.tsx b/graph/client/src/app/ui-components/focused-panel.tsx index 244ed0f54efe2..f4fa32e94b885 100644 --- a/graph/client/src/app/ui-components/focused-panel.tsx +++ b/graph/client/src/app/ui-components/focused-panel.tsx @@ -30,5 +30,3 @@ export const FocusedPanel = memo( ); } ); - -export default FocusedPanel; diff --git a/graph/client/src/app/ui-components/show-hide-all.tsx b/graph/client/src/app/ui-components/show-hide-all.tsx index 8574904f5653d..95a564f936378 100644 --- a/graph/client/src/app/ui-components/show-hide-all.tsx +++ b/graph/client/src/app/ui-components/show-hide-all.tsx @@ -54,5 +54,3 @@ export const ShowHideAll = memo( ); } ); - -export default ShowHideAll; diff --git a/graph/client/src/app/ui-tooltips/graph-tooltip-display.tsx b/graph/client/src/app/ui-tooltips/graph-tooltip-display.tsx index b8feca7e99797..9a8a554e2b703 100644 --- a/graph/client/src/app/ui-tooltips/graph-tooltip-display.tsx +++ b/graph/client/src/app/ui-tooltips/graph-tooltip-display.tsx @@ -1,9 +1,12 @@ -import ProjectNodeToolTip from './project-node-tooltip'; -import ProjectEdgeNodeTooltip from './project-edge-tooltip'; import { useSyncExternalStore } from 'use-sync-external-store/shim'; -import { getTooltipService } from './tooltip-service'; -import TaskNodeTooltip from './task-node-tooltip'; -import { Tooltip } from './tooltip'; +import { getTooltipService } from '../machines/get-services'; +import { + ProjectEdgeNodeTooltip, + ProjectNodeToolTip, + TaskNodeTooltip, + Tooltip, +} from '@nrwl/graph/ui-tooltips'; +import { ProjectNodeActions } from './project-node-actions'; const tooltipService = getTooltipService(); @@ -16,7 +19,11 @@ export function TooltipDisplay() { if (currentTooltip) { switch (currentTooltip.type) { case 'projectNode': - tooltipToRender = ; + tooltipToRender = ( + + + + ); break; case 'projectEdge': tooltipToRender = ; @@ -37,5 +44,3 @@ export function TooltipDisplay() { > ) : null; } - -export default TooltipDisplay; diff --git a/graph/client/src/app/ui-tooltips/project-node-actions.tsx b/graph/client/src/app/ui-tooltips/project-node-actions.tsx new file mode 100644 index 0000000000000..2d19cafae7630 --- /dev/null +++ b/graph/client/src/app/ui-tooltips/project-node-actions.tsx @@ -0,0 +1,65 @@ +import { ProjectNodeToolTipProps } from '@nrwl/graph/ui-tooltips'; +import { getProjectGraphService } from '../machines/get-services'; +import { useRouteConstructor } from '../util'; +import { useNavigate } from 'react-router-dom'; +import { TooltipButton, TooltipLinkButton } from '@nrwl/graph/ui-tooltips'; +import { FlagIcon, MapPinIcon } from '@heroicons/react/24/solid'; + +export function ProjectNodeActions({ id }: ProjectNodeToolTipProps) { + const projectGraphService = getProjectGraphService(); + const { start, end, algorithm } = + projectGraphService.getSnapshot().context.tracing; + const routeConstructor = useRouteConstructor(); + const navigate = useNavigate(); + + function onExclude() { + projectGraphService.send({ + type: 'deselectProject', + projectName: id, + }); + navigate(routeConstructor('/projects', true)); + } + + function onStartTrace() { + navigate( + routeConstructor(`/projects/trace/${encodeURIComponent(id)}`, true) + ); + } + + function onEndTrace() { + navigate( + routeConstructor( + `/projects/trace/${encodeURIComponent(start)}/${encodeURIComponent( + id + )}`, + true + ) + ); + } + + return ( +
+ + Focus + + Exclude + {!start ? ( + + + Start + + ) : ( + + + End + + )} +
+ ); +} diff --git a/graph/client/src/app/ui-tooltips/project-node-tooltip.tsx b/graph/client/src/app/ui-tooltips/project-node-tooltip.tsx deleted file mode 100644 index 4d7146434da9d..0000000000000 --- a/graph/client/src/app/ui-tooltips/project-node-tooltip.tsx +++ /dev/null @@ -1,90 +0,0 @@ -import { getProjectGraphService } from '../machines/get-services'; -import { FlagIcon, MapPinIcon } from '@heroicons/react/24/solid'; -import Tag from '../ui-components/tag'; -import { TooltipButton, TooltipLinkButton } from './tooltip-button'; -import { useRouteConstructor } from '../util'; -import { useNavigate } from 'react-router-dom'; - -export interface ProjectNodeToolTipProps { - type: 'app' | 'lib' | 'e2e'; - id: string; - tags: string[]; -} - -export function ProjectNodeToolTip({ - type, - id, - tags, -}: ProjectNodeToolTipProps) { - const projectGraphService = getProjectGraphService(); - const { start, end, algorithm } = - projectGraphService.getSnapshot().context.tracing; - const routeConstructor = useRouteConstructor(); - const navigate = useNavigate(); - - function onExclude() { - projectGraphService.send({ - type: 'deselectProject', - projectName: id, - }); - navigate(routeConstructor('/projects', true)); - } - - function onStartTrace() { - navigate( - routeConstructor(`/projects/trace/${encodeURIComponent(id)}`, true) - ); - } - - function onEndTrace() { - navigate( - routeConstructor( - `/projects/trace/${encodeURIComponent(start)}/${encodeURIComponent( - id - )}`, - true - ) - ); - } - - return ( -
-

- {type} - {id} -

- {tags.length > 0 ? ( -

- tags -

- {tags.join(', ')} -

- ) : null} -
- - Focus - - Exclude - {!start ? ( - - - Start - - ) : ( - - - End - - )} -
-
- ); -} - -export default ProjectNodeToolTip; diff --git a/graph/client/src/app/ui-tooltips/task-node-tooltip.tsx b/graph/client/src/app/ui-tooltips/task-node-tooltip.tsx deleted file mode 100644 index 5311402796c60..0000000000000 --- a/graph/client/src/app/ui-tooltips/task-node-tooltip.tsx +++ /dev/null @@ -1,26 +0,0 @@ -import Tag from '../ui-components/tag'; -import { useParams } from 'react-router-dom'; - -export interface TaskNodeTooltipProps { - id: string; - executor: string; -} - -export function TaskNodeTooltip({ id, executor }: TaskNodeTooltipProps) { - const params = useParams(); - const selectedWorkspaceId = params['selectedWorkspaceId']; - - const to = selectedWorkspaceId - ? `/${selectedWorkspaceId}/tasks/${id}` - : `/tasks/${id}`; - return ( -
-

- {executor} - {id} -

-
- ); -} - -export default TaskNodeTooltip; diff --git a/graph/client/src/main.tsx b/graph/client/src/main.tsx index 3105c512e9ab5..93fc11e3591ff 100644 --- a/graph/client/src/main.tsx +++ b/graph/client/src/main.tsx @@ -1,7 +1,7 @@ import { StrictMode } from 'react'; -import * as ReactDOM from 'react-dom'; +import { render } from 'react-dom'; import { inspect } from '@xstate/inspect'; -import App from './app/app'; +import { App } from './app/app'; import { ExternalApi } from './app/external-api'; if (window.useXstateInspect === true) { @@ -14,7 +14,7 @@ if (window.useXstateInspect === true) { window.externalApi = new ExternalApi(); if (!window.appConfig) { - ReactDOM.render( + render(

No environment could be found. Please run{' '}

npx nx run graph-client:generate-dev-environment-js
. @@ -22,7 +22,7 @@ if (!window.appConfig) { document.getElementById('app') ); } else { - ReactDOM.render( + render( , diff --git a/graph/client/tailwind.config.js b/graph/client/tailwind.config.js index 428f07ecfdd78..3b56335f1e460 100644 --- a/graph/client/tailwind.config.js +++ b/graph/client/tailwind.config.js @@ -1,9 +1,12 @@ const path = require('path'); +// nx-ignore-next-line +const { createGlobPatternsForDependencies } = require('@nrwl/react/tailwind'); + module.exports = { content: [ path.join(__dirname, 'src/**/*.{js,ts,jsx,tsx,html}'), - // ...createGlobPatternsForDependencies(__dirname), + ...createGlobPatternsForDependencies(__dirname), ], darkMode: 'class', // or 'media' or 'class' theme: { diff --git a/graph/ui-components/.babelrc b/graph/ui-components/.babelrc new file mode 100644 index 0000000000000..ccae900be4278 --- /dev/null +++ b/graph/ui-components/.babelrc @@ -0,0 +1,12 @@ +{ + "presets": [ + [ + "@nrwl/react/babel", + { + "runtime": "automatic", + "useBuiltIns": "usage" + } + ] + ], + "plugins": [] +} diff --git a/graph/ui-components/.eslintrc.json b/graph/ui-components/.eslintrc.json new file mode 100644 index 0000000000000..734ddaceea447 --- /dev/null +++ b/graph/ui-components/.eslintrc.json @@ -0,0 +1,18 @@ +{ + "extends": ["plugin:@nrwl/nx/react", "../../.eslintrc.json"], + "ignorePatterns": ["!**/*"], + "overrides": [ + { + "files": ["*.ts", "*.tsx", "*.js", "*.jsx"], + "rules": {} + }, + { + "files": ["*.ts", "*.tsx"], + "rules": {} + }, + { + "files": ["*.js", "*.jsx"], + "rules": {} + } + ] +} diff --git a/graph/ui-components/.storybook/main.js b/graph/ui-components/.storybook/main.js new file mode 100644 index 0000000000000..e7054830ab823 --- /dev/null +++ b/graph/ui-components/.storybook/main.js @@ -0,0 +1,24 @@ +const rootMain = require('../../.storybook/main'); + +module.exports = { + ...rootMain, + + core: { ...rootMain.core, builder: 'webpack5' }, + + stories: [ + ...rootMain.stories, + '../src/lib/**/*.stories.mdx', + '../src/lib/**/*.stories.@(js|jsx|ts|tsx)', + ], + addons: [...rootMain.addons, '@nrwl/react/plugins/storybook'], + webpackFinal: async (config, { configType }) => { + // apply any global webpack configs that might have been specified in .storybook/main.js + if (rootMain.webpackFinal) { + config = await rootMain.webpackFinal(config, { configType }); + } + + // add your own webpack tweaks if needed + + return config; + }, +}; diff --git a/graph/ui-components/.storybook/preview.js b/graph/ui-components/.storybook/preview.js new file mode 100644 index 0000000000000..cc37ad617e84f --- /dev/null +++ b/graph/ui-components/.storybook/preview.js @@ -0,0 +1,8 @@ +import React from 'react'; +import '../../client/.storybook/tailwind-imports.css'; + +import { rootParameters } from '../../.storybook/preview'; + +export const parameters = { + ...rootParameters, +}; diff --git a/graph/ui-components/.storybook/tailwind-imports.css b/graph/ui-components/.storybook/tailwind-imports.css new file mode 100644 index 0000000000000..b5c61c956711f --- /dev/null +++ b/graph/ui-components/.storybook/tailwind-imports.css @@ -0,0 +1,3 @@ +@tailwind base; +@tailwind components; +@tailwind utilities; diff --git a/graph/ui-components/.storybook/tsconfig.json b/graph/ui-components/.storybook/tsconfig.json new file mode 100644 index 0000000000000..286dc2f6355dd --- /dev/null +++ b/graph/ui-components/.storybook/tsconfig.json @@ -0,0 +1,26 @@ +{ + "extends": "../tsconfig.json", + "compilerOptions": { + "emitDecoratorMetadata": true, + "outDir": "" + }, + "files": [ + "../../../node_modules/@nrwl/react/typings/styled-jsx.d.ts", + "../../../node_modules/@nrwl/react/typings/cssmodule.d.ts", + "../../../node_modules/@nrwl/react/typings/image.d.ts" + ], + "exclude": [ + "../**/*.spec.ts", + "../**/*.spec.js", + "../**/*.spec.tsx", + "../**/*.spec.jsx" + ], + "include": [ + "../src/**/*.stories.ts", + "../src/**/*.stories.js", + "../src/**/*.stories.jsx", + "../src/**/*.stories.tsx", + "../src/**/*.stories.mdx", + "*.js" + ] +} diff --git a/graph/ui-components/README.md b/graph/ui-components/README.md new file mode 100644 index 0000000000000..edebff9c731b0 --- /dev/null +++ b/graph/ui-components/README.md @@ -0,0 +1,7 @@ +# graph-ui-components + +This library was generated with [Nx](https://nx.dev). + +## Running unit tests + +Run `nx test graph-ui-components` to execute the unit tests via [Jest](https://jestjs.io). diff --git a/graph/ui-components/jest.config.ts b/graph/ui-components/jest.config.ts new file mode 100644 index 0000000000000..48db49fd473de --- /dev/null +++ b/graph/ui-components/jest.config.ts @@ -0,0 +1,10 @@ +/* eslint-disable */ +export default { + displayName: 'graph-ui-components', + preset: '../../jest.preset.js', + transform: { + '^.+\\.[tj]sx?$': 'babel-jest', + }, + moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx'], + coverageDirectory: '../../coverage/graph/ui-graph', +}; diff --git a/graph/ui-components/postcss.config.js b/graph/ui-components/postcss.config.js new file mode 100644 index 0000000000000..d743b2e6af150 --- /dev/null +++ b/graph/ui-components/postcss.config.js @@ -0,0 +1,8 @@ +module.exports = { + plugins: { + tailwindcss: { + config: './graph/ui-components/tailwind.config.js', + }, + autoprefixer: {}, + }, +}; diff --git a/graph/ui-components/project.json b/graph/ui-components/project.json new file mode 100644 index 0000000000000..927a0ff952f90 --- /dev/null +++ b/graph/ui-components/project.json @@ -0,0 +1,55 @@ +{ + "name": "graph-ui-components", + "$schema": "../../node_modules/nx/schemas/project-schema.json", + "sourceRoot": "graph/ui-components/src", + "projectType": "library", + "tags": [], + "targets": { + "lint": { + "executor": "@nrwl/linter:eslint", + "outputs": ["{options.outputFile}"], + "options": { + "lintFilePatterns": ["graph/ui-components/**/*.{ts,tsx,js,jsx}"] + } + }, + "test": { + "executor": "@nrwl/jest:jest", + "outputs": ["{workspaceRoot}/coverage/{projectRoot}"], + "options": { + "jestConfig": "graph/ui-components/jest.config.ts", + "passWithNoTests": true + } + }, + "storybook": { + "executor": "@nrwl/storybook:storybook", + "options": { + "uiFramework": "@storybook/react", + "port": 4400, + "config": { + "configFolder": "graph/ui-components/.storybook" + } + }, + "configurations": { + "ci": { + "quiet": true + } + } + }, + "build-storybook": { + "executor": "@nrwl/storybook:build", + "outputs": ["{options.outputPath}"], + "options": { + "uiFramework": "@storybook/react", + "outputPath": "dist/storybook/graph-ui-components", + "config": { + "configFolder": "graph/ui-components/.storybook" + } + }, + "configurations": { + "ci": { + "quiet": true + } + } + } + } +} diff --git a/graph/ui-components/src/index.ts b/graph/ui-components/src/index.ts new file mode 100644 index 0000000000000..09e0853c0eeb9 --- /dev/null +++ b/graph/ui-components/src/index.ts @@ -0,0 +1,3 @@ +export * from './lib/debounced-text-input'; +export * from './lib/tag'; +export * from './lib/dropdown'; diff --git a/graph/client/src/app/ui-components/debounced-text-input.stories.tsx b/graph/ui-components/src/lib/debounced-text-input.stories.tsx similarity index 97% rename from graph/client/src/app/ui-components/debounced-text-input.stories.tsx rename to graph/ui-components/src/lib/debounced-text-input.stories.tsx index a5dbb47c452a9..d66680a451daf 100644 --- a/graph/client/src/app/ui-components/debounced-text-input.stories.tsx +++ b/graph/ui-components/src/lib/debounced-text-input.stories.tsx @@ -21,6 +21,6 @@ const Template: ComponentStory = (args) => ( export const Primary = Template.bind({}); Primary.args = { - currentText: '', + initialText: '', placeholderText: '', }; diff --git a/graph/client/src/app/ui-components/debounced-text-input.tsx b/graph/ui-components/src/lib/debounced-text-input.tsx similarity index 96% rename from graph/client/src/app/ui-components/debounced-text-input.tsx rename to graph/ui-components/src/lib/debounced-text-input.tsx index b17aecd9918c0..e3c062d64a844 100644 --- a/graph/client/src/app/ui-components/debounced-text-input.tsx +++ b/graph/ui-components/src/lib/debounced-text-input.tsx @@ -1,5 +1,5 @@ import { KeyboardEvent, useEffect, useState } from 'react'; -import { useDebounce } from '../hooks/use-debounce'; +import { useDebounce } from './use-debounce'; import { BackspaceIcon, FunnelIcon } from '@heroicons/react/24/outline'; export interface DebouncedTextInputProps { @@ -83,5 +83,3 @@ export function DebouncedTextInput({ ); } - -export default DebouncedTextInput; diff --git a/graph/client/src/app/ui-components/dropdown.stories.tsx b/graph/ui-components/src/lib/dropdown.stories.tsx similarity index 100% rename from graph/client/src/app/ui-components/dropdown.stories.tsx rename to graph/ui-components/src/lib/dropdown.stories.tsx diff --git a/graph/client/src/app/ui-components/dropdown.tsx b/graph/ui-components/src/lib/dropdown.tsx similarity index 96% rename from graph/client/src/app/ui-components/dropdown.tsx rename to graph/ui-components/src/lib/dropdown.tsx index ddeb910981af3..199125f664c7d 100644 --- a/graph/client/src/app/ui-components/dropdown.tsx +++ b/graph/ui-components/src/lib/dropdown.tsx @@ -16,5 +16,3 @@ export function Dropdown(props: DropdownProps) { ); } - -export default Dropdown; diff --git a/graph/client/src/app/ui-components/tag.stories.tsx b/graph/ui-components/src/lib/tag.stories.tsx similarity index 100% rename from graph/client/src/app/ui-components/tag.stories.tsx rename to graph/ui-components/src/lib/tag.stories.tsx diff --git a/graph/client/src/app/ui-components/tag.tsx b/graph/ui-components/src/lib/tag.tsx similarity index 96% rename from graph/client/src/app/ui-components/tag.tsx rename to graph/ui-components/src/lib/tag.tsx index 61c095db7f4f8..a780d7095c6c8 100644 --- a/graph/client/src/app/ui-components/tag.tsx +++ b/graph/ui-components/src/lib/tag.tsx @@ -17,5 +17,3 @@ export function Tag({ className, children, ...rest }: TagProps) { ); } - -export default Tag; diff --git a/graph/client/src/app/hooks/use-debounce.ts b/graph/ui-components/src/lib/use-debounce.ts similarity index 100% rename from graph/client/src/app/hooks/use-debounce.ts rename to graph/ui-components/src/lib/use-debounce.ts diff --git a/graph/ui-components/tailwind.config.js b/graph/ui-components/tailwind.config.js new file mode 100644 index 0000000000000..3b56335f1e460 --- /dev/null +++ b/graph/ui-components/tailwind.config.js @@ -0,0 +1,40 @@ +const path = require('path'); + +// nx-ignore-next-line +const { createGlobPatternsForDependencies } = require('@nrwl/react/tailwind'); + +module.exports = { + content: [ + path.join(__dirname, 'src/**/*.{js,ts,jsx,tsx,html}'), + ...createGlobPatternsForDependencies(__dirname), + ], + darkMode: 'class', // or 'media' or 'class' + theme: { + extend: { + typography: { + DEFAULT: { + css: { + 'code::before': { + content: '', + }, + 'code::after': { + content: '', + }, + 'blockquote p:first-of-type::before': { + content: '', + }, + 'blockquote p:last-of-type::after': { + content: '', + }, + }, + }, + }, + }, + }, + variants: { + extend: { + translate: ['group-hover'], + }, + }, + plugins: [require('@tailwindcss/typography')], +}; diff --git a/graph/ui-components/tsconfig.json b/graph/ui-components/tsconfig.json new file mode 100644 index 0000000000000..c9c11726914cb --- /dev/null +++ b/graph/ui-components/tsconfig.json @@ -0,0 +1,23 @@ +{ + "compilerOptions": { + "jsx": "react-jsx", + "allowJs": false, + "esModuleInterop": false, + "allowSyntheticDefaultImports": true, + "strict": true + }, + "files": [], + "include": [], + "references": [ + { + "path": "./tsconfig.lib.json" + }, + { + "path": "./tsconfig.spec.json" + }, + { + "path": "./.storybook/tsconfig.json" + } + ], + "extends": "../../tsconfig.base.json" +} diff --git a/graph/ui-components/tsconfig.lib.json b/graph/ui-components/tsconfig.lib.json new file mode 100644 index 0000000000000..e764d29345d36 --- /dev/null +++ b/graph/ui-components/tsconfig.lib.json @@ -0,0 +1,28 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "../../dist/out-tsc", + "types": ["node"], + "lib": ["dom"] + }, + "files": [ + "../../node_modules/@nrwl/react/typings/cssmodule.d.ts", + "../../node_modules/@nrwl/react/typings/image.d.ts" + ], + "exclude": [ + "jest.config.ts", + "src/**/*.spec.ts", + "src/**/*.test.ts", + "src/**/*.spec.tsx", + "src/**/*.test.tsx", + "src/**/*.spec.js", + "src/**/*.test.js", + "src/**/*.spec.jsx", + "src/**/*.test.jsx", + "**/*.stories.ts", + "**/*.stories.js", + "**/*.stories.jsx", + "**/*.stories.tsx" + ], + "include": ["src/**/*.js", "src/**/*.jsx", "src/**/*.ts", "src/**/*.tsx"] +} diff --git a/graph/ui-components/tsconfig.spec.json b/graph/ui-components/tsconfig.spec.json new file mode 100644 index 0000000000000..26ef046ac5e54 --- /dev/null +++ b/graph/ui-components/tsconfig.spec.json @@ -0,0 +1,20 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "../../dist/out-tsc", + "module": "commonjs", + "types": ["jest", "node"] + }, + "include": [ + "jest.config.ts", + "src/**/*.test.ts", + "src/**/*.spec.ts", + "src/**/*.test.tsx", + "src/**/*.spec.tsx", + "src/**/*.test.js", + "src/**/*.spec.js", + "src/**/*.test.jsx", + "src/**/*.spec.jsx", + "src/**/*.d.ts" + ] +} diff --git a/graph/ui-graph/.storybook/main.js b/graph/ui-graph/.storybook/main.js index b17a4cd6ebe5e..e7054830ab823 100644 --- a/graph/ui-graph/.storybook/main.js +++ b/graph/ui-graph/.storybook/main.js @@ -1,4 +1,4 @@ -const rootMain = require('../../../.storybook/main'); +const rootMain = require('../../.storybook/main'); module.exports = { ...rootMain, diff --git a/graph/ui-graph/.storybook/preview-head.html b/graph/ui-graph/.storybook/preview-head.html new file mode 100644 index 0000000000000..928d6bd7814e3 --- /dev/null +++ b/graph/ui-graph/.storybook/preview-head.html @@ -0,0 +1,26 @@ + diff --git a/graph/ui-graph/.storybook/preview.js b/graph/ui-graph/.storybook/preview.js index e69de29bb2d1d..979b36334c4f5 100644 --- a/graph/ui-graph/.storybook/preview.js +++ b/graph/ui-graph/.storybook/preview.js @@ -0,0 +1,5 @@ +import './tailwind-imports.css'; + +import { rootParameters } from '../../.storybook/preview'; + +export const parameters = { ...rootParameters }; diff --git a/graph/ui-graph/.storybook/tailwind-imports.css b/graph/ui-graph/.storybook/tailwind-imports.css new file mode 100644 index 0000000000000..b5c61c956711f --- /dev/null +++ b/graph/ui-graph/.storybook/tailwind-imports.css @@ -0,0 +1,3 @@ +@tailwind base; +@tailwind components; +@tailwind utilities; diff --git a/graph/ui-graph/postcss.config.js b/graph/ui-graph/postcss.config.js new file mode 100644 index 0000000000000..8b2e63b9e6bea --- /dev/null +++ b/graph/ui-graph/postcss.config.js @@ -0,0 +1,10 @@ +const path = require('path'); + +module.exports = { + plugins: { + tailwindcss: { + config: path.join(__dirname, 'tailwind.config.js'), + }, + autoprefixer: {}, + }, +}; diff --git a/graph/ui-graph/src/index.ts b/graph/ui-graph/src/index.ts index add069761afbe..8e29488822804 100644 --- a/graph/ui-graph/src/index.ts +++ b/graph/ui-graph/src/index.ts @@ -1,4 +1,5 @@ export * from './lib/nx-project-graph-viz'; export * from './lib/nx-task-graph-viz'; export * from './lib/graph'; +export * from './lib/tooltip-service'; export * from './lib/graph-interaction-events'; diff --git a/graph/ui-graph/src/lib/graph-interaction-events.ts b/graph/ui-graph/src/lib/graph-interaction-events.ts index 08f14ecdd51d7..967f36cee63bf 100644 --- a/graph/ui-graph/src/lib/graph-interaction-events.ts +++ b/graph/ui-graph/src/lib/graph-interaction-events.ts @@ -1,6 +1,7 @@ import { VirtualElement } from '@floating-ui/react-dom'; import { ProjectNodeDataDefinition } from './util-cytoscape/project-node'; import { TaskNodeDataDefinition } from './util-cytoscape/task-node'; +import { ProjectEdgeDataDefinition } from './util-cytoscape'; interface ProjectNodeClickEvent { type: 'ProjectNodeClick'; @@ -20,20 +21,20 @@ interface EdgeClickEvent { type: 'EdgeClick'; ref: VirtualElement; id: string; - data: { - type: string; - source: string; - target: string; - fileDependencies: { fileName: string; target: string }[]; - }; + data: ProjectEdgeDataDefinition; } interface GraphRegeneratedEvent { type: 'GraphRegenerated'; } +interface BackgroundClickEvent { + type: 'BackgroundClick'; +} + export type GraphInteractionEvents = | ProjectNodeClickEvent | EdgeClickEvent | GraphRegeneratedEvent - | TaskNodeClickEvent; + | TaskNodeClickEvent + | BackgroundClickEvent; diff --git a/graph/ui-graph/src/lib/graph.ts b/graph/ui-graph/src/lib/graph.ts index 4e6cf23fb2430..4d5bc6f8a8459 100644 --- a/graph/ui-graph/src/lib/graph.ts +++ b/graph/ui-graph/src/lib/graph.ts @@ -62,6 +62,7 @@ export class GraphService { } broadcast(event: GraphInteractionEvents) { + console.log(event); this.listeners.forEach((callback) => callback(event)); } diff --git a/graph/ui-graph/src/lib/interfaces.ts b/graph/ui-graph/src/lib/interfaces.ts index d4b6504439d23..b42bfd667273a 100644 --- a/graph/ui-graph/src/lib/interfaces.ts +++ b/graph/ui-graph/src/lib/interfaces.ts @@ -4,6 +4,12 @@ import type { ProjectGraphProjectNode, TaskGraph, } from '@nrwl/devkit'; +import { VirtualElement } from '@floating-ui/react-dom'; +import { + ProjectEdgeNodeTooltipProps, + ProjectNodeToolTipProps, + TaskNodeTooltipProps, +} from '@nrwl/graph/ui-tooltips'; export interface GraphPerfReport { renderTime: number; @@ -95,3 +101,16 @@ export type TaskGraphRenderEvents = type: 'setGroupByProject'; groupByProject: boolean; }; + +export type TooltipEvent = + | { + ref: VirtualElement; + type: 'projectNode'; + props: ProjectNodeToolTipProps; + } + | { ref: VirtualElement; type: 'taskNode'; props: TaskNodeTooltipProps } + | { + ref: VirtualElement; + type: 'projectEdge'; + props: ProjectEdgeNodeTooltipProps; + }; diff --git a/graph/ui-graph/src/lib/nx-graph-viz.stories.tsx b/graph/ui-graph/src/lib/nx-project-graph-viz.stories.tsx similarity index 81% rename from graph/ui-graph/src/lib/nx-graph-viz.stories.tsx rename to graph/ui-graph/src/lib/nx-project-graph-viz.stories.tsx index 23f23ced383f6..89fb71a5ec8df 100644 --- a/graph/ui-graph/src/lib/nx-graph-viz.stories.tsx +++ b/graph/ui-graph/src/lib/nx-project-graph-viz.stories.tsx @@ -3,7 +3,7 @@ import { NxProjectGraphViz } from './nx-project-graph-viz'; const Story: ComponentMeta = { component: NxProjectGraphViz, - title: 'NxGraphViz', + title: 'NxProjectGraphViz', }; export default Story; @@ -19,6 +19,13 @@ Primary.args = { name: 'app', data: { tags: ['scope:cart'], + description: 'This is your top-level app', + files: [ + { + file: 'whatever.ts', + deps: ['lib'], + }, + ], }, }, { @@ -26,6 +33,7 @@ Primary.args = { name: 'lib', data: { tags: ['scope:cart'], + description: 'This lib implements some type of feature for your app.', }, }, { @@ -59,4 +67,5 @@ Primary.args = { affectedProjectIds: [], theme: 'light', height: '450px', + enableTooltips: true, }; diff --git a/graph/ui-graph/src/lib/nx-project-graph-viz.tsx b/graph/ui-graph/src/lib/nx-project-graph-viz.tsx index e916e851454fd..72da6ebda631e 100644 --- a/graph/ui-graph/src/lib/nx-project-graph-viz.tsx +++ b/graph/ui-graph/src/lib/nx-project-graph-viz.tsx @@ -5,8 +5,18 @@ import type { } from 'nx/src/config/project-graph'; import { useEffect, useRef, useState } from 'react'; import { GraphService } from './graph'; +import { useSyncExternalStore } from 'use-sync-external-store/shim'; +import { + ProjectEdgeNodeTooltip, + ProjectNodeToolTip, + TaskNodeTooltip, + Tooltip, +} from '@nrwl/graph/ui-tooltips'; +import { GraphTooltipService } from './tooltip-service'; +import { TooltipEvent } from './interfaces'; type Theme = 'light' | 'dark' | 'system'; + export interface GraphUiGraphProps { projects: ProjectGraphProjectNode[]; groupByFolder: boolean; @@ -15,6 +25,7 @@ export interface GraphUiGraphProps { affectedProjectIds: string[]; theme: Theme; height: string; + enableTooltips: boolean; } function resolveTheme(theme: Theme): 'dark' | 'light' { @@ -25,6 +36,7 @@ function resolveTheme(theme: Theme): 'dark' | 'light' { return darkMedia.matches ? 'dark' : 'light'; } } + export function NxProjectGraphViz({ projects, groupByFolder, @@ -33,9 +45,12 @@ export function NxProjectGraphViz({ affectedProjectIds, theme, height, + enableTooltips, }: GraphUiGraphProps) { const containerRef = useRef(null); const [graph, setGraph] = useState(null); + const [currentTooltip, setCurrenTooltip] = useState(null); + const [resolvedTheme, setResolvedTheme] = useState<'light' | 'dark'>(); const newlyResolvedTheme = resolveTheme(theme); @@ -47,6 +62,7 @@ export function NxProjectGraphViz({ graph.theme = newlyResolvedTheme; } } + useEffect(() => { if (containerRef.current !== null) { import('./graph') @@ -68,18 +84,48 @@ export function NxProjectGraphViz({ collapseEdges: false, }); graph.handleProjectEvent({ type: 'notifyGraphShowAllProjects' }); - setGraph(graph); + + if (enableTooltips) { + const tooltipService = new GraphTooltipService(graph); + tooltipService.subscribe((tooltip) => { + setCurrenTooltip(tooltip); + }); + } }); } }, []); + let tooltipToRender; + if (currentTooltip) { + switch (currentTooltip.type) { + case 'projectNode': + tooltipToRender = ; + break; + case 'projectEdge': + tooltipToRender = ; + break; + case 'taskNode': + tooltipToRender = ; + break; + } + } + return ( -
+
+
+ {tooltipToRender ? ( + + ) : null} +
); } - -export default NxProjectGraphViz; diff --git a/graph/ui-graph/src/lib/nx-task-graph-viz.stories.tsx b/graph/ui-graph/src/lib/nx-task-graph-viz.stories.tsx index 1bd0747a70b2a..a57663364891f 100644 --- a/graph/ui-graph/src/lib/nx-task-graph-viz.stories.tsx +++ b/graph/ui-graph/src/lib/nx-task-graph-viz.stories.tsx @@ -24,6 +24,7 @@ Primary.args = { executor: '@nrwl/js:tsc', }, }, + description: 'The app uses this task to build itself.', }, }, { @@ -36,6 +37,7 @@ Primary.args = { executor: '@nrwl/js:tsc', }, }, + description: 'The lib uses this task to build itself.', }, }, { @@ -107,4 +109,5 @@ Primary.args = { }, taskId: 'app:build', height: '450px', + enableTooltips: true, }; diff --git a/graph/ui-graph/src/lib/nx-task-graph-viz.tsx b/graph/ui-graph/src/lib/nx-task-graph-viz.tsx index dee32a3cf5d3f..07d2c7e6075d9 100644 --- a/graph/ui-graph/src/lib/nx-task-graph-viz.tsx +++ b/graph/ui-graph/src/lib/nx-task-graph-viz.tsx @@ -2,7 +2,14 @@ import type { ProjectGraphProjectNode } from 'nx/src/config/project-graph'; import { useEffect, useRef, useState } from 'react'; import { GraphService } from './graph'; -import { TaskGraphRecord } from './interfaces'; +import { TaskGraphRecord, TooltipEvent } from './interfaces'; +import { + ProjectEdgeNodeTooltip, + ProjectNodeToolTip, + TaskNodeTooltip, + Tooltip, +} from '@nrwl/graph/ui-tooltips'; +import { GraphTooltipService } from './tooltip-service'; type Theme = 'light' | 'dark' | 'system'; @@ -12,6 +19,7 @@ export interface TaskGraphUiGraphProps { taskId: string; theme: Theme; height: string; + enableTooltips: boolean; } function resolveTheme(theme: Theme): 'dark' | 'light' { @@ -29,9 +37,12 @@ export function NxTaskGraphViz({ taskGraphs, theme, height, + enableTooltips, }: TaskGraphUiGraphProps) { const containerRef = useRef(null); const [graph, setGraph] = useState(null); + const [currentTooltip, setCurrenTooltip] = useState(null); + const [resolvedTheme, setResolvedTheme] = useState<'light' | 'dark'>(); const newlyResolvedTheme = resolveTheme(theme); @@ -64,17 +75,42 @@ export function NxTaskGraphViz({ taskIds: [taskId], }); setGraph(graph); + + if (enableTooltips) { + const tooltipService = new GraphTooltipService(graph); + tooltipService.subscribe((tooltip) => { + setCurrenTooltip(tooltip); + }); + } }); } }, []); + let tooltipToRender; + if (currentTooltip) { + switch (currentTooltip.type) { + case 'taskNode': + tooltipToRender = ; + break; + } + } + return ( -
+
+
+ {tooltipToRender ? ( + + ) : null} +
); } - -export default NxTaskGraphViz; diff --git a/graph/client/src/app/ui-tooltips/tooltip-service.ts b/graph/ui-graph/src/lib/tooltip-service.ts similarity index 67% rename from graph/client/src/app/ui-tooltips/tooltip-service.ts rename to graph/ui-graph/src/lib/tooltip-service.ts index 0815819f5a00d..4a75594d66e84 100644 --- a/graph/client/src/app/ui-tooltips/tooltip-service.ts +++ b/graph/ui-graph/src/lib/tooltip-service.ts @@ -1,10 +1,11 @@ -import { getGraphService } from '../machines/graph.service'; - import { VirtualElement } from '@floating-ui/react-dom'; -import { ProjectNodeToolTipProps } from './project-node-tooltip'; -import { ProjectEdgeNodeTooltipProps } from './project-edge-tooltip'; -import { GraphService } from '@nrwl/graph/ui-graph'; -import { TaskNodeTooltipProps } from './task-node-tooltip'; +import { GraphService } from './graph'; +import { + TaskNodeTooltipProps, + ProjectNodeToolTipProps, + ProjectEdgeNodeTooltipProps, +} from '@nrwl/graph/ui-tooltips'; +import { TooltipEvent } from './interfaces'; export class GraphTooltipService { private subscribers: Set = new Set(); @@ -15,11 +16,15 @@ export class GraphTooltipService { case 'GraphRegenerated': this.hideAll(); break; + case 'BackgroundClick': + this.hideAll(); + break; case 'ProjectNodeClick': this.openProjectNodeToolTip(event.ref, { id: event.data.id, tags: event.data.tags, type: event.data.type, + description: event.data.description, }); break; case 'TaskNodeClick': @@ -39,18 +44,7 @@ export class GraphTooltipService { }); } - currentTooltip: - | { - ref: VirtualElement; - type: 'projectNode'; - props: ProjectNodeToolTipProps; - } - | { ref: VirtualElement; type: 'taskNode'; props: TaskNodeTooltipProps } - | { - ref: VirtualElement; - type: 'projectEdge'; - props: ProjectEdgeNodeTooltipProps; - }; + currentTooltip: TooltipEvent; openProjectNodeToolTip(ref: VirtualElement, props: ProjectNodeToolTipProps) { this.currentTooltip = { type: 'projectNode', ref, props }; @@ -84,14 +78,3 @@ export class GraphTooltipService { this.broadcastChange(); } } - -let tooltipService: GraphTooltipService; - -export function getTooltipService(): GraphTooltipService { - if (!tooltipService) { - const graph = getGraphService(); - tooltipService = new GraphTooltipService(graph); - } - - return tooltipService; -} diff --git a/graph/ui-graph/src/lib/util-cytoscape/parent-node.ts b/graph/ui-graph/src/lib/util-cytoscape/parent-node.ts index 47dfb8305dad6..f40152c73a554 100644 --- a/graph/ui-graph/src/lib/util-cytoscape/parent-node.ts +++ b/graph/ui-graph/src/lib/util-cytoscape/parent-node.ts @@ -5,7 +5,7 @@ export class ParentNode { private config: { id: string; parentId: string; label: string } ) {} - getCytoscapeNodeDef(): cy.NodeDefinition { + getCytoscapeNodeDef(): cy.NodeDefinition & { pannable?: boolean } { return { group: 'nodes', classes: 'parentNode', diff --git a/graph/ui-graph/src/lib/util-cytoscape/project-edge.ts b/graph/ui-graph/src/lib/util-cytoscape/project-edge.ts index 8cf748340d74b..7ae7cc7df9bcc 100644 --- a/graph/ui-graph/src/lib/util-cytoscape/project-edge.ts +++ b/graph/ui-graph/src/lib/util-cytoscape/project-edge.ts @@ -2,7 +2,7 @@ import type { ProjectGraphDependency } from '@nrwl/devkit'; import * as cy from 'cytoscape'; -export interface EdgeDataDefinition extends cy.NodeDataDefinition { +export interface ProjectEdgeDataDefinition extends cy.NodeDataDefinition { id: string; source: string; target: string; @@ -14,7 +14,7 @@ export class ProjectEdge { constructor(private dep: ProjectGraphDependency) {} - getCytosacpeNodeDef(): cy.NodeDefinition { + getCytoscapeNodeDef(): cy.EdgeDefinition { let edge: cy.EdgeDefinition; edge = { group: 'edges', diff --git a/graph/ui-graph/src/lib/util-cytoscape/project-node.ts b/graph/ui-graph/src/lib/util-cytoscape/project-node.ts index 6083e4d87e73e..28bff76b89835 100644 --- a/graph/ui-graph/src/lib/util-cytoscape/project-node.ts +++ b/graph/ui-graph/src/lib/util-cytoscape/project-node.ts @@ -7,6 +7,8 @@ export interface ProjectNodeDataDefinition extends cy.NodeDataDefinition { id: string; type: 'app' | 'lib' | 'e2e'; tags: string[]; + + description?: string; } export interface Ancestor { @@ -22,9 +24,13 @@ export class ProjectNode { constructor( private project: ProjectGraphProjectNode, private workspaceRoot: string - ) {} + ) { + console.log(this.project); + } - getCytoscapeNodeDef(groupByFolder: boolean): cy.NodeDefinition { + getCytoscapeNodeDef( + groupByFolder: boolean + ): cy.NodeDefinition & { pannable: boolean } { return { group: 'nodes', data: this.getData(groupByFolder), @@ -46,6 +52,7 @@ export class ProjectNode { : null, files: this.project.data.files, root: this.project.data.root, + description: this.project.data.description, }; } diff --git a/graph/ui-graph/src/lib/util-cytoscape/project-traversal-graph.ts b/graph/ui-graph/src/lib/util-cytoscape/project-traversal-graph.ts index 2870ffe961253..55585ac7785c1 100644 --- a/graph/ui-graph/src/lib/util-cytoscape/project-traversal-graph.ts +++ b/graph/ui-graph/src/lib/util-cytoscape/project-traversal-graph.ts @@ -317,12 +317,13 @@ export class ProjectTraversalGraph { } }); - const projectElements = projectNodes.map((projectNode) => - projectNode.getCytoscapeNodeDef(groupByFolder) - ); + const projectElements: (ElementDefinition & { pannable?: boolean })[] = + projectNodes.map((projectNode) => + projectNode.getCytoscapeNodeDef(groupByFolder) + ); const edgeElements = edgeNodes.map((edgeNode) => - edgeNode.getCytosacpeNodeDef() + edgeNode.getCytoscapeNodeDef() ); elements = projectElements.concat(edgeElements); diff --git a/graph/ui-graph/src/lib/util-cytoscape/render-graph.ts b/graph/ui-graph/src/lib/util-cytoscape/render-graph.ts index efee07e11c323..1cc3fe1454b1e 100644 --- a/graph/ui-graph/src/lib/util-cytoscape/render-graph.ts +++ b/graph/ui-graph/src/lib/util-cytoscape/render-graph.ts @@ -104,6 +104,7 @@ export class RenderGraph { this.listenForEdgeNodeClicks(); this.listenForProjectNodeHovers(); this.listenForTaskNodeClicks(); + this.listenForEmptyClicks(); } render(): { numEdges: number; numNodes: number } { @@ -232,6 +233,7 @@ export class RenderGraph { id: node.id(), type: node.data('type'), tags: node.data('tags'), + description: node.data('description'), }, }); }); @@ -252,6 +254,7 @@ export class RenderGraph { id: node.id(), label: node.data('label'), executor: node.data('executor'), + description: node.data('description'), }, }); }); @@ -259,7 +262,8 @@ export class RenderGraph { private listenForEdgeNodeClicks() { this.cy.$('edge.projectEdge').on('click', (event) => { - const edge: EdgeSingular = event.target; + const edge: EdgeSingular & { popperRef: () => VirtualElement } = + event.target; let ref: VirtualElement = edge.popperRef(); // used only for positioning this.broadcast({ @@ -268,24 +272,26 @@ export class RenderGraph { id: edge.id(), data: { + id: edge.id(), type: edge.data('type'), source: edge.source().id(), target: edge.target().id(), - fileDependencies: edge - .source() - .data('files') - .filter( - (file) => file.deps && file.deps.includes(edge.target().id()) - ) - .map((file) => { - return { - fileName: file.file.replace( - `${edge.source().data('root')}/`, - '' - ), - target: edge.target().id(), - }; - }), + fileDependencies: + edge + .source() + .data('files') + ?.filter( + (file) => file.deps && file.deps.includes(edge.target().id()) + ) + .map((file) => { + return { + fileName: file.file.replace( + `${edge.source().data('root')}/`, + '' + ), + target: edge.target().id(), + }; + }) || [], }, }); }); @@ -321,6 +327,14 @@ export class RenderGraph { }); } + private listenForEmptyClicks(): void { + this.cy.on('click', (event) => { + if (event.target === this.cy) { + this.broadcast({ type: 'BackgroundClick' }); + } + }); + } + getImage() { const bg = switchValueByDarkMode(this.cy, '#0F172A', '#FFFFFF'); return this.cy.png({ bg, full: true }); diff --git a/graph/ui-graph/src/lib/util-cytoscape/task-node.ts b/graph/ui-graph/src/lib/util-cytoscape/task-node.ts index 92a17dcda3a8f..509d64add1c87 100644 --- a/graph/ui-graph/src/lib/util-cytoscape/task-node.ts +++ b/graph/ui-graph/src/lib/util-cytoscape/task-node.ts @@ -6,12 +6,15 @@ export interface TaskNodeDataDefinition extends cy.NodeDataDefinition { id: string; label: string; executor: string; + description?: string; } export class TaskNode { constructor(private task: Task, private project: ProjectGraphProjectNode) {} - getCytoscapeNodeDef(groupByProject: boolean): cy.NodeDefinition { + getCytoscapeNodeDef( + groupByProject: boolean + ): cy.NodeDefinition & { pannable: boolean } { return { group: 'nodes', classes: 'taskNode', @@ -31,6 +34,7 @@ export class TaskNode { label, executor: this.project.data.targets[this.task.target.target].executor, parent: groupByProject ? this.task.target.project : null, + description: this.project.data.description, }; } } diff --git a/graph/ui-graph/tailwind.config.js b/graph/ui-graph/tailwind.config.js new file mode 100644 index 0000000000000..3b56335f1e460 --- /dev/null +++ b/graph/ui-graph/tailwind.config.js @@ -0,0 +1,40 @@ +const path = require('path'); + +// nx-ignore-next-line +const { createGlobPatternsForDependencies } = require('@nrwl/react/tailwind'); + +module.exports = { + content: [ + path.join(__dirname, 'src/**/*.{js,ts,jsx,tsx,html}'), + ...createGlobPatternsForDependencies(__dirname), + ], + darkMode: 'class', // or 'media' or 'class' + theme: { + extend: { + typography: { + DEFAULT: { + css: { + 'code::before': { + content: '', + }, + 'code::after': { + content: '', + }, + 'blockquote p:first-of-type::before': { + content: '', + }, + 'blockquote p:last-of-type::after': { + content: '', + }, + }, + }, + }, + }, + }, + variants: { + extend: { + translate: ['group-hover'], + }, + }, + plugins: [require('@tailwindcss/typography')], +}; diff --git a/graph/ui-tooltips/.babelrc b/graph/ui-tooltips/.babelrc new file mode 100644 index 0000000000000..ccae900be4278 --- /dev/null +++ b/graph/ui-tooltips/.babelrc @@ -0,0 +1,12 @@ +{ + "presets": [ + [ + "@nrwl/react/babel", + { + "runtime": "automatic", + "useBuiltIns": "usage" + } + ] + ], + "plugins": [] +} diff --git a/graph/ui-tooltips/.eslintrc.json b/graph/ui-tooltips/.eslintrc.json new file mode 100644 index 0000000000000..734ddaceea447 --- /dev/null +++ b/graph/ui-tooltips/.eslintrc.json @@ -0,0 +1,18 @@ +{ + "extends": ["plugin:@nrwl/nx/react", "../../.eslintrc.json"], + "ignorePatterns": ["!**/*"], + "overrides": [ + { + "files": ["*.ts", "*.tsx", "*.js", "*.jsx"], + "rules": {} + }, + { + "files": ["*.ts", "*.tsx"], + "rules": {} + }, + { + "files": ["*.js", "*.jsx"], + "rules": {} + } + ] +} diff --git a/graph/ui-tooltips/.storybook/main.js b/graph/ui-tooltips/.storybook/main.js new file mode 100644 index 0000000000000..6468f25555413 --- /dev/null +++ b/graph/ui-tooltips/.storybook/main.js @@ -0,0 +1,22 @@ +const rootMain = require('../../.storybook/main'); + +module.exports = { + ...rootMain, + core: { ...rootMain.core, builder: 'webpack5' }, + stories: [ + ...rootMain.stories, + '../src/lib/**/*.stories.mdx', + '../src/lib/**/*.stories.@(js|jsx|ts|tsx)', + ], + addons: [...rootMain.addons, '@nrwl/react/plugins/storybook'], + webpackFinal: async (config, { configType }) => { + // apply any global webpack configs that might have been specified in .storybook/main.js + if (rootMain.webpackFinal) { + config = await rootMain.webpackFinal(config, { configType }); + } + + // add your own webpack tweaks if needed + + return config; + }, +}; diff --git a/graph/ui-tooltips/.storybook/preview.js b/graph/ui-tooltips/.storybook/preview.js new file mode 100644 index 0000000000000..8c8889d1a414d --- /dev/null +++ b/graph/ui-tooltips/.storybook/preview.js @@ -0,0 +1 @@ +import './tailwind-imports.css'; diff --git a/graph/ui-tooltips/.storybook/tailwind-imports.css b/graph/ui-tooltips/.storybook/tailwind-imports.css new file mode 100644 index 0000000000000..b5c61c956711f --- /dev/null +++ b/graph/ui-tooltips/.storybook/tailwind-imports.css @@ -0,0 +1,3 @@ +@tailwind base; +@tailwind components; +@tailwind utilities; diff --git a/graph/ui-tooltips/.storybook/tsconfig.json b/graph/ui-tooltips/.storybook/tsconfig.json new file mode 100644 index 0000000000000..286dc2f6355dd --- /dev/null +++ b/graph/ui-tooltips/.storybook/tsconfig.json @@ -0,0 +1,26 @@ +{ + "extends": "../tsconfig.json", + "compilerOptions": { + "emitDecoratorMetadata": true, + "outDir": "" + }, + "files": [ + "../../../node_modules/@nrwl/react/typings/styled-jsx.d.ts", + "../../../node_modules/@nrwl/react/typings/cssmodule.d.ts", + "../../../node_modules/@nrwl/react/typings/image.d.ts" + ], + "exclude": [ + "../**/*.spec.ts", + "../**/*.spec.js", + "../**/*.spec.tsx", + "../**/*.spec.jsx" + ], + "include": [ + "../src/**/*.stories.ts", + "../src/**/*.stories.js", + "../src/**/*.stories.jsx", + "../src/**/*.stories.tsx", + "../src/**/*.stories.mdx", + "*.js" + ] +} diff --git a/graph/ui-tooltips/README.md b/graph/ui-tooltips/README.md new file mode 100644 index 0000000000000..0facb27ac5f5f --- /dev/null +++ b/graph/ui-tooltips/README.md @@ -0,0 +1,7 @@ +# graph-ui-tooltips + +This library was generated with [Nx](https://nx.dev). + +## Running unit tests + +Run `nx test graph-ui-tooltips` to execute the unit tests via [Jest](https://jestjs.io). diff --git a/graph/ui-tooltips/jest.config.ts b/graph/ui-tooltips/jest.config.ts new file mode 100644 index 0000000000000..06a3b2b281272 --- /dev/null +++ b/graph/ui-tooltips/jest.config.ts @@ -0,0 +1,10 @@ +/* eslint-disable */ +export default { + displayName: 'graph-ui-tooltips', + preset: '../../jest.preset.js', + transform: { + '^.+\\.[tj]sx?$': 'babel-jest', + }, + moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx'], + coverageDirectory: '../../coverage/graph/ui-graph', +}; diff --git a/graph/ui-tooltips/postcss.config.js b/graph/ui-tooltips/postcss.config.js new file mode 100644 index 0000000000000..8b2e63b9e6bea --- /dev/null +++ b/graph/ui-tooltips/postcss.config.js @@ -0,0 +1,10 @@ +const path = require('path'); + +module.exports = { + plugins: { + tailwindcss: { + config: path.join(__dirname, 'tailwind.config.js'), + }, + autoprefixer: {}, + }, +}; diff --git a/graph/ui-tooltips/project.json b/graph/ui-tooltips/project.json new file mode 100644 index 0000000000000..3a490481b6d1a --- /dev/null +++ b/graph/ui-tooltips/project.json @@ -0,0 +1,55 @@ +{ + "name": "graph-ui-tooltips", + "$schema": "../../node_modules/nx/schemas/project-schema.json", + "sourceRoot": "graph/ui-tooltips/src", + "projectType": "library", + "tags": [], + "targets": { + "lint": { + "executor": "@nrwl/linter:eslint", + "outputs": ["{options.outputFile}"], + "options": { + "lintFilePatterns": ["graph/ui-tooltips/**/*.{ts,tsx,js,jsx}"] + } + }, + "test": { + "executor": "@nrwl/jest:jest", + "outputs": ["{workspaceRoot}/coverage/{projectRoot}"], + "options": { + "jestConfig": "graph/ui-tooltips/jest.config.ts", + "passWithNoTests": true + } + }, + "storybook": { + "executor": "@nrwl/storybook:storybook", + "options": { + "uiFramework": "@storybook/react", + "port": 4400, + "config": { + "configFolder": "graph/ui-tooltips/.storybook" + } + }, + "configurations": { + "ci": { + "quiet": true + } + } + }, + "build-storybook": { + "executor": "@nrwl/storybook:build", + "outputs": ["{options.outputPath}"], + "options": { + "uiFramework": "@storybook/react", + "outputPath": "dist/storybook/graph-ui-tooltips", + "config": { + "configFolder": "graph/ui-tooltips/.storybook" + } + }, + "configurations": { + "ci": { + "quiet": true + } + } + } + } +} diff --git a/graph/ui-tooltips/src/index.ts b/graph/ui-tooltips/src/index.ts new file mode 100644 index 0000000000000..2914249d93be0 --- /dev/null +++ b/graph/ui-tooltips/src/index.ts @@ -0,0 +1,5 @@ +export * from './lib/tooltip'; +export * from './lib/project-edge-tooltip'; +export * from './lib/project-node-tooltip'; +export * from './lib/task-node-tooltip'; +export * from './lib/tooltip-button'; diff --git a/graph/client/src/app/ui-tooltips/project-edge-tooltip.stories.tsx b/graph/ui-tooltips/src/lib/project-edge-tooltip.stories.tsx similarity index 100% rename from graph/client/src/app/ui-tooltips/project-edge-tooltip.stories.tsx rename to graph/ui-tooltips/src/lib/project-edge-tooltip.stories.tsx diff --git a/graph/client/src/app/ui-tooltips/project-edge-tooltip.tsx b/graph/ui-tooltips/src/lib/project-edge-tooltip.tsx similarity index 87% rename from graph/client/src/app/ui-tooltips/project-edge-tooltip.tsx rename to graph/ui-tooltips/src/lib/project-edge-tooltip.tsx index b0f1f8c40e798..26b40f6977a66 100644 --- a/graph/client/src/app/ui-tooltips/project-edge-tooltip.tsx +++ b/graph/ui-tooltips/src/lib/project-edge-tooltip.tsx @@ -1,10 +1,11 @@ -import Tag from '../ui-components/tag'; +import { Tag } from '@nrwl/graph/ui-components'; export interface ProjectEdgeNodeTooltipProps { type: string; source: string; target: string; fileDependencies: Array<{ fileName: string }>; + description?: string; } export function ProjectEdgeNodeTooltip({ @@ -12,6 +13,7 @@ export function ProjectEdgeNodeTooltip({ source, target, fileDependencies, + description, }: ProjectEdgeNodeTooltipProps) { return (
@@ -21,7 +23,8 @@ export function ProjectEdgeNodeTooltip({ {source} → {target} - {type !== 'implicit' ? ( + {description ?

{description}

: null} + {type !== 'implicit' && fileDependencies?.length > 0 ? (
Files @@ -43,5 +46,3 @@ export function ProjectEdgeNodeTooltip({
); } - -export default ProjectEdgeNodeTooltip; diff --git a/graph/client/src/app/ui-tooltips/project-node-tooltip.stories.tsx b/graph/ui-tooltips/src/lib/project-node-tooltip.stories.tsx similarity index 100% rename from graph/client/src/app/ui-tooltips/project-node-tooltip.stories.tsx rename to graph/ui-tooltips/src/lib/project-node-tooltip.stories.tsx diff --git a/graph/ui-tooltips/src/lib/project-node-tooltip.tsx b/graph/ui-tooltips/src/lib/project-node-tooltip.tsx new file mode 100644 index 0000000000000..2570dd63326cb --- /dev/null +++ b/graph/ui-tooltips/src/lib/project-node-tooltip.tsx @@ -0,0 +1,37 @@ +import { Tag } from '@nrwl/graph/ui-components'; +import { ReactNode } from 'react'; + +export interface ProjectNodeToolTipProps { + type: 'app' | 'lib' | 'e2e'; + id: string; + tags: string[]; + description?: string; + + children?: ReactNode | ReactNode[]; +} + +export function ProjectNodeToolTip({ + type, + id, + tags, + children, + description, +}: ProjectNodeToolTipProps) { + return ( +
+

+ {type} + {id} +

+ {tags.length > 0 ? ( +

+ tags +

+ {tags.join(', ')} +

+ ) : null} + {description ?

{description}

: null} + {children} +
+ ); +} diff --git a/graph/client/src/app/ui-tooltips/task-node-tooltip.stories.tsx b/graph/ui-tooltips/src/lib/task-node-tooltip.stories.tsx similarity index 100% rename from graph/client/src/app/ui-tooltips/task-node-tooltip.stories.tsx rename to graph/ui-tooltips/src/lib/task-node-tooltip.stories.tsx diff --git a/graph/ui-tooltips/src/lib/task-node-tooltip.tsx b/graph/ui-tooltips/src/lib/task-node-tooltip.tsx new file mode 100644 index 0000000000000..0e5bf829064d2 --- /dev/null +++ b/graph/ui-tooltips/src/lib/task-node-tooltip.tsx @@ -0,0 +1,23 @@ +import { Tag } from '@nrwl/graph/ui-components'; + +export interface TaskNodeTooltipProps { + id: string; + executor: string; + description?: string; +} + +export function TaskNodeTooltip({ + id, + executor, + description, +}: TaskNodeTooltipProps) { + return ( +
+

+ {executor} + {id} +

+ {description ?

{description}

: null} +
+ ); +} diff --git a/graph/client/src/app/ui-tooltips/tooltip-button.tsx b/graph/ui-tooltips/src/lib/tooltip-button.tsx similarity index 100% rename from graph/client/src/app/ui-tooltips/tooltip-button.tsx rename to graph/ui-tooltips/src/lib/tooltip-button.tsx diff --git a/graph/client/src/app/ui-tooltips/tooltip.tsx b/graph/ui-tooltips/src/lib/tooltip.tsx similarity index 93% rename from graph/client/src/app/ui-tooltips/tooltip.tsx rename to graph/ui-tooltips/src/lib/tooltip.tsx index 312a465f71a86..e141d13bb693d 100644 --- a/graph/client/src/app/ui-tooltips/tooltip.tsx +++ b/graph/ui-tooltips/src/lib/tooltip.tsx @@ -55,12 +55,13 @@ export function Tooltip({ ], }); - const staticSide = { - top: 'bottom', - right: 'left', - bottom: 'top', - left: 'right', - }[finalPlacement.split('-')[0]]; + const staticSide: string = + { + top: 'bottom', + right: 'left', + bottom: 'top', + left: 'right', + }[finalPlacement.split('-')[0]] || 'bottom'; useLayoutEffect(() => { if (!!externalReference) { diff --git a/graph/ui-tooltips/tailwind.config.js b/graph/ui-tooltips/tailwind.config.js new file mode 100644 index 0000000000000..3b56335f1e460 --- /dev/null +++ b/graph/ui-tooltips/tailwind.config.js @@ -0,0 +1,40 @@ +const path = require('path'); + +// nx-ignore-next-line +const { createGlobPatternsForDependencies } = require('@nrwl/react/tailwind'); + +module.exports = { + content: [ + path.join(__dirname, 'src/**/*.{js,ts,jsx,tsx,html}'), + ...createGlobPatternsForDependencies(__dirname), + ], + darkMode: 'class', // or 'media' or 'class' + theme: { + extend: { + typography: { + DEFAULT: { + css: { + 'code::before': { + content: '', + }, + 'code::after': { + content: '', + }, + 'blockquote p:first-of-type::before': { + content: '', + }, + 'blockquote p:last-of-type::after': { + content: '', + }, + }, + }, + }, + }, + }, + variants: { + extend: { + translate: ['group-hover'], + }, + }, + plugins: [require('@tailwindcss/typography')], +}; diff --git a/graph/ui-tooltips/tsconfig.json b/graph/ui-tooltips/tsconfig.json new file mode 100644 index 0000000000000..c9c11726914cb --- /dev/null +++ b/graph/ui-tooltips/tsconfig.json @@ -0,0 +1,23 @@ +{ + "compilerOptions": { + "jsx": "react-jsx", + "allowJs": false, + "esModuleInterop": false, + "allowSyntheticDefaultImports": true, + "strict": true + }, + "files": [], + "include": [], + "references": [ + { + "path": "./tsconfig.lib.json" + }, + { + "path": "./tsconfig.spec.json" + }, + { + "path": "./.storybook/tsconfig.json" + } + ], + "extends": "../../tsconfig.base.json" +} diff --git a/graph/ui-tooltips/tsconfig.lib.json b/graph/ui-tooltips/tsconfig.lib.json new file mode 100644 index 0000000000000..f73f9413ef49a --- /dev/null +++ b/graph/ui-tooltips/tsconfig.lib.json @@ -0,0 +1,27 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "../../dist/out-tsc", + "types": ["node"] + }, + "files": [ + "../../node_modules/@nrwl/react/typings/cssmodule.d.ts", + "../../node_modules/@nrwl/react/typings/image.d.ts" + ], + "exclude": [ + "jest.config.ts", + "src/**/*.spec.ts", + "src/**/*.test.ts", + "src/**/*.spec.tsx", + "src/**/*.test.tsx", + "src/**/*.spec.js", + "src/**/*.test.js", + "src/**/*.spec.jsx", + "src/**/*.test.jsx", + "**/*.stories.ts", + "**/*.stories.js", + "**/*.stories.jsx", + "**/*.stories.tsx" + ], + "include": ["src/**/*.js", "src/**/*.jsx", "src/**/*.ts", "src/**/*.tsx"] +} diff --git a/graph/ui-tooltips/tsconfig.spec.json b/graph/ui-tooltips/tsconfig.spec.json new file mode 100644 index 0000000000000..26ef046ac5e54 --- /dev/null +++ b/graph/ui-tooltips/tsconfig.spec.json @@ -0,0 +1,20 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "../../dist/out-tsc", + "module": "commonjs", + "types": ["jest", "node"] + }, + "include": [ + "jest.config.ts", + "src/**/*.test.ts", + "src/**/*.spec.ts", + "src/**/*.test.tsx", + "src/**/*.spec.tsx", + "src/**/*.test.js", + "src/**/*.spec.js", + "src/**/*.test.jsx", + "src/**/*.spec.jsx", + "src/**/*.d.ts" + ] +} diff --git a/nx-dev/ui-markdoc/src/lib/tags/graph.component.tsx b/nx-dev/ui-markdoc/src/lib/tags/graph.component.tsx index 0682e9404080a..4f6ab852d7ca8 100644 --- a/nx-dev/ui-markdoc/src/lib/tags/graph.component.tsx +++ b/nx-dev/ui-markdoc/src/lib/tags/graph.component.tsx @@ -100,6 +100,7 @@ export function Graph({ workspaceLayout={parsedProps.workspaceLayout} dependencies={parsedProps.dependencies} affectedProjectIds={parsedProps.affectedProjectIds} + enableTooltips={parsedProps.enableTooltips} /> ) : ( )}
diff --git a/package.json b/package.json index 05e711dcd41cb..678b9d372874f 100644 --- a/package.json +++ b/package.json @@ -40,6 +40,7 @@ "@angular/router": "~15.0.1", "@babel/core": "^7.15.0", "@babel/helper-create-regexp-features-plugin": "^7.14.5", + "@babel/preset-react": "^7.14.5", "@babel/preset-typescript": "^7.15.0", "@cypress/react": "^6.0.0", "@cypress/webpack-preprocessor": "^5.12.0", @@ -145,7 +146,7 @@ "eslint-config-prettier": "^8.1.0", "eslint-plugin-cypress": "^2.10.3", "eslint-plugin-import": "2.26.0", - "eslint-plugin-jsx-a11y": "6.5.1", + "eslint-plugin-jsx-a11y": "6.6.1", "eslint-plugin-react": "7.31.11", "eslint-plugin-react-hooks": "4.6.0", "express": "^4.18.1", diff --git a/packages/nx/src/config/project-graph.ts b/packages/nx/src/config/project-graph.ts index c25bf950b4410..4f280d1d57204 100644 --- a/packages/nx/src/config/project-graph.ts +++ b/packages/nx/src/config/project-graph.ts @@ -102,6 +102,8 @@ export interface ProjectGraphProjectNode { * Files associated to the project */ files: FileData[]; + + description?: string; }; } diff --git a/tsconfig.base.json b/tsconfig.base.json index 4ae17f679eecc..f42cd6d4b877d 100644 --- a/tsconfig.base.json +++ b/tsconfig.base.json @@ -30,7 +30,9 @@ "@nrwl/eslint-plugin-nx": ["packages/eslint-plugin-nx/src"], "@nrwl/expo": ["packages/expo"], "@nrwl/express": ["packages/express"], + "@nrwl/graph/ui-components": ["graph/ui-components/src/index.ts"], "@nrwl/graph/ui-graph": ["graph/ui-graph/src/index.ts"], + "@nrwl/graph/ui-tooltips": ["graph/ui-tooltips/src/index.ts"], "@nrwl/jest": ["packages/jest"], "@nrwl/jest/*": ["packages/jest/*"], "@nrwl/js": ["packages/js/src"], diff --git a/yarn.lock b/yarn.lock index e51fd0f31565b..c790ae3a86331 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1836,7 +1836,7 @@ "@babel/types" "^7.4.4" esutils "^2.0.2" -"@babel/preset-react@^7.12.10", "@babel/preset-react@^7.17.12": +"@babel/preset-react@^7.12.10", "@babel/preset-react@^7.14.5", "@babel/preset-react@^7.17.12": version "7.18.6" resolved "https://registry.yarnpkg.com/@babel/preset-react/-/preset-react-7.18.6.tgz#979f76d6277048dc19094c217b507f3ad517dd2d" integrity sha512-zXr6atUmyYdiWRVLOZahakYmOBHtWc2WGCkP8PYTgZi0iJXDY2CN180TdrIW4OGOAdLc7TifzDIvtx6izaRIzg== @@ -1883,7 +1883,7 @@ dependencies: regenerator-runtime "^0.13.10" -"@babel/runtime@^7.10.2", "@babel/runtime@^7.12.1", "@babel/runtime@^7.12.5", "@babel/runtime@^7.14.8", "@babel/runtime@^7.16.3", "@babel/runtime@^7.18.9", "@babel/runtime@^7.3.1", "@babel/runtime@^7.7.2", "@babel/runtime@^7.7.6", "@babel/runtime@^7.8.4", "@babel/runtime@^7.9.2": +"@babel/runtime@^7.10.2", "@babel/runtime@^7.12.1", "@babel/runtime@^7.12.5", "@babel/runtime@^7.14.8", "@babel/runtime@^7.18.9", "@babel/runtime@^7.3.1", "@babel/runtime@^7.7.2", "@babel/runtime@^7.7.6", "@babel/runtime@^7.8.4", "@babel/runtime@^7.9.2": version "7.20.0" resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.20.0.tgz#824a9ef325ffde6f78056059db3168c08785e24a" integrity sha512-NDYdls71fTXoU8TZHfbBWg7DiZfNzClcKui/+kyi6ppD2L1qnWW3VV6CjtaBXSUGGhiTWJ6ereOIkUvenif66Q== @@ -8176,7 +8176,7 @@ aws4@^1.8.0: resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.11.0.tgz#d61f46d83b2519250e2784daf5b09479a8b41c59" integrity sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA== -axe-core@^4.3.5, axe-core@^4.4.3: +axe-core@^4.4.3: version "4.5.0" resolved "https://registry.yarnpkg.com/axe-core/-/axe-core-4.5.0.tgz#6efe2ecdba205fcc9d7ddb3d48c2cf630f70eb5e" integrity sha512-4+rr8eQ7+XXS5nZrKcMO/AikHL0hVqy+lHWAnE3xdHl+aguag8SOQ6eEqLexwLNWgXIMfunGuD3ON1/6Kyet0A== @@ -10703,7 +10703,7 @@ dagre@^0.8.5: graphlib "^2.1.8" lodash "^4.17.15" -damerau-levenshtein@^1.0.7, damerau-levenshtein@^1.0.8: +damerau-levenshtein@^1.0.8: version "1.0.8" resolved "https://registry.yarnpkg.com/damerau-levenshtein/-/damerau-levenshtein-1.0.8.tgz#b43d286ccbd36bc5b2f7ed41caf2d0aba1f8a6e7" integrity sha512-sdQSFB7+llfUcQHUQO3+B8ERRj0Oa4w9POWMI/puGtuf7gFywGmkaLCElnudfTiKZV+NvHqL0ifzdrI8Ro7ESA== @@ -11914,25 +11914,7 @@ eslint-plugin-import@2.26.0, eslint-plugin-import@^2.26.0: resolve "^1.22.0" tsconfig-paths "^3.14.1" -eslint-plugin-jsx-a11y@6.5.1: - version "6.5.1" - resolved "https://registry.yarnpkg.com/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-6.5.1.tgz#cdbf2df901040ca140b6ec14715c988889c2a6d8" - integrity sha512-sVCFKX9fllURnXT2JwLN5Qgo24Ug5NF6dxhkmxsMEUZhXRcGg+X3e1JbJ84YePQKBl5E0ZjAH5Q4rkdcGY99+g== - dependencies: - "@babel/runtime" "^7.16.3" - aria-query "^4.2.2" - array-includes "^3.1.4" - ast-types-flow "^0.0.7" - axe-core "^4.3.5" - axobject-query "^2.2.0" - damerau-levenshtein "^1.0.7" - emoji-regex "^9.2.2" - has "^1.0.3" - jsx-ast-utils "^3.2.1" - language-tags "^1.0.5" - minimatch "^3.0.4" - -eslint-plugin-jsx-a11y@^6.5.1: +eslint-plugin-jsx-a11y@6.6.1, eslint-plugin-jsx-a11y@^6.5.1: version "6.6.1" resolved "https://registry.yarnpkg.com/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-6.6.1.tgz#93736fc91b83fdc38cc8d115deedfc3091aef1ff" integrity sha512-sXgFVNHiWffBq23uiS/JaP6eVR622DqwB4yTzKvGZGcPq6/yZ3WmOZfuBks/vHWo9GaFOqC2ZK4i6+C35knx7Q== @@ -15925,7 +15907,7 @@ jsprim@^2.0.2: json-schema "0.4.0" verror "1.10.0" -"jsx-ast-utils@^2.4.1 || ^3.0.0", jsx-ast-utils@^3.2.1, jsx-ast-utils@^3.3.2: +"jsx-ast-utils@^2.4.1 || ^3.0.0", jsx-ast-utils@^3.3.2: version "3.3.3" resolved "https://registry.yarnpkg.com/jsx-ast-utils/-/jsx-ast-utils-3.3.3.tgz#76b3e6e6cece5c69d49a5792c3d01bd1a0cdc7ea" integrity sha512-fYQHZTZ8jSfmWZ0iyzfwiU4WDX4HpHbMCZ3gPlWYiCl3BoeOTsqKBqnTVfH2rYT7eP5c3sVbeSPHnnJOaTrWiw==