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:
@@ -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": "",
|
||||
|
||||
+1
-9
@@ -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
|
||||
|
||||
+2
-19
@@ -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>
|
||||
)
|
||||
}
|
||||
|
||||
+1
-6
@@ -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')}
|
||||
|
||||
-60
@@ -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)
|
||||
-92
@@ -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>
|
||||
)
|
||||
}
|
||||
+2
-12
@@ -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,
|
||||
}
|
||||
},
|
||||
|
||||
-36
@@ -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
|
||||
-109
@@ -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" />
|
||||
{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)
|
||||
+13
-35
@@ -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(
|
||||
|
||||
+8
-15
@@ -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 ''
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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', [])
|
||||
|
||||
-1
@@ -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)
|
||||
})
|
||||
|
||||
|
||||
+5
-5
@@ -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')
|
||||
|
||||
Reference in New Issue
Block a user