PageCreateButton.tsx 3.4 KB

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