Просмотр исходного кода

Merge pull request #21028 from overleaf/td-bs5-history-header

Migrate history header to Bootstrap 5

GitOrigin-RevId: de875cc698b0892d87d6f120131fc7fc3dc24e51
Tim Down 1 год назад
Родитель
Сommit
17b66e495f

+ 2 - 1
services/web/frontend/js/features/history/components/diff-view/main.tsx

@@ -3,6 +3,7 @@ import { Diff } from '../../services/types/doc'
 import DocumentDiffViewer from './document-diff-viewer'
 import LoadingSpinner from '../../../../shared/components/loading-spinner'
 import { useTranslation } from 'react-i18next'
+import OLNotification from '@/features/ui/components/ol/ol-notification'
 
 type MainProps = {
   diff: Nullable<Diff>
@@ -23,7 +24,7 @@ function Main({ diff, isLoading }: MainProps) {
   if (diff.binary) {
     return (
       <div className="history-content">
-        <div className="alert alert-info">{t('binary_history_error')}</div>
+        <OLNotification content={t('binary_history_error')} type="info" />
       </div>
     )
   }

+ 20 - 14
services/web/frontend/js/features/history/components/diff-view/modals/restore-file-confirm-modal.tsx

@@ -1,6 +1,12 @@
 import { formatTime } from '@/features/utils/format-date'
 import { useMemo } from 'react'
-import { Button, Modal } from 'react-bootstrap'
+import OLModal, {
+  OLModalBody,
+  OLModalFooter,
+  OLModalHeader,
+  OLModalTitle,
+} from '@/features/ui/components/ol/ol-modal'
+import OLButton from '@/features/ui/components/ol/ol-button'
 import { useTranslation } from 'react-i18next'
 
 type RestoreFileConfirmModalProps = {
@@ -21,21 +27,21 @@ export function RestoreFileConfirmModal({
   const time = useMemo(() => formatTime(timestamp, 'h:mm a'), [timestamp])
 
   return (
-    <Modal show={show} onHide={onHide}>
-      <Modal.Header closeButton>
-        <Modal.Title>{t('restore_file_confirmation_title')}</Modal.Title>
-      </Modal.Header>
-      <Modal.Body>
+    <OLModal show={show} onHide={onHide}>
+      <OLModalHeader closeButton>
+        <OLModalTitle>{t('restore_file_confirmation_title')}</OLModalTitle>
+      </OLModalHeader>
+      <OLModalBody>
         {t('restore_file_confirmation_message', { date, time })}
-      </Modal.Body>
-      <Modal.Footer>
-        <Button bsStyle={null} className="btn-secondary" onClick={onHide}>
+      </OLModalBody>
+      <OLModalFooter>
+        <OLButton variant="secondary" onClick={onHide}>
           {t('cancel')}
-        </Button>
-        <Button bsStyle={null} className="btn-primary" onClick={onConfirm}>
+        </OLButton>
+        <OLButton variant="primary" onClick={onConfirm}>
           {t('restore')}
-        </Button>
-      </Modal.Footer>
-    </Modal>
+        </OLButton>
+      </OLModalFooter>
+    </OLModal>
   )
 }

+ 17 - 15
services/web/frontend/js/features/history/components/diff-view/modals/restore-file-error-modal.tsx

@@ -1,4 +1,10 @@
-import { Button, Modal } from 'react-bootstrap'
+import OLModal, {
+  OLModalBody,
+  OLModalFooter,
+  OLModalHeader,
+  OLModalTitle,
+} from '@/features/ui/components/ol/ol-modal'
+import OLButton from '@/features/ui/components/ol/ol-button'
 import { useTranslation } from 'react-i18next'
 
 export function RestoreFileErrorModal({
@@ -9,20 +15,16 @@ export function RestoreFileErrorModal({
   const { t } = useTranslation()
 
   return (
-    <Modal show onHide={resetErrorBoundary}>
-      <Modal.Header closeButton>
-        <Modal.Title>{t('restore_file_error_title')}</Modal.Title>
-      </Modal.Header>
-      <Modal.Body>{t('restore_file_error_message')}</Modal.Body>
-      <Modal.Footer>
-        <Button
-          bsStyle={null}
-          className="btn-secondary"
-          onClick={resetErrorBoundary}
-        >
+    <OLModal show onHide={resetErrorBoundary}>
+      <OLModalHeader closeButton>
+        <OLModalTitle>{t('restore_file_error_title')}</OLModalTitle>
+      </OLModalHeader>
+      <OLModalBody>{t('restore_file_error_message')}</OLModalBody>
+      <OLModalFooter>
+        <OLButton variant="secondary" onClick={resetErrorBoundary}>
           {t('close')}
-        </Button>
-      </Modal.Footer>
-    </Modal>
+        </OLButton>
+      </OLModalFooter>
+    </OLModal>
   )
 }

+ 12 - 8
services/web/frontend/js/features/history/components/diff-view/toolbar/toolbar-restore-file-button.tsx

@@ -1,4 +1,4 @@
-import { Button } from 'react-bootstrap'
+import OLButton from '@/features/ui/components/ol/ol-button'
 import { useTranslation } from 'react-i18next'
 import { useRestoreDeletedFile } from '../../../context/hooks/use-restore-deleted-file'
 import type { HistoryContextValue } from '../../../context/types/history-context-value'
@@ -15,14 +15,18 @@ export default function ToolbarRestoreFileButton({
   const { restoreDeletedFile, isLoading } = useRestoreDeletedFile()
 
   return (
-    <Button
-      className="btn-secondary history-react-toolbar-restore-file-button"
-      bsSize="xs"
-      bsStyle={null}
+    <OLButton
+      variant="secondary"
+      size="sm"
+      className="history-react-toolbar-restore-file-button"
+      isLoading={isLoading}
       onClick={() => restoreDeletedFile(selection)}
-      disabled={isLoading}
+      bs3Props={{
+        bsSize: 'xsmall',
+        loading: isLoading ? `${t('restoring')}…` : t('restore_file'),
+      }}
     >
-      {isLoading ? `${t('restoring')}…` : t('restore_file')}
-    </Button>
+      {t('restore_file')}
+    </OLButton>
   )
 }

+ 11 - 8
services/web/frontend/js/features/history/components/diff-view/toolbar/toolbar-restore-file-to-version-button.tsx

@@ -1,4 +1,4 @@
-import { Button } from 'react-bootstrap'
+import OLButton from '@/features/ui/components/ol/ol-button'
 import { useTranslation } from 'react-i18next'
 import type { HistoryContextValue } from '../../../context/types/history-context-value'
 import withErrorBoundary from '@/infrastructure/error-boundary'
@@ -33,15 +33,18 @@ function ToolbarRestoreFileToVersionButton({
         }}
         onHide={() => setShowConfirmModal(false)}
       />
-      <Button
-        className="btn-secondary"
-        bsSize="xs"
-        bsStyle={null}
+      <OLButton
+        variant="secondary"
+        size="sm"
+        isLoading={isLoading}
         onClick={() => setShowConfirmModal(true)}
-        disabled={isLoading}
+        bs3Props={{
+          bsSize: 'xsmall',
+          loading: isLoading ? `${t('restoring')}…` : t('restore_file_version'),
+        }}
       >
-        {isLoading ? `${t('restoring')}…` : t('restore_file_version')}
-      </Button>
+        {t('restore_file_version')}
+      </OLButton>
     </>
   )
 }

+ 31 - 4
services/web/frontend/stylesheets/bootstrap-5/pages/editor/history.scss

@@ -1,3 +1,15 @@
+:root {
+  --history-react-header-bg: var(--bg-dark-secondary);
+  --history-react-header-color: var(--content-primary-dark);
+  --history-react-separator-color: var(--border-divider-dark);
+}
+
+@include theme('light') {
+  --history-react-header-bg: var(--bg-light-primary);
+  --history-react-header-color: var(--content-primary);
+  --history-react-separator-color: var(--border-divider);
+}
+
 history-root {
   height: 100%;
   display: block;
@@ -20,8 +32,8 @@ history-root {
     @include body-sm;
 
     height: 40px;
-    background-color: var(--bg-dark-secondary);
-    color: var(--content-primary-dark);
+    background-color: var(--history-react-header-bg);
+    color: var(--history-react-header-color);
     display: flex;
     flex-direction: column;
     justify-content: center;
@@ -34,7 +46,7 @@ history-root {
     flex-direction: column;
 
     .toolbar-container {
-      border-bottom: 1px solid var(--border-divider-dark);
+      border-bottom: 1px solid var(--history-react-separator-color);
       padding: 0 var(--spacing-04);
     }
 
@@ -55,7 +67,7 @@ history-root {
     display: flex;
     flex-direction: column;
     width: 320px;
-    border-left: 1px solid var(--border-divider-dark);
+    border-left: 1px solid var(--history-react-separator-color);
     box-sizing: content-box;
   }
 
@@ -292,6 +304,21 @@ history-root {
     text-align: center;
   }
 
+  .history-react-toolbar {
+    display: flex;
+    align-items: center;
+    gap: var(--spacing-04);
+
+    .history-react-toolbar-file-info {
+      flex: 1;
+      text-align: right;
+    }
+
+    .history-react-toolbar-time {
+      font-weight: 700;
+    }
+  }
+
   .history-paywall-prompt {
     padding: var(--history-change-list-padding);