mirror of
https://github.com/overleaf/overleaf.git
synced 2024-11-21 20:47:08 -05:00
Merge pull request #12417 from overleaf/ii-history-react-toggle-switch
[web] Toggle switch history migration GitOrigin-RevId: c0812d03d576bc66dd8878fa80d4ac18dd8576d0
This commit is contained in:
parent
568092e16b
commit
867b37b76f
8 changed files with 147 additions and 20 deletions
|
@ -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": "",
|
||||
|
|
|
@ -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 />
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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>
|
||||
),
|
||||
],
|
||||
}
|
|
@ -46,4 +46,12 @@ history-root {
|
|||
padding: 0 16px;
|
||||
}
|
||||
}
|
||||
|
||||
.toggle-switch-label {
|
||||
flex: 1;
|
||||
|
||||
span {
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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')
|
||||
})
|
||||
})
|
||||
})
|
Loading…
Reference in a new issue