From c38a8f61d628c9c9f726e8da27375f8f728575e7 Mon Sep 17 00:00:00 2001 From: Emily Xiong Date: Tue, 5 Mar 2024 00:52:07 -0500 Subject: [PATCH] feat(graph): add spinner on the projects page --- graph/client/src/app/shell.tsx | 32 +++++++++++++------ graph/ui-components/src/index.ts | 1 + .../ui-components/src/lib/spinner.stories.tsx | 16 ++++++++++ graph/ui-components/src/lib/spinner.tsx | 31 ++++++++++++++++++ 4 files changed, 70 insertions(+), 10 deletions(-) create mode 100644 graph/ui-components/src/lib/spinner.stories.tsx create mode 100644 graph/ui-components/src/lib/spinner.tsx diff --git a/graph/client/src/app/shell.tsx b/graph/client/src/app/shell.tsx index ecfa074d0260b..a670617bf57a8 100644 --- a/graph/client/src/app/shell.tsx +++ b/graph/client/src/app/shell.tsx @@ -6,9 +6,14 @@ import { import classNames from 'classnames'; import { DebuggerPanel } from './ui-components/debugger-panel'; import { getGraphService } from './machines/graph.service'; -import { Outlet, useNavigate, useParams } from 'react-router-dom'; +import { + Outlet, + useNavigate, + useNavigation, + useParams, +} from 'react-router-dom'; import { getSystemTheme, Theme, ThemePanel } from '@nx/graph/ui-theme'; -import { Dropdown } from '@nx/graph/ui-components'; +import { Dropdown, Spinner } from '@nx/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'; @@ -36,8 +41,9 @@ export function Shell(): JSX.Element { } const navigate = useNavigate(); + const { state: navigationState } = useNavigation(); const currentPath = useCurrentPath(); - const { selectedWorkspaceId, selectedTaskId } = useParams(); + const { selectedWorkspaceId } = useParams(); const currentRoute = currentPath.currentPath; const topLevelRoute = currentRoute.startsWith('/tasks') @@ -165,17 +171,23 @@ export function Shell(): JSX.Element { > ) : null} - {!nodesVisible ? ( + {!nodesVisible || navigationState === 'loading' ? (
- -

- Please select a{' '} - {currentRoute.startsWith('/tasks') ? 'task' : 'project'} in the - sidebar. -

+ {navigationState === 'loading' ? ( + + ) : ( + <> + +

+ Please select a{' '} + {currentRoute.startsWith('/tasks') ? 'task' : 'project'} in + the sidebar. +

+ + )}
) : null} diff --git a/graph/ui-components/src/index.ts b/graph/ui-components/src/index.ts index 09e0853c0eeb9..82bc51d1ec3fe 100644 --- a/graph/ui-components/src/index.ts +++ b/graph/ui-components/src/index.ts @@ -1,3 +1,4 @@ export * from './lib/debounced-text-input'; export * from './lib/tag'; export * from './lib/dropdown'; +export * from './lib/spinner'; diff --git a/graph/ui-components/src/lib/spinner.stories.tsx b/graph/ui-components/src/lib/spinner.stories.tsx new file mode 100644 index 0000000000000..c7d7036e05a88 --- /dev/null +++ b/graph/ui-components/src/lib/spinner.stories.tsx @@ -0,0 +1,16 @@ +import type { Meta, StoryObj } from '@storybook/react'; +import { Spinner } from './spinner'; + +const meta: Meta = { + component: Spinner, + title: 'Shared/Spinner', +}; + +export default meta; +type Story = StoryObj; + +export const Primary: Story = { + args: { + className: '', + }, +}; diff --git a/graph/ui-components/src/lib/spinner.tsx b/graph/ui-components/src/lib/spinner.tsx new file mode 100644 index 0000000000000..500a5190cc05b --- /dev/null +++ b/graph/ui-components/src/lib/spinner.tsx @@ -0,0 +1,31 @@ +/** + * Spinner component from https://tailwindcss.com/docs/animation#spin + */ + +import React from 'react'; + +export type SpinnerProps = React.SVGProps; + +export function Spinner({ className, ...rest }: SpinnerProps) { + return ( + + + + + ); +}