dictionary-modal-content.tsx 2.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788
  1. import { useCallback } from 'react'
  2. import { useTranslation } from 'react-i18next'
  3. import { Alert, Button, Modal } from 'react-bootstrap'
  4. import Icon from '../../../shared/components/icon'
  5. import Tooltip from '../../../shared/components/tooltip'
  6. import useAsync from '../../../shared/hooks/use-async'
  7. import { postJSON } from '../../../infrastructure/fetch-json'
  8. import ignoredWords from '../ignored-words'
  9. type DictionaryModalContentProps = {
  10. handleHide: () => void
  11. }
  12. const wordsSortFunction = (a: string, b: string) => a.localeCompare(b)
  13. export default function DictionaryModalContent({
  14. handleHide,
  15. }: DictionaryModalContentProps) {
  16. const { t } = useTranslation()
  17. const { isError, runAsync } = useAsync()
  18. const handleRemove = useCallback(
  19. word => {
  20. ignoredWords.remove(word)
  21. runAsync(
  22. postJSON('/spelling/unlearn', {
  23. body: {
  24. word,
  25. },
  26. })
  27. ).catch(console.error)
  28. },
  29. [runAsync]
  30. )
  31. return (
  32. <>
  33. <Modal.Header closeButton>
  34. <Modal.Title>{t('edit_dictionary')}</Modal.Title>
  35. </Modal.Header>
  36. <Modal.Body>
  37. {isError ? (
  38. <Alert bsStyle="danger">{t('generic_something_went_wrong')}</Alert>
  39. ) : null}
  40. {ignoredWords.learnedWords?.size > 0 ? (
  41. <ul className="list-unstyled dictionary-entries-list">
  42. {[...ignoredWords.learnedWords]
  43. .sort(wordsSortFunction)
  44. .map(learnedWord => (
  45. <li key={learnedWord} className="dictionary-entry">
  46. <span className="dictionary-entry-name">{learnedWord}</span>
  47. <Tooltip
  48. id={`tooltip-remove-learned-word-${learnedWord}`}
  49. description={t('edit_dictionary_remove')}
  50. overlayProps={{ delay: 0 }}
  51. >
  52. <Button
  53. bsStyle="danger"
  54. bsSize="xs"
  55. onClick={() => handleRemove(learnedWord)}
  56. >
  57. <Icon
  58. type="trash-o"
  59. accessibilityLabel={t('edit_dictionary_remove')}
  60. />
  61. </Button>
  62. </Tooltip>
  63. </li>
  64. ))}
  65. </ul>
  66. ) : (
  67. <p className="dictionary-empty-body text-center">
  68. <i>{t('edit_dictionary_empty')}</i>
  69. </p>
  70. )}
  71. </Modal.Body>
  72. <Modal.Footer>
  73. <Button bsStyle={null} className="btn-secondary" onClick={handleHide}>
  74. {t('done')}
  75. </Button>
  76. </Modal.Footer>
  77. </>
  78. )
  79. }