Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[WEB-3698] fix: comments refactor #6759

Merged
merged 13 commits into from
Mar 27, 2025
8 changes: 7 additions & 1 deletion apiserver/plane/app/views/issue/comment.py
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,13 @@ def partial_update(self, request, slug, project_id, issue_id, pk):
issue_comment, data=request.data, partial=True
)
if serializer.is_valid():
serializer.save()
if (
"comment_html" in request.data
and request.data["comment_html"] != issue_comment.comment_html
):
serializer.save(edited_at=timezone.now())
else:
serializer.save()
issue_activity.delay(
type="comment.activity.updated",
requested_data=requested_data,
Expand Down
2 changes: 2 additions & 0 deletions packages/i18n/src/locales/en/translations.json
Original file line number Diff line number Diff line change
Expand Up @@ -331,6 +331,8 @@
"re_generate_key": "Re-generate key",
"export": "Export",
"member": "{count, plural, one{# member} other{# members}}",
"edited": "edited",
"bot": "Bot",

"project_view": {
"sort_by": {
Expand Down
2 changes: 2 additions & 0 deletions packages/i18n/src/locales/es/translations.json
Original file line number Diff line number Diff line change
Expand Up @@ -503,6 +503,8 @@
"re_generate_key": "Regenerar clave",
"export": "Exportar",
"member": "{count, plural, one{# miembro} other{# miembros}}",
"edited": "Modificado",
"bot": "Bot",

"project_view": {
"sort_by": {
Expand Down
2 changes: 2 additions & 0 deletions packages/i18n/src/locales/fr/translations.json
Original file line number Diff line number Diff line change
Expand Up @@ -501,6 +501,8 @@
"re_generate_key": "Régénérer la clé",
"export": "Exporter",
"member": "{count, plural, one{# membre} other{# membres}}",
"edited": "Modifié",
"bot": "Bot",

"project_view": {
"sort_by": {
Expand Down
2 changes: 2 additions & 0 deletions packages/i18n/src/locales/it/translations.json
Original file line number Diff line number Diff line change
Expand Up @@ -500,6 +500,8 @@
"re_generate_key": "Rigenera chiave",
"export": "Esporta",
"member": "{count, plural, one {# membro} other {# membri}}",
"edited": "Modificato",
"bot": "Bot",

"project_view": {
"sort_by": {
Expand Down
2 changes: 2 additions & 0 deletions packages/i18n/src/locales/ja/translations.json
Original file line number Diff line number Diff line change
Expand Up @@ -501,6 +501,8 @@
"re_generate_key": "キーを再生成",
"export": "エクスポート",
"member": "{count, plural, other{# メンバー}}",
"edited": "編集済み",
"bot": "ボット",

"project_view": {
"sort_by": {
Expand Down
2 changes: 2 additions & 0 deletions packages/i18n/src/locales/ko/translations.json
Original file line number Diff line number Diff line change
Expand Up @@ -501,6 +501,8 @@
"re_generate_key": "키 다시 생성",
"export": "내보내기",
"member": "{count, plural, one{# 멤버} other{# 멤버}}",
"edited": "수정됨",
"bot": "봇",

"project_view": {
"sort_by": {
Expand Down
3 changes: 3 additions & 0 deletions packages/i18n/src/locales/pl/translations.json
Original file line number Diff line number Diff line change
Expand Up @@ -499,6 +499,9 @@
"re_generate_key": "Wygeneruj klucz ponownie",
"export": "Eksportuj",
"member": "{count, plural, one{# członek} few{# członkowie} other{# członków}}",
"edited": "Edytowano",
"bot": "Bot",

"project_view": {
"sort_by": {
"created_at": "Utworzono dnia",
Expand Down
2 changes: 2 additions & 0 deletions packages/i18n/src/locales/ru/translations.json
Original file line number Diff line number Diff line change
Expand Up @@ -499,6 +499,8 @@
"re_generate_key": "Перегенерировать ключ",
"export": "Экспорт",
"member": "{count, plural, one{# участник} few{# участника} other{# участников}}",
"edited": "Редактировано",
"bot": "Бот",

"project_view": {
"sort_by": {
Expand Down
2 changes: 2 additions & 0 deletions packages/i18n/src/locales/sk/translations.json
Original file line number Diff line number Diff line change
Expand Up @@ -499,6 +499,8 @@
"re_generate_key": "Znova generovať kľúč",
"export": "Exportovať",
"member": "{count, plural, one{# člen} few{# členovia} other{# členov}}",
"edited": "Upravené",
"bot": "Bot",

"project_view": {
"sort_by": {
Expand Down
3 changes: 3 additions & 0 deletions packages/i18n/src/locales/ua/translations.json
Original file line number Diff line number Diff line change
Expand Up @@ -499,6 +499,9 @@
"re_generate_key": "Повторно згенерувати ключ",
"export": "Експортувати",
"member": "{count, plural, one{# учасник} few{# учасники} other{# учасників}}",
"edited": "Редагувано",
"bot": "Бот",

"project_view": {
"sort_by": {
"created_at": "Створено",
Expand Down
2 changes: 2 additions & 0 deletions packages/i18n/src/locales/zh-CN/translations.json
Original file line number Diff line number Diff line change
Expand Up @@ -501,6 +501,8 @@
"re_generate_key": "重新生成密钥",
"export": "导出",
"member": "{count, plural, other{# 成员}}",
"edited": "已编辑",
"bot": "机器人",

"project_view": {
"sort_by": {
Expand Down
2 changes: 2 additions & 0 deletions packages/i18n/src/locales/zh-TW/translations.json
Original file line number Diff line number Diff line change
Expand Up @@ -501,6 +501,8 @@
"re_generate_key": "重新產生金鑰",
"export": "匯出",
"member": "{count, plural, one{# 位成員} other{# 位成員}}",
"edited": "已編輯",
"bot": "機器人",

"project_view": {
"sort_by": {
Expand Down
26 changes: 26 additions & 0 deletions packages/types/src/issues/activity/issue_comment.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,15 @@ import {
TIssueActivityUserDetail,
} from "./base";
import { EIssueCommentAccessSpecifier } from "../../enums";
import { TFileSignedURLResponse } from "../../file";
import { IUserLite } from "../../users";

export type TCommentReaction = {
id: string;
reaction: string;
actor: string;
actor_detail: IUserLite;
};
export type TIssueComment = {
id: string;
workspace: string;
Expand All @@ -17,6 +25,7 @@ export type TIssueComment = {
actor: string;
actor_detail: TIssueActivityUserDetail;
created_at: string;
edited_at?: string | undefined;
updated_at: string;
created_by: string | undefined;
updated_by: string | undefined;
Expand All @@ -30,6 +39,23 @@ export type TIssueComment = {
access: EIssueCommentAccessSpecifier;
};

export type TCommentsOperations = {
createComment: (data: Partial<TIssueComment>) => Promise<void>;
updateComment: (commentId: string, data: Partial<TIssueComment>) => Promise<void>;
removeComment: (commentId: string) => Promise<void>;
uploadCommentAsset: (blockId: string, file: File, commentId?: string) => Promise<TFileSignedURLResponse>;
addCommentReaction: (commentId: string, reactionEmoji: string) => Promise<void>;
deleteCommentReaction: (commentId: string, reactionEmoji: string, userReactions: TCommentReaction[]) => Promise<void>;
react: (commentId: string, reactionEmoji: string, userReactions: string[]) => Promise<void>;
reactionIds: (commentId: string) =>
| {
[reaction: string]: string[];
}
| undefined;
userReactions: (commentId: string) => string[] | undefined;
getReactionUsers: (reaction: string, reactionIds: Record<string, string[]>) => string;
};

export type TIssueCommentMap = {
[issue_id: string]: TIssueComment;
};
Expand Down
76 changes: 76 additions & 0 deletions web/ce/components/comments/comment-block.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
import { FC, ReactNode, useRef } from "react";
import { observer } from "mobx-react";
// plane imports
import { useTranslation } from "@plane/i18n";
import { TIssueComment } from "@plane/types";
import { Avatar, Tooltip } from "@plane/ui";
import { calculateTimeAgo, cn, getFileURL, renderFormattedDate } from "@plane/utils";
// hooks
import { renderFormattedTime } from "@/helpers/date-time.helper";
import { useMember } from "@/hooks/store";

type TCommentBlock = {
comment: TIssueComment;
ends: "top" | "bottom" | undefined;
quickActions: ReactNode;
children: ReactNode;
};

export const CommentBlock: FC<TCommentBlock> = observer((props) => {
const { comment, ends, quickActions, children } = props;
const commentBlockRef = useRef<HTMLDivElement>(null);
// store hooks
const { getUserDetails } = useMember();
const { t } = useTranslation();
const userDetails = getUserDetails(comment?.actor);

if (!comment || !userDetails) return <></>;
return (
<div
className={`relative flex gap-3 ${ends === "top" ? `pb-2` : ends === "bottom" ? `pt-2` : `py-2`}`}
ref={commentBlockRef}
>
<div
className="absolute left-[13px] top-0 bottom-0 w-0.5 transition-border duration-1000 bg-custom-background-80"
aria-hidden
/>
<div
className={cn(
"flex-shrink-0 relative w-7 h-6 rounded-full transition-border duration-1000 flex justify-center items-center z-[3] uppercase font-medium"
)}
>
<Avatar
size="base"
name={userDetails?.display_name}
src={getFileURL(userDetails?.avatar_url)}
className="flex-shrink-0"
/>
</div>
<div className="flex flex-col gap-3 truncate flex-grow">
<div className="flex w-full gap-2">
<div className="flex-1 flex flex-wrap items-center gap-1">
<div className="text-xs font-medium">
{comment?.actor_detail?.is_bot
? comment?.actor_detail?.first_name + ` ${t("bot")}`
: comment?.actor_detail?.display_name || userDetails.display_name}
</div>
<div className="text-xs text-custom-text-300">
commented{" "}
<Tooltip
tooltipContent={`${renderFormattedDate(comment.created_at)} at ${renderFormattedTime(comment.created_at)}`}
position="bottom"
>
<span className="text-custom-text-350">
{calculateTimeAgo(comment.updated_at)}
{comment.edited_at && ` (${t("edited")})`}
</span>
</Tooltip>
</div>
</div>
<div className="flex-shrink-0 ">{quickActions}</div>
</div>
<div className="text-base mb-2">{children}</div>
</div>
</div>
);
});
1 change: 1 addition & 0 deletions web/ce/components/comments/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from "./comment-block";
Loading