| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113 |
- import ControlLabel from 'react-bootstrap/lib/ControlLabel'
- import { Alert, FormControl } from 'react-bootstrap'
- import FormGroup from 'react-bootstrap/lib/FormGroup'
- import { useCallback } from 'react'
- import { Trans, useTranslation } from 'react-i18next'
- import { useFileTreeCreateName } from '../../contexts/file-tree-create-name'
- import PropTypes from 'prop-types'
- import {
- BlockedFilenameError,
- DuplicateFilenameError,
- InvalidFilenameError,
- } from '../../errors'
- /**
- * A form component that renders a text input with label,
- * plus a validation warning and/or an error message when needed
- */
- export default function FileTreeCreateNameInput({
- label,
- focusName = false,
- classes = {},
- placeholder,
- error,
- }) {
- const { t } = useTranslation()
- // the value is stored in a context provider, so it's available elsewhere in the form
- const { name, setName, touchedName, validName } = useFileTreeCreateName()
- // focus the first part of the filename if needed
- const inputRef = useCallback(
- element => {
- if (element && focusName) {
- window.requestAnimationFrame(() => {
- element.focus()
- element.setSelectionRange(0, element.value.lastIndexOf('.'))
- })
- }
- },
- [focusName]
- )
- return (
- <FormGroup controlId="new-doc-name" className={classes.formGroup}>
- <ControlLabel>{label || t('file_name')}</ControlLabel>
- <FormControl
- type="text"
- placeholder={placeholder || t('file_name')}
- required
- value={name}
- onChange={event => setName(event.target.value)}
- inputRef={inputRef}
- />
- <FormControl.Feedback />
- {touchedName && !validName && (
- <Alert bsStyle="danger" className="row-spaced-small">
- <Trans i18nKey="files_cannot_include_invalid_characters" />
- </Alert>
- )}
- {error && <ErrorMessage error={error} />}
- </FormGroup>
- )
- }
- FileTreeCreateNameInput.propTypes = {
- focusName: PropTypes.bool,
- label: PropTypes.string,
- classes: PropTypes.shape({
- formGroup: PropTypes.string,
- }),
- placeholder: PropTypes.string,
- error: PropTypes.oneOfType([PropTypes.object, PropTypes.string]),
- }
- function ErrorMessage({ error }) {
- // if (typeof error === 'string') {
- // return error
- // }
- switch (error.constructor) {
- case DuplicateFilenameError:
- return (
- <Alert bsStyle="danger" className="row-spaced-small">
- <Trans i18nKey="file_already_exists" />
- </Alert>
- )
- case InvalidFilenameError:
- return (
- <Alert bsStyle="danger" className="row-spaced-small">
- <Trans i18nKey="files_cannot_include_invalid_characters" />
- </Alert>
- )
- case BlockedFilenameError:
- return (
- <Alert bsStyle="danger" className="row-spaced-small">
- <Trans i18nKey="blocked_filename" />
- </Alert>
- )
- default:
- // return <Trans i18nKey="generic_something_went_wrong" />
- return null // other errors are displayed elsewhere
- }
- }
- ErrorMessage.propTypes = {
- error: PropTypes.oneOfType([PropTypes.object, PropTypes.string]).isRequired,
- }
|