mirror of
https://github.com/overleaf/overleaf.git
synced 2024-11-29 13:03:42 -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_document_preamble": "",
|
||||||
"hide_outline": "",
|
"hide_outline": "",
|
||||||
"history": "",
|
"history": "",
|
||||||
|
"history_view_a11y_description": "",
|
||||||
|
"history_view_all": "",
|
||||||
|
"history_view_labels": "",
|
||||||
"hotkey_add_a_comment": "",
|
"hotkey_add_a_comment": "",
|
||||||
"hotkey_autocomplete_menu": "",
|
"hotkey_autocomplete_menu": "",
|
||||||
"hotkey_beginning_of_document": "",
|
"hotkey_beginning_of_document": "",
|
||||||
|
|
|
@ -1,15 +1,21 @@
|
||||||
|
import usePersistedState from '../../../../shared/hooks/use-persisted-state'
|
||||||
import ToggleSwitch from './toggle-switch'
|
import ToggleSwitch from './toggle-switch'
|
||||||
import Main from './main'
|
import Main from './main'
|
||||||
import { useState } from 'react'
|
import { useHistoryContext } from '../../context/history-context'
|
||||||
|
|
||||||
function ChangeList() {
|
function ChangeList() {
|
||||||
// eslint-disable-next-line no-unused-vars
|
const { projectId, isError } = useHistoryContext()
|
||||||
const [labelsOnly, setLabelsOnly] = useState(false)
|
const [labelsOnly, setLabelsOnly] = usePersistedState(
|
||||||
|
`history.userPrefs.showOnlyLabels.${projectId}`,
|
||||||
|
false
|
||||||
|
)
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<aside className="change-list">
|
<aside className="change-list">
|
||||||
<div className="history-header toggle-switch-container">
|
<div className="history-header toggle-switch-container">
|
||||||
<ToggleSwitch />
|
{!isError && (
|
||||||
|
<ToggleSwitch labelsOnly={labelsOnly} setLabelsOnly={setLabelsOnly} />
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
<div className="version-list-container">
|
<div className="version-list-container">
|
||||||
<Main />
|
<Main />
|
||||||
|
|
|
@ -1,5 +1,45 @@
|
||||||
function ToggleSwitch() {
|
import { useTranslation } from 'react-i18next'
|
||||||
return <div>Toggle Switch</div>
|
|
||||||
|
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
|
export default ToggleSwitch
|
||||||
|
|
|
@ -20,8 +20,6 @@ function useHistory() {
|
||||||
const [nextBeforeTimestamp, setNextBeforeTimestamp] =
|
const [nextBeforeTimestamp, setNextBeforeTimestamp] =
|
||||||
useState<HistoryContextValue['nextBeforeTimestamp']>(null)
|
useState<HistoryContextValue['nextBeforeTimestamp']>(null)
|
||||||
const [atEnd, setAtEnd] = useState<HistoryContextValue['atEnd']>(false)
|
const [atEnd, setAtEnd] = useState<HistoryContextValue['atEnd']>(false)
|
||||||
const [showOnlyLabels, setShowOnlyLabels] =
|
|
||||||
useState<HistoryContextValue['showOnlyLabels']>(false)
|
|
||||||
const [userHasFullFeature, setUserHasFullFeature] =
|
const [userHasFullFeature, setUserHasFullFeature] =
|
||||||
useState<HistoryContextValue['userHasFullFeature']>(undefined)
|
useState<HistoryContextValue['userHasFullFeature']>(undefined)
|
||||||
const [freeHistoryLimitHit, setFreeHistoryLimitHit] =
|
const [freeHistoryLimitHit, setFreeHistoryLimitHit] =
|
||||||
|
@ -44,12 +42,8 @@ function useHistory() {
|
||||||
})
|
})
|
||||||
/* eslint-enable no-unused-vars */
|
/* eslint-enable no-unused-vars */
|
||||||
|
|
||||||
const {
|
const { isLoading, isError, error, data, runAsync } =
|
||||||
isLoading: loading,
|
useAsync<{ updates: Update[] }>()
|
||||||
error,
|
|
||||||
data,
|
|
||||||
runAsync,
|
|
||||||
} = useAsync<{ updates: Update[] }>()
|
|
||||||
const updates = useMemo(() => data?.updates ?? [], [data?.updates])
|
const updates = useMemo(() => data?.updates ?? [], [data?.updates])
|
||||||
const loadingFileTree = true
|
const loadingFileTree = true
|
||||||
|
|
||||||
|
@ -92,13 +86,13 @@ function useHistory() {
|
||||||
() => ({
|
() => ({
|
||||||
atEnd,
|
atEnd,
|
||||||
error,
|
error,
|
||||||
|
isError,
|
||||||
|
isLoading,
|
||||||
freeHistoryLimitHit,
|
freeHistoryLimitHit,
|
||||||
loading,
|
|
||||||
labels,
|
labels,
|
||||||
loadingFileTree,
|
loadingFileTree,
|
||||||
nextBeforeTimestamp,
|
nextBeforeTimestamp,
|
||||||
selection,
|
selection,
|
||||||
showOnlyLabels,
|
|
||||||
updates,
|
updates,
|
||||||
userHasFullFeature,
|
userHasFullFeature,
|
||||||
viewMode,
|
viewMode,
|
||||||
|
@ -111,13 +105,13 @@ function useHistory() {
|
||||||
[
|
[
|
||||||
atEnd,
|
atEnd,
|
||||||
error,
|
error,
|
||||||
|
isError,
|
||||||
|
isLoading,
|
||||||
freeHistoryLimitHit,
|
freeHistoryLimitHit,
|
||||||
loading,
|
|
||||||
labels,
|
labels,
|
||||||
loadingFileTree,
|
loadingFileTree,
|
||||||
nextBeforeTimestamp,
|
nextBeforeTimestamp,
|
||||||
selection,
|
selection,
|
||||||
showOnlyLabels,
|
|
||||||
updates,
|
updates,
|
||||||
userHasFullFeature,
|
userHasFullFeature,
|
||||||
viewMode,
|
viewMode,
|
||||||
|
|
|
@ -7,13 +7,13 @@ export type HistoryContextValue = {
|
||||||
updates: Update[]
|
updates: Update[]
|
||||||
viewMode: string
|
viewMode: string
|
||||||
nextBeforeTimestamp: Nullable<number>
|
nextBeforeTimestamp: Nullable<number>
|
||||||
loading: boolean
|
|
||||||
atEnd: boolean
|
atEnd: boolean
|
||||||
userHasFullFeature: boolean | undefined
|
userHasFullFeature: boolean | undefined
|
||||||
freeHistoryLimitHit: boolean
|
freeHistoryLimitHit: boolean
|
||||||
selection: Selection
|
selection: Selection
|
||||||
|
isError: boolean
|
||||||
|
isLoading: boolean
|
||||||
error: Nullable<unknown>
|
error: Nullable<unknown>
|
||||||
showOnlyLabels: boolean
|
|
||||||
labels: Nullable<unknown>
|
labels: Nullable<unknown>
|
||||||
loadingFileTree: boolean
|
loadingFileTree: boolean
|
||||||
projectId: string
|
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;
|
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