project-name-editable-label.js 2.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  1. import { useEffect, useState, useRef } from 'react'
  2. import PropTypes from 'prop-types'
  3. import { OverlayTrigger, Tooltip } from 'react-bootstrap'
  4. import { useTranslation } from 'react-i18next'
  5. import classNames from 'classnames'
  6. import Icon from '../../../shared/components/icon'
  7. function ProjectNameEditableLabel({
  8. projectName,
  9. hasRenamePermissions,
  10. onChange,
  11. className,
  12. }) {
  13. const { t } = useTranslation()
  14. const [isRenaming, setIsRenaming] = useState(false)
  15. const canRename = hasRenamePermissions && !isRenaming
  16. const [inputContent, setInputContent] = useState(projectName)
  17. const inputRef = useRef(null)
  18. useEffect(() => {
  19. if (isRenaming) {
  20. inputRef.current.select()
  21. }
  22. }, [isRenaming])
  23. function startRenaming() {
  24. if (canRename) {
  25. setInputContent(projectName)
  26. setIsRenaming(true)
  27. }
  28. }
  29. function handleKeyDown(event) {
  30. if (event.key === 'Enter') {
  31. event.preventDefault()
  32. setIsRenaming(false)
  33. onChange(event.target.value)
  34. }
  35. }
  36. function handleOnChange(event) {
  37. setInputContent(event.target.value)
  38. }
  39. function handleBlur() {
  40. setIsRenaming(false)
  41. }
  42. return (
  43. <div className={classNames('project-name', className)}>
  44. {!isRenaming && (
  45. <span className="name" onDoubleClick={startRenaming}>
  46. {projectName}
  47. </span>
  48. )}
  49. {isRenaming && (
  50. <input
  51. ref={inputRef}
  52. type="text"
  53. className="form-control"
  54. onKeyDown={handleKeyDown}
  55. onChange={handleOnChange}
  56. onBlur={handleBlur}
  57. value={inputContent}
  58. />
  59. )}
  60. {canRename && (
  61. <OverlayTrigger
  62. placement="bottom"
  63. trigger={['hover', 'focus']}
  64. overlay={<Tooltip id="tooltip-online-user">{t('rename')}</Tooltip>}
  65. >
  66. {/* eslint-disable-next-line jsx-a11y/anchor-is-valid, jsx-a11y/click-events-have-key-events, jsx-a11y/interactive-supports-focus */}
  67. <a className="rename" role="button" onClick={startRenaming}>
  68. <Icon type="pencil" modifier="fw" />
  69. </a>
  70. </OverlayTrigger>
  71. )}
  72. </div>
  73. )
  74. }
  75. ProjectNameEditableLabel.propTypes = {
  76. projectName: PropTypes.string.isRequired,
  77. hasRenamePermissions: PropTypes.bool,
  78. onChange: PropTypes.func.isRequired,
  79. className: PropTypes.string,
  80. }
  81. export default ProjectNameEditableLabel