87 lines
2.8 KiB
TypeScript
87 lines
2.8 KiB
TypeScript
import type { QueryClient, QueryKey } from "@tanstack/react-query";
|
|
import type { Issue } from "@paperclipai/shared";
|
|
import { queryKeys } from "./queryKeys";
|
|
|
|
export type InboxIssueCacheSnapshot = Array<readonly [QueryKey, Issue[] | undefined]>;
|
|
|
|
function inboxIssueQueryPrefixes(companyId: string) {
|
|
return [
|
|
queryKeys.issues.listMineByMe(companyId),
|
|
queryKeys.issues.listTouchedByMe(companyId),
|
|
queryKeys.issues.listUnreadTouchedByMe(companyId),
|
|
] as const;
|
|
}
|
|
|
|
function resolveRestoreIndex(currentData: Issue[], previousData: Issue[], previousIndex: number) {
|
|
for (let index = previousIndex - 1; index >= 0; index -= 1) {
|
|
const beforeIndex = currentData.findIndex((issue) => issue.id === previousData[index]?.id);
|
|
if (beforeIndex >= 0) return beforeIndex + 1;
|
|
}
|
|
|
|
for (let index = previousIndex + 1; index < previousData.length; index += 1) {
|
|
const afterIndex = currentData.findIndex((issue) => issue.id === previousData[index]?.id);
|
|
if (afterIndex >= 0) return afterIndex;
|
|
}
|
|
|
|
return Math.min(previousIndex, currentData.length);
|
|
}
|
|
|
|
export async function cancelInboxIssueQueries(queryClient: QueryClient, companyId: string) {
|
|
await Promise.all(
|
|
inboxIssueQueryPrefixes(companyId).map((queryKey) =>
|
|
queryClient.cancelQueries({ queryKey }),
|
|
),
|
|
);
|
|
}
|
|
|
|
export function snapshotInboxIssueCaches(
|
|
queryClient: QueryClient,
|
|
companyId: string,
|
|
): InboxIssueCacheSnapshot {
|
|
return inboxIssueQueryPrefixes(companyId).flatMap((queryKey) =>
|
|
queryClient.getQueriesData<Issue[]>({ queryKey }),
|
|
);
|
|
}
|
|
|
|
export function removeIssueFromInboxCaches(
|
|
queryClient: QueryClient,
|
|
companyId: string,
|
|
issueId: string,
|
|
) {
|
|
for (const queryKey of inboxIssueQueryPrefixes(companyId)) {
|
|
queryClient.setQueriesData<Issue[]>(
|
|
{ queryKey },
|
|
(cached) => cached?.filter((issue) => issue.id !== issueId),
|
|
);
|
|
}
|
|
}
|
|
|
|
export function restoreIssueToInboxCaches(
|
|
queryClient: QueryClient,
|
|
snapshot: InboxIssueCacheSnapshot,
|
|
issueId: string,
|
|
) {
|
|
for (const [queryKey, previousData] of snapshot) {
|
|
if (!previousData) continue;
|
|
|
|
const previousIndex = previousData.findIndex((issue) => issue.id === issueId);
|
|
if (previousIndex < 0) continue;
|
|
|
|
const issueToRestore = previousData[previousIndex];
|
|
queryClient.setQueryData<Issue[]>(queryKey, (currentData) => {
|
|
if (currentData?.some((issue) => issue.id === issueId)) return currentData;
|
|
|
|
const nextData = [...(currentData ?? [])];
|
|
nextData.splice(resolveRestoreIndex(nextData, previousData, previousIndex), 0, issueToRestore);
|
|
return nextData;
|
|
});
|
|
}
|
|
}
|
|
|
|
export function invalidateInboxIssueQueries(queryClient: QueryClient, companyId: string) {
|
|
for (const queryKey of inboxIssueQueryPrefixes(companyId)) {
|
|
queryClient.invalidateQueries({ queryKey });
|
|
}
|
|
queryClient.invalidateQueries({ queryKey: queryKeys.sidebarBadges(companyId) });
|
|
}
|