Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
83f6c8d
redo useQueryTable so that the types are legit and it returns the data
david-crespo Nov 20, 2024
4de0bb0
fix junky getRowId and use new QueryTable on sleds and physical disks
david-crespo Nov 20, 2024
9406444
get wild with a list-specific helper to make the call sites clean
david-crespo Nov 21, 2024
8cab460
encapsulate pageSize in the query config so it is defined in one place
david-crespo Nov 21, 2024
1a5fbda
do the placeholderData thing for all lists
david-crespo Nov 21, 2024
ca6f430
scroll to top when page changes
david-crespo Nov 22, 2024
65bb5fd
loading spinner on page changes!
david-crespo Nov 22, 2024
fee4c3f
fix the pagination test, test lovely new scroll reset logic
david-crespo Nov 22, 2024
5756dae
fix other e2es, don't scroll reset on browser forward/back
david-crespo Nov 22, 2024
31ddca8
fix bug found while converting other tables, extract useScrollReset
david-crespo Nov 22, 2024
ada4f41
move columns up
david-crespo Nov 20, 2024
022b5f6
convert instance list to new QueryTable, fix polling bug
david-crespo Nov 20, 2024
fbf9413
Merge main into fix-instance-polling
david-crespo Nov 22, 2024
df9e9ad
convert the rest of the tables
david-crespo Nov 22, 2024
505f3db
convert a few more
david-crespo Nov 22, 2024
727f5af
a hard one: IpPoolPage, have to handle rows with no ID field
david-crespo Nov 22, 2024
7b9c8b9
last few easy ones
david-crespo Nov 22, 2024
9918a52
last ones and delete QueryTable
david-crespo Nov 22, 2024
14205ec
rename file back to QueryTable
david-crespo Nov 22, 2024
a83eeda
Merge main into convert-all-tables
david-crespo Nov 23, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion app/api/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,12 @@ import {
wrapQueryClient,
} from './hooks'

export { ensurePrefetched, PAGE_SIZE, type PaginatedQuery } from './hooks'
export {
ensurePrefetched,
usePrefetchedQuery,
PAGE_SIZE,
type PaginatedQuery,
} from './hooks'

export const api = new Api({
// unit tests run in Node, whose fetch implementation requires a full URL
Expand Down
3 changes: 3 additions & 0 deletions app/api/hooks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -232,6 +232,9 @@ export function ensurePrefetched<TData, TError>(
return result as SetNonNullable<typeof result, 'data'>
}

export const usePrefetchedQuery = <TData>(options: UseQueryOptions<TData, ApiError>) =>
ensurePrefetched(useQuery(options), options.queryKey)

const ERRORS_ALLOWED = 'errors-allowed'

/** Result that includes both success and error so it can be cached by RQ */
Expand Down
28 changes: 14 additions & 14 deletions app/pages/ProjectsPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,9 @@ import { Outlet, useNavigate } from 'react-router-dom'

import {
apiQueryClient,
getListQFn,
queryClient,
useApiMutation,
useApiQueryClient,
usePrefetchedApiQuery,
type Project,
} from '@oxide/api'
import { Folder16Icon, Folder24Icon } from '@oxide/design-system/icons/react'
Expand All @@ -24,7 +24,7 @@ import { confirmDelete } from '~/stores/confirm-delete'
import { makeLinkCell } from '~/table/cells/LinkCell'
import { useColsWithActions, type MenuAction } from '~/table/columns/action-col'
import { Columns } from '~/table/columns/common'
import { PAGE_SIZE, useQueryTable } from '~/table/QueryTable'
import { useQueryTable } from '~/table/QueryTable'
import { CreateLink } from '~/ui/lib/CreateButton'
import { EmptyMessage } from '~/ui/lib/EmptyMessage'
import { PageHeader, PageTitle } from '~/ui/lib/PageHeader'
Expand All @@ -42,8 +42,10 @@ const EmptyState = () => (
/>
)

const projectList = getListQFn('projectList', {})

export async function loader() {
await apiQueryClient.prefetchQuery('projectList', { query: { limit: PAGE_SIZE } })
await queryClient.prefetchQuery(projectList.optionsFn())
return null
}

Expand All @@ -60,17 +62,11 @@ Component.displayName = 'ProjectsPage'
export function Component() {
const navigate = useNavigate()

const queryClient = useApiQueryClient()
const { Table } = useQueryTable('projectList', {})
const { data: projects } = usePrefetchedApiQuery('projectList', {
query: { limit: PAGE_SIZE },
})

const { mutateAsync: deleteProject } = useApiMutation('projectDelete', {
onSuccess() {
// TODO: figure out if this is invalidating as expected, can we leave out the query
// altogether, etc. Look at whether limit param matters.
queryClient.invalidateQueries('projectList')
apiQueryClient.invalidateQueries('projectList')
},
})

Expand Down Expand Up @@ -100,6 +96,12 @@ export function Component() {
[deleteProject, navigate]
)

const columns = useColsWithActions(staticCols, makeActions)
const {
table,
query: { data: projects },
} = useQueryTable({ query: projectList, columns, emptyState: <EmptyState /> })

useQuickActions(
useMemo(
() => [
Expand All @@ -117,8 +119,6 @@ export function Component() {
)
)

const columns = useColsWithActions(staticCols, makeActions)

return (
<>
<PageHeader>
Expand All @@ -133,7 +133,7 @@ export function Component() {
<TableActions>
<CreateLink to={pb.projectsNew()}>New Project</CreateLink>
</TableActions>
<Table columns={columns} emptyState={<EmptyState />} />
{table}
<Outlet />
</>
)
Expand Down
18 changes: 12 additions & 6 deletions app/pages/project/disks/DisksPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ import {
apiQueryClient,
diskCan,
genName,
getListQFn,
queryClient,
useApiMutation,
useApiQueryClient,
type Disk,
Expand All @@ -28,7 +30,7 @@ import { addToast } from '~/stores/toast'
import { InstanceLinkCell } from '~/table/cells/InstanceLinkCell'
import { useColsWithActions, type MenuAction } from '~/table/columns/action-col'
import { Columns } from '~/table/columns/common'
import { PAGE_SIZE, useQueryTable } from '~/table/QueryTable'
import { useQueryTable } from '~/table/QueryTable'
import { CreateLink } from '~/ui/lib/CreateButton'
import { EmptyMessage } from '~/ui/lib/EmptyMessage'
import { PageHeader, PageTitle } from '~/ui/lib/PageHeader'
Expand All @@ -48,12 +50,12 @@ const EmptyState = () => (
/>
)

const diskList = (project: string) => getListQFn('diskList', { query: { project } })

DisksPage.loader = async ({ params }: LoaderFunctionArgs) => {
const { project } = getProjectSelector(params)
await Promise.all([
apiQueryClient.prefetchQuery('diskList', {
query: { project, limit: PAGE_SIZE },
}),
queryClient.prefetchQuery(diskList(project).optionsFn()),

// fetch instances and preload into RQ cache so fetches by ID in
// InstanceLinkCell can be mostly instant yet gracefully fall back to
Expand Down Expand Up @@ -97,7 +99,6 @@ const staticCols = [
export function DisksPage() {
const queryClient = useApiQueryClient()
const { project } = useProjectSelector()
const { Table } = useQueryTable('diskList', { query: { project } })

const { mutateAsync: deleteDisk } = useApiMutation('diskDelete', {
onSuccess(_data, variables) {
Expand Down Expand Up @@ -160,6 +161,11 @@ export function DisksPage() {
)

const columns = useColsWithActions(staticCols, makeActions)
const { table } = useQueryTable({
query: diskList(project),
columns,
emptyState: <EmptyState />,
})

return (
<>
Expand All @@ -175,7 +181,7 @@ export function DisksPage() {
<TableActions>
<CreateLink to={pb.disksNew({ project })}>New Disk</CreateLink>
</TableActions>
<Table columns={columns} emptyState={<EmptyState />} />
{table}
<Outlet />
</>
)
Expand Down
31 changes: 17 additions & 14 deletions app/pages/project/floating-ips/FloatingIpsPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,11 @@ import { Outlet, useNavigate, type LoaderFunctionArgs } from 'react-router-dom'

import {
apiQueryClient,
getListQFn,
queryClient,
useApiMutation,
useApiQueryClient,
usePrefetchedApiQuery,
usePrefetchedQuery,
type FloatingIp,
type Instance,
} from '@oxide/api'
Expand All @@ -31,7 +33,7 @@ import { InstanceLinkCell } from '~/table/cells/InstanceLinkCell'
import { IpPoolCell } from '~/table/cells/IpPoolCell'
import { useColsWithActions, type MenuAction } from '~/table/columns/action-col'
import { Columns } from '~/table/columns/common'
import { PAGE_SIZE, useQueryTable } from '~/table/QueryTable'
import { useQueryTable } from '~/table/QueryTable'
import { CopyableIp } from '~/ui/lib/CopyableIp'
import { CreateLink } from '~/ui/lib/CreateButton'
import { EmptyMessage } from '~/ui/lib/EmptyMessage'
Expand All @@ -53,15 +55,15 @@ const EmptyState = () => (
/>
)

const fipList = (project: string) => getListQFn('floatingIpList', { query: { project } })
const instanceList = (project: string) =>
getListQFn('instanceList', { query: { project, limit: ALL_ISH } })

FloatingIpsPage.loader = async ({ params }: LoaderFunctionArgs) => {
const { project } = getProjectSelector(params)
await Promise.all([
apiQueryClient.prefetchQuery('floatingIpList', {
query: { project, limit: PAGE_SIZE },
}),
apiQueryClient.prefetchQuery('instanceList', {
query: { project },
}),
queryClient.prefetchQuery(fipList(project).optionsFn()),
queryClient.prefetchQuery(instanceList(project).optionsFn()),
// fetch IP Pools and preload into RQ cache so fetches by ID in
// IpPoolCell can be mostly instant yet gracefully fall back to
// fetching individually if we don't fetch them all here
Expand Down Expand Up @@ -102,9 +104,7 @@ export function FloatingIpsPage() {
const [floatingIpToModify, setFloatingIpToModify] = useState<FloatingIp | null>(null)
const queryClient = useApiQueryClient()
const { project } = useProjectSelector()
const { data: instances } = usePrefetchedApiQuery('instanceList', {
query: { project },
})
const { data: instances } = usePrefetchedQuery(instanceList(project).optionsFn())
const navigate = useNavigate()

const { mutateAsync: floatingIpDetach } = useApiMutation('floatingIpDetach', {
Expand Down Expand Up @@ -202,9 +202,12 @@ export function FloatingIpsPage() {
[deleteFloatingIp, floatingIpDetach, navigate, project, instances]
)

const { Table } = useQueryTable('floatingIpList', { query: { project } })

const columns = useColsWithActions(staticCols, makeActions)
const { table } = useQueryTable({
query: fipList(project),
columns,
emptyState: <EmptyState />,
})

return (
<>
Expand All @@ -220,7 +223,7 @@ export function FloatingIpsPage() {
<TableActions>
<CreateLink to={pb.floatingIpsNew({ project })}>New Floating IP</CreateLink>
</TableActions>
<Table columns={columns} emptyState={<EmptyState />} />
{table}
<Outlet />
{floatingIpToModify && (
<AttachFloatingIpModal
Expand Down
29 changes: 20 additions & 9 deletions app/pages/project/images/ImagesPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,14 @@ import { createColumnHelper } from '@tanstack/react-table'
import { useCallback, useMemo, useState } from 'react'
import { Outlet, type LoaderFunctionArgs } from 'react-router-dom'

import { apiQueryClient, useApiMutation, useApiQueryClient, type Image } from '@oxide/api'
import {
apiQueryClient,
getListQFn,
queryClient,
useApiMutation,
useApiQueryClient,
type Image,
} from '@oxide/api'
import { Images16Icon, Images24Icon } from '@oxide/design-system/icons/react'

import { DocsPopover } from '~/components/DocsPopover'
Expand All @@ -20,7 +27,7 @@ import { addToast } from '~/stores/toast'
import { makeLinkCell } from '~/table/cells/LinkCell'
import { getActionsCol, type MenuAction } from '~/table/columns/action-col'
import { Columns } from '~/table/columns/common'
import { PAGE_SIZE, useQueryTable } from '~/table/QueryTable'
import { useQueryTable } from '~/table/QueryTable'
import { CreateLink } from '~/ui/lib/CreateButton'
import { EmptyMessage } from '~/ui/lib/EmptyMessage'
import { Message } from '~/ui/lib/Message'
Expand All @@ -42,25 +49,23 @@ const EmptyState = () => (

const colHelper = createColumnHelper<Image>()

const imageList = (project: string) => getListQFn('imageList', { query: { project } })

ImagesPage.loader = async ({ params }: LoaderFunctionArgs) => {
const { project } = getProjectSelector(params)
await apiQueryClient.prefetchQuery('imageList', {
query: { project, limit: PAGE_SIZE },
})
await queryClient.prefetchQuery(imageList(project).optionsFn())
return null
}

export function ImagesPage() {
const { project } = useProjectSelector()
const { Table } = useQueryTable('imageList', { query: { project } })
const queryClient = useApiQueryClient()

const [promoteImageName, setPromoteImageName] = useState<string | null>(null)

const { mutateAsync: deleteImage } = useApiMutation('imageDelete', {
onSuccess(_data, variables) {
addToast(<>Image <HL>{variables.path.image}</HL> deleted</>) // prettier-ignore
queryClient.invalidateQueries('imageList')
apiQueryClient.invalidateQueries('imageList')
},
})

Expand Down Expand Up @@ -97,6 +102,12 @@ export function ImagesPage() {
]
}, [project, makeActions])

const { table } = useQueryTable({
query: imageList(project),
columns,
emptyState: <EmptyState />,
})

return (
<>
<PageHeader>
Expand All @@ -111,7 +122,7 @@ export function ImagesPage() {
<TableActions>
<CreateLink to={pb.projectImagesNew({ project })}>Upload image</CreateLink>
</TableActions>
<Table columns={columns} emptyState={<EmptyState />} />
{table}
{promoteImageName && (
<PromoteImageModal
onDismiss={() => setPromoteImageName(null)}
Expand Down
2 changes: 1 addition & 1 deletion app/pages/project/instances/InstancesPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ import { InstanceStateCell } from '~/table/cells/InstanceStateCell'
import { makeLinkCell } from '~/table/cells/LinkCell'
import { getActionsCol } from '~/table/columns/action-col'
import { Columns } from '~/table/columns/common'
import { useQueryTable } from '~/table/QueryTable2'
import { useQueryTable } from '~/table/QueryTable'
import { CreateLink } from '~/ui/lib/CreateButton'
import { EmptyMessage } from '~/ui/lib/EmptyMessage'
import { PageHeader, PageTitle } from '~/ui/lib/PageHeader'
Expand Down
2 changes: 1 addition & 1 deletion app/pages/project/snapshots/SnapshotsPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ import { confirmDelete } from '~/stores/confirm-delete'
import { SkeletonCell } from '~/table/cells/EmptyCell'
import { useColsWithActions, type MenuAction } from '~/table/columns/action-col'
import { Columns } from '~/table/columns/common'
import { useQueryTable } from '~/table/QueryTable2'
import { useQueryTable } from '~/table/QueryTable'
import { Badge } from '~/ui/lib/Badge'
import { CreateLink } from '~/ui/lib/CreateButton'
import { EmptyMessage } from '~/ui/lib/EmptyMessage'
Expand Down
Loading
Loading