mirror of
https://github.com/alkimake/paperclip.git
synced 2026-06-16 02:40:39 +09:00
Refine issue workflow surfaces and live updates
This commit is contained in:
parent
b4a58ba8a6
commit
03dff1a29a
48 changed files with 2800 additions and 1163 deletions
|
|
@ -23,6 +23,7 @@ describe("LiveUpdatesProvider issue invalidation", () => {
|
|||
action: "issue.updated",
|
||||
details: null,
|
||||
},
|
||||
{ userId: null, agentId: null },
|
||||
);
|
||||
|
||||
expect(invalidations).toContainEqual({
|
||||
|
|
@ -81,12 +82,87 @@ describe("LiveUpdatesProvider issue invalidation", () => {
|
|||
action: "issue.comment_added",
|
||||
details: null,
|
||||
},
|
||||
{ userId: null, agentId: null },
|
||||
);
|
||||
|
||||
expect(invalidations).toContainEqual({
|
||||
queryKey: queryKeys.issues.comments("issue-1"),
|
||||
});
|
||||
});
|
||||
|
||||
it("keeps self-authored comment events from refetching the active issue tree", () => {
|
||||
const invalidations: unknown[] = [];
|
||||
const queryClient = {
|
||||
invalidateQueries: (input: unknown) => {
|
||||
invalidations.push(input);
|
||||
},
|
||||
getQueryData: () => undefined,
|
||||
};
|
||||
|
||||
__liveUpdatesTestUtils.invalidateActivityQueries(
|
||||
queryClient as never,
|
||||
"company-1",
|
||||
{
|
||||
entityType: "issue",
|
||||
entityId: "issue-1",
|
||||
action: "issue.comment_added",
|
||||
actorType: "user",
|
||||
actorId: "user-1",
|
||||
details: null,
|
||||
},
|
||||
{ userId: "user-1", agentId: null },
|
||||
);
|
||||
|
||||
expect(invalidations).toContainEqual({
|
||||
queryKey: queryKeys.issues.detail("issue-1"),
|
||||
refetchType: "inactive",
|
||||
});
|
||||
expect(invalidations).toContainEqual({
|
||||
queryKey: queryKeys.issues.activity("issue-1"),
|
||||
refetchType: "inactive",
|
||||
});
|
||||
expect(invalidations).toContainEqual({
|
||||
queryKey: queryKeys.issues.comments("issue-1"),
|
||||
refetchType: "inactive",
|
||||
});
|
||||
});
|
||||
|
||||
it("treats self-authored comment-driven issue updates as inactive-only refreshes", () => {
|
||||
const invalidations: unknown[] = [];
|
||||
const queryClient = {
|
||||
invalidateQueries: (input: unknown) => {
|
||||
invalidations.push(input);
|
||||
},
|
||||
getQueryData: () => undefined,
|
||||
};
|
||||
|
||||
__liveUpdatesTestUtils.invalidateActivityQueries(
|
||||
queryClient as never,
|
||||
"company-1",
|
||||
{
|
||||
entityType: "issue",
|
||||
entityId: "issue-1",
|
||||
action: "issue.updated",
|
||||
actorType: "user",
|
||||
actorId: "user-1",
|
||||
details: { source: "comment" },
|
||||
},
|
||||
{ userId: "user-1", agentId: null },
|
||||
);
|
||||
|
||||
expect(invalidations).toContainEqual({
|
||||
queryKey: queryKeys.issues.detail("issue-1"),
|
||||
refetchType: "inactive",
|
||||
});
|
||||
expect(invalidations).toContainEqual({
|
||||
queryKey: queryKeys.issues.activity("issue-1"),
|
||||
refetchType: "inactive",
|
||||
});
|
||||
expect(invalidations).not.toContainEqual({
|
||||
queryKey: queryKeys.issues.comments("issue-1"),
|
||||
refetchType: "inactive",
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe("LiveUpdatesProvider visible issue toast suppression", () => {
|
||||
|
|
|
|||
|
|
@ -480,6 +480,7 @@ function invalidateActivityQueries(
|
|||
queryClient: ReturnType<typeof useQueryClient>,
|
||||
companyId: string,
|
||||
payload: Record<string, unknown>,
|
||||
currentActor: { userId: string | null; agentId: string | null },
|
||||
) {
|
||||
queryClient.invalidateQueries({ queryKey: queryKeys.activity(companyId) });
|
||||
queryClient.invalidateQueries({ queryKey: queryKeys.dashboard(companyId) });
|
||||
|
|
@ -488,6 +489,8 @@ function invalidateActivityQueries(
|
|||
const entityType = readString(payload.entityType);
|
||||
const entityId = readString(payload.entityId);
|
||||
const action = readString(payload.action);
|
||||
const actorType = readString(payload.actorType);
|
||||
const actorId = readString(payload.actorId);
|
||||
|
||||
if (entityType === "issue") {
|
||||
queryClient.invalidateQueries({ queryKey: queryKeys.issues.list(companyId) });
|
||||
|
|
@ -496,12 +499,18 @@ function invalidateActivityQueries(
|
|||
queryClient.invalidateQueries({ queryKey: queryKeys.issues.listUnreadTouchedByMe(companyId) });
|
||||
if (entityId) {
|
||||
const details = readRecord(payload.details);
|
||||
const selfCommentActivity =
|
||||
((action === "issue.comment_added") ||
|
||||
(action === "issue.updated" && readString(details?.source) === "comment")) &&
|
||||
((actorType === "user" && !!currentActor.userId && actorId === currentActor.userId) ||
|
||||
(actorType === "agent" && !!currentActor.agentId && actorId === currentActor.agentId));
|
||||
const issueRefs = resolveIssueQueryRefs(queryClient, companyId, entityId, details);
|
||||
for (const ref of issueRefs) {
|
||||
queryClient.invalidateQueries({ queryKey: queryKeys.issues.detail(ref) });
|
||||
queryClient.invalidateQueries({ queryKey: queryKeys.issues.activity(ref) });
|
||||
const invalidationOptions = selfCommentActivity ? { refetchType: "inactive" as const } : undefined;
|
||||
queryClient.invalidateQueries({ queryKey: queryKeys.issues.detail(ref), ...invalidationOptions });
|
||||
queryClient.invalidateQueries({ queryKey: queryKeys.issues.activity(ref), ...invalidationOptions });
|
||||
if (action === "issue.comment_added") {
|
||||
queryClient.invalidateQueries({ queryKey: queryKeys.issues.comments(ref) });
|
||||
queryClient.invalidateQueries({ queryKey: queryKeys.issues.comments(ref), ...invalidationOptions });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -646,7 +655,7 @@ function handleLiveEvent(
|
|||
}
|
||||
|
||||
if (event.type === "activity.logged") {
|
||||
invalidateActivityQueries(queryClient, expectedCompanyId, payload);
|
||||
invalidateActivityQueries(queryClient, expectedCompanyId, payload, currentActor);
|
||||
const action = readString(payload.action);
|
||||
const toast =
|
||||
buildActivityToast(queryClient, expectedCompanyId, payload, currentActor) ??
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue