PageCreateButton.tsx 2.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  1. import React, { useState, useCallback } from 'react';
  2. import { useTranslation } from 'react-i18next';
  3. import { Dropdown } from 'reactstrap';
  4. import { useCreateTemplatePage } from '~/client/services/create-page';
  5. import { toastError } from '~/client/util/toastr';
  6. import { CreateButton } from './CreateButton';
  7. import { DropendMenu } from './DropendMenu';
  8. import { DropendToggle } from './DropendToggle';
  9. import { useCreateNewPage, useCreateTodaysMemo } from './hooks';
  10. const useToastrOnError = <P, R>(method?: (param?: P) => Promise<R|undefined>): (param?: P) => Promise<R|undefined> => {
  11. const { t } = useTranslation('commons');
  12. return useCallback(async(param) => {
  13. try {
  14. return await method?.(param);
  15. }
  16. catch (err) {
  17. toastError(t('toaster.create_failed', { target: 'a page' }));
  18. }
  19. }, [method, t]);
  20. };
  21. export const PageCreateButton = React.memo((): JSX.Element => {
  22. const [isHovered, setIsHovered] = useState(false);
  23. const [dropdownOpen, setDropdownOpen] = useState(false);
  24. const { createNewPage, isCreating: isNewPageCreating } = useCreateNewPage();
  25. // TODO: https://redmine.weseek.co.jp/issues/138806
  26. const { createTodaysMemo, isCreating: isTodaysPageCreating, todaysPath } = useCreateTodaysMemo();
  27. // TODO: https://redmine.weseek.co.jp/issues/138805
  28. const {
  29. createTemplate,
  30. isCreating: isTemplatePageCreating, isCreatable: isTemplatePageCreatable,
  31. } = useCreateTemplatePage();
  32. const createNewPageWithToastr = useToastrOnError(createNewPage);
  33. const createTodaysMemoWithToastr = useToastrOnError(createTodaysMemo);
  34. const createTemplateWithToastr = useToastrOnError(createTemplate);
  35. const onMouseEnterHandler = () => {
  36. setIsHovered(true);
  37. };
  38. const onMouseLeaveHandler = () => {
  39. setIsHovered(false);
  40. setDropdownOpen(false);
  41. };
  42. const toggle = () => setDropdownOpen(!dropdownOpen);
  43. return (
  44. <div
  45. className="d-flex flex-row mt-2"
  46. onMouseEnter={onMouseEnterHandler}
  47. onMouseLeave={onMouseLeaveHandler}
  48. >
  49. <div className="btn-group flex-grow-1">
  50. <CreateButton
  51. className="z-2"
  52. onClick={createNewPageWithToastr}
  53. disabled={isNewPageCreating || isTodaysPageCreating || isTemplatePageCreating}
  54. />
  55. </div>
  56. { isHovered && (
  57. <Dropdown
  58. isOpen={dropdownOpen}
  59. toggle={toggle}
  60. direction="end"
  61. className="position-absolute"
  62. >
  63. <DropendToggle />
  64. <DropendMenu
  65. onClickCreateNewPage={createNewPageWithToastr}
  66. onClickCreateTodaysMemo={createTodaysMemoWithToastr}
  67. onClickCreateTemplate={isTemplatePageCreatable ? createTemplateWithToastr : undefined}
  68. todaysPath={todaysPath}
  69. />
  70. </Dropdown>
  71. )}
  72. </div>
  73. );
  74. });