From d35b43aefcf33b519d3784e55b11607a7e305a2d Mon Sep 17 00:00:00 2001 From: Vamsi krishna Date: Wed, 19 Mar 2025 15:14:07 +0530 Subject: [PATCH 1/2] fix: incomplete activity render for activity in notifications --- .../sidebar/notification-card/content.tsx | 109 ++++++++++++++++++ .../sidebar/notification-card/index.ts | 1 + .../sidebar/notification-card/item.tsx | 68 +++-------- 3 files changed, 123 insertions(+), 55 deletions(-) create mode 100644 web/core/components/workspace-notifications/sidebar/notification-card/content.tsx diff --git a/web/core/components/workspace-notifications/sidebar/notification-card/content.tsx b/web/core/components/workspace-notifications/sidebar/notification-card/content.tsx new file mode 100644 index 00000000000..ecdded0cfb2 --- /dev/null +++ b/web/core/components/workspace-notifications/sidebar/notification-card/content.tsx @@ -0,0 +1,109 @@ +import { FC } from "react"; +import { TNotification } from "@plane/types"; +// components +import { LiteTextReadOnlyEditor } from "@/components/editor"; +// helpers +import { renderFormattedDate } from "@/helpers/date-time.helper"; +import { sanitizeCommentForNotification } from "@/helpers/notification.helper"; +import { replaceUnderscoreIfSnakeCase, stripAndTruncateHTML } from "@/helpers/string.helper"; + +export const NotificationContent: FC<{ + notification: TNotification; + workspaceId: string; + workspaceSlug: string; + projectId: string; + renderCommentBox?: boolean; +}> = ({ notification, workspaceId, workspaceSlug, projectId, renderCommentBox = false }) => { + const { data, triggered_by_details: triggeredBy } = notification; + const notificationField = data?.issue_activity.field; + const newValue = data?.issue_activity.new_value; + const oldValue = data?.issue_activity.old_value; + const verb = data?.issue_activity.verb; + + const renderTriggerName = () => ( + + {triggeredBy?.is_bot ? triggeredBy.first_name : triggeredBy?.display_name}{" "} + + ); + + const renderAction = () => { + if (!notificationField) return ""; + if (notificationField === "duplicate") + return verb === "created" + ? "marked that this work item is a duplicate of" + : "marked that this work item is not a duplicate"; + if (notificationField === "assignees") { + return newValue !== "" ? "added assignee" : "removed assignee"; + } + if (notificationField === "start_date") { + return newValue !== "" ? "set start date" : "removed the start date"; + } + if (notificationField === "target_date") { + return newValue !== "" ? "set due date" : "removed the due date"; + } + if (notificationField === "labels") { + return newValue !== "" ? "added label" : "removed label"; + } + if (notificationField === "parent") { + return newValue !== "" ? "added parent" : "removed parent"; + } + if (notificationField === "relates_to") return "marked that this work item is related to"; + if (notificationField === "comment") return "commented"; + if (notificationField === "archived_at") { + return newValue === "restore" ? "restored the work item" : "archived the work item"; + } + if (notificationField === "None") return null; + + const baseAction = !["comment", "archived_at"].includes(notificationField) ? verb : ""; + return `${baseAction} ${replaceUnderscoreIfSnakeCase(notificationField)}`; + }; + + const renderValue = () => { + if (notificationField === "None") return "the work item and assigned it to you."; + if (notificationField === "comment") return renderCommentBox ? null : sanitizeCommentForNotification(newValue); + if (notificationField === "target_date" || notificationField === "start_date") return renderFormattedDate(newValue); + if (notificationField === "attachment") return "the work item"; + if (notificationField === "description") return stripAndTruncateHTML(newValue || "", 55); + if (notificationField === "archived_at") return null; + if (notificationField === "assignees") return newValue !== "" ? newValue : oldValue; + if (notificationField === "labels") return newValue !== "" ? newValue : oldValue; + if (notificationField === "parent") return newValue !== "" ? newValue : oldValue; + return newValue; + }; + + const shouldShowConnector = ![ + "comment", + "archived_at", + "None", + "assignees", + "labels", + "start_date", + "target_date", + "parent", + ].includes(notificationField || ""); + + return ( + <> + {renderTriggerName()} + {renderAction()} + {verb !== "deleted" && ( + <> + {shouldShowConnector && to } + {renderValue()} + {notificationField === "comment" && renderCommentBox && ( +
+ +
+ )} + {"."} + + )} + + ); +}; diff --git a/web/core/components/workspace-notifications/sidebar/notification-card/index.ts b/web/core/components/workspace-notifications/sidebar/notification-card/index.ts index 8c086a5a81a..d464403479e 100644 --- a/web/core/components/workspace-notifications/sidebar/notification-card/index.ts +++ b/web/core/components/workspace-notifications/sidebar/notification-card/index.ts @@ -1,2 +1,3 @@ export * from "./item"; export * from "./options"; +export * from "./content"; diff --git a/web/core/components/workspace-notifications/sidebar/notification-card/item.tsx b/web/core/components/workspace-notifications/sidebar/notification-card/item.tsx index a0c8142ecd0..63db61780e0 100644 --- a/web/core/components/workspace-notifications/sidebar/notification-card/item.tsx +++ b/web/core/components/workspace-notifications/sidebar/notification-card/item.tsx @@ -10,10 +10,9 @@ import { NotificationOption } from "@/components/workspace-notifications"; import { cn } from "@/helpers/common.helper"; import { calculateTimeAgo, renderFormattedDate, renderFormattedTime } from "@/helpers/date-time.helper"; import { getFileURL } from "@/helpers/file.helper"; -import { sanitizeCommentForNotification } from "@/helpers/notification.helper"; -import { replaceUnderscoreIfSnakeCase, stripAndTruncateHTML } from "@/helpers/string.helper"; // hooks -import { useIssueDetail, useNotification, useWorkspaceNotifications } from "@/hooks/store"; +import { useIssueDetail, useNotification, useWorkspace, useWorkspaceNotifications } from "@/hooks/store"; +import { NotificationContent } from "./content"; type TNotificationItem = { workspaceSlug: string; @@ -26,6 +25,7 @@ export const NotificationItem: FC = observer((props) => { const { currentSelectedNotificationId, setCurrentSelectedNotificationId } = useWorkspaceNotifications(); const { asJson: notification, markNotificationAsRead } = useNotification(notificationId); const { getIsIssuePeeked, setPeekIssue } = useIssueDetail(); + const { getWorkspaceBySlug } = useWorkspace(); // states const [isSnoozeStateModalOpen, setIsSnoozeStateModalOpen] = useState(false); const [customSnoozeModal, setCustomSnoozeModal] = useState(false); @@ -33,6 +33,7 @@ export const NotificationItem: FC = observer((props) => { // derived values const projectId = notification?.project || undefined; const issueId = notification?.data?.issue?.id || undefined; + const workspace = getWorkspaceBySlug(workspaceSlug); const notificationField = notification?.data?.issue_activity.field || undefined; const notificationTriggeredBy = notification.triggered_by_details || undefined; @@ -57,7 +58,8 @@ export const NotificationItem: FC = observer((props) => { } }; - if (!workspaceSlug || !notificationId || !notification?.id || !notificationField) return <>; + if (!workspaceSlug || !notificationId || !notification?.id || !notificationField || !workspace?.id || !projectId) + return <>; return ( = observer((props) => {
-
- {!notification.message ? ( - <> - - {notificationTriggeredBy?.is_bot - ? notificationTriggeredBy?.first_name - : notificationTriggeredBy?.display_name}{" "} - - {!["comment", "archived_at"].includes(notificationField) && notification?.data?.issue_activity.verb}{" "} - {notificationField === "comment" - ? "commented" - : notificationField === "archived_at" - ? notification?.data?.issue_activity.new_value === "restore" - ? "restored the work item" - : "archived the work item" - : notificationField === "None" - ? null - : replaceUnderscoreIfSnakeCase(notificationField)}{" "} - {notification?.data?.issue_activity.verb !== "deleted" && ( - <> - {!["comment", "archived_at", "None"].includes(notificationField) ? "to" : ""} - - {" "} - {notificationField !== "None" ? ( - notificationField !== "comment" ? ( - notificationField === "target_date" ? ( - renderFormattedDate(notification?.data?.issue_activity.new_value) - ) : notificationField === "attachment" ? ( - "the work item" - ) : notificationField === "description" ? ( - stripAndTruncateHTML(notification?.data?.issue_activity.new_value || "", 55) - ) : notificationField === "archived_at" ? null : ( - notification?.data?.issue_activity.new_value - ) - ) : ( - - {sanitizeCommentForNotification( - notification?.data?.issue_activity.new_value ?? undefined - )} - - ) - ) : ( - "the work item and assigned it to you." - )} - - - )} - - ) : ( - {notification.message} - )} +
+
Date: Wed, 19 Mar 2025 15:24:46 +0530 Subject: [PATCH 2/2] fix: handled content overflow for long notification messages --- .../workspace-notifications/sidebar/notification-card/item.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/web/core/components/workspace-notifications/sidebar/notification-card/item.tsx b/web/core/components/workspace-notifications/sidebar/notification-card/item.tsx index 63db61780e0..c7fa3c4878d 100644 --- a/web/core/components/workspace-notifications/sidebar/notification-card/item.tsx +++ b/web/core/components/workspace-notifications/sidebar/notification-card/item.tsx @@ -89,7 +89,7 @@ export const NotificationItem: FC = observer((props) => {
-
+