[web] Show confirmation modal when reverting a file (#18105)

* [web] Show confirmation modal when reverting a file

* only show Revert file in ui even if deleted

* format:fix

* using the same message for every revert

* replace "document" with "file" in confirm dialog

* remove "pull-left" class

* fix split test name

GitOrigin-RevId: ab5937b9a0570cd1fdbe5d71eda0a16ae539dc66
This commit is contained in:
Domagoj Kriskovic 2024-05-13 10:11:06 +02:00 committed by Copybot
parent 373b656e75
commit becef5f236
7 changed files with 117 additions and 53 deletions

View file

@ -1049,6 +1049,7 @@
"resize": "",
"resolve": "",
"resolved_comments": "",
"restore": "",
"restore_file": "",
"restoring": "",
"resync_completed": "",
@ -1057,6 +1058,8 @@
"retry_test": "",
"reverse_x_sort_order": "",
"revert_file": "",
"revert_file_confirmation_message": "",
"revert_file_confirmation_title": "",
"revert_file_error_message": "",
"revert_file_error_title": "",
"revert_pending_plan_change": "",

View file

@ -0,0 +1,41 @@
import { formatTime } from '@/features/utils/format-date'
import { useMemo } from 'react'
import { Button, Modal } from 'react-bootstrap'
import { useTranslation } from 'react-i18next'
type RevertFileConfirmModalProps = {
show: boolean
timestamp: number
onConfirm: () => void
onHide: () => void
}
export function RevertFileConfirmModal({
show,
timestamp,
onConfirm,
onHide,
}: RevertFileConfirmModalProps) {
const { t } = useTranslation()
const date = useMemo(() => formatTime(timestamp, 'Do MMMM'), [timestamp])
const time = useMemo(() => formatTime(timestamp, 'h:mm a'), [timestamp])
return (
<Modal show={show} onHide={onHide}>
<Modal.Header closeButton>
<Modal.Title>{t('revert_file_confirmation_title')}</Modal.Title>
</Modal.Header>
<Modal.Body>
{t('revert_file_confirmation_message', { date, time })}
</Modal.Body>
<Modal.Footer>
<Button bsStyle={null} className="btn-secondary" onClick={onHide}>
{t('cancel')}
</Button>
<Button bsStyle={null} className="btn-primary" onClick={onConfirm}>
{t('restore')}
</Button>
</Modal.Footer>
</Modal>
)
}

View file

@ -0,0 +1,28 @@
import { Button, Modal } from 'react-bootstrap'
import { useTranslation } from 'react-i18next'
export function RevertFileErrorModal({
resetErrorBoundary,
}: {
resetErrorBoundary: VoidFunction
}) {
const { t } = useTranslation()
return (
<Modal show onHide={resetErrorBoundary}>
<Modal.Header closeButton>
<Modal.Title>{t('revert_file_error_title')}</Modal.Title>
</Modal.Header>
<Modal.Body>{t('revert_file_error_message')}</Modal.Body>
<Modal.Footer>
<Button
bsStyle={null}
className="btn-secondary"
onClick={resetErrorBoundary}
>
{t('close')}
</Button>
</Modal.Footer>
</Modal>
)
}

View file

@ -1,8 +1,11 @@
import { Button, Modal } from 'react-bootstrap'
import { Button } from 'react-bootstrap'
import { useTranslation } from 'react-i18next'
import type { HistoryContextValue } from '../../../context/types/history-context-value'
import { useRevertSelectedFile } from '@/features/history/context/hooks/use-revert-selected-file'
import withErrorBoundary from '@/infrastructure/error-boundary'
import { RevertFileConfirmModal } from '../modals/revert-file-confirm-modal'
import { useState } from 'react'
import { RevertFileErrorModal } from '../modals/revert-file-error-modal'
type ToolbarRevertingFileButtonProps = {
selection: HistoryContextValue['selection']
@ -13,47 +16,34 @@ function ToolbarRevertFileButton({
}: ToolbarRevertingFileButtonProps) {
const { t } = useTranslation()
const { revertSelectedFile, isLoading } = useRevertSelectedFile()
const [showConfirmModal, setShowConfirmModal] = useState(false)
if (!selection.updateRange || !selection.selectedFile) {
return null
}
return (
<Button
className="btn-secondary history-react-toolbar-revert-file-button"
bsSize="xs"
bsStyle={null}
onClick={() => revertSelectedFile(selection)}
disabled={isLoading}
>
{isLoading ? `${t('reverting')}` : t('revert_file')}
</Button>
<>
<RevertFileConfirmModal
show={showConfirmModal}
timestamp={selection.updateRange.toVTimestamp}
onConfirm={() => {
setShowConfirmModal(false)
revertSelectedFile(selection)
}}
onHide={() => setShowConfirmModal(false)}
/>
<Button
className="btn-secondary history-react-toolbar-revert-file-button"
bsSize="xs"
bsStyle={null}
onClick={() => setShowConfirmModal(true)}
disabled={isLoading}
>
{isLoading ? `${t('reverting')}` : t('revert_file')}
</Button>
</>
)
}
function ToolbarRevertErrorModal({
resetErrorBoundary,
}: {
resetErrorBoundary: VoidFunction
}) {
const { t } = useTranslation()
return (
<Modal show onHide={resetErrorBoundary}>
<Modal.Header closeButton>
<Modal.Title>{t('revert_file_error_title')}</Modal.Title>
</Modal.Header>
<Modal.Body>{t('revert_file_error_message')}</Modal.Body>
<Modal.Footer>
<Button
bsStyle={null}
className="btn-secondary pull-left"
onClick={resetErrorBoundary}
>
{t('close')}
</Button>
</Modal.Footer>
</Modal>
)
}
export default withErrorBoundary(
ToolbarRevertFileButton,
ToolbarRevertErrorModal
)
export default withErrorBoundary(ToolbarRevertFileButton, RevertFileErrorModal)

View file

@ -14,15 +14,14 @@ type ToolbarProps = {
}
export default function Toolbar({ diff, selection }: ToolbarProps) {
const hasRevertFiles = useFeatureFlag('revert-files')
const hasRevertFile = useFeatureFlag('revert-file')
const showRevertFileButton = hasRevertFile && selection.selectedFile
const showRestoreFileButton =
selection.selectedFile && isFileRemoved(selection.selectedFile)
const showRevertFileButton =
hasRevertFiles &&
selection.selectedFile &&
!isFileRemoved(selection.selectedFile)
isFileRemoved(selection.selectedFile) &&
!showRevertFileButton
return (
<div className="history-react-toolbar">

View file

@ -75,14 +75,15 @@ export function useRevertSelectedFile() {
(selection: HistoryContextValue['selection']) => {
const { selectedFile, files } = selection
if (
selectedFile &&
selectedFile.pathname &&
!isFileRemoved(selectedFile)
) {
if (selectedFile && selectedFile.pathname) {
const file = files.find(file => file.pathname === selectedFile.pathname)
const toVersion = selection.updateRange?.toV
if (file && !isFileRemoved(file) && toVersion) {
if (file) {
const deletedAtV = isFileRemoved(file) ? file.deletedAtV : undefined
const toVersion = deletedAtV ?? selection.updateRange?.toV
if (!toVersion) {
return
}
setState('reverting')
revertFile(projectId, file.pathname, toVersion).then(

View file

@ -1549,6 +1549,8 @@
"return_to_login_page": "Return to Login page",
"reverse_x_sort_order": "Reverse __x__ sort order",
"revert_file": "Revert file",
"revert_file_confirmation_message": "Your current file will revert to the version from __date__ at __time__.",
"revert_file_confirmation_title": "Restore this version?",
"revert_file_error_message": "There was a problem reverting the file version. Please try again in a few moments. If the problem continues please contact us.",
"revert_file_error_title": "Revert File Error",
"revert_pending_plan_change": "Revert scheduled plan change",