frontend: upgrade @tanstack/react-router
This commit is contained in:
4
.github/dependabot.yml
vendored
4
.github/dependabot.yml
vendored
@@ -89,6 +89,10 @@ updates:
|
||||
graphql-codegen:
|
||||
patterns:
|
||||
- "@graphql-codegen/*"
|
||||
tanstack-router:
|
||||
patterns:
|
||||
- "@tanstack/react-router"
|
||||
- "@tanstack/router-*"
|
||||
types:
|
||||
patterns:
|
||||
- "@types/*"
|
||||
|
||||
56
frontend/package-lock.json
generated
56
frontend/package-lock.json
generated
@@ -13,7 +13,7 @@
|
||||
"@radix-ui/react-alert-dialog": "^1.0.5",
|
||||
"@radix-ui/react-dialog": "^1.0.5",
|
||||
"@radix-ui/react-form": "^0.0.3",
|
||||
"@tanstack/react-router": "^1.16.6",
|
||||
"@tanstack/react-router": "^1.20.1",
|
||||
"@types/ua-parser-js": "^0.7.39",
|
||||
"@urql/core": "^4.2.3",
|
||||
"@urql/devtools": "^2.0.3",
|
||||
@@ -48,8 +48,8 @@
|
||||
"@storybook/addon-essentials": "^7.6.17",
|
||||
"@storybook/react": "^7.6.17",
|
||||
"@storybook/react-vite": "^7.6.17",
|
||||
"@tanstack/router-devtools": "^1.16.6",
|
||||
"@tanstack/router-vite-plugin": "^1.16.5",
|
||||
"@tanstack/router-devtools": "^1.20.1",
|
||||
"@tanstack/router-vite-plugin": "^1.20.2",
|
||||
"@testing-library/react": "^14.2.1",
|
||||
"@types/node": "^20.11.24",
|
||||
"@types/react": "^18.2.61",
|
||||
@@ -8162,9 +8162,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@tanstack/react-router": {
|
||||
"version": "1.16.6",
|
||||
"resolved": "https://registry.npmjs.org/@tanstack/react-router/-/react-router-1.16.6.tgz",
|
||||
"integrity": "sha512-d1Kjs38IF3bH7jKwihMBrdnh7BMVOHSNhJ9sltCiP4gLHcZkG7V9BwwJn5yL4V7YHIPNxdrJ3v4yrkvdrPJ0Ww==",
|
||||
"version": "1.20.1",
|
||||
"resolved": "https://registry.npmjs.org/@tanstack/react-router/-/react-router-1.20.1.tgz",
|
||||
"integrity": "sha512-WpWZ4rYC+L3DHCB4+lo9HPVoNkUy4yN9QL+1Z8QSYeUKG0ZAydrqUnL48YBKdSh3bp8FRh09R+74DTP0/lvxAw==",
|
||||
"dependencies": {
|
||||
"@tanstack/history": "1.15.13",
|
||||
"@tanstack/react-store": "^0.2.1",
|
||||
@@ -8201,13 +8201,15 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@tanstack/router-devtools": {
|
||||
"version": "1.16.6",
|
||||
"resolved": "https://registry.npmjs.org/@tanstack/router-devtools/-/router-devtools-1.16.6.tgz",
|
||||
"integrity": "sha512-zjyLuStYA1TM4L1IfgQJ1ZCq36o3UVaLLCVmBBHukxbc6n2cKR2U11BXJW5RpkNZDyAPyGcPLEgJ2qcZCYSDcQ==",
|
||||
"version": "1.20.1",
|
||||
"resolved": "https://registry.npmjs.org/@tanstack/router-devtools/-/router-devtools-1.20.1.tgz",
|
||||
"integrity": "sha512-1t/IE6dR4rGNpdWVLl8G6DN31Uj+UUth6j9AhVox4lRA76O+/JRnpBuh/Q/59CUPN3dR5dY7vLyl96swr/1Nwg==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@tanstack/react-router": "1.16.6",
|
||||
"date-fns": "^2.29.1"
|
||||
"@tanstack/react-router": "1.20.1",
|
||||
"clsx": "^2.1.0",
|
||||
"date-fns": "^2.29.1",
|
||||
"goober": "^2.1.14"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
@@ -8238,9 +8240,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@tanstack/router-generator": {
|
||||
"version": "1.16.5",
|
||||
"resolved": "https://registry.npmjs.org/@tanstack/router-generator/-/router-generator-1.16.5.tgz",
|
||||
"integrity": "sha512-np9+DASQvD4ff+FrCZ4XqRMGpVC6Y2213kma/X05mvo241yh0D5C6paUY7N7pSBPpuTlJbYKi+73cm/xRtK3Hg==",
|
||||
"version": "1.20.0",
|
||||
"resolved": "https://registry.npmjs.org/@tanstack/router-generator/-/router-generator-1.20.0.tgz",
|
||||
"integrity": "sha512-YkxVMi6q3K3V99Xo13dbP4fQDHxGUZi8Z5B7t4XZvwouAj7RDF8Tm8UcJVix8VLWaH4pt1idSXy185GWLTAiTw==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"prettier": "^3.1.1",
|
||||
@@ -8255,12 +8257,12 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@tanstack/router-vite-plugin": {
|
||||
"version": "1.16.5",
|
||||
"resolved": "https://registry.npmjs.org/@tanstack/router-vite-plugin/-/router-vite-plugin-1.16.5.tgz",
|
||||
"integrity": "sha512-rNfAuWIScl0KnjWOda5hzQYgHdwpLu1OljvqZa260UrCB6e32882X2Ci687+OUBfydhZT/V53XtQ+la7/AO5Rw==",
|
||||
"version": "1.20.2",
|
||||
"resolved": "https://registry.npmjs.org/@tanstack/router-vite-plugin/-/router-vite-plugin-1.20.2.tgz",
|
||||
"integrity": "sha512-lZ6fBwXszmzS0n9fbQUDdi0u4f6ZimDXIQhMjZEzqn9yB/IPloqN0ja0Bac78/5C7gJhsZ8YcgH8qRqqXYWGeg==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@tanstack/router-generator": "1.16.5"
|
||||
"@tanstack/router-generator": "1.20.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
@@ -11330,6 +11332,15 @@
|
||||
"integrity": "sha512-au6ydSpg6nsrigcZ4m8Bc9hxjeW+GJ8xh5G3BJCMt4WXe1H10UNaVOamqQTmrx1kjVuxAHIQSNU6hY4Nsn9/ag==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/clsx": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.0.tgz",
|
||||
"integrity": "sha512-m3iNNWpd9rl3jvvcBnu70ylMdrXt8Vlq4HYadnU5fwcOtvkSQWPmj7amUcDT2qYI7risszBjI5AUIUox9D16pg==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/coa": {
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmjs.org/coa/-/coa-2.0.2.tgz",
|
||||
@@ -15212,6 +15223,15 @@
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/goober": {
|
||||
"version": "2.1.14",
|
||||
"resolved": "https://registry.npmjs.org/goober/-/goober-2.1.14.tgz",
|
||||
"integrity": "sha512-4UpC0NdGyAFqLNPnhCT2iHpza2q+RAY3GV85a/mRPdzyPQMsj0KmMMuetdIkzWRbJ+Hgau1EZztq8ImmiMGhsg==",
|
||||
"dev": true,
|
||||
"peerDependencies": {
|
||||
"csstype": "^3.0.10"
|
||||
}
|
||||
},
|
||||
"node_modules/gopd": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz",
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
"@radix-ui/react-alert-dialog": "^1.0.5",
|
||||
"@radix-ui/react-dialog": "^1.0.5",
|
||||
"@radix-ui/react-form": "^0.0.3",
|
||||
"@tanstack/react-router": "^1.16.6",
|
||||
"@tanstack/react-router": "^1.20.1",
|
||||
"@types/ua-parser-js": "^0.7.39",
|
||||
"@urql/core": "^4.2.3",
|
||||
"@urql/devtools": "^2.0.3",
|
||||
@@ -56,8 +56,8 @@
|
||||
"@storybook/addon-essentials": "^7.6.17",
|
||||
"@storybook/react": "^7.6.17",
|
||||
"@storybook/react-vite": "^7.6.17",
|
||||
"@tanstack/router-devtools": "^1.16.6",
|
||||
"@tanstack/router-vite-plugin": "^1.16.5",
|
||||
"@tanstack/router-devtools": "^1.20.1",
|
||||
"@tanstack/router-vite-plugin": "^1.20.2",
|
||||
"@testing-library/react": "^14.2.1",
|
||||
"@types/node": "^20.11.24",
|
||||
"@types/react": "^18.2.61",
|
||||
|
||||
@@ -12,7 +12,11 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
import { LinkComponent, useLinkProps } from "@tanstack/react-router";
|
||||
import {
|
||||
UseLinkPropsOptions,
|
||||
createLink,
|
||||
useLinkProps,
|
||||
} from "@tanstack/react-router";
|
||||
import { Button } from "@vector-im/compound-web";
|
||||
import { forwardRef } from "react";
|
||||
|
||||
@@ -23,24 +27,15 @@ type Props = {
|
||||
destructive?: boolean;
|
||||
};
|
||||
|
||||
export const ButtonLink: LinkComponent<Props> = forwardRef<
|
||||
// XXX: createLink is broken, so we work around it by using useLinkProps directly
|
||||
export const ButtonLink = forwardRef<
|
||||
HTMLAnchorElement,
|
||||
Parameters<typeof useLinkProps>[0] & Props
|
||||
>(({ children, kind, size, destructive, Icon, ...props }, ref) => {
|
||||
Props & UseLinkPropsOptions
|
||||
>(({ children, ...props }, ref) => {
|
||||
const linkProps = useLinkProps(props);
|
||||
|
||||
return (
|
||||
<Button
|
||||
as="a"
|
||||
kind={kind}
|
||||
size={size}
|
||||
destructive={destructive}
|
||||
disabled={props.disabled}
|
||||
Icon={Icon}
|
||||
ref={ref}
|
||||
{...linkProps}
|
||||
>
|
||||
<Button as="a" {...linkProps} ref={ref}>
|
||||
{children}
|
||||
</Button>
|
||||
);
|
||||
}) as LinkComponent<Props>;
|
||||
}) as ReturnType<typeof createLink<typeof Button>>;
|
||||
|
||||
@@ -12,23 +12,13 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
import { LinkComponent, useLinkProps } from "@tanstack/react-router";
|
||||
import { createLink, useLinkProps } from "@tanstack/react-router";
|
||||
import { Link as CompoundLink } from "@vector-im/compound-web";
|
||||
import { forwardRef } from "react";
|
||||
|
||||
type Props = {
|
||||
kind?: "primary" | "critical";
|
||||
};
|
||||
|
||||
export const Link: LinkComponent<Props> = forwardRef<
|
||||
HTMLAnchorElement,
|
||||
Parameters<typeof useLinkProps>[0] & Props
|
||||
>(({ children, kind, ...props }, ref) => {
|
||||
export const Link: ReturnType<typeof createLink<typeof CompoundLink>> = ({
|
||||
children,
|
||||
...props
|
||||
}: Parameters<typeof useLinkProps>[0]) => {
|
||||
const linkProps = useLinkProps(props);
|
||||
|
||||
return (
|
||||
<CompoundLink kind={kind} ref={ref} {...linkProps}>
|
||||
{children}
|
||||
</CompoundLink>
|
||||
);
|
||||
}) as LinkComponent<Props>;
|
||||
return <CompoundLink {...linkProps}>{children}</CompoundLink>;
|
||||
};
|
||||
|
||||
@@ -12,9 +12,13 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
import { LinkComponent, useLinkProps } from "@tanstack/react-router";
|
||||
import {
|
||||
UseLinkPropsOptions,
|
||||
createLink,
|
||||
useLinkProps,
|
||||
} from "@tanstack/react-router";
|
||||
import cx from "classnames";
|
||||
import { forwardRef } from "react";
|
||||
import { AnchorHTMLAttributes, forwardRef } from "react";
|
||||
|
||||
import { DeviceType } from "../../gql/graphql";
|
||||
import ClientAvatar from "../Session/ClientAvatar";
|
||||
@@ -26,28 +30,35 @@ export const Root: React.FC<React.PropsWithChildren> = ({ children }) => (
|
||||
<section className={styles.sessionCardRoot}>{children}</section>
|
||||
);
|
||||
|
||||
// XXX: createLink is broken, so we work around it by using useLinkProps directly
|
||||
type BodyProps = React.PropsWithChildren<{
|
||||
disabled?: boolean;
|
||||
compact?: boolean;
|
||||
}>;
|
||||
export const LinkBody: LinkComponent = forwardRef<
|
||||
export const LinkBody = forwardRef<
|
||||
HTMLAnchorElement,
|
||||
Parameters<typeof useLinkProps>[0] & BodyProps
|
||||
BodyProps & UseLinkPropsOptions
|
||||
>(({ children, disabled, compact, ...props }, ref) => {
|
||||
const linkProps = useLinkProps({
|
||||
className: cx(
|
||||
styles.sessionCard,
|
||||
compact && styles.compact,
|
||||
disabled && styles.disabled,
|
||||
),
|
||||
...props,
|
||||
});
|
||||
const { className, ...linkProps } = useLinkProps({ disabled, ...props });
|
||||
return (
|
||||
<a ref={ref} {...linkProps}>
|
||||
<a
|
||||
className={cx(
|
||||
className,
|
||||
styles.sessionCard,
|
||||
compact && styles.compact,
|
||||
disabled && styles.disabled,
|
||||
)}
|
||||
{...linkProps}
|
||||
ref={ref}
|
||||
>
|
||||
{children}
|
||||
</a>
|
||||
);
|
||||
}) as LinkComponent;
|
||||
}) as ReturnType<
|
||||
typeof createLink<
|
||||
React.FC<BodyProps & AnchorHTMLAttributes<HTMLAnchorElement>>
|
||||
>
|
||||
>;
|
||||
|
||||
export const Body: React.FC<BodyProps> = ({ children, compact, disabled }) => (
|
||||
<div
|
||||
|
||||
@@ -47,7 +47,7 @@ const BrowserSessionsOverview: React.FC<{
|
||||
})}
|
||||
</Body>
|
||||
</div>
|
||||
<Link to="/sessions/browsers">
|
||||
<Link to="/sessions/browsers" search={{ first: 6 }}>
|
||||
{t("frontend.browser_sessions_overview.view_all_button")}
|
||||
</Link>
|
||||
</Block>
|
||||
|
||||
@@ -22,7 +22,7 @@ exports[`BrowserSessionsOverview > renders with no browser sessions 1`] = `
|
||||
<a
|
||||
class="_link_1mzip_17"
|
||||
data-kind="primary"
|
||||
href="/sessions/browsers"
|
||||
href="/sessions/browsers?first=6"
|
||||
rel="noreferrer noopener"
|
||||
>
|
||||
View all
|
||||
@@ -53,7 +53,7 @@ exports[`BrowserSessionsOverview > renders with sessions 1`] = `
|
||||
<a
|
||||
class="_link_1mzip_17"
|
||||
data-kind="primary"
|
||||
href="/sessions/browsers"
|
||||
href="/sessions/browsers?first=6"
|
||||
rel="noreferrer noopener"
|
||||
>
|
||||
View all
|
||||
|
||||
@@ -5,13 +5,14 @@ exports[`<CompatSession /> > renders a finished session 1`] = `
|
||||
className="_sessionCardRoot_e2909e"
|
||||
>
|
||||
<a
|
||||
aria-disabled={true}
|
||||
className="_sessionCard_e2909e _disabled_e2909e"
|
||||
href="/sessions/session-id"
|
||||
onClick={[Function]}
|
||||
onFocus={[Function]}
|
||||
onMouseEnter={[Function]}
|
||||
onMouseLeave={[Function]}
|
||||
onTouchStart={[Function]}
|
||||
role="link"
|
||||
style={{}}
|
||||
>
|
||||
<header
|
||||
|
||||
@@ -5,13 +5,14 @@ exports[`<OAuth2Session /> > renders a finished session 1`] = `
|
||||
className="_sessionCardRoot_e2909e"
|
||||
>
|
||||
<a
|
||||
aria-disabled={true}
|
||||
className="_sessionCard_e2909e _disabled_e2909e"
|
||||
href="/sessions/session-id"
|
||||
onClick={[Function]}
|
||||
onFocus={[Function]}
|
||||
onMouseEnter={[Function]}
|
||||
onMouseLeave={[Function]}
|
||||
onTouchStart={[Function]}
|
||||
role="link"
|
||||
style={{}}
|
||||
>
|
||||
<header
|
||||
@@ -198,13 +199,14 @@ exports[`<OAuth2Session /> > renders correct icon for a native session 1`] = `
|
||||
className="_sessionCardRoot_e2909e"
|
||||
>
|
||||
<a
|
||||
aria-disabled={true}
|
||||
className="_sessionCard_e2909e _disabled_e2909e"
|
||||
href="/sessions/session-id"
|
||||
onClick={[Function]}
|
||||
onFocus={[Function]}
|
||||
onMouseEnter={[Function]}
|
||||
onMouseLeave={[Function]}
|
||||
onTouchStart={[Function]}
|
||||
role="link"
|
||||
style={{}}
|
||||
>
|
||||
<header
|
||||
|
||||
@@ -49,6 +49,9 @@ const actionSchema = z
|
||||
])
|
||||
.catch({ action: undefined });
|
||||
|
||||
// XXX: we probably shouldn't have to specify the search parameters on /sessions/
|
||||
const PAGE_SIZE = 6;
|
||||
|
||||
export const Route = createRootRouteWithContext<{
|
||||
client: Client;
|
||||
}>()({
|
||||
@@ -62,7 +65,7 @@ export const Route = createRootRouteWithContext<{
|
||||
|
||||
case "sessions_list":
|
||||
case "org.matrix.sessions_list":
|
||||
throw redirect({ to: "/sessions" });
|
||||
throw redirect({ to: "/sessions/", search: { last: PAGE_SIZE } });
|
||||
|
||||
case "session_view":
|
||||
case "org.matrix.session_view":
|
||||
@@ -71,7 +74,7 @@ export const Route = createRootRouteWithContext<{
|
||||
to: "/devices/$id",
|
||||
params: { id: search.device_id },
|
||||
});
|
||||
throw redirect({ to: "/sessions" });
|
||||
throw redirect({ to: "/sessions/", search: { last: PAGE_SIZE } });
|
||||
|
||||
case "session_end":
|
||||
case "org.matrix.session_end":
|
||||
@@ -80,11 +83,11 @@ export const Route = createRootRouteWithContext<{
|
||||
to: "/devices/$id",
|
||||
params: { id: search.device_id },
|
||||
});
|
||||
throw redirect({ to: "/sessions" });
|
||||
throw redirect({ to: "/sessions/", search: { last: PAGE_SIZE } });
|
||||
|
||||
case "org.matrix.cross_signing_reset":
|
||||
throw redirect({
|
||||
to: "/reset-cross-signing",
|
||||
to: "/reset-cross-signing/",
|
||||
search: { deepLink: true },
|
||||
});
|
||||
}
|
||||
|
||||
@@ -66,7 +66,7 @@ function NotFound(): React.ReactElement {
|
||||
title={t("frontend.session_detail.alert.title", { deviceId: id })}
|
||||
>
|
||||
{t("frontend.session_detail.alert.text")}
|
||||
<Link from={Route.fullPath} to="..">
|
||||
<Link from={Route.fullPath} to=".." search={{ first: 6 }}>
|
||||
{t("frontend.session_detail.alert.button")}
|
||||
</Link>
|
||||
</Alert>
|
||||
|
||||
@@ -133,7 +133,7 @@ function BrowserSessions(): React.ReactElement {
|
||||
size="sm"
|
||||
disabled={!forwardPage}
|
||||
to={Route.fullPath}
|
||||
search={forwardPage}
|
||||
search={forwardPage || pagination}
|
||||
>
|
||||
{t("common.previous")}
|
||||
</ButtonLink>
|
||||
@@ -146,7 +146,7 @@ function BrowserSessions(): React.ReactElement {
|
||||
size="sm"
|
||||
disabled={!backwardPage}
|
||||
to={Route.fullPath}
|
||||
search={backwardPage}
|
||||
search={backwardPage || pagination}
|
||||
>
|
||||
{t("common.next")}
|
||||
</ButtonLink>
|
||||
|
||||
@@ -176,7 +176,7 @@ function Sessions(): React.ReactElement {
|
||||
size="sm"
|
||||
disabled={!forwardPage}
|
||||
to={Route.fullPath}
|
||||
search={forwardPage}
|
||||
search={forwardPage || pagination}
|
||||
>
|
||||
{t("common.previous")}
|
||||
</ButtonLink>
|
||||
@@ -189,7 +189,7 @@ function Sessions(): React.ReactElement {
|
||||
size="sm"
|
||||
disabled={!backwardPage}
|
||||
to={Route.fullPath}
|
||||
search={backwardPage}
|
||||
search={backwardPage || pagination}
|
||||
>
|
||||
{t("common.next")}
|
||||
</ButtonLink>
|
||||
|
||||
@@ -86,7 +86,9 @@ function NotFound(): React.ReactElement {
|
||||
title={t("frontend.session_detail.alert.title", { deviceId })}
|
||||
>
|
||||
{t("frontend.session_detail.alert.text")}
|
||||
<Link to="/sessions">{t("frontend.session_detail.alert.button")}</Link>
|
||||
<Link to="/sessions" search={{ first: 6 }}>
|
||||
{t("frontend.session_detail.alert.button")}
|
||||
</Link>
|
||||
</Alert>
|
||||
</Layout>
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user