PageCreateButton.tsx 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147
  1. import React, { useCallback, useState } from 'react';
  2. import { useRouter } from 'next/router';
  3. import { createPage } from '~/client/services/page-operation';
  4. import { toastError } from '~/client/util/toastr';
  5. import { useSWRxCurrentPage } from '~/stores/page';
  6. import loggerFactory from '~/utils/logger';
  7. const logger = loggerFactory('growi:cli:PageCreateButton');
  8. export const PageCreateButton = React.memo((): JSX.Element => {
  9. const router = useRouter();
  10. const { data: currentPage, isLoading } = useSWRxCurrentPage();
  11. const [isHovered, setIsHovered] = useState(false);
  12. const [isCreating, setIsCreating] = useState(false);
  13. const onMouseEnterHandler = () => {
  14. setIsHovered(true);
  15. };
  16. const onMouseLeaveHandler = () => {
  17. setIsHovered(false);
  18. };
  19. const onCreateNewPageButtonHandler = useCallback(async() => {
  20. if (isLoading) return;
  21. try {
  22. setIsCreating(true);
  23. const parentPath = currentPage == null
  24. ? '/'
  25. : currentPage.path;
  26. const params = {
  27. isSlackEnabled: false,
  28. slackChannels: '',
  29. grant: currentPage?.grant || 1,
  30. pageTags: [],
  31. grantUserGroupId: currentPage?.grantedGroup?._id,
  32. shouldGeneratePath: true,
  33. };
  34. const response = await createPage(parentPath, '', params);
  35. router.push(`${response.page.id}#edit`);
  36. }
  37. catch (err) {
  38. logger.warn(err);
  39. toastError(err);
  40. }
  41. finally {
  42. setIsCreating(false);
  43. }
  44. }, [currentPage, isLoading, router]);
  45. const onCreateTodaysButtonHandler = useCallback(() => {
  46. // router.push(`${router.pathname}#edit`);
  47. }, [router]);
  48. const onTemplateForChildrenButtonHandler = useCallback(() => {
  49. // router.push(`${router.pathname}/_template#edit`);
  50. }, [router]);
  51. const onTemplateForDescendantsButtonHandler = useCallback(() => {
  52. // router.push(`${router.pathname}/__template#edit`);
  53. }, [router]);
  54. // TODO: update button design
  55. // https://redmine.weseek.co.jp/issues/132683
  56. // TODO: i18n
  57. // https://redmine.weseek.co.jp/issues/132681
  58. return (
  59. <div
  60. className="d-flex flex-row"
  61. onMouseEnter={onMouseEnterHandler}
  62. onMouseLeave={onMouseLeaveHandler}
  63. >
  64. <div className="btn-group">
  65. <button
  66. className="d-block btn btn-primary"
  67. onClick={onCreateNewPageButtonHandler}
  68. type="button"
  69. data-testid="grw-sidebar-nav-page-create-button"
  70. disabled={isCreating}
  71. >
  72. <i className="material-symbols-outlined">edit</i>
  73. </button>
  74. </div>
  75. {isHovered && (
  76. <div className="btn-group dropend">
  77. <button
  78. className="btn btn-secondary dropdown-toggle dropdown-toggle-split position-absolute"
  79. type="button"
  80. data-bs-toggle="dropdown"
  81. aria-expanded="false"
  82. />
  83. <ul className="dropdown-menu">
  84. <li>
  85. <button
  86. className="dropdown-item"
  87. onClick={onCreateNewPageButtonHandler}
  88. type="button"
  89. disabled={isCreating}
  90. >
  91. Create New Page
  92. </button>
  93. </li>
  94. <li><hr className="dropdown-divider" /></li>
  95. <li><span className="text-muted px-3">Create today&apos;s ...</span></li>
  96. {/* TODO: show correct create today's page path */}
  97. {/* https://redmine.weseek.co.jp/issues/132682 */}
  98. <li>
  99. <button
  100. className="dropdown-item"
  101. onClick={onCreateTodaysButtonHandler}
  102. type="button"
  103. >
  104. Create today&apos;s
  105. </button>
  106. </li>
  107. <li><hr className="dropdown-divider" /></li>
  108. <li><span className="text-muted px-3">Child page template</span></li>
  109. <li>
  110. <button
  111. className="dropdown-item"
  112. onClick={onTemplateForChildrenButtonHandler}
  113. type="button"
  114. >
  115. Template for children
  116. </button>
  117. </li>
  118. <li>
  119. <button
  120. className="dropdown-item"
  121. onClick={onTemplateForDescendantsButtonHandler}
  122. type="button"
  123. >
  124. Template for descendants
  125. </button>
  126. </li>
  127. </ul>
  128. </div>
  129. )}
  130. </div>
  131. );
  132. });
  133. PageCreateButton.displayName = 'PageCreateButton';