use-new-page-input.tsx 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  1. import React, { useState, type FC, useCallback } from 'react';
  2. import { shouldCreateWipPage } from '@growi/core/dist/utils';
  3. import { apiv3Post } from '~/client/util/apiv3-client';
  4. import { useSWRxPageChildren } from '~/stores/page-listing';
  5. import { usePageTreeDescCountMap } from '~/stores/ui';
  6. import type { TreeItemToolProps } from '../interfaces';
  7. import { NewPageCreateButton } from './NewPageCreateButton';
  8. import { NewPageInput } from './NewPageInput';
  9. type UseNewPageInput = {
  10. Input: FC<TreeItemToolProps>,
  11. CreateButton: FC<TreeItemToolProps>,
  12. isProcessingSubmission: boolean,
  13. }
  14. export const useNewPageInput = (): UseNewPageInput => {
  15. const [showInput, setShowInput] = useState(false);
  16. const [isProcessingSubmission, setProcessingSubmission] = useState(false);
  17. const { getDescCount } = usePageTreeDescCountMap();
  18. const CreateButton: FC<TreeItemToolProps> = (props) => {
  19. const { itemNode, stateHandlers } = props;
  20. const { page, children } = itemNode;
  21. // descendantCount
  22. const descendantCount = getDescCount(page._id) || page.descendantCount || 0;
  23. const isChildrenLoaded = children?.length > 0;
  24. const hasDescendants = descendantCount > 0 || isChildrenLoaded;
  25. const onClick = useCallback(() => {
  26. setShowInput(true);
  27. if (hasDescendants) {
  28. stateHandlers?.setIsOpen(true);
  29. }
  30. }, [hasDescendants, stateHandlers]);
  31. return (
  32. <NewPageCreateButton
  33. page={page}
  34. onClick={onClick}
  35. />
  36. );
  37. };
  38. const Input: FC<TreeItemToolProps> = (props) => {
  39. const { itemNode, stateHandlers } = props;
  40. const { page, children } = itemNode;
  41. const { mutate: mutateChildren } = useSWRxPageChildren(stateHandlers?.isOpen ? page._id : null);
  42. const { getDescCount } = usePageTreeDescCountMap();
  43. const descendantCount = getDescCount(page._id) || page.descendantCount || 0;
  44. const isChildrenLoaded = children?.length > 0;
  45. const hasDescendants = descendantCount > 0 || isChildrenLoaded;
  46. const submitHandler = useCallback(async(newPagePath: string) => {
  47. setProcessingSubmission(true);
  48. setShowInput(false);
  49. await apiv3Post('/page', {
  50. path: newPagePath,
  51. body: undefined,
  52. grant: page.grant,
  53. // grantUserGroupId: page.grantedGroup,
  54. grantUserGroupIds: page.grantedGroups,
  55. wip: shouldCreateWipPage(newPagePath),
  56. });
  57. mutateChildren();
  58. if (!hasDescendants) {
  59. stateHandlers?.setIsOpen(true);
  60. }
  61. }, [hasDescendants, mutateChildren, page.grant, page.grantedGroups, stateHandlers]);
  62. const submittionFailedHandler = useCallback(() => {
  63. setProcessingSubmission(false);
  64. }, []);
  65. return showInput
  66. ? (
  67. <NewPageInput
  68. page={page}
  69. isEnableActions={props.isEnableActions}
  70. onSubmit={submitHandler}
  71. onSubmittionFailed={submittionFailedHandler}
  72. onCanceled={() => setShowInput(false)}
  73. />
  74. )
  75. : <></>;
  76. };
  77. return {
  78. Input,
  79. CreateButton,
  80. isProcessingSubmission,
  81. };
  82. };