use-create-page-and-transit.tsx 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  1. import { useCallback, useState } from 'react';
  2. import { useRouter } from 'next/router';
  3. import { exist } from '~/client/services/page-operation';
  4. import type { IApiv3PageCreateParams } from '~/interfaces/apiv3';
  5. import { useCurrentPagePath } from '~/stores/page';
  6. import { EditorMode, useEditorMode } from '~/stores/ui';
  7. import loggerFactory from '~/utils/logger';
  8. import { createPage } from './create-page';
  9. const logger = loggerFactory('growi:Navbar:GrowiContextualSubNavigation');
  10. /**
  11. * Invoked when creation and transition has finished
  12. */
  13. type OnCreated = () => void;
  14. /**
  15. * Invoked when either creation or transition has aborted
  16. */
  17. type OnAborted = () => void;
  18. /**
  19. * Always invoked after processing is terminated
  20. */
  21. type OnTerminated = () => void;
  22. type CreatePageAndTransitOpts = {
  23. shouldCheckPageExists?: boolean,
  24. onCreationStart?: OnCreated,
  25. onCreated?: OnCreated,
  26. onAborted?: OnAborted,
  27. onTerminated?: OnTerminated,
  28. }
  29. type CreatePageAndTransit = (
  30. params: IApiv3PageCreateParams,
  31. opts?: CreatePageAndTransitOpts,
  32. ) => Promise<void>;
  33. type UseCreatePageAndTransit = () => {
  34. isCreating: boolean,
  35. createAndTransit: CreatePageAndTransit,
  36. };
  37. export const useCreatePageAndTransit: UseCreatePageAndTransit = () => {
  38. const router = useRouter();
  39. const { data: currentPagePath } = useCurrentPagePath();
  40. const { mutate: mutateEditorMode } = useEditorMode();
  41. const [isCreating, setCreating] = useState(false);
  42. const createAndTransit: CreatePageAndTransit = useCallback(async(params, opts = {}) => {
  43. const {
  44. shouldCheckPageExists,
  45. onCreationStart, onCreated, onAborted, onTerminated,
  46. } = opts;
  47. // check the page existence
  48. if (shouldCheckPageExists && params.path != null) {
  49. const pagePath = params.path;
  50. try {
  51. const { isExist } = await exist(pagePath);
  52. if (isExist) {
  53. // routing
  54. if (pagePath !== currentPagePath) {
  55. await router.push(`${pagePath}#edit`);
  56. }
  57. mutateEditorMode(EditorMode.Editor);
  58. onAborted?.();
  59. return;
  60. }
  61. }
  62. catch (err) {
  63. throw err;
  64. }
  65. finally {
  66. onTerminated?.();
  67. }
  68. }
  69. // create and transit
  70. try {
  71. setCreating(true);
  72. onCreationStart?.();
  73. const response = await createPage(params);
  74. await router.push(`/${response.page._id}#edit`);
  75. mutateEditorMode(EditorMode.Editor);
  76. onCreated?.();
  77. }
  78. catch (err) {
  79. throw err;
  80. }
  81. finally {
  82. onTerminated?.();
  83. setCreating(false);
  84. }
  85. }, [currentPagePath, mutateEditorMode, router]);
  86. return {
  87. isCreating,
  88. createAndTransit,
  89. };
  90. };