diff --git a/services/web/frontend/js/features/review-panel-new/components/review-panel-change.tsx b/services/web/frontend/js/features/review-panel-new/components/review-panel-change.tsx index b6591d593f..047b01e98f 100644 --- a/services/web/frontend/js/features/review-panel-new/components/review-panel-change.tsx +++ b/services/web/frontend/js/features/review-panel-new/components/review-panel-change.tsx @@ -23,146 +23,172 @@ export const ReviewPanelChange = memo<{ editable?: boolean docId: string hoverRanges?: boolean -}>(({ change, aggregate, top, docId, hoverRanges, editable = true }) => { - const { t } = useTranslation() - const { acceptChanges, rejectChanges } = useRangesActionsContext() - const permissions = usePermissionsContext() - const changesUsers = useChangesUsersContext() + hovered?: boolean + onEnter?: () => void + onLeave?: () => void +}>( + ({ + change, + aggregate, + top, + docId, + hoverRanges, + editable = true, + hovered, + onEnter, + onLeave, + }) => { + const { t } = useTranslation() + const { acceptChanges, rejectChanges } = useRangesActionsContext() + const permissions = usePermissionsContext() + const changesUsers = useChangesUsersContext() - if (!changesUsers) { - // if users are not loaded yet, do not show "Unknown" user - return null - } + if (!changesUsers) { + // if users are not loaded yet, do not show "Unknown" user + return null + } - return ( - -
- -
+ return ( + +
+ +
-
-
-
-
- -
-
- {formatTimeBasedOnYear(change.metadata?.ts)} +
+
+
+
+ +
+
+ {formatTimeBasedOnYear(change.metadata?.ts)} +
+ {editable && permissions.write && ( +
+ + + + + + + +
+ )}
- {editable && permissions.write && ( -
- - - - - - - -
- )} -
+ )} -
- {'i' in change.op && ( - <> - {aggregate ? ( - - ) : ( - - )} + {aggregate ? ( + + {t('aggregate_changed')}:{' '} + + {aggregate.op.d} + {' '} + {t('aggregate_to')}{' '} + + {change.op.i} + + + ) : ( + + {t('tracked_change_added')}:  + + {change.op.i} + + + )} + + )} + + {'d' in change.op && ( + <> + - {aggregate ? ( - {t('aggregate_changed')}:{' '} + {t('tracked_change_deleted')}:  - {aggregate.op.d} - {' '} - {t('aggregate_to')}{' '} - - {change.op.i} - + {change.op.d} + - ) : ( - - {t('tracked_change_added')}:  - - {change.op.i} - - - )} - - )} - - {'d' in change.op && ( - <> - - - - {t('tracked_change_deleted')}:  - - {change.op.d} - - - - )} + + )} +
-
- - ) -}) + + ) + } +) ReviewPanelChange.displayName = 'ReviewPanelChange' diff --git a/services/web/frontend/js/features/review-panel-new/components/review-panel-comment-content.tsx b/services/web/frontend/js/features/review-panel-new/components/review-panel-comment-content.tsx index 91689acb4f..82b9a74c74 100644 --- a/services/web/frontend/js/features/review-panel-new/components/review-panel-comment-content.tsx +++ b/services/web/frontend/js/features/review-panel-new/components/review-panel-comment-content.tsx @@ -14,7 +14,9 @@ import useSubmittableTextInput from '../hooks/use-submittable-text-input' export const ReviewPanelCommentContent = memo<{ comment: Change isResolved: boolean -}>(({ comment, isResolved }) => { + onLeave?: () => void + onEnter?: () => void +}>(({ comment, isResolved, onLeave, onEnter }) => { const { t } = useTranslation() const [submitting, setSubmitting] = useState(false) const [error, setError] = useState() @@ -47,7 +49,11 @@ export const ReviewPanelCommentContent = memo<{ } return ( -
+
{thread.messages.map((message, i) => { const isReply = i !== 0 diff --git a/services/web/frontend/js/features/review-panel-new/components/review-panel-comment.tsx b/services/web/frontend/js/features/review-panel-new/components/review-panel-comment.tsx index 44f6a4eeed..03aff9ae9d 100644 --- a/services/web/frontend/js/features/review-panel-new/components/review-panel-comment.tsx +++ b/services/web/frontend/js/features/review-panel-new/components/review-panel-comment.tsx @@ -11,7 +11,10 @@ export const ReviewPanelComment = memo<{ docId: string top?: number hoverRanges?: boolean -}>(({ comment, top, docId, hoverRanges }) => { + onEnter?: () => void + onLeave?: () => void + hovered?: boolean +}>(({ comment, top, hovered, onEnter, onLeave, docId, hoverRanges }) => { const threads = useThreadsContext() const thread = threads?.[comment.op.t] @@ -23,6 +26,7 @@ export const ReviewPanelComment = memo<{ -
+
- + ) }) diff --git a/services/web/frontend/js/features/review-panel-new/components/review-panel-current-file.tsx b/services/web/frontend/js/features/review-panel-new/components/review-panel-current-file.tsx index 929c970583..37cd3dd1ae 100644 --- a/services/web/frontend/js/features/review-panel-new/components/review-panel-current-file.tsx +++ b/services/web/frontend/js/features/review-panel-new/components/review-panel-current-file.tsx @@ -43,6 +43,20 @@ const ReviewPanelCurrentFile: FC = () => { const ranges = useRangesContext() const threads = useThreadsContext() const state = useCodeMirrorStateContext() + const [hoveredEntry, setHoveredEntry] = useState(null) + + const hoverTimeout = useRef(0) + const handleEntryEnter = useCallback((id: string) => { + clearTimeout(hoverTimeout.current) + setHoveredEntry(id) + }, []) + + const handleEntryLeave = useCallback((id: string) => { + clearTimeout(hoverTimeout.current) + hoverTimeout.current = window.setTimeout(() => { + setHoveredEntry(null) + }, 100) + }, []) const [aggregatedRanges, setAggregatedRanges] = useState() @@ -298,6 +312,9 @@ const ReviewPanelCurrentFile: FC = () => { change={change} top={positions.get(change.id)} aggregate={aggregatedRanges.aggregates.get(change.id)} + hovered={hoveredEntry === change.id} + onEnter={() => handleEntryEnter(change.id)} + onLeave={() => handleEntryLeave(change.id)} /> ) )} @@ -310,6 +327,9 @@ const ReviewPanelCurrentFile: FC = () => { key={comment.id} comment={comment} top={positions.get(comment.id)} + hovered={hoveredEntry === comment.id} + onEnter={() => handleEntryEnter(comment.id)} + onLeave={() => handleEntryLeave(comment.id)} /> ) )} diff --git a/services/web/frontend/js/features/review-panel-new/components/review-panel-message.tsx b/services/web/frontend/js/features/review-panel-new/components/review-panel-message.tsx index 6cb678fa02..efb9640f2e 100644 --- a/services/web/frontend/js/features/review-panel-new/components/review-panel-message.tsx +++ b/services/web/frontend/js/features/review-panel-new/components/review-panel-message.tsx @@ -106,6 +106,7 @@ export const ReviewPanelMessage: FC<{ id="resolve-thread" overlayProps={{ placement: 'bottom' }} description={t('resolve_comment')} + tooltipProps={{ className: 'review-panel-tooltip' }} >