mirror of
https://github.com/langgenius/dify.git
synced 2026-04-15 09:57:03 +08:00
add root comment editing in thread menu
This commit is contained in:
parent
d4dae5f8c0
commit
0d3ada2bc9
@ -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(
|
||||
|
||||
@ -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">
|
||||
|
||||
@ -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,
|
||||
|
||||
@ -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 ?? [])}
|
||||
|
||||
@ -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": "رد",
|
||||
|
||||
@ -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",
|
||||
|
||||
@ -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",
|
||||
|
||||
@ -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",
|
||||
|
||||
@ -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": "پاسخ",
|
||||
|
||||
@ -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 l’instant",
|
||||
"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",
|
||||
|
||||
@ -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": "जवाब दें",
|
||||
|
||||
@ -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",
|
||||
|
||||
@ -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",
|
||||
|
||||
@ -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": "返信",
|
||||
|
||||
@ -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": "답글",
|
||||
|
||||
@ -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",
|
||||
|
||||
@ -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",
|
||||
|
||||
@ -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",
|
||||
|
||||
@ -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",
|
||||
|
||||
@ -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",
|
||||
|
||||
@ -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",
|
||||
|
||||
@ -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",
|
||||
|
||||
@ -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",
|
||||
|
||||
@ -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",
|
||||
|
||||
@ -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",
|
||||
|
||||
@ -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": "回复",
|
||||
|
||||
@ -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": "回覆",
|
||||
|
||||
Loading…
Reference in New Issue
Block a user