Skip to content

Commit

Permalink
refactor(ui): Optimize LoadingWrapper experience (#1692)
Browse files Browse the repository at this point in the history
* add debounce in loading-wrapper

* table

* [autofix.ci] apply automated fixes

* update

* update

* [autofix.ci] apply automated fixes

* general form

---------

Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
  • Loading branch information
liangfung and autofix-ci[bot] authored Mar 20, 2024
1 parent 053318e commit 47ce579
Show file tree
Hide file tree
Showing 10 changed files with 285 additions and 250 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import {
RepositoriesQueryVariables,
RepositoryEdge
} from '@/lib/gql/generates/graphql'
import { useIsQueryInitialized, useMutation } from '@/lib/tabby/gql'
import { useMutation } from '@/lib/tabby/gql'
import { listRepositories } from '@/lib/tabby/query'
import { Button } from '@/components/ui/button'
import { IconTrash } from '@/components/ui/icons'
Expand All @@ -29,7 +29,7 @@ import {
TableHeader,
TableRow
} from '@/components/ui/table'
import { ListSkeleton } from '@/components/skeleton'
import LoadingWrapper from '@/components/loading-wrapper'

const deleteRepositoryMutation = graphql(/* GraphQL */ `
mutation deleteRepository($id: ID!) {
Expand All @@ -40,11 +40,10 @@ const deleteRepositoryMutation = graphql(/* GraphQL */ `
const PAGE_SIZE = DEFAULT_PAGE_SIZE
export default function RepositoryTable() {
const client = useClient()
const [{ data, error, fetching, stale }] = useQuery({
const [{ data, fetching }] = useQuery({
query: listRepositories,
variables: { first: PAGE_SIZE }
})
const [initialized] = useIsQueryInitialized({ data, error, stale })

const [currentPage, setCurrentPage] = React.useState(1)
const edges = data?.repositories?.edges
Expand Down Expand Up @@ -115,75 +114,65 @@ export default function RepositoryTable() {
}, [pageNum, currentPage])

return (
<div>
{initialized ? (
<>
<Table className="table-fixed border-b">
<TableHeader>
<TableRow>
<TableHead className="w-[25%]">Name</TableHead>
<TableHead>Git URL</TableHead>
<TableHead className="w-[100px]"></TableHead>
</TableRow>
</TableHeader>
<TableBody>
{!currentPageRepos?.length && currentPage === 1 ? (
<TableRow>
<TableCell colSpan={3} className="h-[100px] text-center">
No Data
</TableCell>
</TableRow>
) : (
<>
{currentPageRepos?.map(x => {
return (
<TableRow key={x.node.id}>
<TableCell className="truncate">
{x.node.name}
</TableCell>
<TableCell className="truncate">
{x.node.gitUrl}
</TableCell>
<TableCell className="flex justify-end">
<div className="flex gap-1">
<Button
size="icon"
variant="hover-destructive"
onClick={() => handleDeleteRepository(x.node)}
>
<IconTrash />
</Button>
</div>
</TableCell>
</TableRow>
)
})}
</>
)}
</TableBody>
</Table>
{showPagination && (
<Pagination className="my-4">
<PaginationContent>
<PaginationItem>
<PaginationPrevious
disabled={!hasPrevPage}
onClick={handleNavToPrevPage}
/>
</PaginationItem>
<PaginationItem>
<PaginationNext
disabled={!hasNextPage}
onClick={handleFetchNextPage}
/>
</PaginationItem>
</PaginationContent>
</Pagination>
<LoadingWrapper loading={fetching}>
<Table className="table-fixed border-b">
<TableHeader>
<TableRow>
<TableHead className="w-[25%]">Name</TableHead>
<TableHead>Git URL</TableHead>
<TableHead className="w-[100px]"></TableHead>
</TableRow>
</TableHeader>
<TableBody>
{!currentPageRepos?.length && currentPage === 1 ? (
<TableRow>
<TableCell colSpan={3} className="h-[100px] text-center">
No Data
</TableCell>
</TableRow>
) : (
<>
{currentPageRepos?.map(x => {
return (
<TableRow key={x.node.id}>
<TableCell className="truncate">{x.node.name}</TableCell>
<TableCell className="truncate">{x.node.gitUrl}</TableCell>
<TableCell className="flex justify-end">
<div className="flex gap-1">
<Button
size="icon"
variant="hover-destructive"
onClick={() => handleDeleteRepository(x.node)}
>
<IconTrash />
</Button>
</div>
</TableCell>
</TableRow>
)
})}
</>
)}
</>
) : (
<ListSkeleton />
</TableBody>
</Table>
{showPagination && (
<Pagination className="my-4">
<PaginationContent>
<PaginationItem>
<PaginationPrevious
disabled={!hasPrevPage}
onClick={handleNavToPrevPage}
/>
</PaginationItem>
<PaginationItem>
<PaginationNext
disabled={!hasNextPage}
onClick={handleFetchNextPage}
/>
</PaginationItem>
</PaginationContent>
</Pagination>
)}
</div>
</LoadingWrapper>
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import { Button, buttonVariants } from '@/components/ui/button'
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card'
import { Skeleton } from '@/components/ui/skeleton'
import { LicenseGuard } from '@/components/license-guard'
import LoadingWrapper from '@/components/loading-wrapper'

import { PROVIDER_METAS } from './constant'
import { SSOHeader } from './sso-header'
Expand Down Expand Up @@ -64,12 +65,15 @@ const OAuthCredentialList = () => {
return (
<div>
<SSOHeader />
{isLoading ? (
<div className="flex flex-col gap-8">
<Skeleton className="h-[180px] w-full rounded-xl" />
<Skeleton className="h-[180px] w-full rounded-xl" />
</div>
) : (
<LoadingWrapper
loading={isLoading}
fallback={
<div className="flex flex-col gap-8">
<Skeleton className="h-[180px] w-full rounded-xl" />
<Skeleton className="h-[180px] w-full rounded-xl" />
</div>
}
>
<div className="flex flex-col items-center gap-4 rounded-lg border-4 border-dashed py-8">
<div>No Data</div>
<div className="flex justify-center">
Expand All @@ -81,7 +85,7 @@ const OAuthCredentialList = () => {
</Link>
</div>
</div>
)}
</LoadingWrapper>
</div>
)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import {
FormMessage
} from '@/components/ui/form'
import { Input } from '@/components/ui/input'
import LoadingWrapper from '@/components/loading-wrapper'
import { FormSkeleton } from '@/components/skeleton'

const updateNetworkSettingMutation = graphql(/* GraphQL */ `
Expand Down Expand Up @@ -114,9 +115,14 @@ export const GeneralNetworkForm = () => {
reexecuteQuery()
}

return data && !stale ? (
<NetworkForm defaultValues={data.networkSetting} onSuccess={onSuccess} />
) : (
<FormSkeleton />
return (
<div className="min-h-[160px]">
<LoadingWrapper loading={!data || stale} fallback={<FormSkeleton />}>
<NetworkForm
defaultValues={data?.networkSetting}
onSuccess={onSuccess}
/>
</LoadingWrapper>
</div>
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import {
import { IconTrash } from '@/components/ui/icons'
import { Input } from '@/components/ui/input'
import { LicenseGuard } from '@/components/license-guard'
import LoadingWrapper from '@/components/loading-wrapper'
import { FormSkeleton } from '@/components/skeleton'

const updateSecuritySettingMutation = graphql(/* GraphQL */ `
Expand Down Expand Up @@ -227,7 +228,7 @@ function buildListValuesFromField(fieldListValue?: Array<{ value: string }>) {
}

export const GeneralSecurityForm = () => {
const [{ data, stale }, reexecuteQuery] = useQuery({
const [{ data, stale, fetching }, reexecuteQuery] = useQuery({
query: securitySetting
})
const onSuccess = () => {
Expand All @@ -241,9 +242,9 @@ export const GeneralSecurityForm = () => {
)
}

return data && !stale ? (
<SecurityForm defaultValues={defaultValues} onSuccess={onSuccess} />
) : (
<FormSkeleton />
return (
<LoadingWrapper loading={fetching || stale} fallback={<FormSkeleton />}>
<SecurityForm defaultValues={defaultValues} onSuccess={onSuccess} />
</LoadingWrapper>
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ import {
TableRow
} from '@/components/ui/table'
import { CopyButton } from '@/components/copy-button'
import LoadingWrapper from '@/components/loading-wrapper'

import CreateInvitationForm from './create-invitation-form'

Expand Down Expand Up @@ -148,40 +149,46 @@ export default function InvitationTable() {
return (
<div>
<CreateInvitationForm onCreated={handleInvitationCreated} />
<Table className="mt-4 border-b">
{!!currentPageInvits?.length && (
<TableHeader>
<TableRow>
<TableHead className="w-[25%]">Invitee</TableHead>
<TableHead className="w-[45%]">Created</TableHead>
<TableHead></TableHead>
</TableRow>
</TableHeader>
)}
<TableBody>
{currentPageInvits?.map(x => {
const link = `${externalUrl}/auth/signup?invitationCode=${x.node.code}`
return (
<TableRow key={x.node.id}>
<TableCell>{x.node.email}</TableCell>
<TableCell>{moment.utc(x.node.createdAt).fromNow()}</TableCell>
<TableCell className="flex justify-end">
<div className="flex gap-1">
<CopyButton value={link} />
<Button
size="icon"
variant="hover-destructive"
onClick={() => handleDeleteInvatation(x.node)}
>
<IconTrash />
</Button>
</div>
</TableCell>
</TableRow>
)
})}
</TableBody>
</Table>
<div className="mt-4">
<LoadingWrapper loading={fetching}>
<Table className="border-b">
{!!currentPageInvits?.length && (
<TableHeader>
<TableRow>
<TableHead className="w-[25%]">Invitee</TableHead>
<TableHead className="w-[45%]">Created</TableHead>
<TableHead></TableHead>
</TableRow>
</TableHeader>
)}
<TableBody>
{currentPageInvits?.map(x => {
const link = `${externalUrl}/auth/signup?invitationCode=${x.node.code}`
return (
<TableRow key={x.node.id}>
<TableCell>{x.node.email}</TableCell>
<TableCell>
{moment.utc(x.node.createdAt).fromNow()}
</TableCell>
<TableCell className="flex justify-end">
<div className="flex gap-1">
<CopyButton value={link} />
<Button
size="icon"
variant="hover-destructive"
onClick={() => handleDeleteInvatation(x.node)}
>
<IconTrash />
</Button>
</div>
</TableCell>
</TableRow>
)
})}
</TableBody>
</Table>
</LoadingWrapper>
</div>
{(hasNextPage || hasPrevPage) && (
<Pagination className="my-4">
<PaginationContent>
Expand Down
Loading

0 comments on commit 47ce579

Please sign in to comment.