NewPageInput.tsx 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081
  1. import React, { type FC, useCallback, useEffect } from 'react';
  2. import nodePath from 'path';
  3. import { pathUtils, pagePathUtils } from '@growi/core/dist/utils';
  4. import { useTranslation } from 'next-i18next';
  5. import { ValidationTarget } from '~/client/util/input-validator';
  6. import { toastWarning, toastError, toastSuccess } from '~/client/util/toastr';
  7. import ClosableTextInput from '~/components/Common/ClosableTextInput';
  8. import type { IPageForItem } from '~/interfaces/page';
  9. import { NotDraggableForClosableTextInput } from '../NotDraggableForClosableTextInput';
  10. type Props = {
  11. page: IPageForItem,
  12. isEnableActions: boolean,
  13. onSubmit?: (newPagePath: string) => Promise<void>,
  14. onSubmittionFailed?: () => void,
  15. onCanceled?: () => void,
  16. };
  17. export const NewPageInput: FC<Props> = (props) => {
  18. const { t } = useTranslation();
  19. const {
  20. page, isEnableActions,
  21. onSubmit, onSubmittionFailed,
  22. onCanceled,
  23. } = props;
  24. const onPressEnterForCreateHandler = async(inputText: string) => {
  25. const parentPath = pathUtils.addTrailingSlash(page.path as string);
  26. const newPagePath = nodePath.resolve(parentPath, inputText);
  27. const isCreatable = pagePathUtils.isCreatablePage(newPagePath);
  28. if (!isCreatable) {
  29. toastWarning(t('you_can_not_create_page_with_this_name'));
  30. return;
  31. }
  32. try {
  33. onSubmit?.(newPagePath);
  34. toastSuccess(t('successfully_saved_the_page'));
  35. }
  36. catch (err) {
  37. toastError(err);
  38. }
  39. finally {
  40. onSubmittionFailed?.();
  41. }
  42. };
  43. const onPressEscHandler = useCallback((event) => {
  44. if (event.keyCode === 27) {
  45. onCanceled?.();
  46. }
  47. }, [onCanceled]);
  48. useEffect(() => {
  49. document.addEventListener('keydown', onPressEscHandler, false);
  50. return () => {
  51. document.removeEventListener('keydown', onPressEscHandler, false);
  52. };
  53. }, [onPressEscHandler]);
  54. return (
  55. <>
  56. {isEnableActions && (
  57. <NotDraggableForClosableTextInput>
  58. <ClosableTextInput
  59. placeholder={t('Input page name')}
  60. onClickOutside={onCanceled}
  61. onPressEnter={onPressEnterForCreateHandler}
  62. validationTarget={ValidationTarget.PAGE}
  63. />
  64. </NotDraggableForClosableTextInput>
  65. )}
  66. </>
  67. );
  68. };