From 4b49b83b138415c3e8e7454f0f2a4176de9af3df Mon Sep 17 00:00:00 2001 From: John Chilton Date: Tue, 24 Oct 2023 22:36:52 -0400 Subject: [PATCH] Fix GQL infinite scrolling in tool shed. --- lib/tool_shed/webapp/frontend/src/apollo.ts | 12 +++- .../src/components/RepositoriesForOwner.vue | 39 ++++-------- .../src/components/RepositoriesGrid.vue | 25 +------- .../pages/RepositoriesByCategory.vue | 43 +++++-------- .../webapp/frontend/src/relayClient.ts | 63 +++++++++++++++++++ 5 files changed, 103 insertions(+), 79 deletions(-) create mode 100644 lib/tool_shed/webapp/frontend/src/relayClient.ts diff --git a/lib/tool_shed/webapp/frontend/src/apollo.ts b/lib/tool_shed/webapp/frontend/src/apollo.ts index 572617f52fc8..b43a3bb3eda7 100644 --- a/lib/tool_shed/webapp/frontend/src/apollo.ts +++ b/lib/tool_shed/webapp/frontend/src/apollo.ts @@ -1,6 +1,15 @@ import { createApolloProvider } from "@vue/apollo-option" import { ApolloClient, InMemoryCache, DefaultOptions } from "@apollo/client/core" +import { loadErrorMessages, loadDevMessages } from "@apollo/client/dev" + +const dev = false +if (dev) { + // Adds messages only in a dev environment + loadDevMessages() + loadErrorMessages() +} + const defaultOptions: DefaultOptions = { watchQuery: { fetchPolicy: "no-cache", @@ -12,9 +21,10 @@ const defaultOptions: DefaultOptions = { }, } +export const cache = new InMemoryCache() export const apolloClient = new ApolloClient({ uri: "/api/graphql/", - cache: new InMemoryCache(), + cache: cache, defaultOptions: defaultOptions, }) diff --git a/lib/tool_shed/webapp/frontend/src/components/RepositoriesForOwner.vue b/lib/tool_shed/webapp/frontend/src/components/RepositoriesForOwner.vue index 28fe8e1f8b35..5db3578ca516 100644 --- a/lib/tool_shed/webapp/frontend/src/components/RepositoriesForOwner.vue +++ b/lib/tool_shed/webapp/frontend/src/components/RepositoriesForOwner.vue @@ -5,7 +5,8 @@ import { nodeToRow } from "@/components/RepositoriesGridInterface" import ErrorBanner from "@/components/ErrorBanner.vue" import LoadingDiv from "@/components/LoadingDiv.vue" import { graphql } from "@/gql" -import { useQuery } from "@vue/apollo-composable" +import type { Query, RelayRepositoryConnection } from "@/gql/graphql" +import { useRelayInfiniteScrollQuery } from "@/relayClient" interface RepositoriesByOwnerProps { username: string @@ -30,34 +31,18 @@ const query = graphql(/* GraphQL */ ` } `) -async function onScroll(): Promise { - const cursor = result.value?.relayRepositoriesForOwner?.pageInfo.endCursor || null - fetchMore({ - variables: { - username: props.username, - cursor: cursor, - }, - // eslint-disable-next-line @typescript-eslint/ban-ts-comment - // @ts-ignore - updateQuery: (previousResult, { fetchMoreResult }) => { - const newRepos = fetchMoreResult?.relayRepositoriesForOwner?.edges || [] - const edges = [...(previousResult?.relayRepositoriesForOwner?.edges || []), ...newRepos] - const pageInfo = { ...fetchMoreResult?.relayRepositoriesForOwner?.pageInfo } - return { - relayRepositoriesForOwner: { - __typename: fetchMoreResult?.relayRepositoriesForOwner?.__typename, - // Merging the tag list - edges: edges, - pageInfo: pageInfo, - }, - } - }, - }) +function toResult(queryResult: Query): RelayRepositoryConnection { + const result = queryResult.relayRepositoriesForOwner + if (!result) { + throw Error("problem") + } + return result as RelayRepositoryConnection } -const { result, loading, error, fetchMore } = useQuery(query, { username: props.username }) + +const { records, error, loading, onScroll } = useRelayInfiniteScrollQuery(query, { username: props.username }, toResult) + const rows = computed(() => { - const nodes = result.value?.relayRepositoriesForOwner?.edges.map((v) => v?.node) - return nodes?.map(nodeToRow) || [] + return records.value.map(nodeToRow) }) -