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

History UI changes- Extracting compare outside dropdown menu

GitOrigin-RevId: 67f51428debefdafe2c9bb746de5da8fc0ac5385
Davinder Singh 3 лет назад
Родитель
Сommit
3490f6a58e

+ 2 - 1
libraries/fetch-utils/test/unit/helpers/TestServer.js

@@ -57,7 +57,8 @@ class TestServer {
     })
 
     this.app.get('/json/basic-auth', (req, res) => {
-      const expectedAuth = 'Basic ' + Buffer.from('user:pass').toString('base64')
+      const expectedAuth =
+        'Basic ' + Buffer.from('user:pass').toString('base64')
       if (req.headers.authorization === expectedAuth) {
         res.json({ key: 'verysecret' })
       } else {

+ 0 - 1
services/web/frontend/extracted-translations.json

@@ -441,7 +441,6 @@
   "history_adding_label": "",
   "history_are_you_sure_delete_label": "",
   "history_compare_from_this_version": "",
-  "history_compare_to_selected_version": "",
   "history_compare_up_to_this_version": "",
   "history_delete_label": "",
   "history_deleting_label": "",

BIN
services/web/frontend/fonts/material-symbols/MaterialSymbolsRounded[FILL,GRAD,opsz,wght].woff2


+ 0 - 15
services/web/frontend/js/features/history/components/change-list/dropdown/label-dropdown-content.tsx

@@ -2,21 +2,16 @@ import Download from './menu-item/download'
 import { Version } from '../../../services/types/update'
 import { ActiveDropdown } from '../../../hooks/use-dropdown-active-item'
 import { useCallback } from 'react'
-import CompareItems from './menu-item/compare-items'
 
 type LabelDropdownContentProps = {
   projectId: string
   version: Version
-  versionTimestamp: number
-  selected: boolean
   closeDropdownForItem: ActiveDropdown['closeDropdownForItem']
 }
 
 function LabelDropdownContent({
   projectId,
   version,
-  versionTimestamp,
-  selected,
   closeDropdownForItem,
 }: LabelDropdownContentProps) {
   const closeDropdown = useCallback(() => {
@@ -30,16 +25,6 @@ function LabelDropdownContent({
         version={version}
         closeDropdown={closeDropdown}
       />
-      <CompareItems
-        updateRange={{
-          fromV: version,
-          toV: version,
-          fromVTimestamp: versionTimestamp,
-          toVTimestamp: versionTimestamp,
-        }}
-        selected={selected}
-        closeDropdown={closeDropdown}
-      />
     </>
   )
 }

+ 56 - 12
services/web/frontend/js/features/history/components/change-list/dropdown/menu-item/compare-items.tsx

@@ -19,16 +19,44 @@ function CompareItems({
   const { t } = useTranslation()
   const { selection } = useHistoryContext()
   const { updateRange: selRange, comparing } = selection
-  const notASelectionBoundary =
+
+  // Comparing mode variables
+  const notASelectionBoundaryComparingMode =
     !!selRange &&
     comparing &&
     updateRange.toV !== selRange.toV &&
     updateRange.fromV !== selRange.fromV
   const showCompareWithSelected = !comparing && !!selRange && !selected
-  const showCompareToThis =
-    notASelectionBoundary && updateRange.toV > selRange.fromV
-  const showCompareFromThis =
-    notASelectionBoundary && updateRange.fromV < selRange.toV
+  const showCompareToThisComparingMode =
+    notASelectionBoundaryComparingMode && updateRange.toV > selRange.toV
+  const showCompareFromThisComparingMode =
+    notASelectionBoundaryComparingMode && updateRange.fromV < selRange.fromV
+
+  // Normal mode variables
+  const notASelectionBoundaryNormalMode =
+    !!selRange &&
+    updateRange.toV !== selRange.toV &&
+    updateRange.fromV !== selRange.fromV
+  const showCompareToThisNormalMode =
+    notASelectionBoundaryNormalMode && updateRange.toV > selRange.toV
+  const showCompareFromThisNormalMode =
+    notASelectionBoundaryNormalMode && updateRange.fromV < selRange.fromV
+
+  let iconTypeNonSelectedVersion = ''
+  let toolTipDescriptionNonSelectedVersion = ''
+
+  if (showCompareToThisNormalMode) {
+    iconTypeNonSelectedVersion = 'align_start'
+    toolTipDescriptionNonSelectedVersion = t(
+      'history_compare_up_to_this_version'
+    )
+  }
+  if (showCompareFromThisNormalMode) {
+    iconTypeNonSelectedVersion = 'align_end'
+    toolTipDescriptionNonSelectedVersion = t(
+      'history_compare_from_this_version'
+    )
+  }
 
   return (
     <>
@@ -36,10 +64,16 @@ function CompareItems({
         <Compare
           comparisonRange={updateRangeUnion(updateRange, selRange)}
           closeDropdown={closeDropdown}
-          text={t('history_compare_to_selected_version')}
+          toolTipDescription={toolTipDescriptionNonSelectedVersion}
+          icon={
+            <MaterialIcon
+              type={iconTypeNonSelectedVersion}
+              className="material-symbols-rounded history-dropdown-icon p-1"
+            />
+          }
         />
       ) : null}
-      {showCompareFromThis ? (
+      {showCompareFromThisComparingMode ? (
         <Compare
           comparisonRange={{
             fromV: updateRange.fromV,
@@ -48,11 +82,16 @@ function CompareItems({
             toVTimestamp: selRange.toVTimestamp,
           }}
           closeDropdown={closeDropdown}
-          text={t('history_compare_from_this_version')}
-          icon={<MaterialIcon type="line_start_circle" className="fa-fw" />}
+          toolTipDescription={t('history_compare_from_this_version')}
+          icon={
+            <MaterialIcon
+              type="align_end"
+              className="material-symbols-rounded history-dropdown-icon p-1"
+            />
+          }
         />
       ) : null}
-      {showCompareToThis ? (
+      {showCompareToThisComparingMode ? (
         <Compare
           comparisonRange={{
             fromV: selRange.fromV,
@@ -61,8 +100,13 @@ function CompareItems({
             toVTimestamp: updateRange.toVTimestamp,
           }}
           closeDropdown={closeDropdown}
-          text={t('history_compare_up_to_this_version')}
-          icon={<MaterialIcon type="line_end_circle" className="fa-fw" />}
+          toolTipDescription={t('history_compare_up_to_this_version')}
+          icon={
+            <MaterialIcon
+              type="align_start"
+              className="material-symbols-rounded history-dropdown-icon p-1"
+            />
+          }
         />
       ) : null}
     </>

+ 19 - 7
services/web/frontend/js/features/history/components/change-list/dropdown/menu-item/compare.tsx

@@ -1,26 +1,27 @@
-import { MenuItem, MenuItemProps } from 'react-bootstrap'
 import Icon from '../../../../../../shared/components/icon'
 import { useHistoryContext } from '../../../../context/history-context'
 import { UpdateRange } from '../../../../services/types/update'
 import { ReactNode } from 'react'
+import Tooltip from '../../../../../../shared/components/tooltip'
+import { Button } from 'react-bootstrap'
 
 type CompareProps = {
   comparisonRange: UpdateRange
-  text: string
   icon?: ReactNode
+  toolTipDescription?: string
   closeDropdown: () => void
 }
 
 function Compare({
   comparisonRange,
-  text,
   closeDropdown,
+  toolTipDescription,
   icon = <Icon type="exchange" fw />,
   ...props
 }: CompareProps) {
   const { setSelection } = useHistoryContext()
 
-  const handleCompareVersion = (e: React.MouseEvent<MenuItemProps>) => {
+  const handleCompareVersion = (e: React.MouseEvent<Button>) => {
     e.stopPropagation()
     closeDropdown()
 
@@ -33,9 +34,20 @@ function Compare({
   }
 
   return (
-    <MenuItem onClick={handleCompareVersion} {...props}>
-      {icon} {text}
-    </MenuItem>
+    <Tooltip
+      description={toolTipDescription}
+      id="compare-btn"
+      overlayProps={{ placement: 'left' }}
+    >
+      <Button
+        bsStyle="link"
+        className="history-compare-btn"
+        onClick={handleCompareVersion}
+      >
+        <span className="sr-only">{toolTipDescription}</span>
+        {icon}
+      </Button>
+    </Tooltip>
   )
 }
 

+ 0 - 11
services/web/frontend/js/features/history/components/change-list/dropdown/version-dropdown-content.tsx

@@ -3,24 +3,18 @@ import Download from './menu-item/download'
 import { LoadedUpdate } from '../../../services/types/update'
 import { useCallback } from 'react'
 import { ActiveDropdown } from '../../../hooks/use-dropdown-active-item'
-import CompareItems from './menu-item/compare-items'
-import { updateRangeForUpdate } from '../../../utils/history-details'
 
 type VersionDropdownContentProps = {
   projectId: string
   update: LoadedUpdate
-  selected: boolean
   closeDropdownForItem: ActiveDropdown['closeDropdownForItem']
 }
 
 function VersionDropdownContent({
   projectId,
   update,
-  selected,
   closeDropdownForItem,
 }: VersionDropdownContentProps) {
-  const updateRange = updateRangeForUpdate(update)
-
   const closeDropdown = useCallback(() => {
     closeDropdownForItem(update)
   }, [closeDropdownForItem, update])
@@ -37,11 +31,6 @@ function VersionDropdownContent({
         version={update.toV}
         closeDropdown={closeDropdown}
       />
-      <CompareItems
-        updateRange={updateRange}
-        selected={selected}
-        closeDropdown={closeDropdown}
-      />
     </>
   )
 }

+ 19 - 2
services/web/frontend/js/features/history/components/change-list/history-version.tsx

@@ -10,9 +10,10 @@ import { LoadedUpdate } from '../../services/types/update'
 import classNames from 'classnames'
 import { updateRangeForUpdate } from '../../utils/history-details'
 import { ActiveDropdown } from '../../hooks/use-dropdown-active-item'
-import { memo } from 'react'
+import { memo, useCallback } from 'react'
 import { HistoryContextValue } from '../../context/types/history-context-value'
 import VersionDropdownContent from './dropdown/version-dropdown-content'
+import CompareItems from './dropdown/menu-item/compare-items'
 
 type HistoryVersionProps = {
   update: LoadedUpdate
@@ -45,6 +46,12 @@ function HistoryVersion({
 }: HistoryVersionProps) {
   const orderedLabels = orderBy(update.labels, ['created_at'], ['desc'])
 
+  const closeDropdown = useCallback(() => {
+    closeDropdownForItem(update)
+  }, [closeDropdownForItem, update])
+
+  const updateRange = updateRangeForUpdate(update)
+
   return (
     <>
       {showDivider ? <hr className="history-version-divider" /> : null}
@@ -75,7 +82,6 @@ function HistoryVersion({
             >
               {dropdownActive ? (
                 <VersionDropdownContent
-                  selected={selected}
                   update={update}
                   projectId={projectId}
                   closeDropdownForItem={closeDropdownForItem}
@@ -83,6 +89,17 @@ function HistoryVersion({
               ) : null}
             </HistoryDropdown>
           )}
+
+          {!selected ? (
+            <span data-testid="compare-icon-version" className="pull-right">
+              <CompareItems
+                updateRange={updateRange}
+                selected={selected}
+                closeDropdown={closeDropdown}
+              />
+            </span>
+          ) : null}
+
           <div className="history-version-main-details">
             <time
               className="history-version-metadata-time"

+ 16 - 2
services/web/frontend/js/features/history/components/change-list/label-list-item.tsx

@@ -11,6 +11,7 @@ import { useTranslation } from 'react-i18next'
 import { ActiveDropdown } from '../../hooks/use-dropdown-active-item'
 import { HistoryContextValue } from '../../context/types/history-context-value'
 import LabelDropdownContent from './dropdown/label-dropdown-content'
+import CompareItems from './dropdown/menu-item/compare-items'
 
 type LabelListItemProps = {
   version: Version
@@ -59,6 +60,9 @@ function LabelListItem({
     },
     [setActiveDropdownItem, version]
   )
+  const closeDropdown = useCallback(() => {
+    closeDropdownForItem(version)
+  }, [closeDropdownForItem, version])
 
   return (
     <HistoryVersionDetails
@@ -75,14 +79,24 @@ function LabelListItem({
       >
         {dropdownActive ? (
           <LabelDropdownContent
-            selected={selected}
             version={version}
-            versionTimestamp={toVTimestamp}
             projectId={projectId}
             closeDropdownForItem={closeDropdownForItem}
           />
         ) : null}
       </HistoryDropdown>
+      <span className="pull-right">
+        <CompareItems
+          updateRange={{
+            fromV: version,
+            toV: version,
+            fromVTimestamp: toVTimestamp,
+            toVTimestamp,
+          }}
+          selected={selected}
+          closeDropdown={closeDropdown}
+        />
+      </span>
       <div className="history-version-main-details">
         {labels.map(label => (
           <div key={label.id} className="history-version-label">

+ 9 - 0
services/web/frontend/stylesheets/app/editor/history-react.less

@@ -375,6 +375,15 @@ history-root {
   }
 }
 
+.history-dropdown-icon {
+  color: @neutral-90;
+}
+
+.history-compare-btn {
+  line-height: 1;
+  padding: 0;
+}
+
 .history-file-tree {
   display: flex !important; // To work around jQuery layout's inline styles
   flex-direction: column;

+ 0 - 1
services/web/locales/en.json

@@ -719,7 +719,6 @@
   "history_adding_label": "Adding label",
   "history_are_you_sure_delete_label": "Are you sure you want to delete the following label",
   "history_compare_from_this_version": "Compare from this version",
-  "history_compare_to_selected_version": "Compare to selected version",
   "history_compare_up_to_this_version": "Compare up to this version",
   "history_delete_label": "Delete label",
   "history_deleting_label": "Deleting label",

+ 37 - 34
services/web/test/frontend/features/history/components/change-list.spec.tsx

@@ -332,14 +332,10 @@ describe('change list', function () {
       cy.findAllByTestId('history-version-details')
         .eq(1)
         .within(() => {
-          cy.findByRole('button', { name: /more actions/i }).click()
-          cy.findByRole('menu').within(() => {
-            cy.findByRole('menuitem', {
-              name: /compare to selected version/i,
-            }).click()
-          })
+          cy.findByRole('button', {
+            name: /Compare/i,
+          }).click()
         })
-      cy.wait('@diff')
       cy.findByLabelText(/all history/i).click({ force: true })
       cy.findAllByTestId('history-version-details').should($versions => {
         const [first, ...rest] = Array.from($versions)
@@ -350,6 +346,40 @@ describe('change list', function () {
     })
   })
 
+  describe('compare mode', function () {
+    beforeEach(function () {
+      mountWithEditorProviders(<ChangeList />, scope, {
+        user: {
+          id: USER_ID,
+          email: USER_EMAIL,
+          isAdmin: true,
+        },
+      })
+      waitForData()
+    })
+
+    it('compares versions', function () {
+      cy.findAllByTestId('history-version-details').should($versions => {
+        const [first, ...rest] = Array.from($versions)
+        expect(first).to.have.attr('data-selected', 'true')
+        rest.forEach(version =>
+          expect(version).to.have.attr('data-selected', 'false')
+        )
+      })
+
+      cy.intercept('GET', '/project/*/filetree/diff*', {
+        body: { diff: [{ pathname: 'main.tex' }, { pathname: 'name.tex' }] },
+      }).as('compareDiff')
+
+      cy.findAllByTestId('history-version-details')
+        .last()
+        .within(() => {
+          cy.findByTestId('compare-icon-version').click()
+        })
+      cy.wait('@compareDiff')
+    })
+  })
+
   describe('dropdown', function () {
     beforeEach(function () {
       mountWithEditorProviders(<ChangeList />, scope, {
@@ -421,33 +451,6 @@ describe('change list', function () {
         })
       cy.wait('@download')
     })
-
-    it('compares versions', function () {
-      cy.findAllByTestId('history-version-details').should($versions => {
-        const [first, ...rest] = Array.from($versions)
-        expect(first).to.have.attr('data-selected', 'true')
-        rest.forEach(version =>
-          expect(version).to.have.attr('data-selected', 'false')
-        )
-      })
-
-      cy.intercept('GET', '/project/*/filetree/diff*', {
-        body: { diff: [{ pathname: 'main.tex' }, { pathname: 'name.tex' }] },
-      }).as('compareDiff')
-
-      cy.findAllByTestId('history-version-details')
-        .last()
-        .within(() => {
-          cy.findByRole('button', { name: /more actions/i }).click()
-          cy.findByRole('menu').within(() => {
-            cy.findByRole('menuitem', {
-              name: /compare to selected version/i,
-            }).click()
-          })
-        })
-
-      cy.wait('@compareDiff')
-    })
   })
 
   describe('paywall', function () {