Merge pull request #25547 from overleaf/dp-remove-reviewer-role-flag-frontend

Clean up reviewer-role feature flag from frontend

GitOrigin-RevId: 0cac59be58b0350c24f57d3e63898246b2bd6881
This commit is contained in:
David
2025-05-16 08:06:00 +00:00
committed by Copybot
parent 899f6d18d6
commit b56556f37b
20 changed files with 47 additions and 617 deletions
@@ -38,7 +38,6 @@
"accept_change_error_description": "",
"accept_change_error_title": "",
"accept_invitation": "",
"accept_or_reject_each_changes_individually": "",
"accept_or_reject_individual_edits": "",
"accept_selected_changes": "",
"accept_terms_and_conditions": "",
@@ -127,7 +126,6 @@
"all_these_experiments_are_available_exclusively": "",
"allows_to_search_by_author_title_etc_possible_to_pull_results_directly_from_your_reference_manager_if_connected": "",
"already_have_a_papers_account": "",
"already_subscribed_try_refreshing_the_page": "",
"an_email_has_already_been_sent_to": "",
"an_error_occured_while_restoring_project": "",
"an_error_occurred_when_verifying_the_coupon_code": "",
@@ -925,10 +923,6 @@
"limited_offer": "",
"limited_to_n_collaborators_per_project": "",
"limited_to_n_collaborators_per_project_plural": "",
"limited_to_n_editors": "",
"limited_to_n_editors_per_project": "",
"limited_to_n_editors_per_project_plural": "",
"limited_to_n_editors_plural": "",
"line": "",
"line_height": "",
"line_width_is_the_width_of_the_line_in_the_current_environment": "",
@@ -1434,7 +1428,6 @@
"review": "",
"review_panel": "",
"review_panel_and_error_logs_moved_to_the_left": "",
"review_your_peers_work": "",
"reviewer": "",
"reviewer_dropbox_sync_message": "",
"reviewing": "",
@@ -1489,7 +1482,6 @@
"search_within_selection": "",
"searched_path_for_lines_containing": "",
"security": "",
"see_changes_in_your_documents_live": "",
"see_suggestions_from_collaborators": "",
"select_a_column_or_a_merged_cell_to_align": "",
"select_a_column_to_adjust_column_width": "",
@@ -1714,8 +1706,6 @@
"tags": "",
"take_short_survey": "",
"take_survey": "",
"tc_everyone": "",
"tc_guests": "",
"tell_the_project_owner_and_ask_them_to_upgrade": "",
"template": "",
"template_description": "",
@@ -1874,13 +1864,7 @@
"total_today": "",
"total_with_subtotal_and_tax": "",
"total_words": "",
"track_any_change_in_real_time": "",
"track_changes": "",
"track_changes_for_everyone": "",
"track_changes_for_guests": "",
"track_changes_for_x": "",
"track_changes_is_off": "",
"track_changes_is_on": "",
"tracked_change_added": "",
"tracked_change_deleted": "",
"transfer_management_of_your_account": "",
@@ -1972,7 +1956,6 @@
"upgrade_to_add_more_collaborators_and_access_collaboration_features": "",
"upgrade_to_get_feature": "",
"upgrade_to_review": "",
"upgrade_to_track_changes": "",
"upgrade_to_unlock_more_time": "",
"upgrade_your_subscription": "",
"upload": "",
@@ -2,28 +2,20 @@ import ReactDOM from 'react-dom'
import { useCodeMirrorViewContext } from '../../source-editor/components/codemirror-context'
import { memo } from 'react'
import ReviewPanel from './review-panel'
import TrackChangesOnWidget from './track-changes-on-widget'
import { useEditorManagerContext } from '@/features/ide-react/context/editor-manager-context'
import ReviewModeSwitcher from './review-mode-switcher'
import getMeta from '@/utils/meta'
import useReviewPanelLayout from '../hooks/use-review-panel-layout'
function ReviewPanelContainer() {
const view = useCodeMirrorViewContext()
const { showPanel, mini } = useReviewPanelLayout()
const { wantTrackChanges } = useEditorManagerContext()
const enableReviewerRole = getMeta('ol-isReviewerRoleEnabled')
if (!view) {
return null
}
const showTrackChangesWidget = !enableReviewerRole && wantTrackChanges && mini
return ReactDOM.createPortal(
<>
{showTrackChangesWidget && <TrackChangesOnWidget />}
{enableReviewerRole && <ReviewModeSwitcher />}
<ReviewModeSwitcher />
{showPanel && <ReviewPanel mini={mini} />}
</>,
view.scrollDOM
@@ -1,35 +1,18 @@
import { FC, memo, useState } from 'react'
import { FC, memo } from 'react'
import { ReviewPanelResolvedThreadsButton } from './review-panel-resolved-threads-button'
import { ReviewPanelTrackChangesMenu } from './review-panel-track-changes-menu'
import ReviewPanelTrackChangesMenuButton from './review-panel-track-changes-menu-button'
import { useTranslation } from 'react-i18next'
import getMeta from '@/utils/meta'
import { PanelHeading } from '@/shared/components/panel-heading'
import useReviewPanelLayout from '../hooks/use-review-panel-layout'
const ReviewPanelHeader: FC = () => {
const isReviewerRoleEnabled = getMeta('ol-isReviewerRoleEnabled')
const [trackChangesMenuExpanded, setTrackChangesMenuExpanded] =
useState(false)
const { closeReviewPanel } = useReviewPanelLayout()
const { t } = useTranslation()
return (
<div className="review-panel-header">
<PanelHeading title={t('review')} handleClose={closeReviewPanel}>
{isReviewerRoleEnabled && <ReviewPanelResolvedThreadsButton />}
<ReviewPanelResolvedThreadsButton />
</PanelHeading>
{!isReviewerRoleEnabled && (
<div className="review-panel-tools">
<ReviewPanelResolvedThreadsButton />
<ReviewPanelTrackChangesMenuButton
menuExpanded={trackChangesMenuExpanded}
setMenuExpanded={setTrackChangesMenuExpanded}
/>
</div>
)}
{trackChangesMenuExpanded && <ReviewPanelTrackChangesMenu />}
</div>
)
}
@@ -5,7 +5,6 @@ import OLTooltip from '@/features/ui/components/ol/ol-tooltip'
import { ReviewPanelResolvedThreadsMenu } from './review-panel-resolved-threads-menu'
import { useTranslation } from 'react-i18next'
import MaterialIcon from '@/shared/components/material-icon'
import getMeta from '@/utils/meta'
export const ReviewPanelResolvedThreadsButton: FC = () => {
const [expanded, setExpanded] = useState(false)
@@ -20,11 +19,7 @@ export const ReviewPanelResolvedThreadsButton: FC = () => {
description={t('resolved_comments')}
>
<button
className={
getMeta('ol-isReviewerRoleEnabled')
? 'review-panel-resolved-comments-toggle-reviewer-role'
: 'review-panel-resolved-comments-toggle'
}
className="review-panel-resolved-comments-toggle"
ref={buttonRef}
onClick={() => setExpanded(true)}
aria-label={t('resolved_comments')}
@@ -1,60 +0,0 @@
import { FC, memo, useState } from 'react'
import { Trans } from 'react-i18next'
import { useEditorManagerContext } from '@/features/ide-react/context/editor-manager-context'
import MaterialIcon from '@/shared/components/material-icon'
import { useProjectContext } from '@/shared/context/project-context'
import UpgradeTrackChangesModalLegacy from './upgrade-track-changes-modal-legacy'
import { send, sendMB } from '@/infrastructure/event-tracking'
const sendAnalytics = () => {
send('subscription-funnel', 'editor-click-feature', 'real-time-track-changes')
sendMB('paywall-prompt', {
'paywall-type': 'track-changes',
})
}
const ReviewPanelTrackChangesMenuButton: FC<{
menuExpanded: boolean
setMenuExpanded: React.Dispatch<React.SetStateAction<boolean>>
}> = ({ menuExpanded, setMenuExpanded }) => {
const project = useProjectContext()
const { wantTrackChanges } = useEditorManagerContext()
const [showModal, setShowModal] = useState(false)
const handleTrackChangesMenuExpand = () => {
if (project.features.trackChanges) {
setMenuExpanded(value => !value)
} else {
sendAnalytics()
setShowModal(true)
}
}
return (
<>
<button
className="track-changes-menu-button"
onClick={handleTrackChangesMenuExpand}
>
{wantTrackChanges && <div className="track-changes-indicator-circle" />}
{wantTrackChanges ? (
<Trans
i18nKey="track_changes_is_on"
components={{ strong: <strong /> }}
/>
) : (
<Trans
i18nKey="track_changes_is_off"
components={{ strong: <strong /> }}
/>
)}
<MaterialIcon type={menuExpanded ? 'expand_more' : 'chevron_right'} />
</button>
<UpgradeTrackChangesModalLegacy show={showModal} setShow={setShowModal} />
</>
)
}
export default memo(ReviewPanelTrackChangesMenuButton)
@@ -1,92 +0,0 @@
import { FC } from 'react'
import TrackChangesToggle from '@/features/review-panel-new/components/track-changes-toggle'
import { useProjectContext } from '@/shared/context/project-context'
import { usePermissionsContext } from '@/features/ide-react/context/permissions-context'
import { useTranslation } from 'react-i18next'
import {
useTrackChangesStateActionsContext,
useTrackChangesStateContext,
} from '../context/track-changes-state-context'
import { useChangesUsersContext } from '../context/changes-users-context'
import { buildName } from '../utils/build-name'
export const ReviewPanelTrackChangesMenu: FC = () => {
const { t } = useTranslation()
const permissions = usePermissionsContext()
const project = useProjectContext()
const trackChanges = useTrackChangesStateContext()
const { saveTrackChanges } = useTrackChangesStateActionsContext()
const changesUsers = useChangesUsersContext()
if (trackChanges === undefined || !changesUsers) {
return null
}
const { onForEveryone, onForGuests, onForMembers } = trackChanges
const canToggle = project.features.trackChanges && permissions.write
return (
<div className="rp-tc-state">
<div className="rp-tc-state-item">
<span className="rp-tc-state-item-name">{t('tc_everyone')}</span>
<TrackChangesToggle
id="track-changes-everyone"
description={t('track_changes_for_everyone')}
handleToggle={() =>
saveTrackChanges(onForEveryone ? { on_for: {} } : { on: true })
}
value={onForEveryone}
disabled={!canToggle}
/>
</div>
{[project.owner, ...project.members].map(member => {
const user = changesUsers.get(member._id) ?? member
const name = buildName(user)
const value = onForEveryone || onForMembers[member._id] === true
return (
<div key={member._id} className="rp-tc-state-item">
<span className="rp-tc-state-item-name">{name}</span>
<TrackChangesToggle
id={`track-changes-${member._id}`}
description={t('track_changes_for_x', { name })}
handleToggle={() => {
saveTrackChanges({
on_for: {
...onForMembers,
[member._id]: !value,
},
on_for_guests: onForGuests,
})
}}
value={value}
disabled={!canToggle || onForEveryone}
/>
</div>
)
})}
<div className="rp-tc-state-item">
<span className="rp-tc-state-item-name">{t('tc_guests')}</span>
<TrackChangesToggle
id="track-changes-guests"
description={t('track_changes_for_guests')}
handleToggle={() =>
saveTrackChanges({
on_for: onForMembers,
on_for_guests: !onForGuests,
})
}
value={onForGuests}
disabled={!canToggle || onForEveryone}
/>
</div>
</div>
)
}
@@ -34,13 +34,10 @@ import { numberOfChangesInSelection } from '../utils/changes-in-selection'
import { useEditorManagerContext } from '@/features/ide-react/context/editor-manager-context'
import classNames from 'classnames'
import useEventListener from '@/shared/hooks/use-event-listener'
import getMeta from '@/utils/meta'
import useReviewPanelLayout from '../hooks/use-review-panel-layout'
const isReviewerRoleEnabled = getMeta('ol-isReviewerRoleEnabled')
const TRACK_CHANGES_ON_WIDGET_HEIGHT = 25
const EDIT_MODE_SWITCH_WIDGET_HEIGHT = 40
const CM_LINE_RIGHT_PADDING = isReviewerRoleEnabled ? 8 : 2
const CM_LINE_RIGHT_PADDING = 8
const TOOLTIP_SHOW_DELAY = 120
const ReviewTooltipMenu: FC = () => {
@@ -190,16 +187,9 @@ const ReviewTooltipMenuContent: FC<{ onAddComment: () => void }> = ({
return
}
let widgetOffset = 0
if (isReviewerRoleEnabled) {
widgetOffset = EDIT_MODE_SWITCH_WIDGET_HEIGHT
} else if (wantTrackChanges && !reviewPanelOpen) {
widgetOffset = TRACK_CHANGES_ON_WIDGET_HEIGHT
}
return {
position: 'fixed' as const,
top: scrollDomRect.top + widgetOffset,
top: scrollDomRect.top + EDIT_MODE_SWITCH_WIDGET_HEIGHT,
right: window.innerWidth - editorRightPos,
}
},
@@ -1,36 +0,0 @@
import { Trans } from 'react-i18next'
import { EditorView } from '@codemirror/view'
import classnames from 'classnames'
import { useCodeMirrorStateContext } from '@/features/source-editor/components/codemirror-context'
import { useLayoutContext } from '@/shared/context/layout-context'
import { useCallback } from 'react'
function TrackChangesOnWidget() {
const { setReviewPanelOpen } = useLayoutContext()
const state = useCodeMirrorStateContext()
const darkTheme = state.facet(EditorView.darkTheme)
const openReviewPanel = useCallback(() => {
setReviewPanelOpen(true)
}, [setReviewPanelOpen])
return (
<div className="review-panel-in-editor-widgets">
<div className="review-panel-in-editor-widgets-inner">
<button
className={classnames('review-panel-track-changes-indicator', {
'review-panel-track-changes-indicator-on-dark': darkTheme,
})}
onClick={openReviewPanel}
>
<Trans
i18nKey="track_changes_is_on"
components={{ strong: <strong /> }}
/>
</button>
</div>
</div>
)
}
export default TrackChangesOnWidget
@@ -1,109 +0,0 @@
import { useTranslation } from 'react-i18next'
import { useProjectContext } from '@/shared/context/project-context'
import { useUserContext } from '@/shared/context/user-context'
import teaserVideo from '../images/teaser-track-changes.mp4'
import teaserImage from '../images/teaser-track-changes.gif'
import { startFreeTrial, upgradePlan } from '@/main/account-upgrade'
import { memo } from 'react'
import OLModal, {
OLModalBody,
OLModalFooter,
OLModalHeader,
OLModalTitle,
} from '@/features/ui/components/ol/ol-modal'
import OLButton from '@/features/ui/components/ol/ol-button'
import OLRow from '@/features/ui/components/ol/ol-row'
import OLCol from '@/features/ui/components/ol/ol-col'
import MaterialIcon from '@/shared/components/material-icon'
type UpgradeTrackChangesModalProps = {
show: boolean
setShow: React.Dispatch<React.SetStateAction<boolean>>
}
function UpgradeTrackChangesModalLegacy({
show,
setShow,
}: UpgradeTrackChangesModalProps) {
const { t } = useTranslation()
const project = useProjectContext()
const user = useUserContext()
return (
<OLModal show={show} onHide={() => setShow(false)}>
<OLModalHeader closeButton>
<OLModalTitle>{t('upgrade_to_track_changes')}</OLModalTitle>
</OLModalHeader>
<OLModalBody>
<div className="teaser-video-container">
{/* eslint-disable-next-line jsx-a11y/media-has-caption */}
<video className="teaser-video" autoPlay loop>
<source src={teaserVideo} type="video/mp4" />
<img
src={teaserImage}
alt={t('demonstrating_track_changes_feature')}
/>
</video>
</div>
<h4 className="teaser-title">
{t('see_changes_in_your_documents_live')}
</h4>
<OLRow>
<OLCol lg={{ span: 10, offset: 1 }}>
<ul className="list-unstyled">
{[
t('track_any_change_in_real_time'),
t('review_your_peers_work'),
t('accept_or_reject_each_changes_individually'),
].map(translation => (
<li key={translation}>
<MaterialIcon type="check" className="align-text-bottom" />
&nbsp;{translation}
</li>
))}
</ul>
</OLCol>
</OLRow>
<p className="small">
{t('already_subscribed_try_refreshing_the_page')}
</p>
{project.owner && (
<div className="text-center">
{project.owner._id === user.id ? (
user.allowedFreeTrial ? (
<OLButton
variant="primary"
onClick={() => startFreeTrial('track-changes')}
>
{t('try_it_for_free')}
</OLButton>
) : (
<OLButton
variant="primary"
onClick={() => upgradePlan('project-sharing')}
>
{t('upgrade')}
</OLButton>
)
) : (
<p>
<strong>
{t(
'please_ask_the_project_owner_to_upgrade_to_track_changes'
)}
</strong>
</p>
)}
</div>
)}
</OLModalBody>
<OLModalFooter>
<OLButton variant="secondary" onClick={() => setShow(false)}>
{t('close')}
</OLButton>
</OLModalFooter>
</OLModal>
)
}
export default memo(UpgradeTrackChangesModalLegacy)
@@ -17,7 +17,6 @@ import { postJSON } from '@/infrastructure/fetch-json'
import useEventListener from '@/shared/hooks/use-event-listener'
import { ProjectContextValue } from '@/shared/context/types/project-context'
import { usePermissionsContext } from '@/features/ide-react/context/permissions-context'
import getMeta from '@/utils/meta'
export type TrackChangesState = {
onForEveryone: boolean
@@ -99,25 +98,15 @@ export const TrackChangesStateProvider: FC<React.PropsWithChildren> = ({
const saveTrackChangesForCurrentUser = useCallback(
async (trackChanges: boolean) => {
if (user.id) {
if (getMeta('ol-isReviewerRoleEnabled')) {
saveTrackChanges({
on_for: {
...onForMembers,
[user.id]: trackChanges,
},
})
} else {
saveTrackChanges({
on_for: {
...onForMembers,
[user.id]: trackChanges,
},
on_for_guests: onForGuests,
})
}
saveTrackChanges({
on_for: {
...onForMembers,
[user.id]: trackChanges,
},
})
}
},
[onForMembers, onForGuests, user.id, saveTrackChanges]
[onForMembers, user.id, saveTrackChanges]
)
const actions = useMemo(
@@ -138,27 +127,16 @@ export const TrackChangesStateProvider: FC<React.PropsWithChildren> = ({
!onForEveryone
) {
const value = onForMembers[user.id]
if (getMeta('ol-isReviewerRoleEnabled')) {
actions.saveTrackChanges({
on_for: {
...onForMembers,
[user.id]: !value,
},
})
} else {
actions.saveTrackChanges({
on_for: {
...onForMembers,
[user.id]: !value,
},
on_for_guests: onForGuests,
})
}
actions.saveTrackChanges({
on_for: {
...onForMembers,
[user.id]: !value,
},
})
}
}, [
actions,
onForMembers,
onForGuests,
onForEveryone,
permissions.write,
project.features.trackChanges,
@@ -1,14 +1,11 @@
import { CSSProperties, useCallback, useEffect, useState } from 'react'
import { useCodeMirrorViewContext } from '@/features/source-editor/components/codemirror-context'
import getMeta from '@/utils/meta'
export const useReviewPanelStyles = (mini: boolean) => {
const view = useCodeMirrorViewContext()
const [styles, setStyles] = useState<CSSProperties>({
'--review-panel-header-height': getMeta('ol-isReviewerRoleEnabled')
? '36px'
: '69px',
'--review-panel-header-height': '36px',
} as CSSProperties)
const updateScrollDomVariables = useCallback((element: HTMLDivElement) => {
@@ -1,8 +1,7 @@
import getMeta from '@/utils/meta'
import { debounce } from 'lodash'
export const OFFSET_FOR_ENTRIES_ABOVE = 70
const COLLAPSED_HEADER_HEIGHT = getMeta('ol-isReviewerRoleEnabled') ? 42 : 75
const COLLAPSED_HEADER_HEIGHT = 42
const GAP_BETWEEN_ENTRIES = 4
export const positionItems = debounce(
@@ -14,7 +14,6 @@ import OLForm from '@/features/ui/components/ol/ol-form'
import OLFormGroup from '@/features/ui/components/ol/ol-form-group'
import { Select } from '@/shared/components/select'
import OLButton from '@/features/ui/components/ol/ol-button'
import getMeta from '@/utils/meta'
export default function AddCollaborators({ readOnly }) {
const [privileges, setPrivileges] = useState('readAndWrite')
@@ -178,29 +177,23 @@ export default function AddCollaborators({ readOnly }) {
])
const privilegeOptions = useMemo(() => {
const options = [
return [
{
key: 'readAndWrite',
label: t('editor'),
},
]
if (getMeta('ol-isReviewerRoleEnabled')) {
options.push({
{
key: 'review',
label: t('reviewer'),
description: !features.trackChanges
? t('comment_only_upgrade_for_track_changes')
: null,
})
}
options.push({
key: 'readOnly',
label: t('viewer'),
})
return options
},
{
key: 'readOnly',
label: t('viewer'),
},
]
}, [features.trackChanges, t])
return (
@@ -14,9 +14,7 @@ import OLButton from '@/features/ui/components/ol/ol-button'
import OLFormGroup from '@/features/ui/components/ol/ol-form-group'
import OLCol from '@/features/ui/components/ol/ol-col'
import MaterialIcon from '@/shared/components/material-icon'
import getMeta from '@/utils/meta'
import { useUserContext } from '@/shared/context/user-context'
import { isSplitTestEnabled } from '@/utils/splitTestUtils'
import { upgradePlan } from '@/main/account-upgrade'
type PermissionsOption = PermissionsLevel | 'removeAccess' | 'downgraded'
@@ -256,21 +254,13 @@ function SelectPrivilege({
const { features } = useProjectContext()
const privileges = useMemo(
(): Privilege[] =>
getMeta('ol-isReviewerRoleEnabled')
? [
{ key: 'owner', label: t('make_owner') },
{ key: 'readAndWrite', label: t('editor') },
{ key: 'review', label: t('reviewer') },
{ key: 'readOnly', label: t('viewer') },
{ key: 'removeAccess', label: t('remove_access') },
]
: [
{ key: 'owner', label: t('make_owner') },
{ key: 'readAndWrite', label: t('editor') },
{ key: 'readOnly', label: t('viewer') },
{ key: 'removeAccess', label: t('remove_access') },
],
(): Privilege[] => [
{ key: 'owner', label: t('make_owner') },
{ key: 'readAndWrite', label: t('editor') },
{ key: 'review', label: t('reviewer') },
{ key: 'readOnly', label: t('viewer') },
{ key: 'removeAccess', label: t('remove_access') },
],
[t]
)
@@ -284,27 +274,13 @@ function SelectPrivilege({
return ''
}
if (hasBeenDowngraded) {
if (isSplitTestEnabled('reviewer-role')) {
return t('limited_to_n_collaborators_per_project', {
count: features.collaborators,
})
} else {
return t('limited_to_n_editors', { count: features.collaborators })
}
} else if (
!canAddCollaborators &&
!['readAndWrite', 'review'].includes(value)
if (
hasBeenDowngraded ||
(!canAddCollaborators && !['readAndWrite', 'review'].includes(value))
) {
if (isSplitTestEnabled('reviewer-role')) {
return t('limited_to_n_collaborators_per_project', {
count: features.collaborators,
})
} else {
return t('limited_to_n_editors_per_project', {
count: features.collaborators,
})
}
return t('limited_to_n_collaborators_per_project', {
count: features.collaborators,
})
} else {
return ''
}
-1
View File
@@ -140,7 +140,6 @@ export interface Meta {
'ol-isProfessional': boolean
'ol-isRegisteredViaGoogle': boolean
'ol-isRestrictedTokenMember': boolean
'ol-isReviewerRoleEnabled': boolean
'ol-isSaas': boolean
'ol-itm_campaign': string
'ol-itm_content': string
@@ -250,75 +250,7 @@ del.review-panel-content-highlight {
z-index: 4;
}
// TODO: Update this when we move the track changes menu to the new design
.rp-tc-state {
position: absolute;
top: 100%;
left: 0;
right: 0;
overflow: hidden;
list-style: none;
padding: 0 var(--spacing-03);
margin: 0;
border-bottom: 1px solid var(--rp-border-grey);
text-align: left;
background-color: var(--white);
max-height: calc(
100vh - var(--review-panel-top) - var(--review-panel-header-height)
);
overflow-y: auto;
.rp-tc-state-item {
display: flex;
align-items: center;
padding: var(--spacing-02) 0;
&:last-of-type {
padding-bottom: var(--spacing-03);
}
}
.rp-tc-state-item-name {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
flex-grow: 1;
font-weight: 600;
}
}
.review-panel-tools {
display: flex;
align-items: center;
justify-content: space-between;
padding-left: var(--spacing-02);
padding-right: var(--spacing-05);
flex-shrink: 0;
flex-basis: 32px;
}
.review-panel-resolved-comments-toggle {
background-color: var(--bg-light-secondary);
font-size: var(--font-size-02);
color: color.adjust($rp-type-blue, $lightness: 25%);
border: solid 1px var(--rp-border-grey);
border-radius: var(--border-radius-base);
padding: 0;
height: 22px;
width: 22px;
line-height: 1.4;
display: flex;
align-items: center;
justify-content: center;
&:hover,
&:focus {
text-decoration: none;
color: var(--rp-type-blue);
}
}
.review-panel-resolved-comments-toggle-reviewer-role {
display: flex;
align-items: center;
border: none;
@@ -333,27 +265,6 @@ del.review-panel-content-highlight {
}
}
.track-changes-indicator-circle {
width: 8px;
height: 8px;
border-radius: 100%;
background-color: var(--bg-accent-01);
}
.track-changes-menu-button {
border: none;
background: none;
padding: 0;
display: flex;
align-items: center;
gap: var(--spacing-02);
font-size: var(--font-size-02);
i {
width: 8px;
}
}
.review-panel-resolved-comments {
--bs-popover-border-width: 1px;
--bs-popover-bg: var(--bg-light-secondary);
@@ -780,56 +691,6 @@ del.review-panel-content-highlight {
pointer-events: none; // this is to prevent mouseLeave event from firing when hovering over the tooltip
}
.review-panel-in-editor-widgets {
position: sticky;
top: 0;
right: 0;
font-size: 11px;
z-index: 2;
font-family: $font-family-base;
.review-panel-in-editor-widgets-inner {
position: absolute;
top: 0;
right: 0;
display: flex;
flex-direction: column;
}
.review-panel-track-changes-indicator {
border: 0;
}
}
.review-panel-track-changes-indicator {
display: block;
padding: 5px 10px;
background-color: rgb(240 240 240 / 90%);
color: var(--rp-type-blue);
text-align: center;
border-bottom-left-radius: 3px;
white-space: nowrap;
&.review-panel-track-changes-indicator-on-dark {
background-color: rgb(88 88 88 / 80%);
color: #fff;
&:hover,
&:focus {
background-color: rgb(88 88 88 / 100%);
color: #fff;
}
}
&:hover,
&:focus {
outline: 0;
text-decoration: none;
background-color: rgb(240 240 240 / 100%);
color: var(--rp-type-blue);
}
}
.review-mode-switcher-container {
position: sticky;
top: 0;
-16
View File
@@ -42,7 +42,6 @@
"accept_change_error_description": "There was an error accepting a track change. Please try again in a few moments.",
"accept_change_error_title": "Accept Change Error",
"accept_invitation": "Accept invitation",
"accept_or_reject_each_changes_individually": "Accept or reject each change individually",
"accept_or_reject_individual_edits": "Accept or reject individual edits",
"accept_selected_changes": "Accept selected changes",
"accept_terms_and_conditions": "Accept terms and conditions",
@@ -154,7 +153,6 @@
"already_have_a_papers_account": "Managing your citations and bibliographies in Overleaf just got way easier! Already have a Papers account? <0>Link your account here</0>.",
"already_have_an_account": "Already have an account?",
"already_have_sl_account": "Already have an __appName__ account?",
"already_subscribed_try_refreshing_the_page": "Already subscribed? Try refreshing the page.",
"also": "Also",
"alternatively_create_new_institution_account": "Alternatively, you can create a <b>new account</b> with your institution email (<b>__email__</b>) by clicking <b>__clickText__</b>.",
"an_email_has_already_been_sent_to": "An email has already been sent to <0>__email__</0>. Please wait and try again later.",
@@ -1206,10 +1204,6 @@
"limited_document_history": "Limited document history",
"limited_to_n_collaborators_per_project": "Limited to __count__ collaborator per project",
"limited_to_n_collaborators_per_project_plural": "Limited to __count__ collaborators per project",
"limited_to_n_editors": "Limited to __count__ editor",
"limited_to_n_editors_per_project": "Limited to __count__ editor per project",
"limited_to_n_editors_per_project_plural": "Limited to __count__ editors per project",
"limited_to_n_editors_plural": "Limited to __count__ editors",
"line_height": "Line Height",
"line_width_is_the_width_of_the_line_in_the_current_environment": "Line width is the width of the line in the current environment. e.g. a full page width in single-column layout or half a page width in a two-column layout.",
"link": "Link",
@@ -1888,7 +1882,6 @@
"review": "Review",
"review_panel": "Review panel",
"review_panel_and_error_logs_moved_to_the_left": "Review panel and error logs moved to the left",
"review_your_peers_work": "Review your peers work",
"reviewer": "Reviewer",
"reviewer_dropbox_sync_message": "As a reviewer you can sync the current project version to Dropbox, but changes made in Dropbox will <0>not</0> sync back to Overleaf.",
"reviewing": "Reviewing",
@@ -1953,7 +1946,6 @@
"searched_path_for_lines_containing": "Searched __path__ for lines containing \"__query__\"",
"secondary_email_password_reset": "That email is registered as a secondary email. Please enter the primary email for your account.",
"security": "Security",
"see_changes_in_your_documents_live": "See changes in your documents, live",
"see_suggestions_from_collaborators": "See suggestions from collaborators",
"select_a_column_or_a_merged_cell_to_align": "Select a column or a merged cell to align",
"select_a_column_to_adjust_column_width": "Select a column to adjust column width",
@@ -2214,8 +2206,6 @@
"take_me_home": "Take me home!",
"take_short_survey": "Take a short survey",
"take_survey": "Take survey",
"tc_everyone": "Everyone",
"tc_guests": "Guests",
"tell_the_project_owner_and_ask_them_to_upgrade": "<0>Tell the project owner</0> and ask them to upgrade their Overleaf plan if you need more compile time.",
"template": "Template",
"template_approved_by_publisher": "This template has been approved by the publisher",
@@ -2402,12 +2392,7 @@
"total_with_subtotal_and_tax": "Total: <0>__total__</0> (__subtotal__ + __tax__ tax) per year",
"total_words": "Total Words",
"tr": "Turkish",
"track_any_change_in_real_time": "Track any change, in real-time",
"track_changes": "Track changes",
"track_changes_for_everyone": "Track changes for everyone",
"track_changes_for_x": "Track changes for __name__",
"track_changes_is_off": "Track changes is <strong>off</strong>",
"track_changes_is_on": "Track changes is <strong>on</strong>",
"tracked_change_added": "Added",
"tracked_change_deleted": "Deleted",
"transfer_management_of_your_account": "Transfer management of your Overleaf account",
@@ -2506,7 +2491,6 @@
"upgrade_to_add_more_collaborators_and_access_collaboration_features": "Upgrade to add more collaborators and access collaboration features like track changes and full project history.",
"upgrade_to_get_feature": "Upgrade to get __feature__, plus:",
"upgrade_to_review": "Upgrade to Review",
"upgrade_to_track_changes": "Upgrade to track changes",
"upgrade_to_unlock_more_time": "Upgrade now to unlock 12x more compile time on our fastest servers.",
"upgrade_your_subscription": "Upgrade your subscription",
"upload": "Upload",
@@ -10,7 +10,6 @@ import { docId } from '../source-editor/helpers/mock-doc'
describe('<ReviewPanel />', function () {
beforeEach(function () {
window.metaAttributesCache.set('ol-isReviewerRoleEnabled', true)
window.metaAttributesCache.set('ol-preventCompileOnLoad', true)
cy.interceptEvents()
@@ -650,7 +649,6 @@ describe('<ReviewPanel /> for free users', function () {
}
beforeEach(function () {
window.metaAttributesCache.set('ol-isReviewerRoleEnabled', true)
window.metaAttributesCache.set('ol-preventCompileOnLoad', true)
cy.interceptEvents()
cy.intercept('GET', '/project/*/changes/users', [])
@@ -94,7 +94,6 @@ describe('<ShareProjectModal/>', function () {
fetchMock.get('/user/contacts', { contacts })
window.metaAttributesCache.set('ol-user', { allowedFreeTrial: true })
window.metaAttributesCache.set('ol-showUpgradePrompt', true)
window.metaAttributesCache.set('ol-isReviewerRoleEnabled', true)
window.metaAttributesCache.set('ol-preventCompileOnLoad', true)
})
@@ -509,7 +509,7 @@ describe('<FigureModal />', function () {
\\end{{}figure}`,
{ delay: 0 }
)
cy.get('[aria-label="Edit figure"]').click()
cy.get('[aria-label="Edit figure"]').click({ force: true })
cy.findByRole('checkbox', { name: 'Include caption' }).should(
'be.checked'
)
@@ -526,7 +526,7 @@ describe('<FigureModal />', function () {
\\end{{}figure}`,
{ delay: 0 }
)
cy.get('[aria-label="Edit figure"]').click()
cy.get('[aria-label="Edit figure"]').click({ force: true })
cy.get('[value="0.75"]').should('be.checked')
})
@@ -539,7 +539,7 @@ describe('<FigureModal />', function () {
\\end{{}figure}`,
{ delay: 0 }
)
cy.get('[aria-label="Edit figure"]').click()
cy.get('[aria-label="Edit figure"]').click({ force: true })
cy.findByRole('checkbox', { name: 'Include label' }).click()
cy.findByRole('checkbox', { name: 'Include label' }).should(
'not.be.checked'
@@ -561,7 +561,7 @@ describe('<FigureModal />', function () {
\\end{{}figure}`,
{ delay: 0 }
)
cy.get('[aria-label="Edit figure"]').click()
cy.get('[aria-label="Edit figure"]').click({ force: true })
cy.findByRole('checkbox', { name: 'Include caption' }).click()
cy.findByRole('checkbox', { name: 'Include caption' }).should(
'not.be.checked'
@@ -585,7 +585,7 @@ describe('<FigureModal />', function () {
text below`,
{ delay: 0 }
)
cy.get('[aria-label="Edit figure"]').click()
cy.get('[aria-label="Edit figure"]').click({ force: true })
cy.findByRole('button', { name: 'Remove or replace figure' }).click()
cy.findByText('Delete figure').click()
cy.get('.cm-content').should('have.text', 'text abovetext below')