add root comment editing in thread menu

This commit is contained in:
hjlarry 2026-04-14 14:09:26 +08:00
parent d4dae5f8c0
commit 0d3ada2bc9
27 changed files with 260 additions and 13 deletions

View File

@ -70,6 +70,9 @@ vi.mock('@/app/components/base/inline-delete-confirm', () => ({
vi.mock('@/app/components/base/ui/avatar', () => ({
Avatar: ({ name }: { name: string }) => <div data-testid="avatar">{name}</div>,
AvatarRoot: ({ children }: { children: React.ReactNode }) => <div data-testid="avatar-root">{children}</div>,
AvatarImage: ({ alt }: { alt: string }) => <div data-testid="avatar-image">{alt}</div>,
AvatarFallback: ({ children }: { children: React.ReactNode }) => <div data-testid="avatar-fallback">{children}</div>,
}))
vi.mock('@/app/components/base/ui/dropdown-menu', () => ({
@ -214,6 +217,26 @@ describe('CommentThread', () => {
expect(container.querySelector('button button')).toBeNull()
})
it('supports editing the root comment when the current user owns the thread', async () => {
const onCommentEdit = vi.fn()
render(
<CommentThread
comment={createComment()}
onClose={vi.fn()}
onCommentEdit={onCommentEdit}
/>,
)
fireEvent.click(screen.getByLabelText('workflow.comments.aria.commentActions'))
fireEvent.click(screen.getByText('workflow.comments.actions.editComment'))
fireEvent.click(screen.getByText('submit-workflow.comments.placeholder.editComment'))
await waitFor(() => {
expect(onCommentEdit).toHaveBeenCalledWith('@Alice original comment', ['user-2'])
})
})
it('submits reply and updates preview hovering state on mouse enter/leave', async () => {
const onReply = vi.fn()
const { container } = render(

View File

@ -35,6 +35,7 @@ type CommentThreadProps = {
onNext?: () => void
canGoPrev?: boolean
canGoNext?: boolean
onCommentEdit?: (content: string, mentionedUserIds?: string[]) => Promise<void> | void
onReply?: (content: string, mentionedUserIds?: string[]) => Promise<void> | void
onReplyEdit?: (replyId: string, content: string, mentionedUserIds?: string[]) => Promise<void> | void
onReplyDelete?: (replyId: string) => void
@ -164,6 +165,7 @@ export const CommentThread: FC<CommentThreadProps> = memo(({
onNext,
canGoPrev,
canGoNext,
onCommentEdit,
onReply,
onReplyEdit,
onReplyDelete,
@ -176,9 +178,11 @@ export const CommentThread: FC<CommentThreadProps> = memo(({
const { userProfile } = useAppContext()
const { t } = useTranslation()
const [replyContent, setReplyContent] = useState('')
const [editingCommentContent, setEditingCommentContent] = useState('')
const [activeReplyMenuId, setActiveReplyMenuId] = useState<string | null>(null)
const [editingReply, setEditingReply] = useState<{ id: string, content: string }>({ id: '', content: '' })
const [deletingReplyId, setDeletingReplyId] = useState<string | null>(null)
const [isCommentEditing, setIsCommentEditing] = useState(false)
const [isSubmittingEdit, setIsSubmittingEdit] = useState(false)
// Focus management refs
@ -203,6 +207,11 @@ export const CommentThread: FC<CommentThreadProps> = memo(({
useEffect(() => {
Promise.resolve().then(() => {
setReplyContent('')
setEditingCommentContent('')
setIsCommentEditing(false)
setEditingReply({ id: '', content: '' })
setActiveReplyMenuId(null)
setDeletingReplyId(null)
})
}, [comment.id])
@ -213,18 +222,18 @@ export const CommentThread: FC<CommentThreadProps> = memo(({
// P0: Auto-focus reply input when thread opens or comment changes
useEffect(() => {
const timer = setTimeout(() => {
if (replyInputRef.current && !editingReply.id && onReply)
if (replyInputRef.current && !editingReply.id && !isCommentEditing && onReply)
replyInputRef.current.focus()
}, 100)
return () => clearTimeout(timer)
}, [comment.id, editingReply.id, onReply])
}, [comment.id, editingReply.id, isCommentEditing, onReply])
// P2: Handle Esc key to close thread
useEffect(() => {
const handleKeyDown = (e: KeyboardEvent) => {
// Don't intercept if actively editing a reply
if (editingReply.id)
if (editingReply.id || isCommentEditing)
return
// Don't intercept if mention dropdown is open (let MentionInput handle it)
@ -240,7 +249,7 @@ export const CommentThread: FC<CommentThreadProps> = memo(({
document.addEventListener('keydown', handleKeyDown, true)
return () => document.removeEventListener('keydown', handleKeyDown, true)
}, [onClose, editingReply.id])
}, [onClose, editingReply.id, isCommentEditing])
const handleReplySubmit = useCallback(async (content: string, mentionedUserIds: string[]) => {
if (!onReply || replySubmitting)
@ -280,9 +289,17 @@ export const CommentThread: FC<CommentThreadProps> = memo(({
const handleStartEdit = useCallback((reply: WorkflowCommentDetailReply) => {
setEditingReply({ id: reply.id, content: reply.content })
setIsCommentEditing(false)
setActiveReplyMenuId(null)
}, [])
const handleStartCommentEdit = useCallback(() => {
setEditingCommentContent(comment.content)
setEditingReply({ id: '', content: '' })
setIsCommentEditing(true)
setActiveReplyMenuId(null)
}, [comment.content])
const handleCancelEdit = useCallback(() => {
setEditingReply({ id: '', content: '' })
@ -292,6 +309,40 @@ export const CommentThread: FC<CommentThreadProps> = memo(({
}, 0)
}, [])
const handleCancelCommentEdit = useCallback(() => {
setEditingCommentContent('')
setIsCommentEditing(false)
setTimeout(() => {
replyInputRef.current?.focus()
}, 0)
}, [])
const handleCommentEditSubmit = useCallback(async (content: string, mentionedUserIds: string[]) => {
if (!onCommentEdit)
return
const trimmed = content.trim()
if (!trimmed)
return
setIsSubmittingEdit(true)
try {
await onCommentEdit(trimmed, mentionedUserIds)
setEditingCommentContent('')
setIsCommentEditing(false)
setTimeout(() => {
replyInputRef.current?.focus()
}, 0)
}
catch (error) {
console.error('Failed to edit comment', error)
}
finally {
setIsSubmittingEdit(false)
}
}, [onCommentEdit])
const handleEditSubmit = useCallback(async (content: string, mentionedUserIds: string[]) => {
if (!onReplyEdit || !editingReply)
return
@ -318,6 +369,7 @@ export const CommentThread: FC<CommentThreadProps> = memo(({
}, [editingReply, onReplyEdit])
const replies = comment.replies || []
const isOwnComment = comment.created_by_account?.id === userProfile?.id
const messageListRef = useRef<HTMLDivElement>(null)
const previousReplyCountRef = useRef<number | undefined>(undefined)
const previousCommentIdRef = useRef<string | undefined>(undefined)
@ -472,15 +524,81 @@ export const CommentThread: FC<CommentThreadProps> = memo(({
ref={messageListRef}
className="relative mt-2 flex-1 overflow-y-auto px-4 pb-4"
>
<div className="-mx-4 rounded-lg px-4 py-2 transition-colors hover:bg-components-panel-on-panel-item-bg-hover">
<ThreadMessage
authorId={comment.created_by_account?.id || ''}
authorName={comment.created_by_account?.name || t('comments.fallback.user', { ns: 'workflow' })}
avatarUrl={comment.created_by_account?.avatar_url || null}
createdAt={comment.created_at}
content={comment.content}
mentionableNames={mentionableNames}
/>
<div className="group relative -mx-4 rounded-lg px-4 py-2 transition-colors hover:bg-components-panel-on-panel-item-bg-hover">
{isOwnComment && !isCommentEditing && (
<div
className={cn(
'absolute top-1 right-1 gap-1',
activeReplyMenuId === comment.id ? 'flex' : 'hidden group-hover:flex',
)}
>
<DropdownMenu
open={activeReplyMenuId === comment.id}
onOpenChange={open => setActiveReplyMenuId(open ? comment.id : null)}
>
<DropdownMenuTrigger
className="flex h-6 w-6 items-center justify-center rounded-md text-text-tertiary hover:bg-state-base-hover hover:text-text-secondary"
aria-label={t('comments.aria.commentActions', { ns: 'workflow' })}
>
<RiMoreFill className="h-4 w-4" />
</DropdownMenuTrigger>
<DropdownMenuContent
placement="bottom-end"
sideOffset={4}
popupClassName="z-[100] w-36 rounded-xl border-[0.5px] border-components-panel-border bg-components-panel-bg-blur shadow-lg backdrop-blur-[10px]"
>
<button
className="flex w-full items-center justify-start rounded-xl px-3 py-2 text-left text-sm text-text-secondary hover:bg-state-base-hover"
onClick={(e) => {
e.stopPropagation()
handleStartCommentEdit()
}}
>
{t('comments.actions.editComment', { ns: 'workflow' })}
</button>
</DropdownMenuContent>
</DropdownMenu>
</div>
)}
{isCommentEditing
? (
<div className="flex gap-3 pt-1">
<div className="shrink-0">
<Avatar
name={comment.created_by_account?.name || t('comments.fallback.user', { ns: 'workflow' })}
avatar={comment.created_by_account?.avatar_url || null}
size="sm"
className="h-8 w-8 rounded-full"
/>
</div>
<div className="min-w-0 flex-1">
<div className="rounded-xl border border-components-chat-input-border bg-components-panel-bg-blur p-1 shadow-md backdrop-blur-[10px]">
<MentionInput
value={editingCommentContent}
onChange={setEditingCommentContent}
onSubmit={handleCommentEditSubmit}
onCancel={handleCancelCommentEdit}
placeholder={t('comments.placeholder.editComment', { ns: 'workflow' })}
disabled={loading}
loading={isSubmittingEdit}
isEditing={true}
className="system-sm-regular"
autoFocus
/>
</div>
</div>
</div>
)
: (
<ThreadMessage
authorId={comment.created_by_account?.id || ''}
authorName={comment.created_by_account?.name || t('comments.fallback.user', { ns: 'workflow' })}
avatarUrl={comment.created_by_account?.avatar_url || null}
createdAt={comment.created_at}
content={comment.content}
mentionableNames={mentionableNames}
/>
)}
</div>
{replies.length > 0 && (
<div className="mt-2 space-y-3 pt-3">

View File

@ -422,6 +422,40 @@ export const useWorkflowComment = () => {
}
}, [activeComment, appId, comments, setComments, setCommentDetailCache, setActiveComment])
const handleCommentUpdate = useCallback(async (commentId: string, content: string, mentionedUserIds: string[] = []) => {
if (!appId)
return
const trimmed = content.trim()
if (!trimmed)
return
const targetComment = comments.find(c => c.id === commentId)
const targetDetail = commentDetailCacheRef.current[commentId]
?? (activeCommentIdRef.current === commentId ? activeComment : null)
const positionX = targetDetail?.position_x ?? targetComment?.position_x
const positionY = targetDetail?.position_y ?? targetComment?.position_y
if (positionX === undefined || positionY === undefined)
return
try {
await updateWorkflowComment(appId, commentId, {
content: trimmed,
position_x: positionX,
position_y: positionY,
mentioned_user_ids: mentionedUserIds,
})
collaborationManager.emitCommentsUpdate(appId)
await refreshActiveComment(commentId)
await loadComments()
}
catch (error) {
console.error('Failed to update comment:', error)
}
}, [activeComment, appId, comments, loadComments, refreshActiveComment])
const handleCommentReply = useCallback(async (commentId: string, content: string, mentionedUserIds: string[] = []) => {
if (!appId)
return
@ -535,6 +569,7 @@ export const useWorkflowComment = () => {
handleCommentResolve,
handleCommentDelete,
handleCommentNavigate,
handleCommentUpdate,
handleCommentReply,
handleCommentReplyUpdate,
handleCommentReplyDelete,

View File

@ -294,6 +294,7 @@ export const Workflow: FC<WorkflowProps> = memo(({
handleActiveCommentClose,
handleCommentResolve,
handleCommentDelete,
handleCommentUpdate,
handleCommentReply,
handleCommentReplyUpdate,
handleCommentReplyDelete,
@ -657,6 +658,7 @@ export const Workflow: FC<WorkflowProps> = memo(({
onClose={handleActiveCommentClose}
onResolve={() => handleCommentResolve(comment.id)}
onDelete={() => handleCommentDeleteClick(comment.id)}
onCommentEdit={(content, ids) => handleCommentUpdate(comment.id, content, ids ?? [])}
onPrev={canGoPrev ? () => handleVisibleCommentNavigate('prev') : undefined}
onNext={canGoNext ? () => handleVisibleCommentNavigate('next') : undefined}
onReply={(content, ids) => handleCommentReply(comment.id, content, ids ?? [])}

View File

@ -112,8 +112,10 @@
"collaboration.historyAction.generic": "قام متعاون بعملية تراجع/إعادة",
"comments.actions.addComment": "Add Comment",
"comments.actions.deleteReply": "حذف الرد",
"comments.actions.editComment": "تعديل التعليق",
"comments.actions.editReply": "تعديل الرد",
"comments.aria.closeComment": "إغلاق التعليق",
"comments.aria.commentActions": "إجراءات التعليق",
"comments.aria.deleteComment": "حذف المناقشة",
"comments.aria.filterComments": "تصفية التعليقات",
"comments.aria.nextComment": "التعليق التالي",
@ -132,6 +134,7 @@
"comments.noComments": "لا توجد تعليقات بعد",
"comments.panelTitle": "التعليقات",
"comments.placeholder.add": "أضف تعليقًا",
"comments.placeholder.editComment": "تعديل التعليق",
"comments.placeholder.editReply": "تعديل الرد",
"comments.placeholder.reply": "رد",
"comments.reply": "رد",

View File

@ -112,8 +112,10 @@
"collaboration.historyAction.generic": "Ein Mitbearbeiter hat Rückgängig/Wiederholen ausgeführt",
"comments.actions.addComment": "Add Comment",
"comments.actions.deleteReply": "Antwort löschen",
"comments.actions.editComment": "Kommentar bearbeiten",
"comments.actions.editReply": "Antwort bearbeiten",
"comments.aria.closeComment": "Kommentar schließen",
"comments.aria.commentActions": "Kommentaraktionen",
"comments.aria.deleteComment": "Kommentar löschen",
"comments.aria.filterComments": "Kommentare filtern",
"comments.aria.nextComment": "Nächster Kommentar",
@ -132,6 +134,7 @@
"comments.noComments": "Noch keine Kommentare",
"comments.panelTitle": "Kommentar",
"comments.placeholder.add": "Kommentar hinzufügen",
"comments.placeholder.editComment": "Kommentar bearbeiten",
"comments.placeholder.editReply": "Antwort bearbeiten",
"comments.placeholder.reply": "Antworten",
"comments.reply": "Antworten",

View File

@ -112,8 +112,10 @@
"collaboration.historyAction.generic": "A collaborator performed an undo/redo action",
"comments.actions.addComment": "Add Comment",
"comments.actions.deleteReply": "Delete reply",
"comments.actions.editComment": "Edit comment",
"comments.actions.editReply": "Edit reply",
"comments.aria.closeComment": "Close comment",
"comments.aria.commentActions": "Comment actions",
"comments.aria.deleteComment": "Delete thread",
"comments.aria.filterComments": "Filter comments",
"comments.aria.nextComment": "Next comment",
@ -132,6 +134,7 @@
"comments.noComments": "No comments yet",
"comments.panelTitle": "Comment",
"comments.placeholder.add": "Add a comment",
"comments.placeholder.editComment": "Edit comment",
"comments.placeholder.editReply": "Edit reply",
"comments.placeholder.reply": "Reply",
"comments.reply": "Reply",

View File

@ -112,8 +112,10 @@
"collaboration.historyAction.generic": "Un colaborador realizó deshacer/rehacer",
"comments.actions.addComment": "Add Comment",
"comments.actions.deleteReply": "Eliminar respuesta",
"comments.actions.editComment": "Editar comentario",
"comments.actions.editReply": "Editar respuesta",
"comments.aria.closeComment": "Cerrar comentario",
"comments.aria.commentActions": "Acciones del comentario",
"comments.aria.deleteComment": "Eliminar comentario",
"comments.aria.filterComments": "Filtrar comentarios",
"comments.aria.nextComment": "Comentario siguiente",
@ -132,6 +134,7 @@
"comments.noComments": "Aún no hay comentarios",
"comments.panelTitle": "Comentario",
"comments.placeholder.add": "Añadir un comentario",
"comments.placeholder.editComment": "Editar comentario",
"comments.placeholder.editReply": "Editar respuesta",
"comments.placeholder.reply": "Responder",
"comments.reply": "Responder",

View File

@ -112,8 +112,10 @@
"collaboration.historyAction.generic": "یک همکار عملیات برگرداندن/انجام مجدد را انجام داد",
"comments.actions.addComment": "Add Comment",
"comments.actions.deleteReply": "حذف پاسخ",
"comments.actions.editComment": "ویرایش دیدگاه",
"comments.actions.editReply": "ویرایش پاسخ",
"comments.aria.closeComment": "بستن دیدگاه",
"comments.aria.commentActions": "عملیات دیدگاه",
"comments.aria.deleteComment": "حذف دیدگاه",
"comments.aria.filterComments": "فیلتر دیدگاه‌ها",
"comments.aria.nextComment": "دیدگاه بعدی",
@ -132,6 +134,7 @@
"comments.noComments": "هنوز دیدگاهی ثبت نشده است",
"comments.panelTitle": "دیدگاه",
"comments.placeholder.add": "افزودن دیدگاه",
"comments.placeholder.editComment": "ویرایش دیدگاه",
"comments.placeholder.editReply": "ویرایش پاسخ",
"comments.placeholder.reply": "پاسخ",
"comments.reply": "پاسخ",

View File

@ -112,8 +112,10 @@
"collaboration.historyAction.generic": "Un collaborateur a effectué une annulation/une réexécution",
"comments.actions.addComment": "Add Comment",
"comments.actions.deleteReply": "Supprimer la réponse",
"comments.actions.editComment": "Modifier le commentaire",
"comments.actions.editReply": "Modifier la réponse",
"comments.aria.closeComment": "Fermer le commentaire",
"comments.aria.commentActions": "Actions du commentaire",
"comments.aria.deleteComment": "Supprimer le commentaire",
"comments.aria.filterComments": "Filtrer les commentaires",
"comments.aria.nextComment": "Commentaire suivant",
@ -132,6 +134,7 @@
"comments.noComments": "Aucun commentaire pour linstant",
"comments.panelTitle": "Commentaire",
"comments.placeholder.add": "Ajouter un commentaire",
"comments.placeholder.editComment": "Modifier le commentaire",
"comments.placeholder.editReply": "Modifier la réponse",
"comments.placeholder.reply": "Répondre",
"comments.reply": "Répondre",

View File

@ -112,8 +112,10 @@
"collaboration.historyAction.generic": "एक सहयोगी ने Undo/Redo किया",
"comments.actions.addComment": "Add Comment",
"comments.actions.deleteReply": "जवाब हटाएं",
"comments.actions.editComment": "टिप्पणी संपादित करें",
"comments.actions.editReply": "जवाब संपादित करें",
"comments.aria.closeComment": "टिप्पणी बंद करें",
"comments.aria.commentActions": "टिप्पणी क्रियाएं",
"comments.aria.deleteComment": "टिप्पणी हटाएं",
"comments.aria.filterComments": "टिप्पणियाँ फ़िल्टर करें",
"comments.aria.nextComment": "अगली टिप्पणी",
@ -132,6 +134,7 @@
"comments.noComments": "अभी तक कोई टिप्पणी नहीं",
"comments.panelTitle": "टिप्पणी",
"comments.placeholder.add": "टिप्पणी जोड़ें",
"comments.placeholder.editComment": "टिप्पणी संपादित करें",
"comments.placeholder.editReply": "जवाब संपादित करें",
"comments.placeholder.reply": "जवाब दें",
"comments.reply": "जवाब दें",

View File

@ -112,8 +112,10 @@
"collaboration.historyAction.generic": "Seorang kolaborator melakukan urungkan/ulang",
"comments.actions.addComment": "Add Comment",
"comments.actions.deleteReply": "Hapus balasan",
"comments.actions.editComment": "Edit komentar",
"comments.actions.editReply": "Edit balasan",
"comments.aria.closeComment": "Tutup komentar",
"comments.aria.commentActions": "Aksi komentar",
"comments.aria.deleteComment": "Hapus komentar",
"comments.aria.filterComments": "Filter komentar",
"comments.aria.nextComment": "Komentar berikutnya",
@ -132,6 +134,7 @@
"comments.noComments": "Belum ada komentar",
"comments.panelTitle": "Komentar",
"comments.placeholder.add": "Tambahkan komentar",
"comments.placeholder.editComment": "Edit komentar",
"comments.placeholder.editReply": "Edit balasan",
"comments.placeholder.reply": "Balas",
"comments.reply": "Balas",

View File

@ -112,8 +112,10 @@
"collaboration.historyAction.generic": "Un collaboratore ha eseguito annulla/ripristina",
"comments.actions.addComment": "Add Comment",
"comments.actions.deleteReply": "Elimina risposta",
"comments.actions.editComment": "Modifica commento",
"comments.actions.editReply": "Modifica risposta",
"comments.aria.closeComment": "Chiudi commento",
"comments.aria.commentActions": "Azioni del commento",
"comments.aria.deleteComment": "Elimina commento",
"comments.aria.filterComments": "Filtra commenti",
"comments.aria.nextComment": "Commento successivo",
@ -132,6 +134,7 @@
"comments.noComments": "Ancora nessun commento",
"comments.panelTitle": "Commento",
"comments.placeholder.add": "Aggiungi un commento",
"comments.placeholder.editComment": "Modifica commento",
"comments.placeholder.editReply": "Modifica risposta",
"comments.placeholder.reply": "Rispondi",
"comments.reply": "Rispondi",

View File

@ -112,8 +112,10 @@
"collaboration.historyAction.generic": "共同編集者が元に戻す/やり直しを実行しました",
"comments.actions.addComment": "Add Comment",
"comments.actions.deleteReply": "返信を削除",
"comments.actions.editComment": "コメントを編集",
"comments.actions.editReply": "返信を編集",
"comments.aria.closeComment": "コメントを閉じる",
"comments.aria.commentActions": "コメントアクション",
"comments.aria.deleteComment": "スレッドを削除",
"comments.aria.filterComments": "コメントを絞り込む",
"comments.aria.nextComment": "次のコメント",
@ -132,6 +134,7 @@
"comments.noComments": "まだコメントがありません",
"comments.panelTitle": "コメント",
"comments.placeholder.add": "コメントを追加",
"comments.placeholder.editComment": "コメントを編集",
"comments.placeholder.editReply": "返信を編集",
"comments.placeholder.reply": "返信",
"comments.reply": "返信",

View File

@ -112,8 +112,10 @@
"collaboration.historyAction.generic": "공동 작업자가 실행 취소/다시 실행을 수행했습니다",
"comments.actions.addComment": "Add Comment",
"comments.actions.deleteReply": "답글 삭제",
"comments.actions.editComment": "댓글 편집",
"comments.actions.editReply": "답글 편집",
"comments.aria.closeComment": "댓글 닫기",
"comments.aria.commentActions": "댓글 작업",
"comments.aria.deleteComment": "댓글 삭제",
"comments.aria.filterComments": "댓글 필터",
"comments.aria.nextComment": "다음 댓글",
@ -132,6 +134,7 @@
"comments.noComments": "아직 댓글이 없습니다",
"comments.panelTitle": "댓글",
"comments.placeholder.add": "댓글 추가",
"comments.placeholder.editComment": "댓글 편집",
"comments.placeholder.editReply": "답글 편집",
"comments.placeholder.reply": "답글",
"comments.reply": "답글",

View File

@ -110,10 +110,13 @@
"chatVariable.storedContent": "Stored content",
"chatVariable.updatedAt": "Updated at ",
"comments.actions.addComment": "Add Comment",
"comments.actions.editComment": "Reactie bewerken",
"comments.aria.commentActions": "Reactieacties",
"comments.aria.filterComments": "Reacties filteren",
"comments.filter.all": "Alles",
"comments.filter.onlyYourThreads": "Alleen jouw threads",
"comments.filter.showResolved": "Opgeloste tonen",
"comments.placeholder.editComment": "Reactie bewerken",
"common.ImageUploadLegacyTip": "You can now create file type variables in the start form. We will no longer support the image upload feature in the future. ",
"common.accessAPIReference": "Access API Reference",
"common.addBlock": "Add Node",

View File

@ -112,8 +112,10 @@
"collaboration.historyAction.generic": "Współpracownik wykonał cofnięcie/ponowienie",
"comments.actions.addComment": "Add Comment",
"comments.actions.deleteReply": "Delete reply",
"comments.actions.editComment": "Edytuj komentarz",
"comments.actions.editReply": "Edit reply",
"comments.aria.closeComment": "Close comment",
"comments.aria.commentActions": "Akcje komentarza",
"comments.aria.deleteComment": "Delete thread",
"comments.aria.filterComments": "Filtruj komentarze",
"comments.aria.nextComment": "Next comment",
@ -132,6 +134,7 @@
"comments.noComments": "No comments yet",
"comments.panelTitle": "Comment",
"comments.placeholder.add": "Add a comment",
"comments.placeholder.editComment": "Edytuj komentarz",
"comments.placeholder.editReply": "Edit reply",
"comments.placeholder.reply": "Reply",
"comments.reply": "Reply",

View File

@ -112,8 +112,10 @@
"collaboration.historyAction.generic": "Um colaborador realizou desfazer/refazer",
"comments.actions.addComment": "Add Comment",
"comments.actions.deleteReply": "Delete reply",
"comments.actions.editComment": "Editar comentário",
"comments.actions.editReply": "Edit reply",
"comments.aria.closeComment": "Close comment",
"comments.aria.commentActions": "Ações do comentário",
"comments.aria.deleteComment": "Delete thread",
"comments.aria.filterComments": "Filtrar comentários",
"comments.aria.nextComment": "Next comment",
@ -132,6 +134,7 @@
"comments.noComments": "No comments yet",
"comments.panelTitle": "Comment",
"comments.placeholder.add": "Add a comment",
"comments.placeholder.editComment": "Editar comentário",
"comments.placeholder.editReply": "Edit reply",
"comments.placeholder.reply": "Reply",
"comments.reply": "Reply",

View File

@ -112,8 +112,10 @@
"collaboration.historyAction.generic": "Un colaborator a efectuat anulare/refacere",
"comments.actions.addComment": "Add Comment",
"comments.actions.deleteReply": "Delete reply",
"comments.actions.editComment": "Editează comentariul",
"comments.actions.editReply": "Edit reply",
"comments.aria.closeComment": "Close comment",
"comments.aria.commentActions": "Acțiuni comentariu",
"comments.aria.deleteComment": "Delete thread",
"comments.aria.filterComments": "Filtrează comentariile",
"comments.aria.nextComment": "Next comment",
@ -132,6 +134,7 @@
"comments.noComments": "No comments yet",
"comments.panelTitle": "Comment",
"comments.placeholder.add": "Add a comment",
"comments.placeholder.editComment": "Editează comentariul",
"comments.placeholder.editReply": "Edit reply",
"comments.placeholder.reply": "Reply",
"comments.reply": "Reply",

View File

@ -112,8 +112,10 @@
"collaboration.historyAction.generic": "Участник выполнил отмену/повтор",
"comments.actions.addComment": "Add Comment",
"comments.actions.deleteReply": "Delete reply",
"comments.actions.editComment": "Редактировать комментарий",
"comments.actions.editReply": "Edit reply",
"comments.aria.closeComment": "Close comment",
"comments.aria.commentActions": "Действия с комментарием",
"comments.aria.deleteComment": "Delete thread",
"comments.aria.filterComments": "Фильтровать комментарии",
"comments.aria.nextComment": "Next comment",
@ -132,6 +134,7 @@
"comments.noComments": "No comments yet",
"comments.panelTitle": "Comment",
"comments.placeholder.add": "Add a comment",
"comments.placeholder.editComment": "Редактировать комментарий",
"comments.placeholder.editReply": "Edit reply",
"comments.placeholder.reply": "Reply",
"comments.reply": "Reply",

View File

@ -112,8 +112,10 @@
"collaboration.historyAction.generic": "Sodelavec je izvedel razveljavitev/ponovitev",
"comments.actions.addComment": "Add Comment",
"comments.actions.deleteReply": "Delete reply",
"comments.actions.editComment": "Uredi komentar",
"comments.actions.editReply": "Edit reply",
"comments.aria.closeComment": "Close comment",
"comments.aria.commentActions": "Dejanja komentarja",
"comments.aria.deleteComment": "Delete thread",
"comments.aria.filterComments": "Filtriraj komentarje",
"comments.aria.nextComment": "Next comment",
@ -132,6 +134,7 @@
"comments.noComments": "No comments yet",
"comments.panelTitle": "Comment",
"comments.placeholder.add": "Add a comment",
"comments.placeholder.editComment": "Uredi komentar",
"comments.placeholder.editReply": "Edit reply",
"comments.placeholder.reply": "Reply",
"comments.reply": "Reply",

View File

@ -112,8 +112,10 @@
"collaboration.historyAction.generic": "ผู้ร่วมงานได้ทำการยกเลิก/ทำซ้ำ",
"comments.actions.addComment": "Add Comment",
"comments.actions.deleteReply": "Delete reply",
"comments.actions.editComment": "แก้ไขความคิดเห็น",
"comments.actions.editReply": "Edit reply",
"comments.aria.closeComment": "Close comment",
"comments.aria.commentActions": "การดำเนินการความคิดเห็น",
"comments.aria.deleteComment": "Delete thread",
"comments.aria.filterComments": "กรองความคิดเห็น",
"comments.aria.nextComment": "Next comment",
@ -132,6 +134,7 @@
"comments.noComments": "No comments yet",
"comments.panelTitle": "Comment",
"comments.placeholder.add": "Add a comment",
"comments.placeholder.editComment": "แก้ไขความคิดเห็น",
"comments.placeholder.editReply": "Edit reply",
"comments.placeholder.reply": "Reply",
"comments.reply": "Reply",

View File

@ -112,8 +112,10 @@
"collaboration.historyAction.generic": "Bir işbirlikçi geri alma/yeniden yapma gerçekleştirdi",
"comments.actions.addComment": "Add Comment",
"comments.actions.deleteReply": "Delete reply",
"comments.actions.editComment": "Yorumu düzenle",
"comments.actions.editReply": "Edit reply",
"comments.aria.closeComment": "Close comment",
"comments.aria.commentActions": "Yorum işlemleri",
"comments.aria.deleteComment": "Delete thread",
"comments.aria.filterComments": "Yorumları filtrele",
"comments.aria.nextComment": "Next comment",
@ -132,6 +134,7 @@
"comments.noComments": "No comments yet",
"comments.panelTitle": "Comment",
"comments.placeholder.add": "Add a comment",
"comments.placeholder.editComment": "Yorumu düzenle",
"comments.placeholder.editReply": "Edit reply",
"comments.placeholder.reply": "Reply",
"comments.reply": "Reply",

View File

@ -112,8 +112,10 @@
"collaboration.historyAction.generic": "Співавтор виконав скасування/повторення",
"comments.actions.addComment": "Add Comment",
"comments.actions.deleteReply": "Delete reply",
"comments.actions.editComment": "Редагувати коментар",
"comments.actions.editReply": "Edit reply",
"comments.aria.closeComment": "Close comment",
"comments.aria.commentActions": "Дії з коментарем",
"comments.aria.deleteComment": "Delete thread",
"comments.aria.filterComments": "Фільтрувати коментарі",
"comments.aria.nextComment": "Next comment",
@ -132,6 +134,7 @@
"comments.noComments": "No comments yet",
"comments.panelTitle": "Comment",
"comments.placeholder.add": "Add a comment",
"comments.placeholder.editComment": "Редагувати коментар",
"comments.placeholder.editReply": "Edit reply",
"comments.placeholder.reply": "Reply",
"comments.reply": "Reply",

View File

@ -112,8 +112,10 @@
"collaboration.historyAction.generic": "Một cộng tác viên đã thực hiện hoàn tác/làm lại",
"comments.actions.addComment": "Add Comment",
"comments.actions.deleteReply": "Delete reply",
"comments.actions.editComment": "Chỉnh sửa bình luận",
"comments.actions.editReply": "Edit reply",
"comments.aria.closeComment": "Close comment",
"comments.aria.commentActions": "Thao tác bình luận",
"comments.aria.deleteComment": "Delete thread",
"comments.aria.filterComments": "Lọc bình luận",
"comments.aria.nextComment": "Next comment",
@ -132,6 +134,7 @@
"comments.noComments": "No comments yet",
"comments.panelTitle": "Comment",
"comments.placeholder.add": "Add a comment",
"comments.placeholder.editComment": "Chỉnh sửa bình luận",
"comments.placeholder.editReply": "Edit reply",
"comments.placeholder.reply": "Reply",
"comments.reply": "Reply",

View File

@ -112,8 +112,10 @@
"collaboration.historyAction.generic": "协作者执行了撤销/重做操作",
"comments.actions.addComment": "Add Comment",
"comments.actions.deleteReply": "删除回复",
"comments.actions.editComment": "编辑评论",
"comments.actions.editReply": "编辑回复",
"comments.aria.closeComment": "关闭评论",
"comments.aria.commentActions": "评论操作",
"comments.aria.deleteComment": "删除讨论",
"comments.aria.filterComments": "筛选评论",
"comments.aria.nextComment": "下一条评论",
@ -132,6 +134,7 @@
"comments.noComments": "暂无评论",
"comments.panelTitle": "评论",
"comments.placeholder.add": "添加评论",
"comments.placeholder.editComment": "编辑评论",
"comments.placeholder.editReply": "编辑回复",
"comments.placeholder.reply": "回复",
"comments.reply": "回复",

View File

@ -112,8 +112,10 @@
"collaboration.historyAction.generic": "協作者執行了復原/重做操作",
"comments.actions.addComment": "Add Comment",
"comments.actions.deleteReply": "刪除回覆",
"comments.actions.editComment": "編輯評論",
"comments.actions.editReply": "編輯回覆",
"comments.aria.closeComment": "關閉評論",
"comments.aria.commentActions": "評論操作",
"comments.aria.deleteComment": "刪除評論",
"comments.aria.filterComments": "篩選評論",
"comments.aria.nextComment": "下一則評論",
@ -132,6 +134,7 @@
"comments.noComments": "暫無評論",
"comments.panelTitle": "評論",
"comments.placeholder.add": "新增評論",
"comments.placeholder.editComment": "編輯評論",
"comments.placeholder.editReply": "編輯回覆",
"comments.placeholder.reply": "回覆",
"comments.reply": "回覆",