Files
overleaf-cep/services/web/frontend/js/features/dictionary/components/dictionary-modal-content.tsx
T
Rebeka Dekany e2a8bf768b Merge intermediate component wrappers into OL-prefixed components (#34996)
* Merge intermediate component wrappers into OL-prefixed components

* Replace all intermediate wrapper consumers with OL-prefixed components directly

* Fix jsx/js files still importing deleted shim components

* Remove duplicate OLNotification imports left by first pass

* Rename OLTagIcon to TagIcon, remove OL prefix

* Rename OLDropdownMenuItem to DropdownMenuItem, remove OL prefix

* Remove OLNotification, use Notification directly

* Move Notification to the main shared component folder

* Update tag-icon import path out of ol/

* Move TagIcon to the main shared component folder

* Update dropdown-menu-item import path out of ol/

* Move DropdownMenuItem to the main shared component folder

* Fix dropdown-menu-item import path to dropdown/ subfolder

* Remove BS5 alias prefixes from shared components

* Restore notification-list wrapper in Notification component

* Add translation for loading button

* Remove redundant import aliasing

* Resolve conflicts

* Restore notification container `notification-list`

GitOrigin-RevId: 24a5af18599a3e02ac6fd61c09cf5a49ef6e0020
2026-09-17 11:19:34 +00:00

105 lines
3.3 KiB
TypeScript

import { useCallback, useState } from 'react'
import { useTranslation } from 'react-i18next'
import useAsync from '../../../shared/hooks/use-async'
import { postJSON } from '../../../infrastructure/fetch-json'
import { debugConsole } from '@/utils/debugging'
import {
OLModalBody,
OLModalFooter,
OLModalHeader,
OLModalTitle,
} from '@/shared/components/ol/ol-modal'
import OLTooltip from '@/shared/components/ol/ol-tooltip'
import Notification from '@/shared/components/notification'
import OLButton from '@/shared/components/ol/ol-button'
import OLIconButton from '@/shared/components/ol/ol-icon-button'
import { learnedWords as initialLearnedWords } from '@/features/source-editor/extensions/spelling/learned-words'
type DictionaryModalContentProps = {
handleHide: () => void
}
const wordsSortFunction = (a: string, b: string) => a.localeCompare(b)
export default function DictionaryModalContent({
handleHide,
}: DictionaryModalContentProps) {
const { t } = useTranslation()
const [learnedWords, setLearnedWords] = useState<Set<string>>(
initialLearnedWords.global
)
const { isError, runAsync } = useAsync()
const handleRemove = useCallback(
(word: string) => {
runAsync(postJSON('/spelling/unlearn', { body: { word } }))
.then(() => {
setLearnedWords(prevLearnedWords => {
const learnedWords = new Set(prevLearnedWords)
learnedWords.delete(word)
return learnedWords
})
window.dispatchEvent(
new CustomEvent('editor:remove-learned-word', { detail: word })
)
})
.catch(debugConsole.error)
},
[runAsync]
)
return (
<>
<OLModalHeader>
<OLModalTitle>{t('edit_dictionary')}</OLModalTitle>
</OLModalHeader>
<OLModalBody>
{isError ? (
<div className="notification-list">
<Notification
type="error"
content={t('generic_something_went_wrong')}
/>
</div>
) : null}
{learnedWords.size > 0 ? (
<ul className="list-unstyled dictionary-entries-list">
{[...learnedWords].sort(wordsSortFunction).map(learnedWord => (
<li key={learnedWord} className="dictionary-entry">
<span className="dictionary-entry-name" translate="no">
{learnedWord}
</span>
<OLTooltip
id={`tooltip-remove-learned-word-${learnedWord}`}
description={t('edit_dictionary_remove')}
overlayProps={{ delay: 0 }}
>
<OLIconButton
variant="danger"
size="sm"
onClick={() => handleRemove(learnedWord)}
icon="delete"
accessibilityLabel={t('edit_dictionary_remove')}
/>
</OLTooltip>
</li>
))}
</ul>
) : (
<p className="dictionary-empty-body text-center">
<i>{t('edit_dictionary_empty')}</i>
</p>
)}
</OLModalBody>
<OLModalFooter>
<OLButton variant="secondary" onClick={handleHide}>
{t('close')}
</OLButton>
</OLModalFooter>
</>
)
}