Skip to content

Commit

Permalink
Maintenance: Mobile - Replace onLoaded method with query
Browse files Browse the repository at this point in the history
  • Loading branch information
sheremet-va committed Apr 18, 2023
1 parent abac114 commit 388d806
Show file tree
Hide file tree
Showing 12 changed files with 148 additions and 129 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ export default (context: Ref<FormFieldContext<FieldEditorProps>>) => {
)

const getKnowledgeBaseMentions = async (query: string) => {
const { data } = await queryHandler.query({ query })
const { data } = await queryHandler.query({ variables: { query } })
return data?.knowledgeBaseAnswerSuggestions || []
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,10 +38,12 @@ export default (context: Ref<FormFieldContext<FieldEditorProps>>) => {
}

const { data } = await queryHandler.query({
query,
customerId: customerId && ensureGraphqlId('User', customerId),
ticketId: ticketId && ensureGraphqlId('Ticket', ticketId),
limit: LIMIT_QUERY_MODULES,
variables: {
query,
customerId: customerId && ensureGraphqlId('User', customerId),
ticketId: ticketId && ensureGraphqlId('Ticket', ticketId),
limit: LIMIT_QUERY_MODULES,
},
})
return data?.textModuleSuggestions || []
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,10 @@ export default (context: Ref<FormFieldContext<FieldEditorProps>>) => {

const getUserMentions = async (query: string, group: string) => {
const { data } = await queryMentionsHandler.query({
query,
groupId: ensureGraphqlId('Group', group),
variables: {
query,
groupId: ensureGraphqlId('Group', group),
},
})
return data?.mentionSuggestions || []
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ const useAuthenticationChanges = () => {

authentication.$subscribe(async (mutation, state) => {
if (state.authenticated && !session.id) {
console.log('SUBSCRIBE-ZZZZZZZZZZZZZZZZZ')
session.checkSession().then(async (sessionId) => {
if (sessionId) {
await authentication.refreshAfterAuthentication()
Expand Down
6 changes: 4 additions & 2 deletions app/frontend/shared/composables/useTicketSignature.ts
Original file line number Diff line number Diff line change
Expand Up @@ -82,8 +82,10 @@ export const useTicketSignature = (ticket?: Ref<TicketById | undefined>) => {

signatureQuery
.query({
groupId: convertToGraphQLId('Group', String(groupId)),
ticketId: ticket?.value?.id,
variables: {
groupId: convertToGraphQLId('Group', String(groupId)),
ticketId: ticket?.value?.id,
},
})
.then(({ data: signature }) => {
const body = signature?.ticketSignature?.renderedBody
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,10 @@ const addSignature = async (
) => {
const ticketSignature = getTicketSignatureQuery()
const { data: signature } = await ticketSignature.query({
groupId: ticket.group.id,
ticketId: ticket.id,
variables: {
groupId: ticket.group.id,
ticketId: ticket.id,
},
})
const text = signature?.ticketSignature?.renderedBody
const id = signature?.ticketSignature?.id
Expand Down
6 changes: 3 additions & 3 deletions app/frontend/shared/i18n/availableLocales.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// Copyright (C) 2012-2023 Zammad Foundation, https://zammad-foundation.org/

import { QueryHandler } from '@shared/server/apollo/handler'
import { useLocalesQuery } from '@shared/graphql/queries/locales.api'
import { useLocalesLazyQuery } from '@shared/graphql/queries/locales.api'
import type { LocalesQuery } from '@shared/graphql/types'

let availableLocales: Maybe<LocalesQuery['locales']>
Expand All @@ -11,8 +11,8 @@ const getAvailableLocales = async (): Promise<
> => {
if (availableLocales !== undefined) return availableLocales

const query = new QueryHandler(useLocalesQuery({ onlyActive: true }))
const result = await query.loadedResult()
const query = new QueryHandler(useLocalesLazyQuery({ onlyActive: true }))
const { data: result } = await query.query()

availableLocales = result?.locales || null

Expand Down
101 changes: 53 additions & 48 deletions app/frontend/shared/server/apollo/handler/QueryHandler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import type {
FetchMoreQueryOptions,
ObservableQuery,
OperationVariables,
QueryOptions,
SubscribeToMoreOptions,
} from '@apollo/client/core'
import type {
Expand All @@ -19,6 +20,7 @@ import type {
import type { ReactiveFunction } from '@shared/types/utils'
import type { UseQueryOptions, UseQueryReturn } from '@vue/apollo-composable'
import { useApolloClient } from '@vue/apollo-composable'
import { getOperationName } from '@apollo/client/utilities'
import BaseHandler from './BaseHandler'

export default class QueryHandler<
Expand All @@ -29,31 +31,72 @@ export default class QueryHandler<
TVariables,
UseQueryReturn<TResult, TVariables>
> {
private firstResultLoaded = false

private lastCancel: (() => void) | null = null

public cancel() {
this.lastCancel?.()
}

public async query(variables?: TVariables) {
/**
* Calls the query immidiately and returns the result in `data` property.
*
* Will throw an error, if used with "useQuery" instead of "useLazyQuery".
*
* Returns cached result, if there is one. Otherwise, will
* `fetch` the result from the server.
*
* If called multiple times, cancels the previous query.
*
* Respects options that were defined in `useLazyQuery`, but can be overriden.
*
* If an error was throws, `data` is `null`, and `error` is the thrown error.
*/
public async query(
options: Omit<QueryOptions<TVariables, TResult>, 'query'> = {},
) {
const {
options: defaultOptions,
document: { value: node },
} = this.operationResult
if (import.meta.env.DEV && !('load' in this.operationResult)) {
let error = `${getOperationName(
node,
)} is initialized with "useQuery" instead of "useLazyQuery". `
error += `If you need to get the value immediately with ".query()", use "useLazyQuery" instead to not start extra network requests. `
error += `"useQuery" should be used inside components to dynamically react to changed data.`
throw new Error(error)
}
this.cancel()
const node = this.operationResult.document.value
const { client } = useApolloClient()
const aborter =
typeof AbortController !== 'undefined' ? new AbortController() : null
this.lastCancel = () => aborter?.abort()
const { fetchPolicy: defaultFetchPolicy, ...defaultOptionsValue } =
'value' in defaultOptions ? defaultOptions.value : defaultOptions
const fetchPolicy =
options.fetchPolicy ||
(defaultFetchPolicy !== 'cache-and-network'
? defaultFetchPolicy
: undefined)
try {
return await client.query<TResult, TVariables>({
...defaultOptionsValue,
...options,
fetchPolicy,
query: node,
variables,
context: {
...defaultOptionsValue.context,
...options.context,
fetchOptions: {
signal: aborter?.signal,
},
},
})
} catch (error) {
return {
data: null,
error,
}
} finally {
this.lastCancel = null
}
Expand Down Expand Up @@ -116,18 +159,20 @@ export default class QueryHandler<
})
}

public refetch(variables?: TVariables): Promise<Maybe<TResult>> {
public refetch(
variables?: TVariables,
): Promise<{ data: Maybe<TResult>; error?: unknown }> {
return new Promise((resolve, reject) => {
const refetch = this.operationResult.refetch(variables)

if (!refetch) {
resolve(null)
resolve({ data: null })
return
}

refetch
.then((result) => {
resolve(result.data)
resolve({ data: result.data })
})
.catch(() => {
reject(this.operationError().value)
Expand Down Expand Up @@ -159,7 +204,6 @@ export default class QueryHandler<
}

public stop(): void {
this.firstResultLoaded = false
this.operationResult.stop()
}

Expand All @@ -168,45 +212,6 @@ export default class QueryHandler<
this.operationResult.start()
}

public async onLoaded(
triggerPossibleRefetch = false,
): Promise<Maybe<TResult>> {
if (this.firstResultLoaded && triggerPossibleRefetch) {
return this.refetch()
}

return new Promise((resolve, reject) => {
let errorUnsubscribe!: () => void
let resultUnsubscribe!: () => void

const onFirstResultLoaded = () => {
this.firstResultLoaded = true
resultUnsubscribe()
errorUnsubscribe()
}

resultUnsubscribe = watch(this.result(), (result) => {
// After a variable change, the result will be reseted.
if (result === undefined) return null

// Remove the watchers again after the promise was resolved.
onFirstResultLoaded()
return resolve(result || null)
})

errorUnsubscribe = watch(this.operationError(), (error) => {
onFirstResultLoaded()
return reject(error)
})
})
}

public loadedResult(triggerPossibleRefetch = false): Promise<Maybe<TResult>> {
return this.onLoaded(triggerPossibleRefetch)
.then((data: Maybe<TResult>) => data)
.catch((error) => error)
}

public watchOnceOnResult(callback: WatchResultCallback<TResult>) {
const watchStopHandle = watch(
this.result(),
Expand Down
Loading

0 comments on commit 388d806

Please sign in to comment.