From a67c1d6657be375a402c2244a914f097a414a0ce Mon Sep 17 00:00:00 2001 From: Luca Steeb Date: Thu, 21 Dec 2023 12:43:55 +0700 Subject: [PATCH] refactor(frontend): extract spinner and loading components (#13) --- .../molecules/brush-chart/brush-chart.tsx | 1 - frontend/app/src/components/ui/loading.tsx | 13 +++++++++++++ .../auth/login/components/user-login-form.tsx | 7 ++----- .../register/components/user-register-form.tsx | 7 ++----- frontend/app/src/pages/main/auth.tsx | 8 ++------ frontend/app/src/pages/main/events/index.tsx | 14 +++----------- frontend/app/src/pages/main/index.tsx | 10 +++------- .../src/pages/main/workers/$worker/index.tsx | 8 ++------ frontend/app/src/pages/main/workers/index.tsx | 8 ++------ .../src/pages/main/workflow-runs/$run/index.tsx | 17 ++++------------- .../app/src/pages/main/workflow-runs/index.tsx | 10 +++------- .../pages/main/workflows/$workflow/index.tsx | 17 ++++------------- frontend/app/src/pages/main/workflows/index.tsx | 8 ++------ .../components/tenant-create-form.tsx | 7 ++----- frontend/app/src/router.tsx | 4 ++-- 15 files changed, 46 insertions(+), 93 deletions(-) create mode 100644 frontend/app/src/components/ui/loading.tsx diff --git a/frontend/app/src/components/molecules/brush-chart/brush-chart.tsx b/frontend/app/src/components/molecules/brush-chart/brush-chart.tsx index 1d71a94cd..5b665da02 100644 --- a/frontend/app/src/components/molecules/brush-chart/brush-chart.tsx +++ b/frontend/app/src/components/molecules/brush-chart/brush-chart.tsx @@ -1,4 +1,3 @@ -/* eslint-disable @typescript-eslint/no-use-before-define */ import { useRef, useState, useMemo } from 'react'; import { scaleTime, scaleLinear } from '@visx/scale'; import appleStock, { AppleStock } from '@visx/mock-data/lib/mocks/appleStock'; diff --git a/frontend/app/src/components/ui/loading.tsx b/frontend/app/src/components/ui/loading.tsx new file mode 100644 index 000000000..099e83261 --- /dev/null +++ b/frontend/app/src/components/ui/loading.tsx @@ -0,0 +1,13 @@ +import { Icons } from '@/components/ui/icons.tsx'; + +export function Spinner() { + return ; +} + +export function Loading() { + return ( +
+ +
+ ); +} diff --git a/frontend/app/src/pages/auth/login/components/user-login-form.tsx b/frontend/app/src/pages/auth/login/components/user-login-form.tsx index 31077ffb9..57d08b93a 100644 --- a/frontend/app/src/pages/auth/login/components/user-login-form.tsx +++ b/frontend/app/src/pages/auth/login/components/user-login-form.tsx @@ -2,11 +2,10 @@ import { cn } from '@/lib/utils'; import { Button } from '@/components/ui/button'; import { Input } from '@/components/ui/input'; import { Label } from '@/components/ui/label'; -import { Icons } from '@/components/ui/icons'; - import { useForm } from 'react-hook-form'; import { zodResolver } from '@hookform/resolvers/zod'; import { z } from 'zod'; +import { Spinner } from '@/components/ui/loading.tsx'; const schema = z.object({ email: z.string().email('Invalid email address'), @@ -73,9 +72,7 @@ export function UserLoginForm({ className, ...props }: UserLoginFormProps) { )} diff --git a/frontend/app/src/pages/auth/register/components/user-register-form.tsx b/frontend/app/src/pages/auth/register/components/user-register-form.tsx index 78ccadbc4..fd3984b94 100644 --- a/frontend/app/src/pages/auth/register/components/user-register-form.tsx +++ b/frontend/app/src/pages/auth/register/components/user-register-form.tsx @@ -2,11 +2,10 @@ import { cn } from '@/lib/utils'; import { Button } from '@/components/ui/button'; import { Input } from '@/components/ui/input'; import { Label } from '@/components/ui/label'; -import { Icons } from '@/components/ui/icons'; - import { useForm } from 'react-hook-form'; import { zodResolver } from '@hookform/resolvers/zod'; import { z } from 'zod'; +import { Spinner } from '@/components/ui/loading.tsx'; const schema = z.object({ name: z.string().min(3, 'Name must be at least 3 characters long'), @@ -96,9 +95,7 @@ export function UserRegisterForm({ )} diff --git a/frontend/app/src/pages/main/auth.tsx b/frontend/app/src/pages/main/auth.tsx index 4a1f85570..621268c9f 100644 --- a/frontend/app/src/pages/main/auth.tsx +++ b/frontend/app/src/pages/main/auth.tsx @@ -7,7 +7,7 @@ import { import api from '@/lib/api'; import queryClient from '@/query-client'; import { useContextFromParent } from '@/lib/outlet'; -import { Icons } from '@/components/ui/icons'; +import { Loading } from '@/components/ui/loading.tsx'; const authMiddleware = async (currentUrl: string) => { try { @@ -69,11 +69,7 @@ export default function Auth() { }); if (!user || !memberships) { - return ( -
- -
- ); + return ; } return ; diff --git a/frontend/app/src/pages/main/events/index.tsx b/frontend/app/src/pages/main/events/index.tsx index e16e01f42..6af5f68eb 100644 --- a/frontend/app/src/pages/main/events/index.tsx +++ b/frontend/app/src/pages/main/events/index.tsx @@ -20,7 +20,6 @@ import api, { import invariant from 'tiny-invariant'; import { useAtom } from 'jotai'; import { currTenantAtom } from '@/lib/atoms'; -import { Icons } from '@/components/ui/icons'; import { FilterOption } from '@/components/molecules/data-table/data-table-toolbar'; import { Dialog, @@ -38,6 +37,7 @@ import { ArrowPathRoundedSquareIcon, } from '@heroicons/react/24/outline'; import { useApiError } from '@/lib/hooks'; +import { Loading } from '@/components/ui/loading.tsx'; export default function Events() { return ( @@ -171,11 +171,7 @@ function EventsTable() { // }, [listEventsQuery.data?.pagination]); if (listEventsQuery.isLoading) { - return ( -
- -
- ); + return ; } const tableColumns = columns({ @@ -285,11 +281,7 @@ function EventDataSection({ event }: { event: Event }) { }); if (getEventDataQuery.isLoading || !getEventDataQuery.data) { - return ( -
- -
- ); + return ; } const eventData = getEventDataQuery.data; diff --git a/frontend/app/src/pages/main/index.tsx b/frontend/app/src/pages/main/index.tsx index 16946c571..8c1cdb0b8 100644 --- a/frontend/app/src/pages/main/index.tsx +++ b/frontend/app/src/pages/main/index.tsx @@ -48,7 +48,7 @@ import { } from '@/lib/outlet'; import { useAtom } from 'jotai'; import { currTenantAtom } from '@/lib/atoms'; -import { Icons } from '@/components/ui/icons'; +import { Loading, Spinner } from '@/components/ui/loading.tsx'; function Main() { const { user, memberships } = useOutletContext< @@ -70,11 +70,7 @@ function Main() { }); if (!user || !memberships) { - return ( -
- -
- ); + return ; } return ( @@ -231,7 +227,7 @@ function TenantSwitcher({ className, memberships }: TenantSwitcherProps) { const [open, setOpen] = React.useState(false); if (!currTenant) { - return ; + return ; } return ( diff --git a/frontend/app/src/pages/main/workers/$worker/index.tsx b/frontend/app/src/pages/main/workers/$worker/index.tsx index f0e646cf9..febf6b848 100644 --- a/frontend/app/src/pages/main/workers/$worker/index.tsx +++ b/frontend/app/src/pages/main/workers/$worker/index.tsx @@ -1,4 +1,3 @@ -import { Icons } from '@/components/ui/icons'; import { Separator } from '@/components/ui/separator'; import { queries } from '@/lib/api'; import { currTenantAtom } from '@/lib/atoms'; @@ -11,6 +10,7 @@ import { ServerStackIcon } from '@heroicons/react/24/outline'; import { Button } from '@/components/ui/button'; import { DataTable } from '@/components/molecules/data-table/data-table'; import { columns } from './components/step-runs-columns'; +import { Loading } from '@/components/ui/loading.tsx'; export default function ExpandedWorkflowRun() { const [tenant] = useAtom(currTenantAtom); @@ -24,11 +24,7 @@ export default function ExpandedWorkflowRun() { }); if (workerQuery.isLoading || !workerQuery.data) { - return ( -
- -
- ); + return ; } const worker = workerQuery.data; diff --git a/frontend/app/src/pages/main/workers/index.tsx b/frontend/app/src/pages/main/workers/index.tsx index e27d9ebb7..d739354e6 100644 --- a/frontend/app/src/pages/main/workers/index.tsx +++ b/frontend/app/src/pages/main/workers/index.tsx @@ -4,10 +4,10 @@ import { queries } from '@/lib/api'; import invariant from 'tiny-invariant'; import { useAtom } from 'jotai'; import { currTenantAtom } from '@/lib/atoms'; -import { Icons } from '@/components/ui/icons'; import { relativeDate } from '@/lib/utils'; import { Link } from 'react-router-dom'; import { Button } from '@/components/ui/button'; +import { Loading } from '@/components/ui/loading.tsx'; export default function Workers() { const [tenant] = useAtom(currTenantAtom); @@ -18,11 +18,7 @@ export default function Workers() { }); if (listWorkersQuery.isLoading || !listWorkersQuery.data?.rows) { - return ( -
- -
- ); + return ; } return ( diff --git a/frontend/app/src/pages/main/workflow-runs/$run/index.tsx b/frontend/app/src/pages/main/workflow-runs/$run/index.tsx index 3f8e495f3..ef52e25e5 100644 --- a/frontend/app/src/pages/main/workflow-runs/$run/index.tsx +++ b/frontend/app/src/pages/main/workflow-runs/$run/index.tsx @@ -1,4 +1,3 @@ -import { Icons } from '@/components/ui/icons'; import { Separator } from '@/components/ui/separator'; import { JobRun, StepRun, StepRunStatus, queries, Event } from '@/lib/api'; import CronPrettifier from 'cronstrue'; @@ -22,6 +21,7 @@ import { RunStatus } from '../components/run-statuses'; import { ColumnDef } from '@tanstack/react-table'; import { useState } from 'react'; import { Code } from '@/components/ui/code'; +import { Loading } from '@/components/ui/loading.tsx'; export default function ExpandedWorkflowRun() { const [expandedStepRuns, setExpandedStepRuns] = useState([]); @@ -37,11 +37,7 @@ export default function ExpandedWorkflowRun() { }); if (runQuery.isLoading || !runQuery.data) { - return ( -
- -
- ); + return ; } const run = runQuery.data; @@ -266,8 +262,7 @@ function StepStatusSection({ stepRun }: { stepRun: StepRun }) { }`; break; case 'PREVIOUS_STEP_TIMED_OUT': - statusText = - 'This step was cancelled because the previous step timed out'; + statusText = `This step was cancelled because the previous step timed out`; break; default: break; @@ -324,11 +319,7 @@ function EventDataSection({ event }: { event: Event }) { }); if (getEventDataQuery.isLoading || !getEventDataQuery.data) { - return ( -
- -
- ); + return ; } const eventData = getEventDataQuery.data; diff --git a/frontend/app/src/pages/main/workflow-runs/index.tsx b/frontend/app/src/pages/main/workflow-runs/index.tsx index 6f51dce9f..ffa46da64 100644 --- a/frontend/app/src/pages/main/workflow-runs/index.tsx +++ b/frontend/app/src/pages/main/workflow-runs/index.tsx @@ -1,4 +1,4 @@ -import { DataTable } from '../../../components/molecules/data-table/data-table'; +import { DataTable } from '@/components/molecules/data-table/data-table.tsx'; import { columns } from './components/workflow-runs-columns'; import { Separator } from '@/components/ui/separator'; import { useMemo, useState } from 'react'; @@ -11,8 +11,8 @@ import { useQuery } from '@tanstack/react-query'; import invariant from 'tiny-invariant'; import { useAtom } from 'jotai'; import { currTenantAtom } from '@/lib/atoms'; -import { Icons } from '@/components/ui/icons'; import { queries } from '@/lib/api'; +import { Loading } from '@/components/ui/loading.tsx'; export default function WorkflowRuns() { return ( @@ -56,11 +56,7 @@ function WorkflowRunsTable() { }); if (listWorkflowRunsQuery.isLoading) { - return ( -
- -
- ); + return ; } return ( diff --git a/frontend/app/src/pages/main/workflows/$workflow/index.tsx b/frontend/app/src/pages/main/workflows/$workflow/index.tsx index 07a01b531..39ccf5b6c 100644 --- a/frontend/app/src/pages/main/workflows/$workflow/index.tsx +++ b/frontend/app/src/pages/main/workflows/$workflow/index.tsx @@ -1,5 +1,4 @@ import { DataTable } from '@/components/molecules/data-table/data-table'; -import { Icons } from '@/components/ui/icons'; import { Separator } from '@/components/ui/separator'; import api, { Workflow, queries } from '@/lib/api'; import { currTenantAtom } from '@/lib/atoms'; @@ -19,6 +18,7 @@ import { Code } from '@/components/ui/code'; import { Badge } from '@/components/ui/badge'; import { relativeDate } from '@/lib/utils'; import { Square3Stack3DIcon } from '@heroicons/react/24/outline'; +import { Loading } from '@/components/ui/loading.tsx'; export async function loader({ params, @@ -37,8 +37,7 @@ export async function loader({ throw error; } else if (isAxiosError(error)) { // TODO: handle error better - redirect('/unauthorized'); - throw new Error('unauthorized'); + throw redirect('/unauthorized'); } } @@ -49,11 +48,7 @@ export default function ExpandedWorkflow() { const workflow = useLoaderData() as Awaited>; if (!workflow) { - return ( -
- -
- ); + return ; } return ( @@ -116,11 +111,7 @@ function WorkflowDefinition() { getWorkflowDefinitionQuery.isLoading || !getWorkflowDefinitionQuery.data ) { - return ( -
- -
- ); + return ; } const workflowDefinition = getWorkflowDefinitionQuery.data; diff --git a/frontend/app/src/pages/main/workflows/index.tsx b/frontend/app/src/pages/main/workflows/index.tsx index add9dc9a9..10a048bbe 100644 --- a/frontend/app/src/pages/main/workflows/index.tsx +++ b/frontend/app/src/pages/main/workflows/index.tsx @@ -5,7 +5,7 @@ import { queries } from '@/lib/api'; import invariant from 'tiny-invariant'; import { useAtom } from 'jotai'; import { currTenantAtom } from '@/lib/atoms'; -import { Icons } from '@/components/ui/icons'; +import { Loading } from '@/components/ui/loading.tsx'; export default function Workflows() { const [tenant] = useAtom(currTenantAtom); @@ -16,11 +16,7 @@ export default function Workflows() { }); if (listWorkflowsQuery.isLoading) { - return ( -
- -
- ); + return ; } return ( diff --git a/frontend/app/src/pages/onboarding/create-tenant/components/tenant-create-form.tsx b/frontend/app/src/pages/onboarding/create-tenant/components/tenant-create-form.tsx index 4a14d7216..2493e3f7a 100644 --- a/frontend/app/src/pages/onboarding/create-tenant/components/tenant-create-form.tsx +++ b/frontend/app/src/pages/onboarding/create-tenant/components/tenant-create-form.tsx @@ -2,8 +2,7 @@ import { cn } from '@/lib/utils'; import { Button } from '@/components/ui/button'; import { Input } from '@/components/ui/input'; import { Label } from '@/components/ui/label'; -import { Icons } from '@/components/ui/icons'; - +import { Spinner } from '@/components/ui/loading.tsx'; import { useForm } from 'react-hook-form'; import { zodResolver } from '@hookform/resolvers/zod'; import { z } from 'zod'; @@ -127,9 +126,7 @@ export function TenantCreateForm({ )} diff --git a/frontend/app/src/router.tsx b/frontend/app/src/router.tsx index 88a81a9fd..b9dbfd054 100644 --- a/frontend/app/src/router.tsx +++ b/frontend/app/src/router.tsx @@ -1,4 +1,4 @@ -import React from 'react'; +import { FC } from 'react'; import { createBrowserRouter, RouterProvider } from 'react-router-dom'; const routes = [ @@ -140,7 +140,7 @@ const routes = [ const router = createBrowserRouter(routes, { basename: '/' }); -const Router: React.FC = () => { +const Router: FC = () => { return ; };