mirror of
https://github.com/oxynote/oxynote.git
synced 2026-10-17 19:09:19 +02:00
394 lines
8.8 KiB
TypeScript
394 lines
8.8 KiB
TypeScript
import { nanoid } from "nanoid"
|
|
import isDeepEqual from "fast-deep-equal"
|
|
|
|
export const DOCUMENT_HOOK_QUERY_KEYS = {
|
|
list: (docId: string, branchId: string) =>
|
|
["documents", "hooks", docId, branchId] as const,
|
|
}
|
|
|
|
export default function () {
|
|
const { $coreAPIClient } = useNuxtApp()
|
|
const queryCache = useQueryCache()
|
|
const { fetchOrganization } = useAuthSession()
|
|
|
|
function useFetchDocumentHooksByDocID(
|
|
docIdRef: MaybeRefOrGetter<string | null | undefined>,
|
|
branchIdRef: MaybeRefOrGetter<string | null | undefined>,
|
|
) {
|
|
return useQuery({
|
|
key: () =>
|
|
DOCUMENT_HOOK_QUERY_KEYS.list(
|
|
toValue(docIdRef) || "",
|
|
toValue(branchIdRef) || "",
|
|
),
|
|
query: async () => {
|
|
const docId = toValue(docIdRef)
|
|
const branchId = toValue(branchIdRef)
|
|
if (!docId || !branchId) {
|
|
return []
|
|
}
|
|
|
|
const res = await $coreAPIClient<DocumentHooksResponse>(
|
|
`/api/documents/${docId}/hooks?branchId=${encodeURIComponent(branchId)}`,
|
|
{ method: "GET" },
|
|
)
|
|
|
|
return res
|
|
},
|
|
enabled: () => !!toValue(docIdRef) && !!toValue(branchIdRef),
|
|
refetchOnMount: false,
|
|
refetchOnWindowFocus: false,
|
|
refetchOnReconnect: false,
|
|
staleTime: 3 * 60 * 1000, // 3 mins
|
|
autoRefetch: true,
|
|
})
|
|
}
|
|
|
|
const createDocumentHookByDocID = useMutation({
|
|
onMutate: ({
|
|
docId,
|
|
req,
|
|
}: {
|
|
docId: string
|
|
req: DocumentHookCreateRequest
|
|
}) => {
|
|
if (!isXid(docId) || !isXid(req.branchId)) {
|
|
// optimisticInserts use nanoid
|
|
return
|
|
}
|
|
|
|
const organizationId = fetchOrganization.data.value?.data?.id
|
|
if (!organizationId) {
|
|
return
|
|
}
|
|
|
|
const key = DOCUMENT_HOOK_QUERY_KEYS.list(docId, req.branchId)
|
|
const oldHooks = clone(
|
|
queryCache.getQueryData<DocumentHooksResponse>(key),
|
|
)
|
|
const id = nanoid()
|
|
const newHook: DocumentHook = {
|
|
id: id,
|
|
crossBranchId: id,
|
|
type: req.type,
|
|
documentId: docId,
|
|
branchId: req.branchId,
|
|
organizationId: organizationId,
|
|
blockId: req.blockId,
|
|
settings: req.settings,
|
|
state: defaultDocumentHookState(req.type),
|
|
status: "active",
|
|
score: "100",
|
|
createdAt: new Date(),
|
|
updatedAt: new Date(),
|
|
}
|
|
const newHooks = [newHook, ...(oldHooks ?? [])]
|
|
|
|
queryCache.setQueryData(key, newHooks)
|
|
queryCache.cancelQueries({ key })
|
|
|
|
return { newHooks, oldHooks, key }
|
|
},
|
|
mutation: async ({
|
|
docId,
|
|
req,
|
|
}: {
|
|
docId: string
|
|
req: DocumentHookCreateRequest
|
|
}) => {
|
|
if (!isXid(docId) || !isXid(req.branchId)) {
|
|
// optimisticInserts use nanoid
|
|
return
|
|
}
|
|
|
|
return await $coreAPIClient<DocumentHookCreateResponse>(
|
|
`/api/documents/${docId}/hooks`,
|
|
{
|
|
method: "POST",
|
|
body: req,
|
|
},
|
|
)
|
|
},
|
|
async onSuccess(_data, { docId, req }) {
|
|
if (!isXid(docId) || !isXid(req.branchId)) {
|
|
// optimisticInserts use nanoid
|
|
return
|
|
}
|
|
|
|
// the key is rebuilt from the variables rather than read off the
|
|
// context: onMutate skips the optimistic insert (and its context)
|
|
// without an organization, but the request still went out
|
|
await queryCache.invalidateQueries({
|
|
key: DOCUMENT_HOOK_QUERY_KEYS.list(docId, req.branchId),
|
|
})
|
|
},
|
|
onError(_err, { docId, req }, ctx) {
|
|
if (!isXid(docId) || !isXid(req.branchId) || !ctx.key) {
|
|
return
|
|
}
|
|
|
|
const cachedHooks = queryCache.getQueryData<DocumentHooksResponse>(
|
|
ctx.key,
|
|
)
|
|
if (!isDeepEqual(ctx.newHooks, cachedHooks)) {
|
|
return
|
|
}
|
|
|
|
// rollback
|
|
queryCache.setQueryData(ctx.key, ctx.oldHooks)
|
|
},
|
|
})
|
|
|
|
const updateDocumentHookByDocID = useMutation({
|
|
onMutate: ({
|
|
docId,
|
|
branchId,
|
|
hookId,
|
|
req,
|
|
}: {
|
|
docId: string
|
|
branchId: string
|
|
hookId: string
|
|
req: DocumentHookUpdateRequest
|
|
}) => {
|
|
if (!isXid(docId) || !isXid(branchId) || !isXid(hookId)) {
|
|
// optimisticInserts use nanoid
|
|
return
|
|
}
|
|
|
|
const key = DOCUMENT_HOOK_QUERY_KEYS.list(docId, branchId)
|
|
const oldHooks = clone(
|
|
queryCache.getQueryData<DocumentHooksResponse>(key),
|
|
)
|
|
const newHooks = clone(oldHooks) ?? []
|
|
|
|
for (const h of newHooks) {
|
|
if (h.id === hookId) {
|
|
h.settings = req.settings
|
|
h.updatedAt = new Date()
|
|
|
|
break
|
|
}
|
|
}
|
|
|
|
queryCache.setQueryData(key, newHooks)
|
|
queryCache.cancelQueries({ key })
|
|
|
|
return { newHooks, oldHooks, key }
|
|
},
|
|
mutation: async ({
|
|
docId,
|
|
branchId,
|
|
hookId,
|
|
req,
|
|
}: {
|
|
docId: string
|
|
branchId: string
|
|
hookId: string
|
|
req: DocumentHookUpdateRequest
|
|
}) => {
|
|
if (!isXid(docId) || !isXid(branchId) || !isXid(hookId)) {
|
|
// optimisticInserts use nanoid
|
|
return
|
|
}
|
|
|
|
return await $coreAPIClient<DocumentHookUpdateResponse>(
|
|
`/api/documents/${docId}/hooks/${hookId}`,
|
|
{
|
|
method: "PUT",
|
|
body: req,
|
|
},
|
|
)
|
|
},
|
|
async onSuccess(_data, { docId, branchId, hookId }) {
|
|
if (!isXid(docId) || !isXid(branchId) || !isXid(hookId)) {
|
|
// optimisticInserts use nanoid
|
|
return
|
|
}
|
|
|
|
await queryCache.invalidateQueries({
|
|
key: DOCUMENT_HOOK_QUERY_KEYS.list(docId, branchId),
|
|
})
|
|
},
|
|
onError(_err, { docId, branchId, hookId }, ctx) {
|
|
if (!isXid(docId) || !isXid(branchId) || !isXid(hookId) || !ctx.key) {
|
|
return
|
|
}
|
|
|
|
const cachedHooks = queryCache.getQueryData(ctx.key)
|
|
if (!isDeepEqual(ctx.newHooks, cachedHooks)) {
|
|
return
|
|
}
|
|
|
|
// rollback
|
|
queryCache.setQueryData(ctx.key, ctx.oldHooks)
|
|
},
|
|
})
|
|
|
|
const deleteDocumentHookByDocID = useMutation({
|
|
onMutate: ({
|
|
docId,
|
|
branchId,
|
|
hookId,
|
|
}: {
|
|
docId: string
|
|
branchId: string
|
|
hookId: string
|
|
}) => {
|
|
if (!isXid(docId) || !isXid(branchId) || !isXid(hookId)) {
|
|
// optimisticInserts use nanoid
|
|
return
|
|
}
|
|
|
|
const key = DOCUMENT_HOOK_QUERY_KEYS.list(docId, branchId)
|
|
const oldHooks = clone(
|
|
queryCache.getQueryData<DocumentHooksResponse>(key),
|
|
)
|
|
const newHooks = clone(oldHooks) ?? []
|
|
|
|
const index = newHooks.findIndex((h) => h.id === hookId)
|
|
if (index !== -1) {
|
|
newHooks.splice(index, 1)
|
|
}
|
|
|
|
queryCache.setQueryData(key, newHooks)
|
|
queryCache.cancelQueries({ key })
|
|
|
|
return { newHooks, oldHooks, key }
|
|
},
|
|
mutation: async ({
|
|
docId,
|
|
branchId,
|
|
hookId,
|
|
}: {
|
|
docId: string
|
|
branchId: string
|
|
hookId: string
|
|
}) => {
|
|
if (!isXid(docId) || !isXid(branchId) || !isXid(hookId)) {
|
|
// optimisticInserts use nanoid
|
|
return
|
|
}
|
|
|
|
await $coreAPIClient(`/api/documents/${docId}/hooks/${hookId}`, {
|
|
method: "DELETE",
|
|
})
|
|
},
|
|
async onSuccess(_data, { docId, branchId, hookId }) {
|
|
if (!isXid(docId) || !isXid(branchId) || !isXid(hookId)) {
|
|
// optimisticInserts use nanoid
|
|
return
|
|
}
|
|
|
|
await queryCache.invalidateQueries({
|
|
key: DOCUMENT_HOOK_QUERY_KEYS.list(docId, branchId),
|
|
})
|
|
},
|
|
onError(_err, { docId, branchId, hookId }, ctx) {
|
|
if (!isXid(docId) || !isXid(branchId) || !isXid(hookId) || !ctx.key) {
|
|
return
|
|
}
|
|
|
|
const cachedHooks = queryCache.getQueryData(ctx.key)
|
|
if (!isDeepEqual(ctx.newHooks, cachedHooks)) {
|
|
return
|
|
}
|
|
|
|
// rollback
|
|
queryCache.setQueryData(ctx.key, ctx.oldHooks)
|
|
},
|
|
})
|
|
|
|
const resetDocumentHookByDocID = useMutation({
|
|
onMutate: ({
|
|
docId,
|
|
branchId,
|
|
hookId,
|
|
}: {
|
|
docId: string
|
|
branchId: string
|
|
hookId: string
|
|
}) => {
|
|
if (!isXid(docId) || !isXid(branchId) || !isXid(hookId)) {
|
|
// optimisticInserts use nanoid
|
|
return
|
|
}
|
|
|
|
const key = DOCUMENT_HOOK_QUERY_KEYS.list(docId, branchId)
|
|
const oldHooks = clone(
|
|
queryCache.getQueryData<DocumentHooksResponse>(key),
|
|
)
|
|
const newHooks = clone(oldHooks) ?? []
|
|
|
|
for (const h of newHooks) {
|
|
if (h.id === hookId) {
|
|
h.state = defaultDocumentHookState(h.type)
|
|
h.status = "active"
|
|
h.updatedAt = new Date()
|
|
|
|
break
|
|
}
|
|
}
|
|
|
|
queryCache.setQueryData(key, newHooks)
|
|
queryCache.cancelQueries({ key })
|
|
|
|
return { newHooks, oldHooks, key }
|
|
},
|
|
mutation: async ({
|
|
docId,
|
|
branchId,
|
|
hookId,
|
|
}: {
|
|
docId: string
|
|
branchId: string
|
|
hookId: string
|
|
}) => {
|
|
if (!isXid(docId) || !isXid(branchId) || !isXid(hookId)) {
|
|
// optimisticInserts use nanoid
|
|
return
|
|
}
|
|
|
|
return await $coreAPIClient<DocumentHookResponse>(
|
|
`/api/documents/${docId}/hooks/${hookId}/reset`,
|
|
{
|
|
method: "PUT",
|
|
},
|
|
)
|
|
},
|
|
async onSuccess(_data, { docId, branchId, hookId }) {
|
|
if (!isXid(docId) || !isXid(branchId) || !isXid(hookId)) {
|
|
// optimisticInserts use nanoid
|
|
return
|
|
}
|
|
|
|
await queryCache.invalidateQueries({
|
|
key: DOCUMENT_HOOK_QUERY_KEYS.list(docId, branchId),
|
|
})
|
|
},
|
|
onError(_err, { docId, branchId, hookId }, ctx) {
|
|
if (!isXid(docId) || !isXid(branchId) || !isXid(hookId) || !ctx.key) {
|
|
return
|
|
}
|
|
|
|
const cachedHooks = queryCache.getQueryData<DocumentHooksResponse>(
|
|
ctx.key,
|
|
)
|
|
if (!isDeepEqual(ctx.newHooks, cachedHooks)) {
|
|
return
|
|
}
|
|
|
|
// rollback
|
|
queryCache.setQueryData(ctx.key, ctx.oldHooks)
|
|
},
|
|
})
|
|
|
|
return {
|
|
useFetchDocumentHooksByDocID,
|
|
createDocumentHookByDocID,
|
|
updateDocumentHookByDocID,
|
|
deleteDocumentHookByDocID,
|
|
resetDocumentHookByDocID,
|
|
}
|
|
}
|