Fix "show more/less" options in new review panel (#21700)

* Fix "show all/less" options in new review panel

* added newLineCharsLimit, inline options

* fix scss lint

GitOrigin-RevId: 98f29c76d4efda225515162cde0961e55acd5545
This commit is contained in:
Domagoj Kriskovic 2024-11-08 15:23:57 +01:00 committed by Copybot
parent 595c60327e
commit 8b0b923063
6 changed files with 124 additions and 75 deletions

View file

@ -15,15 +15,7 @@ import { useChangesUsersContext } from '../context/changes-users-context'
import { ReviewPanelChangeUser } from './review-panel-change-user'
import { ReviewPanelEntry } from './review-panel-entry'
import { useModalsContext } from '@/features/ide-react/context/modals-context'
const TEXT_CHAR_LIMIT = 50
const truncateText = (text: string) => {
if (text.length > TEXT_CHAR_LIMIT) {
return text.slice(0, TEXT_CHAR_LIMIT) + '...'
}
return text
}
import { ExpandableContent } from './review-panel-expandable-content'
export const ReviewPanelChange = memo<{
change: Change<EditOperation>
@ -172,18 +164,27 @@ export const ReviewPanelChange = memo<{
<span>
{t('aggregate_changed')}:{' '}
<del className="review-panel-content-highlight">
{truncateText(aggregate.op.d)}
<ExpandableContent
inline
content={aggregate.op.d}
checkNewLines={false}
/>
</del>{' '}
{t('aggregate_to')}{' '}
<ins className="review-panel-content-highlight">
{truncateText(change.op.i)}
</ins>
<ExpandableContent
inline
content={change.op.i}
checkNewLines={false}
/>
</span>
) : (
<span>
{t('tracked_change_added')}:&nbsp;
<ins className="review-panel-content-highlight">
{truncateText(change.op.i)}
<ExpandableContent
content={change.op.i}
checkNewLines={false}
/>
</ins>
</span>
)}
@ -200,7 +201,10 @@ export const ReviewPanelChange = memo<{
<span>
{t('tracked_change_deleted')}:&nbsp;
<del className="review-panel-content-highlight">
{truncateText(change.op.d)}
<ExpandableContent
content={change.op.d}
checkNewLines={false}
/>
</del>
</span>
</>

View file

@ -1,24 +1,34 @@
import { FC, useCallback, useEffect, useRef, useState } from 'react'
import classNames from 'classnames'
import { FC, useCallback, useRef, useState } from 'react'
import OLButton from '@/features/ui/components/ol/ol-button'
import { useTranslation } from 'react-i18next'
import classNames from 'classnames'
export const ExpandableContent: FC<{ className?: string }> = ({
children,
export const ExpandableContent: FC<{
className?: string
content: string
contentLimit?: number
newLineCharsLimit?: number
checkNewLines?: boolean
inline?: boolean
}> = ({
content,
className,
contentLimit = 50,
newLineCharsLimit = 3,
checkNewLines = true,
inline = false,
}) => {
const { t } = useTranslation()
const contentRef = useRef<HTMLDivElement>(null)
const [isExpanded, setIsExpanded] = useState(false)
const [isOverflowing, setIsOverflowing] = useState(false)
useEffect(() => {
if (contentRef.current) {
setIsOverflowing(
contentRef.current.scrollHeight > contentRef.current.clientHeight
const limit = checkNewLines
? Math.min(
contentLimit,
indexOfNthLine(content, newLineCharsLimit) ?? Infinity
)
}
}, [])
: contentLimit
const isOverflowing = content.length > limit
const handleShowMore = useCallback(() => {
setIsExpanded(true)
@ -35,19 +45,19 @@ export const ExpandableContent: FC<{ className?: string }> = ({
}, [])
return (
<div>
<>
<div
ref={contentRef}
className={classNames(
'review-panel-content-expandable',
{
'review-panel-content-expanded': isExpanded,
},
className
)}
className={classNames('review-panel-expandable-content', className)}
>
{children}
{isExpanded ? content : content.slice(0, limit)}
{isOverflowing && !isExpanded && '...'}
</div>
<div
className={classNames('review-panel-expandable-links', {
'review-panel-expandable-inline': inline,
})}
>
{isExpanded ? (
<OLButton
variant="link"
@ -68,5 +78,21 @@ export const ExpandableContent: FC<{ className?: string }> = ({
)
)}
</div>
</>
)
}
function indexOfNthLine(content: string, n: number) {
if (n < 1) return null
let line = 0
for (let i = 0; i < content.length; i++) {
if (content[i] === '\n') {
line++
if (line === n) {
return i
}
}
}
return null
}

View file

@ -112,9 +112,11 @@ export const ReviewPanelMessage: FC<{
autoFocus // eslint-disable-line jsx-a11y/no-autofocus
/>
) : (
<ExpandableContent className="review-panel-comment-body">
{message.content}
</ExpandableContent>
<ExpandableContent
className="review-panel-comment-body"
checkNewLines
content={message.content}
/>
)}
{deleting && (

View file

@ -97,9 +97,11 @@ export const ReviewPanelResolvedThread: FC<{
<div className="review-panel-resolved-comment-quoted-text-label">
{t('quoted_text')}
</div>
<ExpandableContent className="review-panel-resolved-comment-quoted-text-quote">
{comment?.op.c}
</ExpandableContent>
<ExpandableContent
className="review-panel-resolved-comment-quoted-text-quote"
content={comment?.op.c}
checkNewLines
/>
</div>
<ReviewPanelCommentContent comment={comment} isResolved />

View file

@ -361,19 +361,26 @@
font-size: @font-size-02;
color: @content-primary;
overflow-wrap: anywhere;
white-space: pre-wrap;
}
.review-panel-content-expandable {
display: -webkit-box;
text-overflow: ellipsis;
-webkit-box-orient: vertical;
-webkit-line-clamp: 3;
line-clamp: 3;
overflow: hidden;
.review-panel-expandable-content {
display: inline;
padding-right: var(--spacing-02);
}
.review-panel-content-expanded {
display: block;
.review-panel-expandable-inline {
display: inline;
}
.review-panel-expandable-links {
.btn-inline-link {
text-decoration: none;
line-height: 1;
}
.btn-inline-link:hover {
text-decoration: underline;
}
}
.review-panel-comment-input {

View file

@ -366,19 +366,27 @@
font-size: var(--font-size-02);
color: var(--content-primary);
overflow-wrap: anywhere;
white-space: pre-wrap;
}
.review-panel-content-expandable {
display: -webkit-box;
text-overflow: ellipsis;
-webkit-box-orient: vertical;
-webkit-line-clamp: 3;
line-clamp: 3;
overflow: hidden;
.review-panel-expandable-content {
display: inline;
padding-right: var(--spacing-02);
}
.review-panel-content-expanded {
display: block;
.review-panel-expandable-inline {
display: inline;
}
.review-panel-expandable-links {
.btn-inline-link {
text-decoration: none;
line-height: 1;
}
.btn-inline-link:hover {
text-decoration: underline;
}
}
.review-panel-comment-input {