PageCreateButton.tsx 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  1. import React, { useState, useCallback } from 'react';
  2. import type { IUserHasId } from '@growi/core';
  3. import { pagePathUtils } from '@growi/core/dist/utils';
  4. import { format } from 'date-fns';
  5. import { useTranslation } from 'react-i18next';
  6. import { Dropdown } from 'reactstrap';
  7. import { useOnTemplateButtonClicked } from '~/client/services/use-on-template-button-clicked';
  8. import { toastError } from '~/client/util/toastr';
  9. import { LabelType } from '~/interfaces/template';
  10. import { useCurrentUser } from '~/stores/context';
  11. import { useCurrentPagePath, useSWRxCurrentPage } from '~/stores/page';
  12. import { CreateButton } from './CreateButton';
  13. import { DropendMenu } from './DropendMenu';
  14. import { DropendToggle } from './DropendToggle';
  15. import { useOnNewButtonClicked, useOnTodaysButtonClicked } from './hooks';
  16. const generateTodaysPath = (currentUser: IUserHasId, parentDirName: string) => {
  17. const now = format(new Date(), 'yyyy/MM/dd');
  18. const userHomepagePath = pagePathUtils.userHomepagePath(currentUser);
  19. return `${userHomepagePath}/${parentDirName}/${now}`;
  20. };
  21. export const PageCreateButton = React.memo((): JSX.Element => {
  22. const { t } = useTranslation('commons');
  23. const { data: currentPagePath, isLoading: isLoadingPagePath } = useCurrentPagePath();
  24. const { data: currentPage, isLoading } = useSWRxCurrentPage();
  25. const { data: currentUser } = useCurrentUser();
  26. const [isHovered, setIsHovered] = useState(false);
  27. const [dropdownOpen, setDropdownOpen] = useState(false);
  28. const todaysPath = currentUser == null
  29. ? null
  30. : generateTodaysPath(currentUser, t('create_page_dropdown.todays.memo'));
  31. const { onClickHandler: onClickNewButton, isPageCreating: isNewPageCreating } = useOnNewButtonClicked(
  32. currentPage?.path, currentPage?.grant, currentPage?.grantedGroups, isLoading,
  33. );
  34. // TODO: https://redmine.weseek.co.jp/issues/138806
  35. const { onClickHandler: onClickTodaysButton, isPageCreating: isTodaysPageCreating } = useOnTodaysButtonClicked(todaysPath);
  36. // TODO: https://redmine.weseek.co.jp/issues/138805
  37. const { onClickHandler: onClickTemplateButton, isPageCreating: isTemplatePageCreating } = useOnTemplateButtonClicked(currentPagePath, isLoadingPagePath);
  38. const onClickTemplateButtonHandler = useCallback(async(label: LabelType) => {
  39. try {
  40. await onClickTemplateButton(label);
  41. }
  42. catch (err) {
  43. toastError(err);
  44. }
  45. }, [onClickTemplateButton]);
  46. const onMouseEnterHandler = () => {
  47. setIsHovered(true);
  48. };
  49. const onMouseLeaveHandler = () => {
  50. setIsHovered(false);
  51. setDropdownOpen(false);
  52. };
  53. const toggle = () => setDropdownOpen(!dropdownOpen);
  54. return (
  55. <div
  56. className="d-flex flex-row"
  57. onMouseEnter={onMouseEnterHandler}
  58. onMouseLeave={onMouseLeaveHandler}
  59. >
  60. <div className="btn-group flex-grow-1">
  61. <CreateButton
  62. className="z-2"
  63. onClick={onClickNewButton}
  64. disabled={isNewPageCreating || isTodaysPageCreating || isTemplatePageCreating}
  65. />
  66. </div>
  67. { isHovered && (
  68. <Dropdown
  69. isOpen={dropdownOpen}
  70. toggle={toggle}
  71. direction="end"
  72. className="position-absolute"
  73. >
  74. <DropendToggle />
  75. <DropendMenu
  76. onClickCreateNewPageButtonHandler={onClickNewButton}
  77. onClickCreateTodaysButtonHandler={onClickTodaysButton}
  78. onClickTemplateButtonHandler={onClickTemplateButtonHandler}
  79. todaysPath={todaysPath}
  80. />
  81. </Dropdown>
  82. )}
  83. </div>
  84. );
  85. });