From 1567dbb6d61cdfad2eccda50a0b09695327fc31a Mon Sep 17 00:00:00 2001 From: Kerry Archibald Date: Thu, 21 Sep 2023 12:22:43 +1200 Subject: [PATCH] add app sessions list --- .../UserSessionsOverview/AppSessionsList.tsx | 26 +- .../UserSessionsOverview.module.css | 27 -- .../UserSessionsOverview.stories.tsx | 135 ---------- .../UserSessionsOverview.test.tsx | 103 -------- .../UserSessionsOverview.tsx | 75 +----- .../BrowserSessionsOverview.test.tsx.snap | 65 +++++ .../UserSessionsOverview.test.tsx.snap | 3 + .../components/UserSessionsOverview/index.ts | 2 +- frontend/src/gql/gql.ts | 20 +- frontend/src/gql/graphql.ts | 232 ++---------------- frontend/src/graphql.ts | 2 +- frontend/src/pages/SessionsOverview.tsx | 2 +- 12 files changed, 121 insertions(+), 571 deletions(-) delete mode 100644 frontend/src/components/UserSessionsOverview/UserSessionsOverview.module.css delete mode 100644 frontend/src/components/UserSessionsOverview/UserSessionsOverview.stories.tsx delete mode 100644 frontend/src/components/UserSessionsOverview/UserSessionsOverview.test.tsx create mode 100644 frontend/src/components/UserSessionsOverview/__snapshots__/BrowserSessionsOverview.test.tsx.snap create mode 100644 frontend/src/components/UserSessionsOverview/__snapshots__/UserSessionsOverview.test.tsx.snap diff --git a/frontend/src/components/UserSessionsOverview/AppSessionsList.tsx b/frontend/src/components/UserSessionsOverview/AppSessionsList.tsx index 40d53586..d338d9af 100644 --- a/frontend/src/components/UserSessionsOverview/AppSessionsList.tsx +++ b/frontend/src/components/UserSessionsOverview/AppSessionsList.tsx @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -import { H6, Text } from "@vector-im/compound-web"; +import { H5 } from "@vector-im/compound-web"; import { atom, useAtomValue, useSetAtom } from "jotai"; import { atomFamily } from "jotai/utils"; import { atomWithQuery } from "jotai-urql"; @@ -28,6 +28,8 @@ import { } from "../../pagination"; import { isOk, unwrap, unwrapOk } from "../../result"; import BlockList from "../BlockList"; +import CompatSession from "../CompatSession"; +import OAuth2Session from "../OAuth2Session"; import PaginationControls from "../PaginationControls"; const QUERY = graphql(/* GraphQL */ ` @@ -53,6 +55,7 @@ const QUERY = graphql(/* GraphQL */ ` edges { cursor node { + __typename ...CompatSession_session ...OAuth2Session_session } @@ -72,7 +75,7 @@ const QUERY = graphql(/* GraphQL */ ` const filterAtom = atom(SessionState.Active); const currentPaginationAtom = atomForCurrentPagination(); -const appSessionListFamily = atomFamily((userId: string) => { +export const appSessionListFamily = atomFamily((userId: string) => { const appSessionListQuery = atomWithQuery({ query: QUERY, getVariables: (get) => ({ @@ -124,8 +127,23 @@ const AppSessionsList: React.FC<{ userId: string }> = ({ userId }) => { return ( -
Apps
- {`${appSessions.totalCount} active sessions`} +
+
Apps
+
+ {appSessions.edges.map((session) => { + switch (session.node.__typename) { + case "Oauth2Session": + return ( + + ); + case "CompatSession": + return ( + + ); + default: + throw new Error("Unexpected session type."); + } + })} paginate(prevPage) : null} onNext={nextPage ? (): void => paginate(nextPage) : null} diff --git a/frontend/src/components/UserSessionsOverview/UserSessionsOverview.module.css b/frontend/src/components/UserSessionsOverview/UserSessionsOverview.module.css deleted file mode 100644 index b7a53fdc..00000000 --- a/frontend/src/components/UserSessionsOverview/UserSessionsOverview.module.css +++ /dev/null @@ -1,27 +0,0 @@ -/* 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. - */ - -.session-list-block { - display: flex; - flex-direction: row; - justify-content: space-between; - align-items: flex-start; - gap: var(--cpd-space-1x); - } - -.session-list-block-info { - display: flex; - flex-direction: column; - } \ No newline at end of file diff --git a/frontend/src/components/UserSessionsOverview/UserSessionsOverview.stories.tsx b/frontend/src/components/UserSessionsOverview/UserSessionsOverview.stories.tsx deleted file mode 100644 index b7bb3e03..00000000 --- a/frontend/src/components/UserSessionsOverview/UserSessionsOverview.stories.tsx +++ /dev/null @@ -1,135 +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 { Provider } from "jotai"; -import { useHydrateAtoms } from "jotai/utils"; - -import { makeFragmentData } from "../../gql"; -import { appConfigAtom, locationAtom } from "../../routing"; -import { FRAGMENT as EMAIL_FRAGMENT } from "../UserEmail"; - -import UserSessionsOverview, { FRAGMENT } from "./UserSessionsOverview"; - -type Props = { - primaryEmail: string | null; - unverifiedEmails: number; - confirmedEmails: number; - oauth2Sessions: number; - browserSessions: number; - compatSessions: number; -}; - -const WithHomePage: React.FC> = ({ children }) => { - useHydrateAtoms([ - [appConfigAtom, { root: "/" }], - [locationAtom, { pathname: "/" }], - ]); - return <>{children}; -}; - -const Template: React.FC = ({ - primaryEmail: email, - unverifiedEmails, - confirmedEmails, - oauth2Sessions, - browserSessions, - compatSessions, -}) => { - let primaryEmail = null; - if (email) { - primaryEmail = { - id: "email:123", - ...makeFragmentData( - { - id: "email:123", - email, - confirmedAt: new Date(), - }, - EMAIL_FRAGMENT, - ), - }; - } - const data = makeFragmentData( - { - id: "user:123", - primaryEmail, - unverifiedEmails: { - totalCount: unverifiedEmails, - }, - confirmedEmails: { - totalCount: confirmedEmails, - }, - oauth2Sessions: { - totalCount: oauth2Sessions, - }, - browserSessions: { - totalCount: browserSessions, - }, - compatSessions: { - totalCount: compatSessions, - }, - }, - FRAGMENT, - ); - return ( - - - - - - ); -}; - -const meta = { - title: "Pages/User Sessions Overview", - component: Template, - tags: ["autodocs"], -} satisfies Meta; - -export default meta; -type Story = StoryObj; - -export const Basic: Story = { - args: { - primaryEmail: "hello@example.com", - unverifiedEmails: 0, - confirmedEmails: 5, - oauth2Sessions: 3, - compatSessions: 1, - browserSessions: 2, - }, -}; - -export const Empty: Story = { - args: { - primaryEmail: "hello@example.com", - unverifiedEmails: 0, - confirmedEmails: 1, - oauth2Sessions: 0, - compatSessions: 0, - browserSessions: 0, - }, -}; - -export const UnverifiedEmails: Story = { - args: { - primaryEmail: "hello@example.com", - unverifiedEmails: 1, - confirmedEmails: 1, - oauth2Sessions: 0, - compatSessions: 0, - browserSessions: 0, - }, -}; diff --git a/frontend/src/components/UserSessionsOverview/UserSessionsOverview.test.tsx b/frontend/src/components/UserSessionsOverview/UserSessionsOverview.test.tsx deleted file mode 100644 index c3c1537e..00000000 --- a/frontend/src/components/UserSessionsOverview/UserSessionsOverview.test.tsx +++ /dev/null @@ -1,103 +0,0 @@ -// 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 { create } from "react-test-renderer"; -import { describe, expect, it } from "vitest"; - -import { makeFragmentData } from "../../gql"; -import { FRAGMENT as EMAIL_FRAGMENT } from "../UserEmail"; - -import UserSessionsOverview, { FRAGMENT } from "./"; - -describe("UserSessionsOverview", () => { - it("render an simple ", () => { - const primaryEmail = makeFragmentData( - { - id: "email:123", - email: "hello@example.com", - confirmedAt: new Date(), - }, - EMAIL_FRAGMENT, - ); - - const user = makeFragmentData( - { - id: "user:123", - primaryEmail: { - id: "email:123", - ...primaryEmail, - }, - compatSessions: { - totalCount: 0, - }, - browserSessions: { - totalCount: 0, - }, - oauth2Sessions: { - totalCount: 0, - }, - unverifiedEmails: { - totalCount: 0, - }, - confirmedEmails: { - totalCount: 1, - }, - }, - FRAGMENT, - ); - const component = create(); - const tree = component.toJSON(); - expect(tree).toMatchSnapshot(); - }); - - it("render a with sessions", () => { - const primaryEmail = makeFragmentData( - { - id: "email:123", - email: "hello@example.com", - confirmedAt: new Date(), - }, - EMAIL_FRAGMENT, - ); - - const user = makeFragmentData( - { - id: "user:123", - primaryEmail: { - id: "email:123", - ...primaryEmail, - }, - compatSessions: { - totalCount: 1, - }, - browserSessions: { - totalCount: 2, - }, - oauth2Sessions: { - totalCount: 3, - }, - unverifiedEmails: { - totalCount: 0, - }, - confirmedEmails: { - totalCount: 1, - }, - }, - FRAGMENT, - ); - const component = create(); - const tree = component.toJSON(); - expect(tree).toMatchSnapshot(); - }); -}); diff --git a/frontend/src/components/UserSessionsOverview/UserSessionsOverview.tsx b/frontend/src/components/UserSessionsOverview/UserSessionsOverview.tsx index 8ef2ec07..c2a30728 100644 --- a/frontend/src/components/UserSessionsOverview/UserSessionsOverview.tsx +++ b/frontend/src/components/UserSessionsOverview/UserSessionsOverview.tsx @@ -12,90 +12,23 @@ // See the License for the specific language governing permissions and // limitations under the License. -import { Body, H3, H6 } from "@vector-im/compound-web"; +import { H3 } from "@vector-im/compound-web"; -import { FragmentType, graphql, useFragment } from "../../gql"; -import { Link } from "../../routing"; -import Block from "../Block"; +import { FragmentType, useFragment } from "../../gql"; import BlockList from "../BlockList"; import AppSessionsList from "./AppSessionsList"; -import styles from "./UserSessionsOverview.module.css"; - -export const FRAGMENT = graphql(/* GraphQL */ ` - fragment UserSessionsOverview_user on User { - id - - primaryEmail { - id - ...UserEmail_email - } - - confirmedEmails: emails(first: 0, state: CONFIRMED) { - totalCount - } - - browserSessions(first: 0, state: ACTIVE) { - totalCount - } - - oauth2Sessions(first: 0, state: ACTIVE) { - totalCount - } - - compatSessions(first: 0, state: ACTIVE) { - totalCount - } - } -`); +import BrowserSessionsOverview, { FRAGMENT } from "./BrowserSessionsOverview"; const UserSessionsOverview: React.FC<{ user: FragmentType; }> = ({ user }) => { const data = useFragment(FRAGMENT, user); - // allow this until we get i18n - const pluraliseSession = (count: number): string => - count === 1 ? "session" : "sessions"; - - // user friendly description of sessions is: - // browser -> browser - // oauth2 sessions -> New apps - // compatibility sessions -> Regular apps - return ( - {/* This is a short term solution, so I won't bother extracting these blocks into components */}

Where you're signed in

- -
-
Browser
- - {data.browserSessions.totalCount} active{" "} - {pluraliseSession(data.browserSessions.totalCount)} - -
- - View all - -
-
-
compatSessions
- - {data.compatSessions.totalCount} active{" "} - {pluraliseSession(data.compatSessions.totalCount)} - -
-
-
oauth2Sessions
- - {data.oauth2Sessions.totalCount} active{" "} - {pluraliseSession(data.oauth2Sessions.totalCount)} - - - View all - -
+
); diff --git a/frontend/src/components/UserSessionsOverview/__snapshots__/BrowserSessionsOverview.test.tsx.snap b/frontend/src/components/UserSessionsOverview/__snapshots__/BrowserSessionsOverview.test.tsx.snap new file mode 100644 index 00000000..357c046f --- /dev/null +++ b/frontend/src/components/UserSessionsOverview/__snapshots__/BrowserSessionsOverview.test.tsx.snap @@ -0,0 +1,65 @@ +// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html + +exports[`BrowserSessionsOverview > renders with no browser sessions 1`] = ` +
+
+
+
+ Browsers +
+

+ 0 + active + + sessions +

+
+ + View all + +
+
+`; + +exports[`BrowserSessionsOverview > renders with sessions 1`] = ` +
+
+
+
+ Browsers +
+

+ 2 + active + + sessions +

+
+ + View all + +
+
+`; diff --git a/frontend/src/components/UserSessionsOverview/__snapshots__/UserSessionsOverview.test.tsx.snap b/frontend/src/components/UserSessionsOverview/__snapshots__/UserSessionsOverview.test.tsx.snap new file mode 100644 index 00000000..38bda964 --- /dev/null +++ b/frontend/src/components/UserSessionsOverview/__snapshots__/UserSessionsOverview.test.tsx.snap @@ -0,0 +1,3 @@ +// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html + +exports[`UserSessionsOverview > render an simple 1`] = `
`; diff --git a/frontend/src/components/UserSessionsOverview/index.ts b/frontend/src/components/UserSessionsOverview/index.ts index 5b9dce61..c6936252 100644 --- a/frontend/src/components/UserSessionsOverview/index.ts +++ b/frontend/src/components/UserSessionsOverview/index.ts @@ -12,4 +12,4 @@ // See the License for the specific language governing permissions and // limitations under the License. -export { default, FRAGMENT } from "./UserSessionsOverview"; +export { default } from "./UserSessionsOverview"; diff --git a/frontend/src/gql/gql.ts b/frontend/src/gql/gql.ts index e0b4b800..0c26edcf 100644 --- a/frontend/src/gql/gql.ts +++ b/frontend/src/gql/gql.ts @@ -57,10 +57,10 @@ const documents = { types.UserPrimaryEmailDocument, "\n mutation SetDisplayName($userId: ID!, $displayName: String) {\n setDisplayName(input: { userId: $userId, displayName: $displayName }) {\n status\n user {\n id\n matrix {\n displayName\n }\n }\n }\n }\n": types.SetDisplayNameDocument, - "\n query AppSessionList(\n $userId: ID!\n $state: SessionState\n $first: Int\n $after: String\n $last: Int\n $before: String\n ) {\n user(id: $userId) {\n id\n appSessions(\n first: $first\n after: $after\n last: $last\n before: $before\n state: $state\n ) {\n totalCount\n\n edges {\n cursor\n node {\n ...CompatSession_session\n ...OAuth2Session_session\n }\n }\n\n pageInfo {\n hasNextPage\n hasPreviousPage\n startCursor\n endCursor\n }\n }\n }\n }\n": + "\n query AppSessionList(\n $userId: ID!\n $state: SessionState\n $first: Int\n $after: String\n $last: Int\n $before: String\n ) {\n user(id: $userId) {\n id\n appSessions(\n first: $first\n after: $after\n last: $last\n before: $before\n state: $state\n ) {\n totalCount\n\n edges {\n cursor\n node {\n __typename\n ...CompatSession_session\n ...OAuth2Session_session\n }\n }\n\n pageInfo {\n hasNextPage\n hasPreviousPage\n startCursor\n endCursor\n }\n }\n }\n }\n": types.AppSessionListDocument, - "\n fragment UserSessionsOverview_user on User {\n id\n\n primaryEmail {\n id\n ...UserEmail_email\n }\n\n confirmedEmails: emails(first: 0, state: CONFIRMED) {\n totalCount\n }\n\n browserSessions(first: 0, state: ACTIVE) {\n totalCount\n }\n\n oauth2Sessions(first: 0, state: ACTIVE) {\n totalCount\n }\n\n compatSessions(first: 0, state: ACTIVE) {\n totalCount\n }\n }\n": - types.UserSessionsOverview_UserFragmentDoc, + "\n fragment BrowserSessionsOverview_user on User {\n id\n\n browserSessions(first: 0, state: ACTIVE) {\n totalCount\n }\n }\n": + types.BrowserSessionsOverview_UserFragmentDoc, "\n fragment UserEmail_verifyEmail on UserEmail {\n id\n email\n }\n": types.UserEmail_VerifyEmailFragmentDoc, "\n mutation VerifyEmail($id: ID!, $code: String!) {\n verifyEmail(input: { userEmailId: $id, code: $code }) {\n status\n\n user {\n id\n primaryEmail {\n id\n }\n }\n\n email {\n id\n ...UserEmail_email\n }\n }\n }\n": @@ -73,7 +73,7 @@ const documents = { types.BrowserSessionQueryDocument, "\n query OAuth2ClientQuery($id: ID!) {\n oauth2Client(id: $id) {\n ...OAuth2Client_detail\n }\n }\n": types.OAuth2ClientQueryDocument, - "\n query SessionsOverviewQuery {\n viewer {\n __typename\n\n ... on User {\n id\n ...UserSessionsOverview_user\n }\n }\n }\n": + "\n query SessionsOverviewQuery {\n viewer {\n __typename\n\n ... on User {\n id\n ...BrowserSessionsOverview_user\n }\n }\n }\n": types.SessionsOverviewQueryDocument, "\n query VerifyEmailQuery($id: ID!) {\n userEmail(id: $id) {\n ...UserEmail_verifyEmail\n }\n }\n": types.VerifyEmailQueryDocument, @@ -229,14 +229,14 @@ export function graphql( * 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 AppSessionList(\n $userId: ID!\n $state: SessionState\n $first: Int\n $after: String\n $last: Int\n $before: String\n ) {\n user(id: $userId) {\n id\n appSessions(\n first: $first\n after: $after\n last: $last\n before: $before\n state: $state\n ) {\n totalCount\n\n edges {\n cursor\n node {\n ...CompatSession_session\n ...OAuth2Session_session\n }\n }\n\n pageInfo {\n hasNextPage\n hasPreviousPage\n startCursor\n endCursor\n }\n }\n }\n }\n", -): (typeof documents)["\n query AppSessionList(\n $userId: ID!\n $state: SessionState\n $first: Int\n $after: String\n $last: Int\n $before: String\n ) {\n user(id: $userId) {\n id\n appSessions(\n first: $first\n after: $after\n last: $last\n before: $before\n state: $state\n ) {\n totalCount\n\n edges {\n cursor\n node {\n ...CompatSession_session\n ...OAuth2Session_session\n }\n }\n\n pageInfo {\n hasNextPage\n hasPreviousPage\n startCursor\n endCursor\n }\n }\n }\n }\n"]; + source: "\n query AppSessionList(\n $userId: ID!\n $state: SessionState\n $first: Int\n $after: String\n $last: Int\n $before: String\n ) {\n user(id: $userId) {\n id\n appSessions(\n first: $first\n after: $after\n last: $last\n before: $before\n state: $state\n ) {\n totalCount\n\n edges {\n cursor\n node {\n __typename\n ...CompatSession_session\n ...OAuth2Session_session\n }\n }\n\n pageInfo {\n hasNextPage\n hasPreviousPage\n startCursor\n endCursor\n }\n }\n }\n }\n", +): (typeof documents)["\n query AppSessionList(\n $userId: ID!\n $state: SessionState\n $first: Int\n $after: String\n $last: Int\n $before: String\n ) {\n user(id: $userId) {\n id\n appSessions(\n first: $first\n after: $after\n last: $last\n before: $before\n state: $state\n ) {\n totalCount\n\n edges {\n cursor\n node {\n __typename\n ...CompatSession_session\n ...OAuth2Session_session\n }\n }\n\n pageInfo {\n hasNextPage\n hasPreviousPage\n startCursor\n endCursor\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 UserSessionsOverview_user on User {\n id\n\n primaryEmail {\n id\n ...UserEmail_email\n }\n\n confirmedEmails: emails(first: 0, state: CONFIRMED) {\n totalCount\n }\n\n browserSessions(first: 0, state: ACTIVE) {\n totalCount\n }\n\n oauth2Sessions(first: 0, state: ACTIVE) {\n totalCount\n }\n\n compatSessions(first: 0, state: ACTIVE) {\n totalCount\n }\n }\n", -): (typeof documents)["\n fragment UserSessionsOverview_user on User {\n id\n\n primaryEmail {\n id\n ...UserEmail_email\n }\n\n confirmedEmails: emails(first: 0, state: CONFIRMED) {\n totalCount\n }\n\n browserSessions(first: 0, state: ACTIVE) {\n totalCount\n }\n\n oauth2Sessions(first: 0, state: ACTIVE) {\n totalCount\n }\n\n compatSessions(first: 0, state: ACTIVE) {\n totalCount\n }\n }\n"]; + source: "\n fragment BrowserSessionsOverview_user on User {\n id\n\n browserSessions(first: 0, state: ACTIVE) {\n totalCount\n }\n }\n", +): (typeof documents)["\n fragment BrowserSessionsOverview_user on User {\n id\n\n browserSessions(first: 0, state: ACTIVE) {\n totalCount\n }\n }\n"]; /** * The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. */ @@ -277,8 +277,8 @@ export function graphql( * 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 SessionsOverviewQuery {\n viewer {\n __typename\n\n ... on User {\n id\n ...UserSessionsOverview_user\n }\n }\n }\n", -): (typeof documents)["\n query SessionsOverviewQuery {\n viewer {\n __typename\n\n ... on User {\n id\n ...UserSessionsOverview_user\n }\n }\n }\n"]; + source: "\n query SessionsOverviewQuery {\n viewer {\n __typename\n\n ... on User {\n id\n ...BrowserSessionsOverview_user\n }\n }\n }\n", +): (typeof documents)["\n query SessionsOverviewQuery {\n viewer {\n __typename\n\n ... on User {\n id\n ...BrowserSessionsOverview_user\n }\n }\n }\n"]; /** * The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. */ diff --git a/frontend/src/gql/graphql.ts b/frontend/src/gql/graphql.ts index a140bd0b..c471b040 100644 --- a/frontend/src/gql/graphql.ts +++ b/frontend/src/gql/graphql.ts @@ -1496,12 +1496,12 @@ export type AppSessionListQuery = { __typename?: "AppSessionEdge"; cursor: string; node: - | ({ __typename?: "CompatSession" } & { + | ({ __typename: "CompatSession" } & { " $fragmentRefs"?: { CompatSession_SessionFragment: CompatSession_SessionFragment; }; }) - | ({ __typename?: "Oauth2Session" } & { + | ({ __typename: "Oauth2Session" } & { " $fragmentRefs"?: { OAuth2Session_SessionFragment: OAuth2Session_SessionFragment; }; @@ -1518,28 +1518,14 @@ export type AppSessionListQuery = { } | null; }; -export type UserSessionsOverview_UserFragment = { +export type BrowserSessionsOverview_UserFragment = { __typename?: "User"; id: string; - primaryEmail?: - | ({ __typename?: "UserEmail"; id: string } & { - " $fragmentRefs"?: { UserEmail_EmailFragment: UserEmail_EmailFragment }; - }) - | null; - confirmedEmails: { __typename?: "UserEmailConnection"; totalCount: number }; browserSessions: { __typename?: "BrowserSessionConnection"; totalCount: number; }; - oauth2Sessions: { - __typename?: "Oauth2SessionConnection"; - totalCount: number; - }; - compatSessions: { - __typename?: "CompatSessionConnection"; - totalCount: number; - }; -} & { " $fragmentName"?: "UserSessionsOverview_UserFragment" }; +} & { " $fragmentName"?: "BrowserSessionsOverview_UserFragment" }; export type UserEmail_VerifyEmailFragment = { __typename?: "UserEmail"; @@ -1646,7 +1632,7 @@ export type SessionsOverviewQueryQuery = { | { __typename: "Anonymous" } | ({ __typename: "User"; id: string } & { " $fragmentRefs"?: { - UserSessionsOverview_UserFragment: UserSessionsOverview_UserFragment; + BrowserSessionsOverview_UserFragment: BrowserSessionsOverview_UserFragment; }; }); }; @@ -1857,12 +1843,12 @@ export const UserEmail_EmailFragmentDoc = { }, ], } as unknown as DocumentNode; -export const UserSessionsOverview_UserFragmentDoc = { +export const BrowserSessionsOverview_UserFragmentDoc = { kind: "Document", definitions: [ { kind: "FragmentDefinition", - name: { kind: "Name", value: "UserSessionsOverview_user" }, + name: { kind: "Name", value: "BrowserSessionsOverview_user" }, typeCondition: { kind: "NamedType", name: { kind: "Name", value: "User" }, @@ -1871,43 +1857,6 @@ export const UserSessionsOverview_UserFragmentDoc = { kind: "SelectionSet", selections: [ { kind: "Field", name: { kind: "Name", value: "id" } }, - { - kind: "Field", - name: { kind: "Name", value: "primaryEmail" }, - selectionSet: { - kind: "SelectionSet", - selections: [ - { kind: "Field", name: { kind: "Name", value: "id" } }, - { - kind: "FragmentSpread", - name: { kind: "Name", value: "UserEmail_email" }, - }, - ], - }, - }, - { - kind: "Field", - alias: { kind: "Name", value: "confirmedEmails" }, - name: { kind: "Name", value: "emails" }, - arguments: [ - { - kind: "Argument", - name: { kind: "Name", value: "first" }, - value: { kind: "IntValue", value: "0" }, - }, - { - kind: "Argument", - name: { kind: "Name", value: "state" }, - value: { kind: "EnumValue", value: "CONFIRMED" }, - }, - ], - selectionSet: { - kind: "SelectionSet", - selections: [ - { kind: "Field", name: { kind: "Name", value: "totalCount" } }, - ], - }, - }, { kind: "Field", name: { kind: "Name", value: "browserSessions" }, @@ -1930,71 +1879,11 @@ export const UserSessionsOverview_UserFragmentDoc = { ], }, }, - { - kind: "Field", - name: { kind: "Name", value: "oauth2Sessions" }, - arguments: [ - { - kind: "Argument", - name: { kind: "Name", value: "first" }, - value: { kind: "IntValue", value: "0" }, - }, - { - kind: "Argument", - name: { kind: "Name", value: "state" }, - value: { kind: "EnumValue", value: "ACTIVE" }, - }, - ], - selectionSet: { - kind: "SelectionSet", - selections: [ - { kind: "Field", name: { kind: "Name", value: "totalCount" } }, - ], - }, - }, - { - kind: "Field", - name: { kind: "Name", value: "compatSessions" }, - arguments: [ - { - kind: "Argument", - name: { kind: "Name", value: "first" }, - value: { kind: "IntValue", value: "0" }, - }, - { - kind: "Argument", - name: { kind: "Name", value: "state" }, - value: { kind: "EnumValue", value: "ACTIVE" }, - }, - ], - selectionSet: { - kind: "SelectionSet", - selections: [ - { kind: "Field", name: { kind: "Name", value: "totalCount" } }, - ], - }, - }, - ], - }, - }, - { - kind: "FragmentDefinition", - name: { kind: "Name", value: "UserEmail_email" }, - typeCondition: { - kind: "NamedType", - name: { kind: "Name", value: "UserEmail" }, - }, - selectionSet: { - kind: "SelectionSet", - selections: [ - { kind: "Field", name: { kind: "Name", value: "id" } }, - { kind: "Field", name: { kind: "Name", value: "email" } }, - { kind: "Field", name: { kind: "Name", value: "confirmedAt" } }, ], }, }, ], -} as unknown as DocumentNode; +} as unknown as DocumentNode; export const UserEmail_VerifyEmailFragmentDoc = { kind: "Document", definitions: [ @@ -4138,6 +4027,10 @@ export const AppSessionListDocument = { selectionSet: { kind: "SelectionSet", selections: [ + { + kind: "Field", + name: { kind: "Name", value: "__typename" }, + }, { kind: "FragmentSpread", name: { @@ -4683,7 +4576,7 @@ export const SessionsOverviewQueryDocument = { kind: "FragmentSpread", name: { kind: "Name", - value: "UserSessionsOverview_user", + value: "BrowserSessionsOverview_user", }, }, ], @@ -4697,23 +4590,7 @@ export const SessionsOverviewQueryDocument = { }, { kind: "FragmentDefinition", - name: { kind: "Name", value: "UserEmail_email" }, - typeCondition: { - kind: "NamedType", - name: { kind: "Name", value: "UserEmail" }, - }, - selectionSet: { - kind: "SelectionSet", - selections: [ - { kind: "Field", name: { kind: "Name", value: "id" } }, - { kind: "Field", name: { kind: "Name", value: "email" } }, - { kind: "Field", name: { kind: "Name", value: "confirmedAt" } }, - ], - }, - }, - { - kind: "FragmentDefinition", - name: { kind: "Name", value: "UserSessionsOverview_user" }, + name: { kind: "Name", value: "BrowserSessionsOverview_user" }, typeCondition: { kind: "NamedType", name: { kind: "Name", value: "User" }, @@ -4722,43 +4599,6 @@ export const SessionsOverviewQueryDocument = { kind: "SelectionSet", selections: [ { kind: "Field", name: { kind: "Name", value: "id" } }, - { - kind: "Field", - name: { kind: "Name", value: "primaryEmail" }, - selectionSet: { - kind: "SelectionSet", - selections: [ - { kind: "Field", name: { kind: "Name", value: "id" } }, - { - kind: "FragmentSpread", - name: { kind: "Name", value: "UserEmail_email" }, - }, - ], - }, - }, - { - kind: "Field", - alias: { kind: "Name", value: "confirmedEmails" }, - name: { kind: "Name", value: "emails" }, - arguments: [ - { - kind: "Argument", - name: { kind: "Name", value: "first" }, - value: { kind: "IntValue", value: "0" }, - }, - { - kind: "Argument", - name: { kind: "Name", value: "state" }, - value: { kind: "EnumValue", value: "CONFIRMED" }, - }, - ], - selectionSet: { - kind: "SelectionSet", - selections: [ - { kind: "Field", name: { kind: "Name", value: "totalCount" } }, - ], - }, - }, { kind: "Field", name: { kind: "Name", value: "browserSessions" }, @@ -4781,50 +4621,6 @@ export const SessionsOverviewQueryDocument = { ], }, }, - { - kind: "Field", - name: { kind: "Name", value: "oauth2Sessions" }, - arguments: [ - { - kind: "Argument", - name: { kind: "Name", value: "first" }, - value: { kind: "IntValue", value: "0" }, - }, - { - kind: "Argument", - name: { kind: "Name", value: "state" }, - value: { kind: "EnumValue", value: "ACTIVE" }, - }, - ], - selectionSet: { - kind: "SelectionSet", - selections: [ - { kind: "Field", name: { kind: "Name", value: "totalCount" } }, - ], - }, - }, - { - kind: "Field", - name: { kind: "Name", value: "compatSessions" }, - arguments: [ - { - kind: "Argument", - name: { kind: "Name", value: "first" }, - value: { kind: "IntValue", value: "0" }, - }, - { - kind: "Argument", - name: { kind: "Name", value: "state" }, - value: { kind: "EnumValue", value: "ACTIVE" }, - }, - ], - selectionSet: { - kind: "SelectionSet", - selections: [ - { kind: "Field", name: { kind: "Name", value: "totalCount" } }, - ], - }, - }, ], }, }, diff --git a/frontend/src/graphql.ts b/frontend/src/graphql.ts index 75191ec1..5ad4c824 100644 --- a/frontend/src/graphql.ts +++ b/frontend/src/graphql.ts @@ -130,7 +130,7 @@ const exchanges = [ ]; export const client = createClient({ - url: "/graphql", + url: "/graphql?testtest", // Add the devtools exchange in development exchanges: import.meta.env.DEV ? [devtoolsExchange, ...exchanges] : exchanges, }); diff --git a/frontend/src/pages/SessionsOverview.tsx b/frontend/src/pages/SessionsOverview.tsx index 3e7b5cd1..34f630c7 100644 --- a/frontend/src/pages/SessionsOverview.tsx +++ b/frontend/src/pages/SessionsOverview.tsx @@ -30,7 +30,7 @@ const QUERY = graphql(/* GraphQL */ ` ... on User { id - ...UserSessionsOverview_user + ...BrowserSessionsOverview_user } } }