You've already forked authentication-service
mirror of
https://github.com/matrix-org/matrix-authentication-service.git
synced 2025-07-29 22:01:14 +03:00
frontend: Migrate to jotai and urql
This cuts the bundle size by 50% and makes it easier to reason about state. It removes the usage of react-router-dom and replaces it with a simple router atom based on jotai-location. Since the screens will be quite simple, I don't expect that we'll need the advanced caching features of react-relay, hence the switch to urql.
This commit is contained in:
@ -1,6 +1,5 @@
|
||||
import { ArgTypes, Decorator, Parameters } from "@storybook/react";
|
||||
import { useLayoutEffect } from "react";
|
||||
import { createMemoryRouter, RouterProvider } from "react-router-dom";
|
||||
import "../src/index.css";
|
||||
|
||||
export const parameters: Parameters = {
|
||||
@ -60,15 +59,4 @@ const withThemeProvider: Decorator = (Story, context) => {
|
||||
);
|
||||
};
|
||||
|
||||
const withRouter: Decorator = (Story, _context) => {
|
||||
const router = createMemoryRouter([
|
||||
{
|
||||
path: "/*",
|
||||
element: <Story />,
|
||||
},
|
||||
]);
|
||||
|
||||
return <RouterProvider router={router} />;
|
||||
};
|
||||
|
||||
export const decorators: Decorator[] = [withThemeProvider, withRouter];
|
||||
export const decorators: Decorator[] = [withThemeProvider];
|
||||
|
16
frontend/codegen.ts
Normal file
16
frontend/codegen.ts
Normal file
@ -0,0 +1,16 @@
|
||||
import { CodegenConfig } from "@graphql-codegen/cli";
|
||||
|
||||
const config: CodegenConfig = {
|
||||
schema: "./schema.graphql",
|
||||
documents: ["src/**/*.tsx", "!src/gql/**/*"],
|
||||
ignoreNoDocuments: true, // for better experience with the watcher
|
||||
generates: {
|
||||
"./src/gql/": {
|
||||
preset: "client",
|
||||
plugins: [],
|
||||
},
|
||||
},
|
||||
hooks: { afterAllFileWrite: ["eslint --fix"] },
|
||||
};
|
||||
|
||||
export default config;
|
2136
frontend/package-lock.json
generated
2136
frontend/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@ -5,9 +5,8 @@
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
"generate": "relay-compiler && eslint --fix .",
|
||||
"lint": "relay-compiler --validate && eslint . && tsc",
|
||||
"relay": "relay-compiler",
|
||||
"generate": "graphql-codegen && eslint --fix .",
|
||||
"lint": "graphql-codegen && eslint . && tsc",
|
||||
"build": "npm run lint && vite build --base=./ && npm run build:templates",
|
||||
"build:templates": "tailwindcss --postcss --minify --config ./tailwind.templates.config.cjs -o dist/tailwind.css",
|
||||
"preview": "vite preview",
|
||||
@ -17,14 +16,18 @@
|
||||
"build-storybook": "storybook build"
|
||||
},
|
||||
"dependencies": {
|
||||
"@urql/core": "^3.2.2",
|
||||
"date-fns": "^2.29.3",
|
||||
"graphql": "^16.6.0",
|
||||
"jotai": "^2.0.3",
|
||||
"jotai-location": "^0.5.1",
|
||||
"jotai-urql": "^0.5.0",
|
||||
"react": "^18.2.0",
|
||||
"react-dom": "^18.2.0",
|
||||
"react-relay": "^15.0.0",
|
||||
"react-router-dom": "^6.9.0",
|
||||
"relay-runtime": "^15.0.0"
|
||||
"react-dom": "^18.2.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@graphql-codegen/cli": "^3.2.2",
|
||||
"@graphql-codegen/client-preset": "^2.1.1",
|
||||
"@graphql-eslint/eslint-plugin": "^3.16.1",
|
||||
"@storybook/addon-actions": "^7.0.0-rc.3",
|
||||
"@storybook/addon-backgrounds": "^7.0.0-rc.3",
|
||||
@ -40,10 +43,7 @@
|
||||
"@types/node": "^18.15.3",
|
||||
"@types/react": "^18.0.28",
|
||||
"@types/react-dom": "^18.0.11",
|
||||
"@types/react-relay": "^14.1.3",
|
||||
"@types/react-test-renderer": "^18.0.0",
|
||||
"@types/relay-runtime": "^14.1.9",
|
||||
"@types/relay-test-utils": "^14.1.0",
|
||||
"@vitejs/plugin-react": "^3.1.0",
|
||||
"@vitest/coverage-c8": "^0.29.3",
|
||||
"autoprefixer": "^10.4.14",
|
||||
@ -54,14 +54,12 @@
|
||||
"postcss": "^8.4.21",
|
||||
"prettier": "^2.8.4",
|
||||
"react-test-renderer": "^18.2.0",
|
||||
"relay-compiler": "^15.0.0",
|
||||
"relay-test-utils": "^15.0.0",
|
||||
"storybook": "^7.0.0-rc.3",
|
||||
"tailwindcss": "^3.2.7",
|
||||
"typescript": "^5.0.2",
|
||||
"vite": "^4.2.0",
|
||||
"vitest": "^0.29.3",
|
||||
"vite-plugin-eslint": "^1.8.1",
|
||||
"vite-plugin-relay-lite": "^0.4.3"
|
||||
"vite-plugin-graphql-codegen": "^3.1.0",
|
||||
"vitest": "^0.29.3"
|
||||
}
|
||||
}
|
||||
|
@ -1,11 +0,0 @@
|
||||
{
|
||||
"src": "./src",
|
||||
"schema": "./schema.graphql",
|
||||
"language": "typescript",
|
||||
"eagerEsModules": true,
|
||||
"exclude": [
|
||||
"**/node_modules/**",
|
||||
"**/__mocks__/**",
|
||||
"**/__generated__/**"
|
||||
]
|
||||
}
|
@ -1,74 +0,0 @@
|
||||
// Copyright 2022 The Matrix.org Foundation C.I.C.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
import {
|
||||
Environment,
|
||||
Network,
|
||||
RecordSource,
|
||||
Store,
|
||||
Variables,
|
||||
RequestParameters,
|
||||
CacheConfig,
|
||||
} from "relay-runtime";
|
||||
|
||||
async function fetchRelay(
|
||||
params: RequestParameters,
|
||||
variables: Variables,
|
||||
_cacheConfig: CacheConfig
|
||||
) {
|
||||
const response = await fetch("/graphql", {
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
body: JSON.stringify({
|
||||
query: params.text,
|
||||
variables,
|
||||
}),
|
||||
});
|
||||
|
||||
// Get the response as JSON
|
||||
const json = await response.json();
|
||||
|
||||
// GraphQL returns exceptions (for example, a missing required variable) in the "errors"
|
||||
// property of the response. If any exceptions occurred when processing the request,
|
||||
// throw an error to indicate to the developer what went wrong.
|
||||
if (Array.isArray(json.errors)) {
|
||||
console.log(json.errors);
|
||||
throw new Error(
|
||||
`Error fetching GraphQL query '${
|
||||
params.name
|
||||
}' with variables '${JSON.stringify(variables)}': ${JSON.stringify(
|
||||
json.errors
|
||||
)}`
|
||||
);
|
||||
}
|
||||
|
||||
// Otherwise, return the full payload.
|
||||
return json;
|
||||
}
|
||||
|
||||
// Export a singleton instance of Relay Environment configured with our network layer:
|
||||
const environment = new Environment({
|
||||
network: Network.create(fetchRelay),
|
||||
store: new Store(new RecordSource(), {
|
||||
// This property tells Relay to not immediately clear its cache when the user
|
||||
// navigates around the app. Relay will hold onto the specified number of
|
||||
// query results, allowing the user to return to recently visited pages
|
||||
// and reusing cached data if its available/fresh.
|
||||
gcReleaseBufferSize: 10,
|
||||
}),
|
||||
});
|
||||
|
||||
export default environment;
|
@ -12,52 +12,153 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
import { lazy, Suspense } from "react";
|
||||
import { createBrowserRouter, Outlet, RouterProvider } from "react-router-dom";
|
||||
import { lazy, Suspense, useTransition } from "react";
|
||||
import { atomWithLocation } from "jotai-location";
|
||||
import { atom, useAtomValue, useSetAtom } from "jotai";
|
||||
|
||||
import Layout from "./components/Layout";
|
||||
import LoadingSpinner from "./components/LoadingSpinner";
|
||||
|
||||
type Location = {
|
||||
pathname?: string;
|
||||
searchParams?: URLSearchParams;
|
||||
};
|
||||
|
||||
type HomeRoute = { type: "home" };
|
||||
type DumbRoute = { type: "dumb" };
|
||||
type OAuth2ClientRoute = { type: "client"; id: string };
|
||||
type BrowserSessionRoute = { type: "session"; id: string };
|
||||
type UnknownRoute = { type: "unknown"; segments: string[] };
|
||||
|
||||
export type Route =
|
||||
| HomeRoute
|
||||
| DumbRoute
|
||||
| OAuth2ClientRoute
|
||||
| BrowserSessionRoute
|
||||
| UnknownRoute;
|
||||
|
||||
const routeToSegments = (route: Route): string[] => {
|
||||
switch (route.type) {
|
||||
case "home":
|
||||
return [];
|
||||
case "dumb":
|
||||
return ["dumb"];
|
||||
case "client":
|
||||
return ["client", route.id];
|
||||
case "session":
|
||||
return ["session", route.id];
|
||||
case "unknown":
|
||||
return route.segments;
|
||||
}
|
||||
};
|
||||
|
||||
const segmentsToRoute = (segments: string[]): Route => {
|
||||
if (segments.length === 0 || (segments.length === 1 && segments[0] === "")) {
|
||||
return { type: "home" };
|
||||
}
|
||||
|
||||
if (segments.length === 1 && segments[0] === "dumb") {
|
||||
return { type: "dumb" };
|
||||
}
|
||||
|
||||
if (segments.length === 2 && segments[0] === "client") {
|
||||
return { type: "client", id: segments[1] };
|
||||
}
|
||||
|
||||
if (segments.length === 2 && segments[0] === "session") {
|
||||
return { type: "session", id: segments[1] };
|
||||
}
|
||||
|
||||
return { type: "unknown", segments };
|
||||
};
|
||||
|
||||
const routeToPath = (route: Route): string =>
|
||||
routeToSegments(route)
|
||||
.map((part) => encodeURIComponent(part))
|
||||
.join("/");
|
||||
|
||||
const pathToRoute = (path: string): Route => {
|
||||
const segments = path.split("/").map(decodeURIComponent);
|
||||
return segmentsToRoute(segments);
|
||||
};
|
||||
|
||||
const locationToRoute = (location: Location): Route => {
|
||||
if (
|
||||
!location.pathname ||
|
||||
!location.pathname.startsWith(window.APP_CONFIG.root)
|
||||
) {
|
||||
throw new Error("Invalid location");
|
||||
}
|
||||
|
||||
const path = location.pathname.slice(window.APP_CONFIG.root.length);
|
||||
return pathToRoute(path);
|
||||
};
|
||||
|
||||
const locationAtom = atomWithLocation();
|
||||
export const routeAtom = atom(
|
||||
(get) => locationToRoute(get(locationAtom)),
|
||||
(_get, set, value: Route) => {
|
||||
set(locationAtom, {
|
||||
pathname: window.APP_CONFIG.root + routeToPath(value),
|
||||
});
|
||||
}
|
||||
);
|
||||
|
||||
const Home = lazy(() => import("./pages/Home"));
|
||||
const OAuth2Client = lazy(() => import("./pages/OAuth2Client"));
|
||||
const BrowserSession = lazy(() => import("./pages/BrowserSession"));
|
||||
|
||||
export const router = createBrowserRouter(
|
||||
[
|
||||
{
|
||||
path: "/",
|
||||
element: (
|
||||
<Layout>
|
||||
<Suspense fallback={<LoadingSpinner />}>
|
||||
<Outlet />
|
||||
</Suspense>
|
||||
</Layout>
|
||||
),
|
||||
children: [
|
||||
{
|
||||
index: true,
|
||||
element: <Home />,
|
||||
},
|
||||
{
|
||||
path: "dumb",
|
||||
element: <>Hello from another dumb page.</>,
|
||||
},
|
||||
{
|
||||
path: "client/:id",
|
||||
element: <OAuth2Client />,
|
||||
},
|
||||
{
|
||||
path: "session/:id",
|
||||
element: <BrowserSession />,
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
{
|
||||
basename: window.APP_CONFIG.root,
|
||||
const InnerRouter: React.FC = () => {
|
||||
const route = useAtomValue(routeAtom);
|
||||
|
||||
switch (route.type) {
|
||||
case "home":
|
||||
return <Home />;
|
||||
case "client":
|
||||
return <OAuth2Client id={route.id} />;
|
||||
case "session":
|
||||
return <BrowserSession id={route.id} />;
|
||||
case "dumb":
|
||||
return <>Dumb route.</>;
|
||||
case "unknown":
|
||||
return <>Unknown route {JSON.stringify(route.segments)}</>;
|
||||
}
|
||||
};
|
||||
|
||||
const Router = () => (
|
||||
<Layout>
|
||||
<Suspense fallback={<LoadingSpinner />}>
|
||||
<InnerRouter />
|
||||
</Suspense>
|
||||
</Layout>
|
||||
);
|
||||
|
||||
const Router = () => <RouterProvider router={router} />;
|
||||
export const Link: React.FC<
|
||||
{
|
||||
route: Route;
|
||||
children: React.ReactNode;
|
||||
} & React.HTMLProps<HTMLAnchorElement>
|
||||
> = ({ route, children, ...props }) => {
|
||||
const path = routeToPath(route);
|
||||
const setRoute = useSetAtom(routeAtom);
|
||||
|
||||
// TODO: we should probably have more user control over this
|
||||
const [isPending, startTransition] = useTransition();
|
||||
|
||||
return (
|
||||
<a
|
||||
href={path}
|
||||
onClick={(e) => {
|
||||
e.preventDefault();
|
||||
startTransition(() => {
|
||||
setRoute(route);
|
||||
});
|
||||
}}
|
||||
{...props}
|
||||
>
|
||||
{isPending ? "Loading..." : children}
|
||||
</a>
|
||||
);
|
||||
};
|
||||
|
||||
export default Router;
|
||||
|
24
frontend/src/atoms.ts
Normal file
24
frontend/src/atoms.ts
Normal file
@ -0,0 +1,24 @@
|
||||
// Copyright 2023 The Matrix.org Foundation C.I.C.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
import type { ReactElement } from "react";
|
||||
import { useHydrateAtoms } from "jotai/utils";
|
||||
import { clientAtom } from "jotai-urql";
|
||||
|
||||
import { client } from "./graphql";
|
||||
|
||||
export const HydrateAtoms = ({ children }: { children: ReactElement }) => {
|
||||
useHydrateAtoms([[clientAtom, client]]);
|
||||
return children;
|
||||
};
|
@ -12,33 +12,30 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
import type { BrowserSession_session$key } from "./__generated__/BrowserSession_session.graphql";
|
||||
import { graphql, useFragment } from "react-relay";
|
||||
|
||||
import Block from "./Block";
|
||||
import { Body, Subtitle } from "./Typography";
|
||||
import DateTime from "./DateTime";
|
||||
import { Link } from "react-router-dom";
|
||||
import { Link } from "../Router";
|
||||
import { FragmentType, graphql, useFragment } from "../gql";
|
||||
|
||||
const FRAGMENT = graphql(/* GraphQL */ `
|
||||
fragment BrowserSession_session on BrowserSession {
|
||||
id
|
||||
createdAt
|
||||
lastAuthentication {
|
||||
id
|
||||
createdAt
|
||||
}
|
||||
}
|
||||
`);
|
||||
|
||||
type Props = {
|
||||
session: BrowserSession_session$key;
|
||||
session: FragmentType<typeof FRAGMENT>;
|
||||
isCurrent: boolean;
|
||||
};
|
||||
|
||||
const BrowserSession: React.FC<Props> = ({ session, isCurrent }) => {
|
||||
const data = useFragment(
|
||||
graphql`
|
||||
fragment BrowserSession_session on BrowserSession {
|
||||
id
|
||||
createdAt
|
||||
lastAuthentication {
|
||||
id
|
||||
createdAt
|
||||
}
|
||||
}
|
||||
`,
|
||||
session
|
||||
);
|
||||
const data = useFragment(FRAGMENT, session);
|
||||
|
||||
const lastAuthentication = data.lastAuthentication?.createdAt;
|
||||
const createdAt = data.createdAt;
|
||||
@ -48,7 +45,7 @@ const BrowserSession: React.FC<Props> = ({ session, isCurrent }) => {
|
||||
{isCurrent && <Subtitle>Current session</Subtitle>}
|
||||
<Body>
|
||||
<Link
|
||||
to={`/session/${data.id}`}
|
||||
route={{ type: "session", id: data.id }}
|
||||
className="text-links hover:text-links/75"
|
||||
>
|
||||
Started: <DateTime datetime={createdAt} />
|
||||
|
@ -12,38 +12,32 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
import { graphql, usePaginationFragment } from "react-relay";
|
||||
import BlockList from "./BlockList";
|
||||
import BrowserSession from "./BrowserSession";
|
||||
import Button from "./Button";
|
||||
import { Title } from "./Typography";
|
||||
import { FragmentType, graphql, useFragment } from "../gql";
|
||||
|
||||
import { BrowserSessionList_user$key } from "./__generated__/BrowserSessionList_user.graphql";
|
||||
const FRAGMENT = graphql(/* GraphQL */ `
|
||||
fragment BrowserSessionList_user on User {
|
||||
browserSessions(first: $count, after: $cursor) {
|
||||
edges {
|
||||
cursor
|
||||
node {
|
||||
id
|
||||
...BrowserSession_session
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
`);
|
||||
|
||||
type Props = {
|
||||
user: BrowserSessionList_user$key;
|
||||
user: FragmentType<typeof FRAGMENT>;
|
||||
currentSessionId: string;
|
||||
};
|
||||
|
||||
const BrowserSessionList: React.FC<Props> = ({ user, currentSessionId }) => {
|
||||
const { data, loadNext, hasNext } = usePaginationFragment(
|
||||
graphql`
|
||||
fragment BrowserSessionList_user on User
|
||||
@refetchable(queryName: "BrowserSessionListQuery") {
|
||||
browserSessions(first: $count, after: $cursor)
|
||||
@connection(key: "BrowserSessionList_user_browserSessions") {
|
||||
edges {
|
||||
cursor
|
||||
node {
|
||||
id
|
||||
...BrowserSession_session
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
`,
|
||||
user
|
||||
);
|
||||
const data = useFragment(FRAGMENT, user);
|
||||
|
||||
return (
|
||||
<BlockList>
|
||||
@ -55,7 +49,6 @@ const BrowserSessionList: React.FC<Props> = ({ user, currentSessionId }) => {
|
||||
isCurrent={n.node.id === currentSessionId}
|
||||
/>
|
||||
))}
|
||||
{hasNext && <Button onClick={() => loadNext(2)}>Load more</Button>}
|
||||
</BlockList>
|
||||
);
|
||||
};
|
||||
|
@ -12,33 +12,31 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
import type { CompatSsoLogin_login$key } from "./__generated__/CompatSsoLogin_login.graphql";
|
||||
import { graphql, useFragment } from "react-relay";
|
||||
import Block from "./Block";
|
||||
import { Body, Bold, Code } from "./Typography";
|
||||
import DateTime from "./DateTime";
|
||||
import { FragmentType, graphql, useFragment } from "../gql";
|
||||
|
||||
const FRAGMENT = graphql(/* GraphQL */ `
|
||||
fragment CompatSsoLogin_login on CompatSsoLogin {
|
||||
id
|
||||
redirectUri
|
||||
createdAt
|
||||
session {
|
||||
id
|
||||
createdAt
|
||||
deviceId
|
||||
finishedAt
|
||||
}
|
||||
}
|
||||
`);
|
||||
|
||||
type Props = {
|
||||
login: CompatSsoLogin_login$key;
|
||||
login: FragmentType<typeof FRAGMENT>;
|
||||
};
|
||||
|
||||
const CompatSsoLogin: React.FC<Props> = ({ login }) => {
|
||||
const data = useFragment(
|
||||
graphql`
|
||||
fragment CompatSsoLogin_login on CompatSsoLogin {
|
||||
id
|
||||
redirectUri
|
||||
createdAt
|
||||
session {
|
||||
id
|
||||
createdAt
|
||||
deviceId
|
||||
finishedAt
|
||||
}
|
||||
}
|
||||
`,
|
||||
login
|
||||
);
|
||||
const data = useFragment(FRAGMENT, login);
|
||||
|
||||
let info = null;
|
||||
if (data.session) {
|
||||
|
@ -12,35 +12,30 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
import { graphql, usePaginationFragment } from "react-relay";
|
||||
import BlockList from "./BlockList";
|
||||
import Button from "./Button";
|
||||
import CompatSsoLogin from "./CompatSsoLogin";
|
||||
import { Title } from "./Typography";
|
||||
import { CompatSsoLoginList_user$key } from "./__generated__/CompatSsoLoginList_user.graphql";
|
||||
import { FragmentType, graphql, useFragment } from "../gql";
|
||||
|
||||
const FRAGMENT = graphql(/* GraphQL */ `
|
||||
fragment CompatSsoLoginList_user on User {
|
||||
compatSsoLogins(first: $count, after: $cursor) {
|
||||
edges {
|
||||
node {
|
||||
id
|
||||
...CompatSsoLogin_login
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
`);
|
||||
|
||||
type Props = {
|
||||
user: CompatSsoLoginList_user$key;
|
||||
user: FragmentType<typeof FRAGMENT>;
|
||||
};
|
||||
|
||||
const CompatSsoLoginList: React.FC<Props> = ({ user }) => {
|
||||
const { data, loadNext, hasNext } = usePaginationFragment(
|
||||
graphql`
|
||||
fragment CompatSsoLoginList_user on User
|
||||
@refetchable(queryName: "CompatSsoLoginListQuery") {
|
||||
compatSsoLogins(first: $count, after: $cursor)
|
||||
@connection(key: "CompatSsoLoginList_user_compatSsoLogins") {
|
||||
edges {
|
||||
node {
|
||||
id
|
||||
...CompatSsoLogin_login
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
`,
|
||||
user
|
||||
);
|
||||
const data = useFragment(FRAGMENT, user);
|
||||
|
||||
return (
|
||||
<BlockList>
|
||||
@ -48,7 +43,6 @@ const CompatSsoLoginList: React.FC<Props> = ({ user }) => {
|
||||
{data.compatSsoLogins.edges.map((n) => (
|
||||
<CompatSsoLogin login={n.node} key={n.node.id} />
|
||||
))}
|
||||
{hasNext && <Button onClick={() => loadNext(2)}>Load more</Button>}
|
||||
</BlockList>
|
||||
);
|
||||
};
|
||||
|
@ -19,8 +19,8 @@ const Layout: React.FC<{ children?: React.ReactNode }> = ({ children }) => {
|
||||
return (
|
||||
<div className="bg-grey-25 text-black-900 dark:bg-black-800 dark:text-white flex flex-col min-h-screen">
|
||||
<NavBar className="mx-auto px-3 py-4 container">
|
||||
<NavItem to="/">Home</NavItem>
|
||||
<NavItem to="/dumb">Dumb</NavItem>
|
||||
<NavItem route={{ type: "home" }}>Home</NavItem>
|
||||
<NavItem route={{ type: "dumb" }}>Dumb</NavItem>
|
||||
</NavBar>
|
||||
|
||||
<main className="mx-auto p-4 container">{children}</main>
|
||||
|
@ -12,25 +12,29 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
import { NavLink, To } from "react-router-dom";
|
||||
import { useAtomValue } from "jotai";
|
||||
import { Link, Route, routeAtom } from "../Router";
|
||||
|
||||
const NavItem: React.FC<{ to: To; children: React.ReactNode }> = ({
|
||||
to,
|
||||
const NavItem: React.FC<{ route: Route; children: React.ReactNode }> = ({
|
||||
route,
|
||||
children,
|
||||
}) => (
|
||||
<li className="m-1 mr-0">
|
||||
<NavLink
|
||||
to={to}
|
||||
className={({ isActive }) =>
|
||||
(isActive
|
||||
? "bg-accent text-white"
|
||||
: "hover:bg-grey-100 dark:hover:bg-grey-450 opacity-80 hover:opacity-100") +
|
||||
" p-2 rounded block uppercase font-medium"
|
||||
}
|
||||
>
|
||||
{children}
|
||||
</NavLink>
|
||||
</li>
|
||||
);
|
||||
}) => {
|
||||
const currentRoute = useAtomValue(routeAtom);
|
||||
return (
|
||||
<li className="m-1 mr-0">
|
||||
<Link
|
||||
route={route}
|
||||
className={
|
||||
(currentRoute.type === route.type
|
||||
? "bg-accent text-white"
|
||||
: "hover:bg-grey-100 dark:hover:bg-grey-450 opacity-80 hover:opacity-100") +
|
||||
" p-2 rounded block uppercase font-medium"
|
||||
}
|
||||
>
|
||||
{children}
|
||||
</Link>
|
||||
</li>
|
||||
);
|
||||
};
|
||||
|
||||
export default NavItem;
|
||||
|
@ -1,95 +0,0 @@
|
||||
// Copyright 2022 The Matrix.org Foundation C.I.C.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
import type { Meta, StoryObj } from "@storybook/react";
|
||||
import {
|
||||
graphql,
|
||||
RelayEnvironmentProvider,
|
||||
useLazyLoadQuery,
|
||||
} from "react-relay";
|
||||
import { createMockEnvironment, MockPayloadGenerator } from "relay-test-utils";
|
||||
|
||||
import OAuth2Session from "./OAuth2Session";
|
||||
import { OAuth2SessionStoriesQuery } from "./__generated__/OAuth2SessionStoriesQuery.graphql";
|
||||
|
||||
type TemplateProps = {
|
||||
scope: string;
|
||||
clientId: string;
|
||||
clientName: string;
|
||||
clientUri: string;
|
||||
};
|
||||
|
||||
const Template: React.FC<TemplateProps> = ({
|
||||
scope,
|
||||
clientId,
|
||||
clientName,
|
||||
clientUri,
|
||||
}) => {
|
||||
const environment = createMockEnvironment();
|
||||
environment.mock.queueOperationResolver((operation) =>
|
||||
MockPayloadGenerator.generate(operation, {
|
||||
Oauth2Session() {
|
||||
return {
|
||||
scope,
|
||||
};
|
||||
},
|
||||
|
||||
Oauth2Client() {
|
||||
return {
|
||||
clientId,
|
||||
clientName,
|
||||
clientUri,
|
||||
};
|
||||
},
|
||||
})
|
||||
);
|
||||
|
||||
const Render = () => {
|
||||
const data = useLazyLoadQuery<OAuth2SessionStoriesQuery>(
|
||||
graphql`
|
||||
query OAuth2SessionStoriesQuery @relay_test_operation {
|
||||
session: node(id: "test-id") {
|
||||
...OAuth2Session_session
|
||||
}
|
||||
}
|
||||
`,
|
||||
{}
|
||||
);
|
||||
|
||||
return <OAuth2Session session={data.session!!} />;
|
||||
};
|
||||
|
||||
return (
|
||||
<RelayEnvironmentProvider environment={environment}>
|
||||
<Render />
|
||||
</RelayEnvironmentProvider>
|
||||
);
|
||||
};
|
||||
|
||||
const meta = {
|
||||
title: "Components/OAuth 2.0 Session",
|
||||
component: Template,
|
||||
tags: ["autodocs"],
|
||||
args: {
|
||||
scope: "openid",
|
||||
clientId: "aaabbbcccdddeee",
|
||||
clientName: "My client",
|
||||
clientUri: "https://example.com/",
|
||||
},
|
||||
} satisfies Meta<typeof Template>;
|
||||
|
||||
export default meta;
|
||||
type Story = StoryObj<typeof Template>;
|
||||
|
||||
export const Basic: Story = {};
|
@ -12,38 +12,36 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
import type { OAuth2Session_session$key } from "./__generated__/OAuth2Session_session.graphql";
|
||||
import { graphql, useFragment } from "react-relay";
|
||||
import { Body, Bold, Code } from "./Typography";
|
||||
import Block from "./Block";
|
||||
import { Link } from "react-router-dom";
|
||||
import { Link } from "../Router";
|
||||
import { FragmentType, graphql, useFragment } from "../gql";
|
||||
|
||||
const FRAGMENT = graphql(/* GraphQL */ `
|
||||
fragment OAuth2Session_session on Oauth2Session {
|
||||
id
|
||||
scope
|
||||
client {
|
||||
id
|
||||
clientId
|
||||
clientName
|
||||
clientUri
|
||||
}
|
||||
}
|
||||
`);
|
||||
|
||||
type Props = {
|
||||
session: OAuth2Session_session$key;
|
||||
session: FragmentType<typeof FRAGMENT>;
|
||||
};
|
||||
|
||||
const OAuth2Session: React.FC<Props> = ({ session }) => {
|
||||
const data = useFragment(
|
||||
graphql`
|
||||
fragment OAuth2Session_session on Oauth2Session {
|
||||
id
|
||||
scope
|
||||
client {
|
||||
id
|
||||
clientId
|
||||
clientName
|
||||
clientUri
|
||||
}
|
||||
}
|
||||
`,
|
||||
session
|
||||
);
|
||||
const data = useFragment(FRAGMENT, session);
|
||||
|
||||
return (
|
||||
<Block>
|
||||
<Body>
|
||||
<Link
|
||||
to={`/client/${data.client.id}`}
|
||||
route={{ type: "client", id: data.client.id }}
|
||||
className="text-links hover:text-links/75"
|
||||
>
|
||||
Client ID: <Code>{data.client.clientId}</Code>
|
||||
|
@ -12,37 +12,32 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
import { graphql, usePaginationFragment } from "react-relay";
|
||||
import BlockList from "./BlockList";
|
||||
import Button from "./Button";
|
||||
import OAuth2Session from "./OAuth2Session";
|
||||
import { Title } from "./Typography";
|
||||
|
||||
import { OAuth2SessionList_user$key } from "./__generated__/OAuth2SessionList_user.graphql";
|
||||
import { FragmentType, graphql, useFragment } from "../gql";
|
||||
|
||||
const FRAGMENT = graphql(/* GraphQL */ `
|
||||
fragment OAuth2SessionList_user on User {
|
||||
oauth2Sessions(first: $count, after: $cursor) {
|
||||
edges {
|
||||
cursor
|
||||
node {
|
||||
id
|
||||
...OAuth2Session_session
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
`);
|
||||
|
||||
type Props = {
|
||||
user: OAuth2SessionList_user$key;
|
||||
user: FragmentType<typeof FRAGMENT>;
|
||||
};
|
||||
|
||||
const OAuth2SessionList: React.FC<Props> = ({ user }) => {
|
||||
const { data, loadNext, hasNext } = usePaginationFragment(
|
||||
graphql`
|
||||
fragment OAuth2SessionList_user on User
|
||||
@refetchable(queryName: "OAuth2SessionListQuery") {
|
||||
oauth2Sessions(first: $count, after: $cursor)
|
||||
@connection(key: "OAuth2SessionList_user_oauth2Sessions") {
|
||||
edges {
|
||||
cursor
|
||||
node {
|
||||
id
|
||||
...OAuth2Session_session
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
`,
|
||||
user
|
||||
);
|
||||
const data = useFragment(FRAGMENT, user);
|
||||
|
||||
return (
|
||||
<BlockList>
|
||||
@ -50,7 +45,6 @@ const OAuth2SessionList: React.FC<Props> = ({ user }) => {
|
||||
{data.oauth2Sessions.edges.map((n) => (
|
||||
<OAuth2Session key={n.cursor} session={n.node} />
|
||||
))}
|
||||
{hasNext && <Button onClick={() => loadNext(2)}>Load more</Button>}
|
||||
</BlockList>
|
||||
);
|
||||
};
|
||||
|
@ -1,244 +0,0 @@
|
||||
/**
|
||||
* @generated SignedSource<<2e2beb7aa6522ccc21b080d150de618a>>
|
||||
* @lightSyntaxTransform
|
||||
* @nogrep
|
||||
*/
|
||||
|
||||
/* tslint:disable */
|
||||
/* eslint-disable */
|
||||
// @ts-nocheck
|
||||
|
||||
import { ConcreteRequest, Query } from 'relay-runtime';
|
||||
import { FragmentRefs } from "relay-runtime";
|
||||
export type BrowserSessionListQuery$variables = {
|
||||
count?: number | null;
|
||||
cursor?: string | null;
|
||||
id: string;
|
||||
};
|
||||
export type BrowserSessionListQuery$data = {
|
||||
readonly node: {
|
||||
readonly " $fragmentSpreads": FragmentRefs<"BrowserSessionList_user">;
|
||||
} | null;
|
||||
};
|
||||
export type BrowserSessionListQuery = {
|
||||
response: BrowserSessionListQuery$data;
|
||||
variables: BrowserSessionListQuery$variables;
|
||||
};
|
||||
|
||||
const node: ConcreteRequest = (function(){
|
||||
var v0 = [
|
||||
{
|
||||
"defaultValue": null,
|
||||
"kind": "LocalArgument",
|
||||
"name": "count"
|
||||
},
|
||||
{
|
||||
"defaultValue": null,
|
||||
"kind": "LocalArgument",
|
||||
"name": "cursor"
|
||||
},
|
||||
{
|
||||
"defaultValue": null,
|
||||
"kind": "LocalArgument",
|
||||
"name": "id"
|
||||
}
|
||||
],
|
||||
v1 = [
|
||||
{
|
||||
"kind": "Variable",
|
||||
"name": "id",
|
||||
"variableName": "id"
|
||||
}
|
||||
],
|
||||
v2 = {
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "__typename",
|
||||
"storageKey": null
|
||||
},
|
||||
v3 = {
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "id",
|
||||
"storageKey": null
|
||||
},
|
||||
v4 = [
|
||||
{
|
||||
"kind": "Variable",
|
||||
"name": "after",
|
||||
"variableName": "cursor"
|
||||
},
|
||||
{
|
||||
"kind": "Variable",
|
||||
"name": "first",
|
||||
"variableName": "count"
|
||||
}
|
||||
],
|
||||
v5 = {
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "createdAt",
|
||||
"storageKey": null
|
||||
};
|
||||
return {
|
||||
"fragment": {
|
||||
"argumentDefinitions": (v0/*: any*/),
|
||||
"kind": "Fragment",
|
||||
"metadata": null,
|
||||
"name": "BrowserSessionListQuery",
|
||||
"selections": [
|
||||
{
|
||||
"alias": null,
|
||||
"args": (v1/*: any*/),
|
||||
"concreteType": null,
|
||||
"kind": "LinkedField",
|
||||
"name": "node",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
{
|
||||
"args": null,
|
||||
"kind": "FragmentSpread",
|
||||
"name": "BrowserSessionList_user"
|
||||
}
|
||||
],
|
||||
"storageKey": null
|
||||
}
|
||||
],
|
||||
"type": "RootQuery",
|
||||
"abstractKey": null
|
||||
},
|
||||
"kind": "Request",
|
||||
"operation": {
|
||||
"argumentDefinitions": (v0/*: any*/),
|
||||
"kind": "Operation",
|
||||
"name": "BrowserSessionListQuery",
|
||||
"selections": [
|
||||
{
|
||||
"alias": null,
|
||||
"args": (v1/*: any*/),
|
||||
"concreteType": null,
|
||||
"kind": "LinkedField",
|
||||
"name": "node",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
(v2/*: any*/),
|
||||
(v3/*: any*/),
|
||||
{
|
||||
"kind": "InlineFragment",
|
||||
"selections": [
|
||||
{
|
||||
"alias": null,
|
||||
"args": (v4/*: any*/),
|
||||
"concreteType": "BrowserSessionConnection",
|
||||
"kind": "LinkedField",
|
||||
"name": "browserSessions",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"concreteType": "BrowserSessionEdge",
|
||||
"kind": "LinkedField",
|
||||
"name": "edges",
|
||||
"plural": true,
|
||||
"selections": [
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "cursor",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"concreteType": "BrowserSession",
|
||||
"kind": "LinkedField",
|
||||
"name": "node",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
(v3/*: any*/),
|
||||
(v5/*: any*/),
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"concreteType": "Authentication",
|
||||
"kind": "LinkedField",
|
||||
"name": "lastAuthentication",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
(v3/*: any*/),
|
||||
(v5/*: any*/)
|
||||
],
|
||||
"storageKey": null
|
||||
},
|
||||
(v2/*: any*/)
|
||||
],
|
||||
"storageKey": null
|
||||
}
|
||||
],
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"concreteType": "PageInfo",
|
||||
"kind": "LinkedField",
|
||||
"name": "pageInfo",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "endCursor",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "hasNextPage",
|
||||
"storageKey": null
|
||||
}
|
||||
],
|
||||
"storageKey": null
|
||||
}
|
||||
],
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": (v4/*: any*/),
|
||||
"filters": null,
|
||||
"handle": "connection",
|
||||
"key": "BrowserSessionList_user_browserSessions",
|
||||
"kind": "LinkedHandle",
|
||||
"name": "browserSessions"
|
||||
}
|
||||
],
|
||||
"type": "User",
|
||||
"abstractKey": null
|
||||
}
|
||||
],
|
||||
"storageKey": null
|
||||
}
|
||||
]
|
||||
},
|
||||
"params": {
|
||||
"cacheID": "c05f614c382cae0bed080006b43f14f3",
|
||||
"id": null,
|
||||
"metadata": {},
|
||||
"name": "BrowserSessionListQuery",
|
||||
"operationKind": "query",
|
||||
"text": "query BrowserSessionListQuery(\n $count: Int\n $cursor: String\n $id: ID!\n) {\n node(id: $id) {\n __typename\n ...BrowserSessionList_user\n id\n }\n}\n\nfragment BrowserSessionList_user on User {\n browserSessions(first: $count, after: $cursor) {\n edges {\n cursor\n node {\n id\n ...BrowserSession_session\n __typename\n }\n }\n pageInfo {\n endCursor\n hasNextPage\n }\n }\n id\n}\n\nfragment BrowserSession_session on BrowserSession {\n id\n createdAt\n lastAuthentication {\n id\n createdAt\n }\n}\n"
|
||||
}
|
||||
};
|
||||
})();
|
||||
|
||||
(node as any).hash = "5f21c429aa98b854c17d3f9eb83b81d8";
|
||||
|
||||
export default node;
|
@ -1,170 +0,0 @@
|
||||
/**
|
||||
* @generated SignedSource<<3b7505958556a142e2d9926ae631f0e0>>
|
||||
* @lightSyntaxTransform
|
||||
* @nogrep
|
||||
*/
|
||||
|
||||
/* tslint:disable */
|
||||
/* eslint-disable */
|
||||
// @ts-nocheck
|
||||
|
||||
import { ReaderFragment, RefetchableFragment } from 'relay-runtime';
|
||||
import { FragmentRefs } from "relay-runtime";
|
||||
export type BrowserSessionList_user$data = {
|
||||
readonly browserSessions: {
|
||||
readonly edges: ReadonlyArray<{
|
||||
readonly cursor: string;
|
||||
readonly node: {
|
||||
readonly id: string;
|
||||
readonly " $fragmentSpreads": FragmentRefs<"BrowserSession_session">;
|
||||
};
|
||||
}>;
|
||||
};
|
||||
readonly id: string;
|
||||
readonly " $fragmentType": "BrowserSessionList_user";
|
||||
};
|
||||
export type BrowserSessionList_user$key = {
|
||||
readonly " $data"?: BrowserSessionList_user$data;
|
||||
readonly " $fragmentSpreads": FragmentRefs<"BrowserSessionList_user">;
|
||||
};
|
||||
|
||||
import BrowserSessionListQuery_graphql from './BrowserSessionListQuery.graphql';
|
||||
|
||||
const node: ReaderFragment = (function(){
|
||||
var v0 = [
|
||||
"browserSessions"
|
||||
],
|
||||
v1 = {
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "id",
|
||||
"storageKey": null
|
||||
};
|
||||
return {
|
||||
"argumentDefinitions": [
|
||||
{
|
||||
"kind": "RootArgument",
|
||||
"name": "count"
|
||||
},
|
||||
{
|
||||
"kind": "RootArgument",
|
||||
"name": "cursor"
|
||||
}
|
||||
],
|
||||
"kind": "Fragment",
|
||||
"metadata": {
|
||||
"connection": [
|
||||
{
|
||||
"count": "count",
|
||||
"cursor": "cursor",
|
||||
"direction": "forward",
|
||||
"path": (v0/*: any*/)
|
||||
}
|
||||
],
|
||||
"refetch": {
|
||||
"connection": {
|
||||
"forward": {
|
||||
"count": "count",
|
||||
"cursor": "cursor"
|
||||
},
|
||||
"backward": null,
|
||||
"path": (v0/*: any*/)
|
||||
},
|
||||
"fragmentPathInResult": [
|
||||
"node"
|
||||
],
|
||||
"operation": BrowserSessionListQuery_graphql,
|
||||
"identifierField": "id"
|
||||
}
|
||||
},
|
||||
"name": "BrowserSessionList_user",
|
||||
"selections": [
|
||||
{
|
||||
"alias": "browserSessions",
|
||||
"args": null,
|
||||
"concreteType": "BrowserSessionConnection",
|
||||
"kind": "LinkedField",
|
||||
"name": "__BrowserSessionList_user_browserSessions_connection",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"concreteType": "BrowserSessionEdge",
|
||||
"kind": "LinkedField",
|
||||
"name": "edges",
|
||||
"plural": true,
|
||||
"selections": [
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "cursor",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"concreteType": "BrowserSession",
|
||||
"kind": "LinkedField",
|
||||
"name": "node",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
(v1/*: any*/),
|
||||
{
|
||||
"args": null,
|
||||
"kind": "FragmentSpread",
|
||||
"name": "BrowserSession_session"
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "__typename",
|
||||
"storageKey": null
|
||||
}
|
||||
],
|
||||
"storageKey": null
|
||||
}
|
||||
],
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"concreteType": "PageInfo",
|
||||
"kind": "LinkedField",
|
||||
"name": "pageInfo",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "endCursor",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "hasNextPage",
|
||||
"storageKey": null
|
||||
}
|
||||
],
|
||||
"storageKey": null
|
||||
}
|
||||
],
|
||||
"storageKey": null
|
||||
},
|
||||
(v1/*: any*/)
|
||||
],
|
||||
"type": "User",
|
||||
"abstractKey": null
|
||||
};
|
||||
})();
|
||||
|
||||
(node as any).hash = "5f21c429aa98b854c17d3f9eb83b81d8";
|
||||
|
||||
export default node;
|
@ -1,71 +0,0 @@
|
||||
/**
|
||||
* @generated SignedSource<<f204c3033b21cfa962537b2dd72f4469>>
|
||||
* @lightSyntaxTransform
|
||||
* @nogrep
|
||||
*/
|
||||
|
||||
/* tslint:disable */
|
||||
/* eslint-disable */
|
||||
// @ts-nocheck
|
||||
|
||||
import { Fragment, ReaderFragment } from 'relay-runtime';
|
||||
import { FragmentRefs } from "relay-runtime";
|
||||
export type BrowserSession_session$data = {
|
||||
readonly createdAt: any;
|
||||
readonly id: string;
|
||||
readonly lastAuthentication: {
|
||||
readonly createdAt: any;
|
||||
readonly id: string;
|
||||
} | null;
|
||||
readonly " $fragmentType": "BrowserSession_session";
|
||||
};
|
||||
export type BrowserSession_session$key = {
|
||||
readonly " $data"?: BrowserSession_session$data;
|
||||
readonly " $fragmentSpreads": FragmentRefs<"BrowserSession_session">;
|
||||
};
|
||||
|
||||
const node: ReaderFragment = (function(){
|
||||
var v0 = {
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "id",
|
||||
"storageKey": null
|
||||
},
|
||||
v1 = {
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "createdAt",
|
||||
"storageKey": null
|
||||
};
|
||||
return {
|
||||
"argumentDefinitions": [],
|
||||
"kind": "Fragment",
|
||||
"metadata": null,
|
||||
"name": "BrowserSession_session",
|
||||
"selections": [
|
||||
(v0/*: any*/),
|
||||
(v1/*: any*/),
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"concreteType": "Authentication",
|
||||
"kind": "LinkedField",
|
||||
"name": "lastAuthentication",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
(v0/*: any*/),
|
||||
(v1/*: any*/)
|
||||
],
|
||||
"storageKey": null
|
||||
}
|
||||
],
|
||||
"type": "BrowserSession",
|
||||
"abstractKey": null
|
||||
};
|
||||
})();
|
||||
|
||||
(node as any).hash = "04d6adf0b2a1bf2098938ef30f195c4a";
|
||||
|
||||
export default node;
|
@ -1,265 +0,0 @@
|
||||
/**
|
||||
* @generated SignedSource<<3e111db0c30af3251a88326deea5562c>>
|
||||
* @lightSyntaxTransform
|
||||
* @nogrep
|
||||
*/
|
||||
|
||||
/* tslint:disable */
|
||||
/* eslint-disable */
|
||||
// @ts-nocheck
|
||||
|
||||
import { ConcreteRequest, Query } from 'relay-runtime';
|
||||
import { FragmentRefs } from "relay-runtime";
|
||||
export type CompatSsoLoginListQuery$variables = {
|
||||
count?: number | null;
|
||||
cursor?: string | null;
|
||||
id: string;
|
||||
};
|
||||
export type CompatSsoLoginListQuery$data = {
|
||||
readonly node: {
|
||||
readonly " $fragmentSpreads": FragmentRefs<"CompatSsoLoginList_user">;
|
||||
} | null;
|
||||
};
|
||||
export type CompatSsoLoginListQuery = {
|
||||
response: CompatSsoLoginListQuery$data;
|
||||
variables: CompatSsoLoginListQuery$variables;
|
||||
};
|
||||
|
||||
const node: ConcreteRequest = (function(){
|
||||
var v0 = [
|
||||
{
|
||||
"defaultValue": null,
|
||||
"kind": "LocalArgument",
|
||||
"name": "count"
|
||||
},
|
||||
{
|
||||
"defaultValue": null,
|
||||
"kind": "LocalArgument",
|
||||
"name": "cursor"
|
||||
},
|
||||
{
|
||||
"defaultValue": null,
|
||||
"kind": "LocalArgument",
|
||||
"name": "id"
|
||||
}
|
||||
],
|
||||
v1 = [
|
||||
{
|
||||
"kind": "Variable",
|
||||
"name": "id",
|
||||
"variableName": "id"
|
||||
}
|
||||
],
|
||||
v2 = {
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "__typename",
|
||||
"storageKey": null
|
||||
},
|
||||
v3 = {
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "id",
|
||||
"storageKey": null
|
||||
},
|
||||
v4 = [
|
||||
{
|
||||
"kind": "Variable",
|
||||
"name": "after",
|
||||
"variableName": "cursor"
|
||||
},
|
||||
{
|
||||
"kind": "Variable",
|
||||
"name": "first",
|
||||
"variableName": "count"
|
||||
}
|
||||
],
|
||||
v5 = {
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "createdAt",
|
||||
"storageKey": null
|
||||
};
|
||||
return {
|
||||
"fragment": {
|
||||
"argumentDefinitions": (v0/*: any*/),
|
||||
"kind": "Fragment",
|
||||
"metadata": null,
|
||||
"name": "CompatSsoLoginListQuery",
|
||||
"selections": [
|
||||
{
|
||||
"alias": null,
|
||||
"args": (v1/*: any*/),
|
||||
"concreteType": null,
|
||||
"kind": "LinkedField",
|
||||
"name": "node",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
{
|
||||
"args": null,
|
||||
"kind": "FragmentSpread",
|
||||
"name": "CompatSsoLoginList_user"
|
||||
}
|
||||
],
|
||||
"storageKey": null
|
||||
}
|
||||
],
|
||||
"type": "RootQuery",
|
||||
"abstractKey": null
|
||||
},
|
||||
"kind": "Request",
|
||||
"operation": {
|
||||
"argumentDefinitions": (v0/*: any*/),
|
||||
"kind": "Operation",
|
||||
"name": "CompatSsoLoginListQuery",
|
||||
"selections": [
|
||||
{
|
||||
"alias": null,
|
||||
"args": (v1/*: any*/),
|
||||
"concreteType": null,
|
||||
"kind": "LinkedField",
|
||||
"name": "node",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
(v2/*: any*/),
|
||||
(v3/*: any*/),
|
||||
{
|
||||
"kind": "InlineFragment",
|
||||
"selections": [
|
||||
{
|
||||
"alias": null,
|
||||
"args": (v4/*: any*/),
|
||||
"concreteType": "CompatSsoLoginConnection",
|
||||
"kind": "LinkedField",
|
||||
"name": "compatSsoLogins",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"concreteType": "CompatSsoLoginEdge",
|
||||
"kind": "LinkedField",
|
||||
"name": "edges",
|
||||
"plural": true,
|
||||
"selections": [
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"concreteType": "CompatSsoLogin",
|
||||
"kind": "LinkedField",
|
||||
"name": "node",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
(v3/*: any*/),
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "redirectUri",
|
||||
"storageKey": null
|
||||
},
|
||||
(v5/*: any*/),
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"concreteType": "CompatSession",
|
||||
"kind": "LinkedField",
|
||||
"name": "session",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
(v3/*: any*/),
|
||||
(v5/*: any*/),
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "deviceId",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "finishedAt",
|
||||
"storageKey": null
|
||||
}
|
||||
],
|
||||
"storageKey": null
|
||||
},
|
||||
(v2/*: any*/)
|
||||
],
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "cursor",
|
||||
"storageKey": null
|
||||
}
|
||||
],
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"concreteType": "PageInfo",
|
||||
"kind": "LinkedField",
|
||||
"name": "pageInfo",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "endCursor",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "hasNextPage",
|
||||
"storageKey": null
|
||||
}
|
||||
],
|
||||
"storageKey": null
|
||||
}
|
||||
],
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": (v4/*: any*/),
|
||||
"filters": null,
|
||||
"handle": "connection",
|
||||
"key": "CompatSsoLoginList_user_compatSsoLogins",
|
||||
"kind": "LinkedHandle",
|
||||
"name": "compatSsoLogins"
|
||||
}
|
||||
],
|
||||
"type": "User",
|
||||
"abstractKey": null
|
||||
}
|
||||
],
|
||||
"storageKey": null
|
||||
}
|
||||
]
|
||||
},
|
||||
"params": {
|
||||
"cacheID": "45c6342d3a53a3e3b2b18617796cf654",
|
||||
"id": null,
|
||||
"metadata": {},
|
||||
"name": "CompatSsoLoginListQuery",
|
||||
"operationKind": "query",
|
||||
"text": "query CompatSsoLoginListQuery(\n $count: Int\n $cursor: String\n $id: ID!\n) {\n node(id: $id) {\n __typename\n ...CompatSsoLoginList_user\n id\n }\n}\n\nfragment CompatSsoLoginList_user on User {\n compatSsoLogins(first: $count, after: $cursor) {\n edges {\n node {\n id\n ...CompatSsoLogin_login\n __typename\n }\n cursor\n }\n pageInfo {\n endCursor\n hasNextPage\n }\n }\n id\n}\n\nfragment CompatSsoLogin_login on CompatSsoLogin {\n id\n redirectUri\n createdAt\n session {\n id\n createdAt\n deviceId\n finishedAt\n }\n}\n"
|
||||
}
|
||||
};
|
||||
})();
|
||||
|
||||
(node as any).hash = "cafc795d1bf9643ac6155c017e66c858";
|
||||
|
||||
export default node;
|
@ -1,169 +0,0 @@
|
||||
/**
|
||||
* @generated SignedSource<<4ace8ea8668e3dc638df21400c690bd8>>
|
||||
* @lightSyntaxTransform
|
||||
* @nogrep
|
||||
*/
|
||||
|
||||
/* tslint:disable */
|
||||
/* eslint-disable */
|
||||
// @ts-nocheck
|
||||
|
||||
import { ReaderFragment, RefetchableFragment } from 'relay-runtime';
|
||||
import { FragmentRefs } from "relay-runtime";
|
||||
export type CompatSsoLoginList_user$data = {
|
||||
readonly compatSsoLogins: {
|
||||
readonly edges: ReadonlyArray<{
|
||||
readonly node: {
|
||||
readonly id: string;
|
||||
readonly " $fragmentSpreads": FragmentRefs<"CompatSsoLogin_login">;
|
||||
};
|
||||
}>;
|
||||
};
|
||||
readonly id: string;
|
||||
readonly " $fragmentType": "CompatSsoLoginList_user";
|
||||
};
|
||||
export type CompatSsoLoginList_user$key = {
|
||||
readonly " $data"?: CompatSsoLoginList_user$data;
|
||||
readonly " $fragmentSpreads": FragmentRefs<"CompatSsoLoginList_user">;
|
||||
};
|
||||
|
||||
import CompatSsoLoginListQuery_graphql from './CompatSsoLoginListQuery.graphql';
|
||||
|
||||
const node: ReaderFragment = (function(){
|
||||
var v0 = [
|
||||
"compatSsoLogins"
|
||||
],
|
||||
v1 = {
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "id",
|
||||
"storageKey": null
|
||||
};
|
||||
return {
|
||||
"argumentDefinitions": [
|
||||
{
|
||||
"kind": "RootArgument",
|
||||
"name": "count"
|
||||
},
|
||||
{
|
||||
"kind": "RootArgument",
|
||||
"name": "cursor"
|
||||
}
|
||||
],
|
||||
"kind": "Fragment",
|
||||
"metadata": {
|
||||
"connection": [
|
||||
{
|
||||
"count": "count",
|
||||
"cursor": "cursor",
|
||||
"direction": "forward",
|
||||
"path": (v0/*: any*/)
|
||||
}
|
||||
],
|
||||
"refetch": {
|
||||
"connection": {
|
||||
"forward": {
|
||||
"count": "count",
|
||||
"cursor": "cursor"
|
||||
},
|
||||
"backward": null,
|
||||
"path": (v0/*: any*/)
|
||||
},
|
||||
"fragmentPathInResult": [
|
||||
"node"
|
||||
],
|
||||
"operation": CompatSsoLoginListQuery_graphql,
|
||||
"identifierField": "id"
|
||||
}
|
||||
},
|
||||
"name": "CompatSsoLoginList_user",
|
||||
"selections": [
|
||||
{
|
||||
"alias": "compatSsoLogins",
|
||||
"args": null,
|
||||
"concreteType": "CompatSsoLoginConnection",
|
||||
"kind": "LinkedField",
|
||||
"name": "__CompatSsoLoginList_user_compatSsoLogins_connection",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"concreteType": "CompatSsoLoginEdge",
|
||||
"kind": "LinkedField",
|
||||
"name": "edges",
|
||||
"plural": true,
|
||||
"selections": [
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"concreteType": "CompatSsoLogin",
|
||||
"kind": "LinkedField",
|
||||
"name": "node",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
(v1/*: any*/),
|
||||
{
|
||||
"args": null,
|
||||
"kind": "FragmentSpread",
|
||||
"name": "CompatSsoLogin_login"
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "__typename",
|
||||
"storageKey": null
|
||||
}
|
||||
],
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "cursor",
|
||||
"storageKey": null
|
||||
}
|
||||
],
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"concreteType": "PageInfo",
|
||||
"kind": "LinkedField",
|
||||
"name": "pageInfo",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "endCursor",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "hasNextPage",
|
||||
"storageKey": null
|
||||
}
|
||||
],
|
||||
"storageKey": null
|
||||
}
|
||||
],
|
||||
"storageKey": null
|
||||
},
|
||||
(v1/*: any*/)
|
||||
],
|
||||
"type": "User",
|
||||
"abstractKey": null
|
||||
};
|
||||
})();
|
||||
|
||||
(node as any).hash = "cafc795d1bf9643ac6155c017e66c858";
|
||||
|
||||
export default node;
|
@ -1,95 +0,0 @@
|
||||
/**
|
||||
* @generated SignedSource<<20e2b233e5154ea60632046abc2aa29a>>
|
||||
* @lightSyntaxTransform
|
||||
* @nogrep
|
||||
*/
|
||||
|
||||
/* tslint:disable */
|
||||
/* eslint-disable */
|
||||
// @ts-nocheck
|
||||
|
||||
import { Fragment, ReaderFragment } from 'relay-runtime';
|
||||
import { FragmentRefs } from "relay-runtime";
|
||||
export type CompatSsoLogin_login$data = {
|
||||
readonly createdAt: any;
|
||||
readonly id: string;
|
||||
readonly redirectUri: any;
|
||||
readonly session: {
|
||||
readonly createdAt: any;
|
||||
readonly deviceId: string;
|
||||
readonly finishedAt: any | null;
|
||||
readonly id: string;
|
||||
} | null;
|
||||
readonly " $fragmentType": "CompatSsoLogin_login";
|
||||
};
|
||||
export type CompatSsoLogin_login$key = {
|
||||
readonly " $data"?: CompatSsoLogin_login$data;
|
||||
readonly " $fragmentSpreads": FragmentRefs<"CompatSsoLogin_login">;
|
||||
};
|
||||
|
||||
const node: ReaderFragment = (function(){
|
||||
var v0 = {
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "id",
|
||||
"storageKey": null
|
||||
},
|
||||
v1 = {
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "createdAt",
|
||||
"storageKey": null
|
||||
};
|
||||
return {
|
||||
"argumentDefinitions": [],
|
||||
"kind": "Fragment",
|
||||
"metadata": null,
|
||||
"name": "CompatSsoLogin_login",
|
||||
"selections": [
|
||||
(v0/*: any*/),
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "redirectUri",
|
||||
"storageKey": null
|
||||
},
|
||||
(v1/*: any*/),
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"concreteType": "CompatSession",
|
||||
"kind": "LinkedField",
|
||||
"name": "session",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
(v0/*: any*/),
|
||||
(v1/*: any*/),
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "deviceId",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "finishedAt",
|
||||
"storageKey": null
|
||||
}
|
||||
],
|
||||
"storageKey": null
|
||||
}
|
||||
],
|
||||
"type": "CompatSsoLogin",
|
||||
"abstractKey": null
|
||||
};
|
||||
})();
|
||||
|
||||
(node as any).hash = "7be3b416b1023cea0de7a87b9738e5d5";
|
||||
|
||||
export default node;
|
@ -1,263 +0,0 @@
|
||||
/**
|
||||
* @generated SignedSource<<816340b05858a7b5a61aca0a72c21c46>>
|
||||
* @lightSyntaxTransform
|
||||
* @nogrep
|
||||
*/
|
||||
|
||||
/* tslint:disable */
|
||||
/* eslint-disable */
|
||||
// @ts-nocheck
|
||||
|
||||
import { ConcreteRequest, Query } from 'relay-runtime';
|
||||
import { FragmentRefs } from "relay-runtime";
|
||||
export type OAuth2SessionListQuery$variables = {
|
||||
count?: number | null;
|
||||
cursor?: string | null;
|
||||
id: string;
|
||||
};
|
||||
export type OAuth2SessionListQuery$data = {
|
||||
readonly node: {
|
||||
readonly " $fragmentSpreads": FragmentRefs<"OAuth2SessionList_user">;
|
||||
} | null;
|
||||
};
|
||||
export type OAuth2SessionListQuery = {
|
||||
response: OAuth2SessionListQuery$data;
|
||||
variables: OAuth2SessionListQuery$variables;
|
||||
};
|
||||
|
||||
const node: ConcreteRequest = (function(){
|
||||
var v0 = [
|
||||
{
|
||||
"defaultValue": null,
|
||||
"kind": "LocalArgument",
|
||||
"name": "count"
|
||||
},
|
||||
{
|
||||
"defaultValue": null,
|
||||
"kind": "LocalArgument",
|
||||
"name": "cursor"
|
||||
},
|
||||
{
|
||||
"defaultValue": null,
|
||||
"kind": "LocalArgument",
|
||||
"name": "id"
|
||||
}
|
||||
],
|
||||
v1 = [
|
||||
{
|
||||
"kind": "Variable",
|
||||
"name": "id",
|
||||
"variableName": "id"
|
||||
}
|
||||
],
|
||||
v2 = {
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "__typename",
|
||||
"storageKey": null
|
||||
},
|
||||
v3 = {
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "id",
|
||||
"storageKey": null
|
||||
},
|
||||
v4 = [
|
||||
{
|
||||
"kind": "Variable",
|
||||
"name": "after",
|
||||
"variableName": "cursor"
|
||||
},
|
||||
{
|
||||
"kind": "Variable",
|
||||
"name": "first",
|
||||
"variableName": "count"
|
||||
}
|
||||
];
|
||||
return {
|
||||
"fragment": {
|
||||
"argumentDefinitions": (v0/*: any*/),
|
||||
"kind": "Fragment",
|
||||
"metadata": null,
|
||||
"name": "OAuth2SessionListQuery",
|
||||
"selections": [
|
||||
{
|
||||
"alias": null,
|
||||
"args": (v1/*: any*/),
|
||||
"concreteType": null,
|
||||
"kind": "LinkedField",
|
||||
"name": "node",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
{
|
||||
"args": null,
|
||||
"kind": "FragmentSpread",
|
||||
"name": "OAuth2SessionList_user"
|
||||
}
|
||||
],
|
||||
"storageKey": null
|
||||
}
|
||||
],
|
||||
"type": "RootQuery",
|
||||
"abstractKey": null
|
||||
},
|
||||
"kind": "Request",
|
||||
"operation": {
|
||||
"argumentDefinitions": (v0/*: any*/),
|
||||
"kind": "Operation",
|
||||
"name": "OAuth2SessionListQuery",
|
||||
"selections": [
|
||||
{
|
||||
"alias": null,
|
||||
"args": (v1/*: any*/),
|
||||
"concreteType": null,
|
||||
"kind": "LinkedField",
|
||||
"name": "node",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
(v2/*: any*/),
|
||||
(v3/*: any*/),
|
||||
{
|
||||
"kind": "InlineFragment",
|
||||
"selections": [
|
||||
{
|
||||
"alias": null,
|
||||
"args": (v4/*: any*/),
|
||||
"concreteType": "Oauth2SessionConnection",
|
||||
"kind": "LinkedField",
|
||||
"name": "oauth2Sessions",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"concreteType": "Oauth2SessionEdge",
|
||||
"kind": "LinkedField",
|
||||
"name": "edges",
|
||||
"plural": true,
|
||||
"selections": [
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "cursor",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"concreteType": "Oauth2Session",
|
||||
"kind": "LinkedField",
|
||||
"name": "node",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
(v3/*: any*/),
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "scope",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"concreteType": "Oauth2Client",
|
||||
"kind": "LinkedField",
|
||||
"name": "client",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
(v3/*: any*/),
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "clientId",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "clientName",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "clientUri",
|
||||
"storageKey": null
|
||||
}
|
||||
],
|
||||
"storageKey": null
|
||||
},
|
||||
(v2/*: any*/)
|
||||
],
|
||||
"storageKey": null
|
||||
}
|
||||
],
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"concreteType": "PageInfo",
|
||||
"kind": "LinkedField",
|
||||
"name": "pageInfo",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "endCursor",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "hasNextPage",
|
||||
"storageKey": null
|
||||
}
|
||||
],
|
||||
"storageKey": null
|
||||
}
|
||||
],
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": (v4/*: any*/),
|
||||
"filters": null,
|
||||
"handle": "connection",
|
||||
"key": "OAuth2SessionList_user_oauth2Sessions",
|
||||
"kind": "LinkedHandle",
|
||||
"name": "oauth2Sessions"
|
||||
}
|
||||
],
|
||||
"type": "User",
|
||||
"abstractKey": null
|
||||
}
|
||||
],
|
||||
"storageKey": null
|
||||
}
|
||||
]
|
||||
},
|
||||
"params": {
|
||||
"cacheID": "26d1b723940d396f1af608f36ff05ce6",
|
||||
"id": null,
|
||||
"metadata": {},
|
||||
"name": "OAuth2SessionListQuery",
|
||||
"operationKind": "query",
|
||||
"text": "query OAuth2SessionListQuery(\n $count: Int\n $cursor: String\n $id: ID!\n) {\n node(id: $id) {\n __typename\n ...OAuth2SessionList_user\n id\n }\n}\n\nfragment OAuth2SessionList_user on User {\n oauth2Sessions(first: $count, after: $cursor) {\n edges {\n cursor\n node {\n id\n ...OAuth2Session_session\n __typename\n }\n }\n pageInfo {\n endCursor\n hasNextPage\n }\n }\n id\n}\n\nfragment OAuth2Session_session on Oauth2Session {\n id\n scope\n client {\n id\n clientId\n clientName\n clientUri\n }\n}\n"
|
||||
}
|
||||
};
|
||||
})();
|
||||
|
||||
(node as any).hash = "17ef23458a73705550aa33e7f73e41cf";
|
||||
|
||||
export default node;
|
@ -1,170 +0,0 @@
|
||||
/**
|
||||
* @generated SignedSource<<8cb936a8cc1a9ab2a877a4ea92622c88>>
|
||||
* @lightSyntaxTransform
|
||||
* @nogrep
|
||||
*/
|
||||
|
||||
/* tslint:disable */
|
||||
/* eslint-disable */
|
||||
// @ts-nocheck
|
||||
|
||||
import { ReaderFragment, RefetchableFragment } from 'relay-runtime';
|
||||
import { FragmentRefs } from "relay-runtime";
|
||||
export type OAuth2SessionList_user$data = {
|
||||
readonly id: string;
|
||||
readonly oauth2Sessions: {
|
||||
readonly edges: ReadonlyArray<{
|
||||
readonly cursor: string;
|
||||
readonly node: {
|
||||
readonly id: string;
|
||||
readonly " $fragmentSpreads": FragmentRefs<"OAuth2Session_session">;
|
||||
};
|
||||
}>;
|
||||
};
|
||||
readonly " $fragmentType": "OAuth2SessionList_user";
|
||||
};
|
||||
export type OAuth2SessionList_user$key = {
|
||||
readonly " $data"?: OAuth2SessionList_user$data;
|
||||
readonly " $fragmentSpreads": FragmentRefs<"OAuth2SessionList_user">;
|
||||
};
|
||||
|
||||
import OAuth2SessionListQuery_graphql from './OAuth2SessionListQuery.graphql';
|
||||
|
||||
const node: ReaderFragment = (function(){
|
||||
var v0 = [
|
||||
"oauth2Sessions"
|
||||
],
|
||||
v1 = {
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "id",
|
||||
"storageKey": null
|
||||
};
|
||||
return {
|
||||
"argumentDefinitions": [
|
||||
{
|
||||
"kind": "RootArgument",
|
||||
"name": "count"
|
||||
},
|
||||
{
|
||||
"kind": "RootArgument",
|
||||
"name": "cursor"
|
||||
}
|
||||
],
|
||||
"kind": "Fragment",
|
||||
"metadata": {
|
||||
"connection": [
|
||||
{
|
||||
"count": "count",
|
||||
"cursor": "cursor",
|
||||
"direction": "forward",
|
||||
"path": (v0/*: any*/)
|
||||
}
|
||||
],
|
||||
"refetch": {
|
||||
"connection": {
|
||||
"forward": {
|
||||
"count": "count",
|
||||
"cursor": "cursor"
|
||||
},
|
||||
"backward": null,
|
||||
"path": (v0/*: any*/)
|
||||
},
|
||||
"fragmentPathInResult": [
|
||||
"node"
|
||||
],
|
||||
"operation": OAuth2SessionListQuery_graphql,
|
||||
"identifierField": "id"
|
||||
}
|
||||
},
|
||||
"name": "OAuth2SessionList_user",
|
||||
"selections": [
|
||||
{
|
||||
"alias": "oauth2Sessions",
|
||||
"args": null,
|
||||
"concreteType": "Oauth2SessionConnection",
|
||||
"kind": "LinkedField",
|
||||
"name": "__OAuth2SessionList_user_oauth2Sessions_connection",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"concreteType": "Oauth2SessionEdge",
|
||||
"kind": "LinkedField",
|
||||
"name": "edges",
|
||||
"plural": true,
|
||||
"selections": [
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "cursor",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"concreteType": "Oauth2Session",
|
||||
"kind": "LinkedField",
|
||||
"name": "node",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
(v1/*: any*/),
|
||||
{
|
||||
"args": null,
|
||||
"kind": "FragmentSpread",
|
||||
"name": "OAuth2Session_session"
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "__typename",
|
||||
"storageKey": null
|
||||
}
|
||||
],
|
||||
"storageKey": null
|
||||
}
|
||||
],
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"concreteType": "PageInfo",
|
||||
"kind": "LinkedField",
|
||||
"name": "pageInfo",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "endCursor",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "hasNextPage",
|
||||
"storageKey": null
|
||||
}
|
||||
],
|
||||
"storageKey": null
|
||||
}
|
||||
],
|
||||
"storageKey": null
|
||||
},
|
||||
(v1/*: any*/)
|
||||
],
|
||||
"type": "User",
|
||||
"abstractKey": null
|
||||
};
|
||||
})();
|
||||
|
||||
(node as any).hash = "17ef23458a73705550aa33e7f73e41cf";
|
||||
|
||||
export default node;
|
@ -1,197 +0,0 @@
|
||||
/**
|
||||
* @generated SignedSource<<82179715f61e6a03437d696941ceaf16>>
|
||||
* @lightSyntaxTransform
|
||||
* @nogrep
|
||||
*/
|
||||
|
||||
/* tslint:disable */
|
||||
/* eslint-disable */
|
||||
// @ts-nocheck
|
||||
|
||||
import { ConcreteRequest, Query } from 'relay-runtime';
|
||||
import { FragmentRefs } from "relay-runtime";
|
||||
export type OAuth2SessionStoriesQuery$variables = {};
|
||||
export type OAuth2SessionStoriesQuery$data = {
|
||||
readonly session: {
|
||||
readonly " $fragmentSpreads": FragmentRefs<"OAuth2Session_session">;
|
||||
} | null;
|
||||
};
|
||||
export type OAuth2SessionStoriesQuery = {
|
||||
response: OAuth2SessionStoriesQuery$data;
|
||||
variables: OAuth2SessionStoriesQuery$variables;
|
||||
};
|
||||
|
||||
const node: ConcreteRequest = (function(){
|
||||
var v0 = [
|
||||
{
|
||||
"kind": "Literal",
|
||||
"name": "id",
|
||||
"value": "test-id"
|
||||
}
|
||||
],
|
||||
v1 = {
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "id",
|
||||
"storageKey": null
|
||||
},
|
||||
v2 = {
|
||||
"enumValues": null,
|
||||
"nullable": false,
|
||||
"plural": false,
|
||||
"type": "String"
|
||||
},
|
||||
v3 = {
|
||||
"enumValues": null,
|
||||
"nullable": false,
|
||||
"plural": false,
|
||||
"type": "ID"
|
||||
};
|
||||
return {
|
||||
"fragment": {
|
||||
"argumentDefinitions": [],
|
||||
"kind": "Fragment",
|
||||
"metadata": null,
|
||||
"name": "OAuth2SessionStoriesQuery",
|
||||
"selections": [
|
||||
{
|
||||
"alias": "session",
|
||||
"args": (v0/*: any*/),
|
||||
"concreteType": null,
|
||||
"kind": "LinkedField",
|
||||
"name": "node",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
{
|
||||
"args": null,
|
||||
"kind": "FragmentSpread",
|
||||
"name": "OAuth2Session_session"
|
||||
}
|
||||
],
|
||||
"storageKey": "node(id:\"test-id\")"
|
||||
}
|
||||
],
|
||||
"type": "RootQuery",
|
||||
"abstractKey": null
|
||||
},
|
||||
"kind": "Request",
|
||||
"operation": {
|
||||
"argumentDefinitions": [],
|
||||
"kind": "Operation",
|
||||
"name": "OAuth2SessionStoriesQuery",
|
||||
"selections": [
|
||||
{
|
||||
"alias": "session",
|
||||
"args": (v0/*: any*/),
|
||||
"concreteType": null,
|
||||
"kind": "LinkedField",
|
||||
"name": "node",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "__typename",
|
||||
"storageKey": null
|
||||
},
|
||||
(v1/*: any*/),
|
||||
{
|
||||
"kind": "InlineFragment",
|
||||
"selections": [
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "scope",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"concreteType": "Oauth2Client",
|
||||
"kind": "LinkedField",
|
||||
"name": "client",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
(v1/*: any*/),
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "clientId",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "clientName",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "clientUri",
|
||||
"storageKey": null
|
||||
}
|
||||
],
|
||||
"storageKey": null
|
||||
}
|
||||
],
|
||||
"type": "Oauth2Session",
|
||||
"abstractKey": null
|
||||
}
|
||||
],
|
||||
"storageKey": "node(id:\"test-id\")"
|
||||
}
|
||||
]
|
||||
},
|
||||
"params": {
|
||||
"cacheID": "2b2911cfb421c557245313732f0813e0",
|
||||
"id": null,
|
||||
"metadata": {
|
||||
"relayTestingSelectionTypeInfo": {
|
||||
"session": {
|
||||
"enumValues": null,
|
||||
"nullable": true,
|
||||
"plural": false,
|
||||
"type": "Node"
|
||||
},
|
||||
"session.__typename": (v2/*: any*/),
|
||||
"session.client": {
|
||||
"enumValues": null,
|
||||
"nullable": false,
|
||||
"plural": false,
|
||||
"type": "Oauth2Client"
|
||||
},
|
||||
"session.client.clientId": (v2/*: any*/),
|
||||
"session.client.clientName": {
|
||||
"enumValues": null,
|
||||
"nullable": true,
|
||||
"plural": false,
|
||||
"type": "String"
|
||||
},
|
||||
"session.client.clientUri": {
|
||||
"enumValues": null,
|
||||
"nullable": true,
|
||||
"plural": false,
|
||||
"type": "Url"
|
||||
},
|
||||
"session.client.id": (v3/*: any*/),
|
||||
"session.id": (v3/*: any*/),
|
||||
"session.scope": (v2/*: any*/)
|
||||
}
|
||||
},
|
||||
"name": "OAuth2SessionStoriesQuery",
|
||||
"operationKind": "query",
|
||||
"text": "query OAuth2SessionStoriesQuery {\n session: node(id: \"test-id\") {\n __typename\n ...OAuth2Session_session\n id\n }\n}\n\nfragment OAuth2Session_session on Oauth2Session {\n id\n scope\n client {\n id\n clientId\n clientName\n clientUri\n }\n}\n"
|
||||
}
|
||||
};
|
||||
})();
|
||||
|
||||
(node as any).hash = "d60f8f0abfc0b70236d89328bc5c0e85";
|
||||
|
||||
export default node;
|
@ -1,92 +0,0 @@
|
||||
/**
|
||||
* @generated SignedSource<<599452efb8ce96e81a5e9500668ff055>>
|
||||
* @lightSyntaxTransform
|
||||
* @nogrep
|
||||
*/
|
||||
|
||||
/* tslint:disable */
|
||||
/* eslint-disable */
|
||||
// @ts-nocheck
|
||||
|
||||
import { Fragment, ReaderFragment } from 'relay-runtime';
|
||||
import { FragmentRefs } from "relay-runtime";
|
||||
export type OAuth2Session_session$data = {
|
||||
readonly client: {
|
||||
readonly clientId: string;
|
||||
readonly clientName: string | null;
|
||||
readonly clientUri: any | null;
|
||||
readonly id: string;
|
||||
};
|
||||
readonly id: string;
|
||||
readonly scope: string;
|
||||
readonly " $fragmentType": "OAuth2Session_session";
|
||||
};
|
||||
export type OAuth2Session_session$key = {
|
||||
readonly " $data"?: OAuth2Session_session$data;
|
||||
readonly " $fragmentSpreads": FragmentRefs<"OAuth2Session_session">;
|
||||
};
|
||||
|
||||
const node: ReaderFragment = (function(){
|
||||
var v0 = {
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "id",
|
||||
"storageKey": null
|
||||
};
|
||||
return {
|
||||
"argumentDefinitions": [],
|
||||
"kind": "Fragment",
|
||||
"metadata": null,
|
||||
"name": "OAuth2Session_session",
|
||||
"selections": [
|
||||
(v0/*: any*/),
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "scope",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"concreteType": "Oauth2Client",
|
||||
"kind": "LinkedField",
|
||||
"name": "client",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
(v0/*: any*/),
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "clientId",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "clientName",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "clientUri",
|
||||
"storageKey": null
|
||||
}
|
||||
],
|
||||
"storageKey": null
|
||||
}
|
||||
],
|
||||
"type": "Oauth2Session",
|
||||
"abstractKey": null
|
||||
};
|
||||
})();
|
||||
|
||||
(node as any).hash = "d9fa36c7f93b7cef4d5a038d19f768b1";
|
||||
|
||||
export default node;
|
54
frontend/src/gql/fragment-masking.ts
Normal file
54
frontend/src/gql/fragment-masking.ts
Normal file
@ -0,0 +1,54 @@
|
||||
import {
|
||||
ResultOf,
|
||||
TypedDocumentNode as DocumentNode,
|
||||
} from "@graphql-typed-document-node/core";
|
||||
|
||||
export type FragmentType<TDocumentType extends DocumentNode<any, any>> =
|
||||
TDocumentType extends DocumentNode<infer TType, any>
|
||||
? TType extends { " $fragmentName"?: infer TKey }
|
||||
? TKey extends string
|
||||
? { " $fragmentRefs"?: { [key in TKey]: TType } }
|
||||
: never
|
||||
: never
|
||||
: never;
|
||||
|
||||
// return non-nullable if `fragmentType` is non-nullable
|
||||
export function useFragment<TType>(
|
||||
_documentNode: DocumentNode<TType, any>,
|
||||
fragmentType: FragmentType<DocumentNode<TType, any>>
|
||||
): TType;
|
||||
// return nullable if `fragmentType` is nullable
|
||||
export function useFragment<TType>(
|
||||
_documentNode: DocumentNode<TType, any>,
|
||||
fragmentType: FragmentType<DocumentNode<TType, any>> | null | undefined
|
||||
): TType | null | undefined;
|
||||
// return array of non-nullable if `fragmentType` is array of non-nullable
|
||||
export function useFragment<TType>(
|
||||
_documentNode: DocumentNode<TType, any>,
|
||||
fragmentType: ReadonlyArray<FragmentType<DocumentNode<TType, any>>>
|
||||
): ReadonlyArray<TType>;
|
||||
// return array of nullable if `fragmentType` is array of nullable
|
||||
export function useFragment<TType>(
|
||||
_documentNode: DocumentNode<TType, any>,
|
||||
fragmentType:
|
||||
| ReadonlyArray<FragmentType<DocumentNode<TType, any>>>
|
||||
| null
|
||||
| undefined
|
||||
): ReadonlyArray<TType> | null | undefined;
|
||||
export function useFragment<TType>(
|
||||
_documentNode: DocumentNode<TType, any>,
|
||||
fragmentType:
|
||||
| FragmentType<DocumentNode<TType, any>>
|
||||
| ReadonlyArray<FragmentType<DocumentNode<TType, any>>>
|
||||
| null
|
||||
| undefined
|
||||
): TType | ReadonlyArray<TType> | null | undefined {
|
||||
return fragmentType as any;
|
||||
}
|
||||
|
||||
export function makeFragmentData<
|
||||
F extends DocumentNode,
|
||||
FT extends ResultOf<F>
|
||||
>(data: FT, _fragment: F): FragmentType<F> {
|
||||
return data as FragmentType<F>;
|
||||
}
|
82
frontend/src/gql/gql.ts
Normal file
82
frontend/src/gql/gql.ts
Normal file
@ -0,0 +1,82 @@
|
||||
/* eslint-disable */
|
||||
import * as types from './graphql';
|
||||
import { TypedDocumentNode as DocumentNode } from '@graphql-typed-document-node/core';
|
||||
|
||||
/**
|
||||
* Map of all GraphQL operations in the project.
|
||||
*
|
||||
* This map has several performance disadvantages:
|
||||
* 1. It is not tree-shakeable, so it will include all operations in the project.
|
||||
* 2. It is not minifiable, so the string of a GraphQL query will be multiple times inside the bundle.
|
||||
* 3. It does not support dead code elimination, so it will add unused operations.
|
||||
*
|
||||
* Therefore it is highly recommended to use the babel or swc plugin for production.
|
||||
*/
|
||||
const documents = {
|
||||
"\n fragment BrowserSession_session on BrowserSession {\n id\n createdAt\n lastAuthentication {\n id\n createdAt\n }\n }\n": types.BrowserSession_SessionFragmentDoc,
|
||||
"\n fragment BrowserSessionList_user on User {\n browserSessions(first: $count, after: $cursor) {\n edges {\n cursor\n node {\n id\n ...BrowserSession_session\n }\n }\n }\n }\n": types.BrowserSessionList_UserFragmentDoc,
|
||||
"\n fragment CompatSsoLogin_login on CompatSsoLogin {\n id\n redirectUri\n createdAt\n session {\n id\n createdAt\n deviceId\n finishedAt\n }\n }\n": types.CompatSsoLogin_LoginFragmentDoc,
|
||||
"\n fragment CompatSsoLoginList_user on User {\n compatSsoLogins(first: $count, after: $cursor) {\n edges {\n node {\n id\n ...CompatSsoLogin_login\n }\n }\n }\n }\n": types.CompatSsoLoginList_UserFragmentDoc,
|
||||
"\n fragment OAuth2Session_session on Oauth2Session {\n id\n scope\n client {\n id\n clientId\n clientName\n clientUri\n }\n }\n": types.OAuth2Session_SessionFragmentDoc,
|
||||
"\n fragment OAuth2SessionList_user on User {\n oauth2Sessions(first: $count, after: $cursor) {\n edges {\n cursor\n node {\n id\n ...OAuth2Session_session\n }\n }\n }\n }\n": types.OAuth2SessionList_UserFragmentDoc,
|
||||
"\n query BrowserSessionQuery($id: ID!) {\n browserSession(id: $id) {\n id\n createdAt\n lastAuthentication {\n id\n createdAt\n }\n user {\n id\n username\n }\n }\n }\n": types.BrowserSessionQueryDocument,
|
||||
"\n query HomeQuery($count: Int!, $cursor: String) {\n currentBrowserSession {\n id\n user {\n id\n username\n\n ...CompatSsoLoginList_user\n ...BrowserSessionList_user\n ...OAuth2SessionList_user\n }\n }\n }\n": types.HomeQueryDocument,
|
||||
"\n query OAuth2ClientQuery($id: ID!) {\n oauth2Client(id: $id) {\n id\n clientId\n clientName\n clientUri\n tosUri\n policyUri\n redirectUris\n }\n }\n": types.OAuth2ClientQueryDocument,
|
||||
};
|
||||
|
||||
/**
|
||||
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
|
||||
*
|
||||
*
|
||||
* @example
|
||||
* ```ts
|
||||
* const query = graphql(`query GetUser($id: ID!) { user(id: $id) { name } }`);
|
||||
* ```
|
||||
*
|
||||
* The query argument is unknown!
|
||||
* Please regenerate the types.
|
||||
*/
|
||||
export function graphql(source: string): unknown;
|
||||
|
||||
/**
|
||||
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
|
||||
*/
|
||||
export function graphql(source: "\n fragment BrowserSession_session on BrowserSession {\n id\n createdAt\n lastAuthentication {\n id\n createdAt\n }\n }\n"): (typeof documents)["\n fragment BrowserSession_session on BrowserSession {\n id\n createdAt\n lastAuthentication {\n id\n createdAt\n }\n }\n"];
|
||||
/**
|
||||
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
|
||||
*/
|
||||
export function graphql(source: "\n fragment BrowserSessionList_user on User {\n browserSessions(first: $count, after: $cursor) {\n edges {\n cursor\n node {\n id\n ...BrowserSession_session\n }\n }\n }\n }\n"): (typeof documents)["\n fragment BrowserSessionList_user on User {\n browserSessions(first: $count, after: $cursor) {\n edges {\n cursor\n node {\n id\n ...BrowserSession_session\n }\n }\n }\n }\n"];
|
||||
/**
|
||||
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
|
||||
*/
|
||||
export function graphql(source: "\n fragment CompatSsoLogin_login on CompatSsoLogin {\n id\n redirectUri\n createdAt\n session {\n id\n createdAt\n deviceId\n finishedAt\n }\n }\n"): (typeof documents)["\n fragment CompatSsoLogin_login on CompatSsoLogin {\n id\n redirectUri\n createdAt\n session {\n id\n createdAt\n deviceId\n finishedAt\n }\n }\n"];
|
||||
/**
|
||||
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
|
||||
*/
|
||||
export function graphql(source: "\n fragment CompatSsoLoginList_user on User {\n compatSsoLogins(first: $count, after: $cursor) {\n edges {\n node {\n id\n ...CompatSsoLogin_login\n }\n }\n }\n }\n"): (typeof documents)["\n fragment CompatSsoLoginList_user on User {\n compatSsoLogins(first: $count, after: $cursor) {\n edges {\n node {\n id\n ...CompatSsoLogin_login\n }\n }\n }\n }\n"];
|
||||
/**
|
||||
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
|
||||
*/
|
||||
export function graphql(source: "\n fragment OAuth2Session_session on Oauth2Session {\n id\n scope\n client {\n id\n clientId\n clientName\n clientUri\n }\n }\n"): (typeof documents)["\n fragment OAuth2Session_session on Oauth2Session {\n id\n scope\n client {\n id\n clientId\n clientName\n clientUri\n }\n }\n"];
|
||||
/**
|
||||
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
|
||||
*/
|
||||
export function graphql(source: "\n fragment OAuth2SessionList_user on User {\n oauth2Sessions(first: $count, after: $cursor) {\n edges {\n cursor\n node {\n id\n ...OAuth2Session_session\n }\n }\n }\n }\n"): (typeof documents)["\n fragment OAuth2SessionList_user on User {\n oauth2Sessions(first: $count, after: $cursor) {\n edges {\n cursor\n node {\n id\n ...OAuth2Session_session\n }\n }\n }\n }\n"];
|
||||
/**
|
||||
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
|
||||
*/
|
||||
export function graphql(source: "\n query BrowserSessionQuery($id: ID!) {\n browserSession(id: $id) {\n id\n createdAt\n lastAuthentication {\n id\n createdAt\n }\n user {\n id\n username\n }\n }\n }\n"): (typeof documents)["\n query BrowserSessionQuery($id: ID!) {\n browserSession(id: $id) {\n id\n createdAt\n lastAuthentication {\n id\n createdAt\n }\n user {\n id\n username\n }\n }\n }\n"];
|
||||
/**
|
||||
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
|
||||
*/
|
||||
export function graphql(source: "\n query HomeQuery($count: Int!, $cursor: String) {\n currentBrowserSession {\n id\n user {\n id\n username\n\n ...CompatSsoLoginList_user\n ...BrowserSessionList_user\n ...OAuth2SessionList_user\n }\n }\n }\n"): (typeof documents)["\n query HomeQuery($count: Int!, $cursor: String) {\n currentBrowserSession {\n id\n user {\n id\n username\n\n ...CompatSsoLoginList_user\n ...BrowserSessionList_user\n ...OAuth2SessionList_user\n }\n }\n }\n"];
|
||||
/**
|
||||
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
|
||||
*/
|
||||
export function graphql(source: "\n query OAuth2ClientQuery($id: ID!) {\n oauth2Client(id: $id) {\n id\n clientId\n clientName\n clientUri\n tosUri\n policyUri\n redirectUris\n }\n }\n"): (typeof documents)["\n query OAuth2ClientQuery($id: ID!) {\n oauth2Client(id: $id) {\n id\n clientId\n clientName\n clientUri\n tosUri\n policyUri\n redirectUris\n }\n }\n"];
|
||||
|
||||
export function graphql(source: string) {
|
||||
return (documents as any)[source] ?? {};
|
||||
}
|
||||
|
||||
export type DocumentType<TDocumentNode extends DocumentNode<any, any>> = TDocumentNode extends DocumentNode< infer TType, any> ? TType : never;
|
507
frontend/src/gql/graphql.ts
Normal file
507
frontend/src/gql/graphql.ts
Normal file
File diff suppressed because one or more lines are too long
2
frontend/src/gql/index.ts
Normal file
2
frontend/src/gql/index.ts
Normal file
@ -0,0 +1,2 @@
|
||||
export * from "./fragment-masking";
|
||||
export * from "./gql";
|
25
frontend/src/graphql.ts
Normal file
25
frontend/src/graphql.ts
Normal file
@ -0,0 +1,25 @@
|
||||
// Copyright 2023 The Matrix.org Foundation C.I.C.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
import {
|
||||
createClient,
|
||||
dedupExchange,
|
||||
cacheExchange,
|
||||
fetchExchange,
|
||||
} from "@urql/core";
|
||||
|
||||
export const client = createClient({
|
||||
url: "/graphql",
|
||||
exchanges: [dedupExchange, cacheExchange, fetchExchange],
|
||||
});
|
@ -14,18 +14,20 @@
|
||||
|
||||
import React from "react";
|
||||
import ReactDOM from "react-dom/client";
|
||||
import { RelayEnvironmentProvider } from "react-relay";
|
||||
import { Provider } from "jotai";
|
||||
|
||||
import LoadingScreen from "./components/LoadingScreen";
|
||||
import RelayEnvironment from "./RelayEnvironment";
|
||||
import Router from "./Router";
|
||||
import { HydrateAtoms } from "./atoms";
|
||||
|
||||
ReactDOM.createRoot(document.getElementById("root") as HTMLElement).render(
|
||||
<React.StrictMode>
|
||||
<RelayEnvironmentProvider environment={RelayEnvironment}>
|
||||
<React.Suspense fallback={<LoadingScreen />}>
|
||||
<Router />
|
||||
</React.Suspense>
|
||||
</RelayEnvironmentProvider>
|
||||
<Provider>
|
||||
<HydrateAtoms>
|
||||
<React.Suspense fallback={<LoadingScreen />}>
|
||||
<Router />
|
||||
</React.Suspense>
|
||||
</HydrateAtoms>
|
||||
</Provider>
|
||||
</React.StrictMode>
|
||||
);
|
||||
|
@ -12,35 +12,31 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
import { graphql, useLazyLoadQuery } from "react-relay";
|
||||
import { useParams } from "react-router-dom";
|
||||
import { useAtomValue } from "jotai";
|
||||
import { atomsWithQuery } from "jotai-urql";
|
||||
import { useMemo } from "react";
|
||||
import { graphql } from "../gql";
|
||||
|
||||
import type { BrowserSessionQuery } from "./__generated__/BrowserSessionQuery.graphql";
|
||||
|
||||
const BrowserSession: React.FC = () => {
|
||||
const { id } = useParams();
|
||||
if (!id) {
|
||||
throw new Error("Missing parameter");
|
||||
}
|
||||
|
||||
const data = useLazyLoadQuery<BrowserSessionQuery>(
|
||||
graphql`
|
||||
query BrowserSessionQuery($id: ID!) {
|
||||
browserSession(id: $id) {
|
||||
id
|
||||
createdAt
|
||||
lastAuthentication {
|
||||
id
|
||||
createdAt
|
||||
}
|
||||
user {
|
||||
id
|
||||
username
|
||||
}
|
||||
}
|
||||
const QUERY = graphql(/* GraphQL */ `
|
||||
query BrowserSessionQuery($id: ID!) {
|
||||
browserSession(id: $id) {
|
||||
id
|
||||
createdAt
|
||||
lastAuthentication {
|
||||
id
|
||||
createdAt
|
||||
}
|
||||
`,
|
||||
{ id }
|
||||
user {
|
||||
id
|
||||
username
|
||||
}
|
||||
}
|
||||
}
|
||||
`);
|
||||
|
||||
const BrowserSession: React.FC<{ id: string }> = ({ id }) => {
|
||||
const data = useAtomValue(
|
||||
useMemo(() => atomsWithQuery(QUERY, () => ({ id })), [id])[0]
|
||||
);
|
||||
|
||||
return (
|
||||
|
@ -12,33 +12,35 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
import { graphql, useLazyLoadQuery } from "react-relay";
|
||||
import BrowserSessionList from "../components/BrowserSessionList";
|
||||
import { useAtomValue } from "jotai";
|
||||
import { atomsWithQuery } from "jotai-urql";
|
||||
|
||||
import BrowserSessionList from "../components/BrowserSessionList";
|
||||
import CompatSsoLoginList from "../components/CompatSsoLoginList";
|
||||
import OAuth2SessionList from "../components/OAuth2SessionList";
|
||||
import Typography from "../components/Typography";
|
||||
import type { HomeQuery } from "./__generated__/HomeQuery.graphql";
|
||||
import { graphql } from "../gql";
|
||||
|
||||
const QUERY = graphql(/* GraphQL */ `
|
||||
query HomeQuery($count: Int!, $cursor: String) {
|
||||
currentBrowserSession {
|
||||
id
|
||||
user {
|
||||
id
|
||||
username
|
||||
|
||||
...CompatSsoLoginList_user
|
||||
...BrowserSessionList_user
|
||||
...OAuth2SessionList_user
|
||||
}
|
||||
}
|
||||
}
|
||||
`);
|
||||
|
||||
const [homeDataAtom] = atomsWithQuery(QUERY, () => ({ count: 10 }));
|
||||
|
||||
const Home: React.FC = () => {
|
||||
const data = useLazyLoadQuery<HomeQuery>(
|
||||
graphql`
|
||||
query HomeQuery($count: Int!, $cursor: String) {
|
||||
currentBrowserSession {
|
||||
id
|
||||
user {
|
||||
id
|
||||
username
|
||||
|
||||
...CompatSsoLoginList_user
|
||||
...BrowserSessionList_user
|
||||
...OAuth2SessionList_user
|
||||
}
|
||||
}
|
||||
}
|
||||
`,
|
||||
{ count: 2 }
|
||||
);
|
||||
const data = useAtomValue(homeDataAtom);
|
||||
|
||||
if (data.currentBrowserSession) {
|
||||
const session = data.currentBrowserSession;
|
||||
|
@ -12,32 +12,28 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
import { graphql, useLazyLoadQuery } from "react-relay";
|
||||
import { useParams } from "react-router-dom";
|
||||
import { useAtomValue } from "jotai";
|
||||
import { useMemo } from "react";
|
||||
import { atomsWithQuery } from "jotai-urql";
|
||||
import { graphql } from "../gql";
|
||||
|
||||
import type { OAuth2ClientQuery } from "./__generated__/OAuth2ClientQuery.graphql";
|
||||
|
||||
const OAuth2Client: React.FC = () => {
|
||||
const { id } = useParams();
|
||||
if (!id) {
|
||||
throw new Error("Missing parameter");
|
||||
const QUERY = graphql(/* GraphQL */ `
|
||||
query OAuth2ClientQuery($id: ID!) {
|
||||
oauth2Client(id: $id) {
|
||||
id
|
||||
clientId
|
||||
clientName
|
||||
clientUri
|
||||
tosUri
|
||||
policyUri
|
||||
redirectUris
|
||||
}
|
||||
}
|
||||
`);
|
||||
|
||||
const data = useLazyLoadQuery<OAuth2ClientQuery>(
|
||||
graphql`
|
||||
query OAuth2ClientQuery($id: ID!) {
|
||||
oauth2Client(id: $id) {
|
||||
id
|
||||
clientId
|
||||
clientName
|
||||
clientUri
|
||||
tosUri
|
||||
policyUri
|
||||
redirectUris
|
||||
}
|
||||
}
|
||||
`,
|
||||
{ id }
|
||||
const OAuth2Client: React.FC<{ id: string }> = ({ id }) => {
|
||||
const data = useAtomValue(
|
||||
useMemo(() => atomsWithQuery(QUERY, () => ({ id })), [id])[0]
|
||||
);
|
||||
|
||||
return (
|
||||
|
@ -1,139 +0,0 @@
|
||||
/**
|
||||
* @generated SignedSource<<f53c0d7dd710ddd990f1dc215274fc5f>>
|
||||
* @lightSyntaxTransform
|
||||
* @nogrep
|
||||
*/
|
||||
|
||||
/* tslint:disable */
|
||||
/* eslint-disable */
|
||||
// @ts-nocheck
|
||||
|
||||
import { ConcreteRequest, Query } from 'relay-runtime';
|
||||
export type BrowserSessionQuery$variables = {
|
||||
id: string;
|
||||
};
|
||||
export type BrowserSessionQuery$data = {
|
||||
readonly browserSession: {
|
||||
readonly createdAt: any;
|
||||
readonly id: string;
|
||||
readonly lastAuthentication: {
|
||||
readonly createdAt: any;
|
||||
readonly id: string;
|
||||
} | null;
|
||||
readonly user: {
|
||||
readonly id: string;
|
||||
readonly username: string;
|
||||
};
|
||||
} | null;
|
||||
};
|
||||
export type BrowserSessionQuery = {
|
||||
response: BrowserSessionQuery$data;
|
||||
variables: BrowserSessionQuery$variables;
|
||||
};
|
||||
|
||||
const node: ConcreteRequest = (function(){
|
||||
var v0 = [
|
||||
{
|
||||
"defaultValue": null,
|
||||
"kind": "LocalArgument",
|
||||
"name": "id"
|
||||
}
|
||||
],
|
||||
v1 = {
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "id",
|
||||
"storageKey": null
|
||||
},
|
||||
v2 = {
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "createdAt",
|
||||
"storageKey": null
|
||||
},
|
||||
v3 = [
|
||||
{
|
||||
"alias": null,
|
||||
"args": [
|
||||
{
|
||||
"kind": "Variable",
|
||||
"name": "id",
|
||||
"variableName": "id"
|
||||
}
|
||||
],
|
||||
"concreteType": "BrowserSession",
|
||||
"kind": "LinkedField",
|
||||
"name": "browserSession",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
(v1/*: any*/),
|
||||
(v2/*: any*/),
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"concreteType": "Authentication",
|
||||
"kind": "LinkedField",
|
||||
"name": "lastAuthentication",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
(v1/*: any*/),
|
||||
(v2/*: any*/)
|
||||
],
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"concreteType": "User",
|
||||
"kind": "LinkedField",
|
||||
"name": "user",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
(v1/*: any*/),
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "username",
|
||||
"storageKey": null
|
||||
}
|
||||
],
|
||||
"storageKey": null
|
||||
}
|
||||
],
|
||||
"storageKey": null
|
||||
}
|
||||
];
|
||||
return {
|
||||
"fragment": {
|
||||
"argumentDefinitions": (v0/*: any*/),
|
||||
"kind": "Fragment",
|
||||
"metadata": null,
|
||||
"name": "BrowserSessionQuery",
|
||||
"selections": (v3/*: any*/),
|
||||
"type": "RootQuery",
|
||||
"abstractKey": null
|
||||
},
|
||||
"kind": "Request",
|
||||
"operation": {
|
||||
"argumentDefinitions": (v0/*: any*/),
|
||||
"kind": "Operation",
|
||||
"name": "BrowserSessionQuery",
|
||||
"selections": (v3/*: any*/)
|
||||
},
|
||||
"params": {
|
||||
"cacheID": "5374afccfa4da28a64cdce6585ac1907",
|
||||
"id": null,
|
||||
"metadata": {},
|
||||
"name": "BrowserSessionQuery",
|
||||
"operationKind": "query",
|
||||
"text": "query BrowserSessionQuery(\n $id: ID!\n) {\n browserSession(id: $id) {\n id\n createdAt\n lastAuthentication {\n id\n createdAt\n }\n user {\n id\n username\n }\n }\n}\n"
|
||||
}
|
||||
};
|
||||
})();
|
||||
|
||||
(node as any).hash = "c73293a99a0214448861bed340594304";
|
||||
|
||||
export default node;
|
441
frontend/src/pages/__generated__/HomeQuery.graphql.ts
generated
441
frontend/src/pages/__generated__/HomeQuery.graphql.ts
generated
@ -1,441 +0,0 @@
|
||||
/**
|
||||
* @generated SignedSource<<b9d5536e28bde5c8929747fab28aae0e>>
|
||||
* @lightSyntaxTransform
|
||||
* @nogrep
|
||||
*/
|
||||
|
||||
/* tslint:disable */
|
||||
/* eslint-disable */
|
||||
// @ts-nocheck
|
||||
|
||||
import { ConcreteRequest, Query } from 'relay-runtime';
|
||||
import { FragmentRefs } from "relay-runtime";
|
||||
export type HomeQuery$variables = {
|
||||
count: number;
|
||||
cursor?: string | null;
|
||||
};
|
||||
export type HomeQuery$data = {
|
||||
readonly currentBrowserSession: {
|
||||
readonly id: string;
|
||||
readonly user: {
|
||||
readonly id: string;
|
||||
readonly username: string;
|
||||
readonly " $fragmentSpreads": FragmentRefs<"BrowserSessionList_user" | "CompatSsoLoginList_user" | "OAuth2SessionList_user">;
|
||||
};
|
||||
} | null;
|
||||
};
|
||||
export type HomeQuery = {
|
||||
response: HomeQuery$data;
|
||||
variables: HomeQuery$variables;
|
||||
};
|
||||
|
||||
const node: ConcreteRequest = (function(){
|
||||
var v0 = [
|
||||
{
|
||||
"defaultValue": null,
|
||||
"kind": "LocalArgument",
|
||||
"name": "count"
|
||||
},
|
||||
{
|
||||
"defaultValue": null,
|
||||
"kind": "LocalArgument",
|
||||
"name": "cursor"
|
||||
}
|
||||
],
|
||||
v1 = {
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "id",
|
||||
"storageKey": null
|
||||
},
|
||||
v2 = {
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "username",
|
||||
"storageKey": null
|
||||
},
|
||||
v3 = [
|
||||
{
|
||||
"kind": "Variable",
|
||||
"name": "after",
|
||||
"variableName": "cursor"
|
||||
},
|
||||
{
|
||||
"kind": "Variable",
|
||||
"name": "first",
|
||||
"variableName": "count"
|
||||
}
|
||||
],
|
||||
v4 = {
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "createdAt",
|
||||
"storageKey": null
|
||||
},
|
||||
v5 = {
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "__typename",
|
||||
"storageKey": null
|
||||
},
|
||||
v6 = {
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "cursor",
|
||||
"storageKey": null
|
||||
},
|
||||
v7 = {
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"concreteType": "PageInfo",
|
||||
"kind": "LinkedField",
|
||||
"name": "pageInfo",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "endCursor",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "hasNextPage",
|
||||
"storageKey": null
|
||||
}
|
||||
],
|
||||
"storageKey": null
|
||||
};
|
||||
return {
|
||||
"fragment": {
|
||||
"argumentDefinitions": (v0/*: any*/),
|
||||
"kind": "Fragment",
|
||||
"metadata": null,
|
||||
"name": "HomeQuery",
|
||||
"selections": [
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"concreteType": "BrowserSession",
|
||||
"kind": "LinkedField",
|
||||
"name": "currentBrowserSession",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
(v1/*: any*/),
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"concreteType": "User",
|
||||
"kind": "LinkedField",
|
||||
"name": "user",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
(v1/*: any*/),
|
||||
(v2/*: any*/),
|
||||
{
|
||||
"args": null,
|
||||
"kind": "FragmentSpread",
|
||||
"name": "CompatSsoLoginList_user"
|
||||
},
|
||||
{
|
||||
"args": null,
|
||||
"kind": "FragmentSpread",
|
||||
"name": "BrowserSessionList_user"
|
||||
},
|
||||
{
|
||||
"args": null,
|
||||
"kind": "FragmentSpread",
|
||||
"name": "OAuth2SessionList_user"
|
||||
}
|
||||
],
|
||||
"storageKey": null
|
||||
}
|
||||
],
|
||||
"storageKey": null
|
||||
}
|
||||
],
|
||||
"type": "RootQuery",
|
||||
"abstractKey": null
|
||||
},
|
||||
"kind": "Request",
|
||||
"operation": {
|
||||
"argumentDefinitions": (v0/*: any*/),
|
||||
"kind": "Operation",
|
||||
"name": "HomeQuery",
|
||||
"selections": [
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"concreteType": "BrowserSession",
|
||||
"kind": "LinkedField",
|
||||
"name": "currentBrowserSession",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
(v1/*: any*/),
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"concreteType": "User",
|
||||
"kind": "LinkedField",
|
||||
"name": "user",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
(v1/*: any*/),
|
||||
(v2/*: any*/),
|
||||
{
|
||||
"alias": null,
|
||||
"args": (v3/*: any*/),
|
||||
"concreteType": "CompatSsoLoginConnection",
|
||||
"kind": "LinkedField",
|
||||
"name": "compatSsoLogins",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"concreteType": "CompatSsoLoginEdge",
|
||||
"kind": "LinkedField",
|
||||
"name": "edges",
|
||||
"plural": true,
|
||||
"selections": [
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"concreteType": "CompatSsoLogin",
|
||||
"kind": "LinkedField",
|
||||
"name": "node",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
(v1/*: any*/),
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "redirectUri",
|
||||
"storageKey": null
|
||||
},
|
||||
(v4/*: any*/),
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"concreteType": "CompatSession",
|
||||
"kind": "LinkedField",
|
||||
"name": "session",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
(v1/*: any*/),
|
||||
(v4/*: any*/),
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "deviceId",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "finishedAt",
|
||||
"storageKey": null
|
||||
}
|
||||
],
|
||||
"storageKey": null
|
||||
},
|
||||
(v5/*: any*/)
|
||||
],
|
||||
"storageKey": null
|
||||
},
|
||||
(v6/*: any*/)
|
||||
],
|
||||
"storageKey": null
|
||||
},
|
||||
(v7/*: any*/)
|
||||
],
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": (v3/*: any*/),
|
||||
"filters": null,
|
||||
"handle": "connection",
|
||||
"key": "CompatSsoLoginList_user_compatSsoLogins",
|
||||
"kind": "LinkedHandle",
|
||||
"name": "compatSsoLogins"
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": (v3/*: any*/),
|
||||
"concreteType": "BrowserSessionConnection",
|
||||
"kind": "LinkedField",
|
||||
"name": "browserSessions",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"concreteType": "BrowserSessionEdge",
|
||||
"kind": "LinkedField",
|
||||
"name": "edges",
|
||||
"plural": true,
|
||||
"selections": [
|
||||
(v6/*: any*/),
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"concreteType": "BrowserSession",
|
||||
"kind": "LinkedField",
|
||||
"name": "node",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
(v1/*: any*/),
|
||||
(v4/*: any*/),
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"concreteType": "Authentication",
|
||||
"kind": "LinkedField",
|
||||
"name": "lastAuthentication",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
(v1/*: any*/),
|
||||
(v4/*: any*/)
|
||||
],
|
||||
"storageKey": null
|
||||
},
|
||||
(v5/*: any*/)
|
||||
],
|
||||
"storageKey": null
|
||||
}
|
||||
],
|
||||
"storageKey": null
|
||||
},
|
||||
(v7/*: any*/)
|
||||
],
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": (v3/*: any*/),
|
||||
"filters": null,
|
||||
"handle": "connection",
|
||||
"key": "BrowserSessionList_user_browserSessions",
|
||||
"kind": "LinkedHandle",
|
||||
"name": "browserSessions"
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": (v3/*: any*/),
|
||||
"concreteType": "Oauth2SessionConnection",
|
||||
"kind": "LinkedField",
|
||||
"name": "oauth2Sessions",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"concreteType": "Oauth2SessionEdge",
|
||||
"kind": "LinkedField",
|
||||
"name": "edges",
|
||||
"plural": true,
|
||||
"selections": [
|
||||
(v6/*: any*/),
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"concreteType": "Oauth2Session",
|
||||
"kind": "LinkedField",
|
||||
"name": "node",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
(v1/*: any*/),
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "scope",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"concreteType": "Oauth2Client",
|
||||
"kind": "LinkedField",
|
||||
"name": "client",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
(v1/*: any*/),
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "clientId",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "clientName",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "clientUri",
|
||||
"storageKey": null
|
||||
}
|
||||
],
|
||||
"storageKey": null
|
||||
},
|
||||
(v5/*: any*/)
|
||||
],
|
||||
"storageKey": null
|
||||
}
|
||||
],
|
||||
"storageKey": null
|
||||
},
|
||||
(v7/*: any*/)
|
||||
],
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": (v3/*: any*/),
|
||||
"filters": null,
|
||||
"handle": "connection",
|
||||
"key": "OAuth2SessionList_user_oauth2Sessions",
|
||||
"kind": "LinkedHandle",
|
||||
"name": "oauth2Sessions"
|
||||
}
|
||||
],
|
||||
"storageKey": null
|
||||
}
|
||||
],
|
||||
"storageKey": null
|
||||
}
|
||||
]
|
||||
},
|
||||
"params": {
|
||||
"cacheID": "c2c8afebb1acbce26f8d164d911c5833",
|
||||
"id": null,
|
||||
"metadata": {},
|
||||
"name": "HomeQuery",
|
||||
"operationKind": "query",
|
||||
"text": "query HomeQuery(\n $count: Int!\n $cursor: String\n) {\n currentBrowserSession {\n id\n user {\n id\n username\n ...CompatSsoLoginList_user\n ...BrowserSessionList_user\n ...OAuth2SessionList_user\n }\n }\n}\n\nfragment BrowserSessionList_user on User {\n browserSessions(first: $count, after: $cursor) {\n edges {\n cursor\n node {\n id\n ...BrowserSession_session\n __typename\n }\n }\n pageInfo {\n endCursor\n hasNextPage\n }\n }\n id\n}\n\nfragment BrowserSession_session on BrowserSession {\n id\n createdAt\n lastAuthentication {\n id\n createdAt\n }\n}\n\nfragment CompatSsoLoginList_user on User {\n compatSsoLogins(first: $count, after: $cursor) {\n edges {\n node {\n id\n ...CompatSsoLogin_login\n __typename\n }\n cursor\n }\n pageInfo {\n endCursor\n hasNextPage\n }\n }\n id\n}\n\nfragment CompatSsoLogin_login on CompatSsoLogin {\n id\n redirectUri\n createdAt\n session {\n id\n createdAt\n deviceId\n finishedAt\n }\n}\n\nfragment OAuth2SessionList_user on User {\n oauth2Sessions(first: $count, after: $cursor) {\n edges {\n cursor\n node {\n id\n ...OAuth2Session_session\n __typename\n }\n }\n pageInfo {\n endCursor\n hasNextPage\n }\n }\n id\n}\n\nfragment OAuth2Session_session on Oauth2Session {\n id\n scope\n client {\n id\n clientId\n clientName\n clientUri\n }\n}\n"
|
||||
}
|
||||
};
|
||||
})();
|
||||
|
||||
(node as any).hash = "f26e9c3756edccc8584de5f359fd96bd";
|
||||
|
||||
export default node;
|
@ -1,137 +0,0 @@
|
||||
/**
|
||||
* @generated SignedSource<<fdd196c5ae97e597805f98077fefcd7d>>
|
||||
* @lightSyntaxTransform
|
||||
* @nogrep
|
||||
*/
|
||||
|
||||
/* tslint:disable */
|
||||
/* eslint-disable */
|
||||
// @ts-nocheck
|
||||
|
||||
import { ConcreteRequest, Query } from 'relay-runtime';
|
||||
export type OAuth2ClientQuery$variables = {
|
||||
id: string;
|
||||
};
|
||||
export type OAuth2ClientQuery$data = {
|
||||
readonly oauth2Client: {
|
||||
readonly clientId: string;
|
||||
readonly clientName: string | null;
|
||||
readonly clientUri: any | null;
|
||||
readonly id: string;
|
||||
readonly policyUri: any | null;
|
||||
readonly redirectUris: ReadonlyArray<any>;
|
||||
readonly tosUri: any | null;
|
||||
} | null;
|
||||
};
|
||||
export type OAuth2ClientQuery = {
|
||||
response: OAuth2ClientQuery$data;
|
||||
variables: OAuth2ClientQuery$variables;
|
||||
};
|
||||
|
||||
const node: ConcreteRequest = (function(){
|
||||
var v0 = [
|
||||
{
|
||||
"defaultValue": null,
|
||||
"kind": "LocalArgument",
|
||||
"name": "id"
|
||||
}
|
||||
],
|
||||
v1 = [
|
||||
{
|
||||
"alias": null,
|
||||
"args": [
|
||||
{
|
||||
"kind": "Variable",
|
||||
"name": "id",
|
||||
"variableName": "id"
|
||||
}
|
||||
],
|
||||
"concreteType": "Oauth2Client",
|
||||
"kind": "LinkedField",
|
||||
"name": "oauth2Client",
|
||||
"plural": false,
|
||||
"selections": [
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "id",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "clientId",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "clientName",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "clientUri",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "tosUri",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "policyUri",
|
||||
"storageKey": null
|
||||
},
|
||||
{
|
||||
"alias": null,
|
||||
"args": null,
|
||||
"kind": "ScalarField",
|
||||
"name": "redirectUris",
|
||||
"storageKey": null
|
||||
}
|
||||
],
|
||||
"storageKey": null
|
||||
}
|
||||
];
|
||||
return {
|
||||
"fragment": {
|
||||
"argumentDefinitions": (v0/*: any*/),
|
||||
"kind": "Fragment",
|
||||
"metadata": null,
|
||||
"name": "OAuth2ClientQuery",
|
||||
"selections": (v1/*: any*/),
|
||||
"type": "RootQuery",
|
||||
"abstractKey": null
|
||||
},
|
||||
"kind": "Request",
|
||||
"operation": {
|
||||
"argumentDefinitions": (v0/*: any*/),
|
||||
"kind": "Operation",
|
||||
"name": "OAuth2ClientQuery",
|
||||
"selections": (v1/*: any*/)
|
||||
},
|
||||
"params": {
|
||||
"cacheID": "49e24d5c368a8c2c148643b971fe179c",
|
||||
"id": null,
|
||||
"metadata": {},
|
||||
"name": "OAuth2ClientQuery",
|
||||
"operationKind": "query",
|
||||
"text": "query OAuth2ClientQuery(\n $id: ID!\n) {\n oauth2Client(id: $id) {\n id\n clientId\n clientName\n clientUri\n tosUri\n policyUri\n redirectUris\n }\n}\n"
|
||||
}
|
||||
};
|
||||
})();
|
||||
|
||||
(node as any).hash = "31b4804eb435b5822480ff57775d13a4";
|
||||
|
||||
export default node;
|
@ -16,7 +16,7 @@
|
||||
import { defineConfig } from "vite";
|
||||
import eslint from "vite-plugin-eslint";
|
||||
import react from "@vitejs/plugin-react";
|
||||
import relay from "vite-plugin-relay-lite";
|
||||
import codegen from "vite-plugin-graphql-codegen";
|
||||
|
||||
export default defineConfig({
|
||||
base: "/app/",
|
||||
@ -26,12 +26,12 @@ export default defineConfig({
|
||||
sourcemap: true,
|
||||
},
|
||||
plugins: [
|
||||
codegen(),
|
||||
react(),
|
||||
eslint({
|
||||
// Explicitly set the config file, else storybook gets confused
|
||||
overrideConfigFile: "./.eslintrc.cjs",
|
||||
}),
|
||||
relay(),
|
||||
],
|
||||
server: {
|
||||
proxy: {
|
||||
@ -44,7 +44,7 @@ export default defineConfig({
|
||||
coverage: {
|
||||
provider: "c8",
|
||||
src: ["./src/"],
|
||||
exclude: ["**/__generated__/**", "**/*.d.ts", "**/*.stories.*"],
|
||||
exclude: ["**/gql/**", "**/*.d.ts", "**/*.stories.*"],
|
||||
all: true,
|
||||
},
|
||||
},
|
||||
|
Reference in New Issue
Block a user