mirror of
https://github.com/docmost/docmost.git
synced 2026-05-08 23:33:09 +08:00
ca9558b246
* feat: resolve comment (EE) * Add resolve to comment mark in editor (EE) * comment ui permissions * sticky comment state tabs (EE) * cleanup * feat: add space_id to comments and allow space admins to delete any comment - Add space_id column to comments table with data migration from pages - Add last_edited_by_id, resolved_by_id, and updated_at columns to comments - Update comment deletion permissions to allow space admins to delete any comment - Backfill space_id on old comments * fix foreign keys
128 lines
4.0 KiB
TypeScript
128 lines
4.0 KiB
TypeScript
import React from "react";
|
|
import { socketAtom } from "@/features/websocket/atoms/socket-atom.ts";
|
|
import { useAtom } from "jotai";
|
|
import { InfiniteData, useQueryClient } from "@tanstack/react-query";
|
|
import { WebSocketEvent } from "@/features/websocket/types";
|
|
import { IPage } from "../page/types/page.types";
|
|
import { IPagination } from "@/lib/types";
|
|
import {
|
|
invalidateOnCreatePage,
|
|
invalidateOnDeletePage,
|
|
invalidateOnMovePage,
|
|
invalidateOnUpdatePage,
|
|
} from "../page/queries/page-query";
|
|
import { RQ_KEY } from "../comment/queries/comment-query";
|
|
import { queryClient } from "@/main.tsx";
|
|
import { IComment } from "@/features/comment/types/comment.types";
|
|
|
|
export const useQuerySubscription = () => {
|
|
const queryClient = useQueryClient();
|
|
const [socket] = useAtom(socketAtom);
|
|
|
|
React.useEffect(() => {
|
|
socket?.on("message", (event) => {
|
|
const data: WebSocketEvent = event;
|
|
|
|
let entity = null;
|
|
let queryKeyId = null;
|
|
|
|
switch (data.operation) {
|
|
case "invalidate":
|
|
queryClient.invalidateQueries({
|
|
queryKey: [...data.entity, data.id].filter(Boolean),
|
|
});
|
|
break;
|
|
case "invalidateComment":
|
|
queryClient.invalidateQueries({
|
|
queryKey: RQ_KEY(data.pageId),
|
|
});
|
|
break;
|
|
case "addTreeNode":
|
|
invalidateOnCreatePage(data.payload.data);
|
|
break;
|
|
case "moveTreeNode":
|
|
invalidateOnMovePage();
|
|
break;
|
|
case "deleteTreeNode":
|
|
invalidateOnDeletePage(data.payload.node.id);
|
|
break;
|
|
case "updateOne":
|
|
entity = data.entity[0];
|
|
if (entity === "pages") {
|
|
// we have to do this because the usePageQuery cache key is the slugId.
|
|
queryKeyId = data.payload.slugId;
|
|
} else {
|
|
queryKeyId = data.id;
|
|
}
|
|
|
|
// only update if data was already in cache
|
|
if (queryClient.getQueryData([...data.entity, queryKeyId])) {
|
|
queryClient.setQueryData([...data.entity, queryKeyId], {
|
|
...queryClient.getQueryData([...data.entity, queryKeyId]),
|
|
...data.payload,
|
|
});
|
|
}
|
|
|
|
if (entity === "pages") {
|
|
invalidateOnUpdatePage(
|
|
data.spaceId,
|
|
data.payload.parentPageId,
|
|
data.id,
|
|
data.payload.title,
|
|
data.payload.icon,
|
|
);
|
|
}
|
|
|
|
/*
|
|
queryClient.setQueriesData(
|
|
{ queryKey: [data.entity, data.id] },
|
|
(oldData: any) => {
|
|
const update = (entity: Record<string, unknown>) =>
|
|
entity.id === data.id ? { ...entity, ...data.payload } : entity;
|
|
return Array.isArray(oldData)
|
|
? oldData.map(update)
|
|
: update(oldData as Record<string, unknown>);
|
|
},
|
|
);
|
|
*/
|
|
break;
|
|
case "refetchRootTreeNodeEvent": {
|
|
const spaceId = data.spaceId;
|
|
queryClient.refetchQueries({
|
|
queryKey: ["root-sidebar-pages", spaceId],
|
|
});
|
|
|
|
queryClient.invalidateQueries({
|
|
queryKey: ["recent-changes", spaceId],
|
|
});
|
|
break;
|
|
}
|
|
case "resolveComment": {
|
|
const currentComments = queryClient.getQueryData(
|
|
RQ_KEY(data.pageId),
|
|
) as IPagination<IComment>;
|
|
|
|
if (currentComments && currentComments.items) {
|
|
const updatedComments = currentComments.items.map((comment) =>
|
|
comment.id === data.commentId
|
|
? {
|
|
...comment,
|
|
resolvedAt: data.resolvedAt,
|
|
resolvedById: data.resolvedById,
|
|
resolvedBy: data.resolvedBy
|
|
}
|
|
: comment,
|
|
);
|
|
|
|
queryClient.setQueryData(RQ_KEY(data.pageId), {
|
|
...currentComments,
|
|
items: updatedComments,
|
|
});
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
});
|
|
}, [queryClient, socket]);
|
|
};
|