shoc-frontend-new/src/domain/work-orders/utils/comment-highlight.ts
albrand 74e7c526e8 fix(notifications): re-open tab and match API mentions for event highlights
Re-apply the requested slide-over tab on every open via an open counter, so a
second comment/mention notification for the work order already on screen still
switches to Comments and re-scrolls to the highlighted comment. Treat a board
comment's mentions id array (plain @Name text) as a mention alongside encoded
@[id:name] tokens so mention items highlight and comment items exclude them.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-09-18 14:01:55 -03:00

45 lines
2.1 KiB
TypeScript

import type { WorkOrderComment } from "@/domain/work-orders/types/work-order-detail";
import { isOwnWorkOrderComment } from "@/domain/work-orders/utils/comment-ownership";
import { extractMentionIds } from "@/domain/work-orders/utils/comment-mentions";
import type { CommentHighlight } from "@/domain/work-orders/utils/work-order-deep-link";
/**
* Ids of the comments a notification was raised for. The feed starts a comment item at its first
* unanswered comment and a mention item at the mentioning comment, so this is every comment by
* someone else from that moment on, split the same way the feed splits them: comments that
* mention the user belong to Mentions, the rest to Recent activity.
*/
// Board comment times arrive as UTC without a zone designator; read them as UTC, not local time.
function parseUtc(value: string): number {
return Date.parse(/(Z|[+-]\d{2}:?\d{2})$/i.test(value) ? value : `${value}Z`);
}
export function highlightedCommentIds(
comments: WorkOrderComment[],
highlight: CommentHighlight | null | undefined,
currentUserId: string | number | null | undefined,
): Set<string> {
const ids = new Set<string>();
const since = highlight == null ? Number.NaN : parseUtc(highlight.since);
if (highlight == null || Number.isNaN(since) || currentUserId == null || currentUserId === "") {
return ids;
}
const userId = String(currentUserId);
for (const comment of comments) {
const createdAt = parseUtc(comment.createdDate);
if (Number.isNaN(createdAt) || createdAt < since || isOwnWorkOrderComment(comment, userId)) {
continue;
}
// Board comments expose mentions two ways: an encoded `@[id:name]` token in the text, or a
// `mentions` id array alongside plain `@Name` text. Treat either as a mention of the user.
const mentionIds = new Set(extractMentionIds(comment.commenttext ?? ""));
for (const id of comment.mentions ?? []) {
mentionIds.add(String(id));
}
const mentionsUser = mentionIds.has(userId);
if (mentionsUser === highlight.mentions) {
ids.add(String(comment.id));
}
}
return ids;
}