-
Notifications
You must be signed in to change notification settings - Fork 16
Using RR loaders all over for clean page transitions #1101
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
f21c7a9
2164f85
c7f36e4
5c17e8a
1c3b0e2
159875e
6e9c445
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -5,6 +5,27 @@ import invariant from 'tiny-invariant' | |
| const err = (param: string) => | ||
| `Param '${param}' not found in route. You might be rendering a component under the wrong route.` | ||
|
|
||
| export const requireParams = | ||
| <K extends string = never>(...requiredKeys: K[]) => | ||
| (params: Readonly<Params<string>>) => { | ||
| const requiredParams: { [k in K]?: string } = {} | ||
| if (process.env.NODE_ENV !== 'production') { | ||
| for (const k of requiredKeys) { | ||
| const value = params[k] | ||
| invariant(k in params && value, err(k)) | ||
| requiredParams[k] = value | ||
| } | ||
| } | ||
| return requiredParams as { readonly [k in K]: string } | ||
| } | ||
|
|
||
| export const requireOrgParams = requireParams('orgName') | ||
| export const requireProjectParams = requireParams('orgName', 'projectName') | ||
| export const requireInstanceParams = requireParams('orgName', 'projectName', 'instanceName') | ||
| export const requireVpcParams = requireParams('orgName', 'projectName', 'vpcName') | ||
|
|
||
| export const useVpcParams = () => requireVpcParams(useParams()) | ||
|
|
||
|
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. could live without the helpers but they're kind of nice?
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yeah, I think they're good. Shortens the params and makes them a bit explicit, so I'm good with it. |
||
| /** | ||
| * Wrapper for RR's `useParams` that guarantees (in dev) that the specified | ||
| * params are present. No keys besides those specified are present on the result | ||
|
|
@@ -13,17 +34,7 @@ const err = (param: string) => | |
| // default of never is required to prevent the highly undesirable property that if | ||
| // you don't pass any arguments, the result object thinks every property is defined | ||
| export function useRequiredParams<K extends string = never>(...requiredKeys: K[]) { | ||
| const params = useParams() | ||
| // same as below except we build an object with only the specified keys | ||
| const requiredParams: { [k in K]?: string } = {} | ||
| if (process.env.NODE_ENV !== 'production') { | ||
| for (const k of requiredKeys) { | ||
| const value = params[k] | ||
| invariant(k in params && value, err(k)) | ||
| requiredParams[k] = value | ||
| } | ||
| } | ||
| return requiredParams as { readonly [k in K]: string } | ||
| return requireParams(...requiredKeys)(useParams()) | ||
| } | ||
|
|
||
| /** | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,8 +1,10 @@ | ||
| import { createColumnHelper } from '@tanstack/react-table' | ||
| import { getCoreRowModel, useReactTable } from '@tanstack/react-table' | ||
| import { useMemo, useState } from 'react' | ||
| import type { LoaderFunctionArgs } from 'react-router-dom' | ||
|
|
||
| import { | ||
| apiQueryClient, | ||
| orgRoleOrder, | ||
| setUserRole, | ||
| useApiMutation, | ||
|
|
@@ -24,9 +26,7 @@ import { | |
| } from '@oxide/ui' | ||
|
|
||
| import { OrgAccessAddUserSideModal, OrgAccessEditUserSideModal } from 'app/forms/org-access' | ||
| import { useRequiredParams } from 'app/hooks' | ||
|
|
||
| type UserRow = UserAccessRow<OrganizationRole> | ||
| import { requireOrgParams, useRequiredParams } from 'app/hooks' | ||
|
|
||
| const EmptyState = ({ onClick }: { onClick: () => void }) => ( | ||
| <TableEmptyBox> | ||
|
|
@@ -40,9 +40,19 @@ const EmptyState = ({ onClick }: { onClick: () => void }) => ( | |
| </TableEmptyBox> | ||
| ) | ||
|
|
||
| OrgAccessPage.loader = async ({ params }: LoaderFunctionArgs) => { | ||
| await Promise.all([ | ||
| apiQueryClient.prefetchQuery('organizationPolicyView', requireOrgParams(params)), | ||
| // used in useUserAccessRows to resolve user names | ||
| apiQueryClient.prefetchQuery('userList', { limit: 200 }), | ||
| ]) | ||
| } | ||
|
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this |
||
|
|
||
| type UserRow = UserAccessRow<OrganizationRole> | ||
|
|
||
| const colHelper = createColumnHelper<UserRow>() | ||
|
|
||
| export const OrgAccessPage = () => { | ||
| export function OrgAccessPage() { | ||
|
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. changed all of these to use |
||
| const [addModalOpen, setAddModalOpen] = useState(false) | ||
| const [editingUserRow, setEditingUserRow] = useState<UserRow | null>(null) | ||
| const orgParams = useRequiredParams('orgName') | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.