diff --git a/apps/app/components/core/feeds.tsx b/apps/app/components/core/feeds.tsx new file mode 100644 index 000000000..9cd1e28d9 --- /dev/null +++ b/apps/app/components/core/feeds.tsx @@ -0,0 +1,277 @@ +import React from "react"; +import Image from "next/image"; + +// icons +import { + ArrowTopRightOnSquareIcon, + CalendarDaysIcon, + ChartBarIcon, + ChatBubbleBottomCenterTextIcon, + ChatBubbleLeftEllipsisIcon, + RectangleGroupIcon, + Squares2X2Icon, + UserIcon, +} from "@heroicons/react/24/outline"; +import { BlockedIcon, BlockerIcon, CyclesIcon, TagIcon, UserGroupIcon } from "components/icons"; +// helpers +import { renderShortNumericDateFormat, timeAgo } from "helpers/date-time.helper"; +import { addSpaceIfCamelCase } from "helpers/string.helper"; +// types +import RemirrorRichTextEditor from "components/rich-text-editor"; +import Link from "next/link"; + +const activityDetails: { + [key: string]: { + message?: string; + icon: JSX.Element; + }; +} = { + assignee: { + message: "removed the assignee", + icon: , + }, + assignees: { + message: "added a new assignee", + icon: , + }, + blocks: { + message: "marked this issue being blocked by", + icon: , + }, + blocking: { + message: "marked this issue is blocking", + icon: , + }, + cycles: { + message: "set the cycle to", + icon: , + }, + labels: { + icon: , + }, + modules: { + message: "set the module to", + icon: , + }, + state: { + message: "set the state to", + icon: , + }, + priority: { + message: "set the priority to", + icon: , + }, + name: { + message: "set the name to", + icon: , + }, + description: { + message: "updated the description.", + icon: , + }, + target_date: { + message: "set the due date to", + icon: , + }, + parent: { + message: "set the parent to", + icon: , + }, +}; + +export const Feeds: React.FC = ({ activities }) => ( + + + {activities.map((activity: any, activityIdx: number) => { + // determines what type of action is performed + let action = activityDetails[activity.field as keyof typeof activityDetails]?.message; + if (activity.field === "labels") { + action = activity.new_value !== "" ? "added a new label" : "removed the label"; + } else if (activity.field === "blocking") { + action = + activity.new_value !== "" + ? "marked this issue is blocking" + : "removed the issue from blocking"; + } else if (activity.field === "blocks") { + action = + activity.new_value !== "" ? "marked this issue being blocked by" : "removed blocker"; + } else if (activity.field === "target_date") { + action = + activity.new_value && activity.new_value !== "" + ? "set the due date to" + : "removed the due date"; + } else if (activity.field === "parent") { + action = + activity.new_value && activity.new_value !== "" + ? "set the parent to" + : "removed the parent"; + } else if (activity.field === "priority") { + action = + activity.new_value && activity.new_value !== "" + ? "set the priority to" + : "removed the priority"; + } else if (activity.field === "description") { + action = "updated the"; + } + // for values that are after the action clause + let value: any = activity.new_value ? activity.new_value : activity.old_value; + if ( + activity.verb === "created" && + activity.field !== "cycles" && + activity.field !== "modules" + ) { + const { workspace_detail, project, issue } = activity; + value = ( + + created{" "} + + + this issue. + + + + ); + } else if (activity.field === "state") { + value = activity.new_value ? addSpaceIfCamelCase(activity.new_value) : "None"; + } else if (activity.field === "labels") { + let name; + let id = "#000000"; + if (activity.new_value !== "") { + name = activity.new_value; + id = activity.new_identifier ? activity.new_identifier : id; + } else { + name = activity.old_value; + id = activity.old_identifier ? activity.old_identifier : id; + } + + value = name; + } else if (activity.field === "assignees") { + value = activity.new_value; + } else if (activity.field === "target_date") { + const date = + activity.new_value && activity.new_value !== "" + ? activity.new_value + : activity.old_value; + value = renderShortNumericDateFormat(date as string); + } else if (activity.field === "description") { + value = "description"; + } + + if (activity.field === "comment") { + return ( + + + + {activity.actor_detail.avatar && activity.actor_detail.avatar !== "" ? ( + + ) : ( + + {activity.actor_detail.first_name.charAt(0)} + + )} + + + + + + + + + {activity.actor_detail.first_name} + {activity.actor_detail.is_bot ? "Bot" : " " + activity.actor_detail.last_name} + + + Commented {timeAgo(activity.created_at)} + + + + ({})} + noBorder + customClassName="text-xs bg-gray-100" + /> + + + + + ); + } + + if ("field" in activity && activity.field !== "updated_by") { + return ( + + + {activities.length > 1 && activityIdx !== activities.length - 1 ? ( + + ) : null} + + <> + + + + + {activity.field ? ( + activityDetails[activity.field as keyof typeof activityDetails]?.icon + ) : activity.actor_detail.avatar && + activity.actor_detail.avatar !== "" ? ( + + ) : ( + + {activity.actor_detail.first_name.charAt(0)} + + )} + + + + + + + + {activity.actor_detail.first_name} + {activity.actor_detail.is_bot + ? " Bot" + : " " + activity.actor_detail.last_name} + + {action} + {value} + {timeAgo(activity.created_at)} + + + > + + + + ); + } + })} + + +); diff --git a/apps/app/components/core/index.ts b/apps/app/components/core/index.ts index 6ce5074f5..93135aad1 100644 --- a/apps/app/components/core/index.ts +++ b/apps/app/components/core/index.ts @@ -11,3 +11,4 @@ export * from "./link-modal"; export * from "./not-authorized-view"; export * from "./image-picker-popover"; export * from "./filter-list"; +export * from "./feeds"; diff --git a/apps/app/pages/[workspaceSlug]/me/profile/activity.tsx b/apps/app/pages/[workspaceSlug]/me/profile/activity.tsx index bcc596843..cfd74d16a 100644 --- a/apps/app/pages/[workspaceSlug]/me/profile/activity.tsx +++ b/apps/app/pages/[workspaceSlug]/me/profile/activity.tsx @@ -11,8 +11,7 @@ import AppLayout from "layouts/app-layout"; // ui import { Loader } from "components/ui"; import { BreadcrumbItem, Breadcrumbs } from "components/breadcrumbs"; -// helpers -import { timeAgo } from "helpers/date-time.helper"; +import { Feeds } from "components/core"; // fetch-keys import { USER_ACTIVITY } from "constants/fetch-keys"; @@ -33,21 +32,9 @@ const ProfileActivity = () => { profilePage > {userActivity ? ( - - {userActivity.results.length > 0 - ? userActivity.results.map((activity) => ( - - - {activity.comment} - - {timeAgo(activity.created_at)} - - )) - : null} - + userActivity.results.length > 0 ? ( + + ) : null ) : (
+ Commented {timeAgo(activity.created_at)} +