Merge pull request #12417 from overleaf/ii-history-react-toggle-switch

[web] Toggle switch history migration

GitOrigin-RevId: c0812d03d576bc66dd8878fa80d4ac18dd8576d0
This commit is contained in:
ilkin-overleaf 2023-03-29 10:54:53 +03:00 committed by Copybot
parent 568092e16b
commit 867b37b76f
8 changed files with 147 additions and 20 deletions

View file

@ -347,6 +347,9 @@
"hide_document_preamble": "",
"hide_outline": "",
"history": "",
"history_view_a11y_description": "",
"history_view_all": "",
"history_view_labels": "",
"hotkey_add_a_comment": "",
"hotkey_autocomplete_menu": "",
"hotkey_beginning_of_document": "",

View file

@ -1,15 +1,21 @@
import usePersistedState from '../../../../shared/hooks/use-persisted-state'
import ToggleSwitch from './toggle-switch'
import Main from './main'
import { useState } from 'react'
import { useHistoryContext } from '../../context/history-context'
function ChangeList() {
// eslint-disable-next-line no-unused-vars
const [labelsOnly, setLabelsOnly] = useState(false)
const { projectId, isError } = useHistoryContext()
const [labelsOnly, setLabelsOnly] = usePersistedState(
`history.userPrefs.showOnlyLabels.${projectId}`,
false
)
return (
<aside className="change-list">
<div className="history-header toggle-switch-container">
<ToggleSwitch />
{!isError && (
<ToggleSwitch labelsOnly={labelsOnly} setLabelsOnly={setLabelsOnly} />
)}
</div>
<div className="version-list-container">
<Main />

View file

@ -1,5 +1,45 @@
function ToggleSwitch() {
return <div>Toggle Switch</div>
import { useTranslation } from 'react-i18next'
type ToggleSwitchProps = {
labelsOnly: boolean
setLabelsOnly: React.Dispatch<
React.SetStateAction<ToggleSwitchProps['labelsOnly']>
>
}
function ToggleSwitch({ labelsOnly, setLabelsOnly }: ToggleSwitchProps) {
const { t } = useTranslation()
return (
<fieldset className="toggle-switch">
<legend className="sr-only">{t('history_view_a11y_description')}</legend>
<input
type="radio"
name="labels-only-toggle-switch"
checked={!labelsOnly}
onChange={() => setLabelsOnly(false)}
className="toggle-switch-input"
id="toggle-switch-all-history"
/>
<label
htmlFor="toggle-switch-all-history"
className="toggle-switch-label"
>
<span>{t('history_view_all')}</span>
</label>
<input
type="radio"
name="labels-only-toggle-switch"
checked={labelsOnly}
onChange={() => setLabelsOnly(true)}
className="toggle-switch-input"
id="toggle-switch-labels"
/>
<label htmlFor="toggle-switch-labels" className="toggle-switch-label">
<span>{t('history_view_labels')}</span>
</label>
</fieldset>
)
}
export default ToggleSwitch

View file

@ -20,8 +20,6 @@ function useHistory() {
const [nextBeforeTimestamp, setNextBeforeTimestamp] =
useState<HistoryContextValue['nextBeforeTimestamp']>(null)
const [atEnd, setAtEnd] = useState<HistoryContextValue['atEnd']>(false)
const [showOnlyLabels, setShowOnlyLabels] =
useState<HistoryContextValue['showOnlyLabels']>(false)
const [userHasFullFeature, setUserHasFullFeature] =
useState<HistoryContextValue['userHasFullFeature']>(undefined)
const [freeHistoryLimitHit, setFreeHistoryLimitHit] =
@ -44,12 +42,8 @@ function useHistory() {
})
/* eslint-enable no-unused-vars */
const {
isLoading: loading,
error,
data,
runAsync,
} = useAsync<{ updates: Update[] }>()
const { isLoading, isError, error, data, runAsync } =
useAsync<{ updates: Update[] }>()
const updates = useMemo(() => data?.updates ?? [], [data?.updates])
const loadingFileTree = true
@ -92,13 +86,13 @@ function useHistory() {
() => ({
atEnd,
error,
isError,
isLoading,
freeHistoryLimitHit,
loading,
labels,
loadingFileTree,
nextBeforeTimestamp,
selection,
showOnlyLabels,
updates,
userHasFullFeature,
viewMode,
@ -111,13 +105,13 @@ function useHistory() {
[
atEnd,
error,
isError,
isLoading,
freeHistoryLimitHit,
loading,
labels,
loadingFileTree,
nextBeforeTimestamp,
selection,
showOnlyLabels,
updates,
userHasFullFeature,
viewMode,

View file

@ -7,13 +7,13 @@ export type HistoryContextValue = {
updates: Update[]
viewMode: string
nextBeforeTimestamp: Nullable<number>
loading: boolean
atEnd: boolean
userHasFullFeature: boolean | undefined
freeHistoryLimitHit: boolean
selection: Selection
isError: boolean
isLoading: boolean
error: Nullable<unknown>
showOnlyLabels: boolean
labels: Nullable<unknown>
loadingFileTree: boolean
projectId: string

View file

@ -0,0 +1,41 @@
import { useState } from 'react'
import ToggleSwitchComponent from '../../js/features/history/components/change-list/toggle-switch'
export const LabelsOnlyToggleSwitch = () => {
const [labelsOnly, setLabelsOnly] = useState(false)
return (
<ToggleSwitchComponent
labelsOnly={labelsOnly}
setLabelsOnly={setLabelsOnly}
/>
)
}
export default {
title: 'History / Change list',
component: ToggleSwitchComponent,
argTypes: {
labelsOnly: {
table: {
disable: true,
},
},
setLabelsOnly: {
table: {
disable: true,
},
},
},
decorators: [
(Story: React.ComponentType) => (
<div className="history-react">
<div className="change-list">
<div className="history-header toggle-switch-container">
<Story />
</div>
</div>
</div>
),
],
}

View file

@ -46,4 +46,12 @@ history-root {
padding: 0 16px;
}
}
.toggle-switch-label {
flex: 1;
span {
display: block;
}
}
}

View file

@ -0,0 +1,35 @@
import { useState } from 'react'
import ToggleSwitch from '../../../../../frontend/js/features/history/components/change-list/toggle-switch'
describe('change list', function () {
describe('toggle switch', function () {
it('renders switch buttons', function () {
cy.mount(<ToggleSwitch labelsOnly={false} setLabelsOnly={() => {}} />)
cy.findByLabelText(/all history/i)
cy.findByLabelText(/labels/i)
})
it('toggles "all history" and "labels" buttons', function () {
function ToggleSwitchWrapped({ labelsOnly }: { labelsOnly: boolean }) {
const [labelsOnlyLocal, setLabelsOnlyLocal] = useState(labelsOnly)
return (
<ToggleSwitch
labelsOnly={labelsOnlyLocal}
setLabelsOnly={setLabelsOnlyLocal}
/>
)
}
cy.mount(<ToggleSwitchWrapped labelsOnly={false} />)
cy.findByLabelText(/all history/i).as('all-history')
cy.findByLabelText(/labels/i).as('labels')
cy.get('@all-history').should('be.checked')
cy.get('@labels').should('not.be.checked')
cy.get('@labels').click({ force: true })
cy.get('@all-history').should('not.be.checked')
cy.get('@labels').should('be.checked')
})
})
})