mirror of
https://github.com/zammad/zammad
synced 2026-05-24 09:48:36 +00:00
90 lines
2.5 KiB
TypeScript
90 lines
2.5 KiB
TypeScript
// Copyright (C) 2012-2026 Zammad Foundation, https://zammad-foundation.org/
|
|
|
|
import { watch } from 'vue'
|
|
|
|
import type {
|
|
OperationSubscriptionOptionsReturn,
|
|
OperationSubscriptionsResult,
|
|
WatchResultCallback,
|
|
} from '#shared/types/server/apollo/handler.ts'
|
|
|
|
import { BaseHandler } from './BaseHandler.ts'
|
|
|
|
import type { FetchResult, OperationVariables } from '@apollo/client/core'
|
|
import type { UseSubscriptionReturn } from '@vue/apollo-composable'
|
|
import type { Ref, WatchStopHandle } from 'vue'
|
|
|
|
export default class SubscriptionHandler<
|
|
TResult = OperationSubscriptionsResult,
|
|
TVariables extends OperationVariables = OperationVariables,
|
|
> extends BaseHandler<TResult, TVariables, UseSubscriptionReturn<TResult, TVariables>> {
|
|
public subscribed = false
|
|
|
|
public options(): OperationSubscriptionOptionsReturn<TResult, TVariables> {
|
|
return this.operationResult.options
|
|
}
|
|
|
|
public start(): void {
|
|
this.operationResult.start()
|
|
}
|
|
|
|
public stop(): void {
|
|
this.operationResult.stop()
|
|
}
|
|
|
|
public result(): Ref<Maybe<TResult> | undefined> {
|
|
return this.operationResult.result
|
|
}
|
|
|
|
public onResult(
|
|
callback: (
|
|
result: FetchResult<TResult, Record<string, unknown>, Record<string, unknown>>,
|
|
) => void,
|
|
) {
|
|
this.operationResult.onResult(callback)
|
|
}
|
|
|
|
public async onSubscribed(): Promise<Maybe<TResult> | undefined> {
|
|
return new Promise((resolve, reject) => {
|
|
// eslint-disable-next-line prefer-const
|
|
let errorUnsubscribe!: () => void
|
|
// eslint-disable-next-line prefer-const
|
|
let resultUnsubscribe!: () => void
|
|
|
|
const onFirstResultLoaded = () => {
|
|
resultUnsubscribe()
|
|
errorUnsubscribe()
|
|
}
|
|
|
|
resultUnsubscribe = watch(this.result(), (result) => {
|
|
this.subscribed = true
|
|
|
|
// Remove the watchers again after the promise was resolved.
|
|
onFirstResultLoaded()
|
|
return resolve(result || null)
|
|
})
|
|
|
|
errorUnsubscribe = watch(this.operationError(), (error) => {
|
|
onFirstResultLoaded()
|
|
return reject(error)
|
|
})
|
|
})
|
|
}
|
|
|
|
public watchOnResult(callback: WatchResultCallback<TResult>): WatchStopHandle {
|
|
return watch(
|
|
this.result(),
|
|
(result) => {
|
|
if (!result) {
|
|
return
|
|
}
|
|
callback(result)
|
|
},
|
|
{
|
|
// Needed for when the component is mounted after the first mount, in this case
|
|
// result will already contain the data and the watch will otherwise not be triggered.
|
|
immediate: true,
|
|
},
|
|
)
|
|
}
|
|
}
|