RevisionLoader.tsx 2.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182
  1. import React, { useState, useEffect } from 'react';
  2. import type { Ref, IRevision, IRevisionHasId } from '@growi/core';
  3. import { useTranslation } from 'next-i18next';
  4. import type { RendererOptions } from '~/interfaces/renderer-options';
  5. import { useSWRxPageRevision } from '~/stores/page';
  6. import loggerFactory from '~/utils/logger';
  7. import { LoadingSpinner } from '../LoadingSpinner';
  8. import RevisionRenderer from './RevisionRenderer';
  9. export const ROOT_ELEM_ID = 'revision-loader' as const;
  10. export type RevisionLoaderProps = {
  11. rendererOptions: RendererOptions,
  12. pageId: string,
  13. revisionId: Ref<IRevision>,
  14. onRevisionLoaded?: (revision: IRevisionHasId) => void,
  15. }
  16. const logger = loggerFactory('growi:Page:RevisionLoader');
  17. /**
  18. * Load data from server and render RevisionBody component
  19. */
  20. export const RevisionLoader = (props: RevisionLoaderProps): JSX.Element => {
  21. const { t } = useTranslation();
  22. const {
  23. rendererOptions, pageId, revisionId, onRevisionLoaded,
  24. } = props;
  25. const { data: pageRevision, isLoading, error } = useSWRxPageRevision(pageId, revisionId);
  26. const [markdown, setMarkdown] = useState<string>('');
  27. useEffect(() => {
  28. if (pageRevision != null) {
  29. setMarkdown(pageRevision?.body ?? '');
  30. if (onRevisionLoaded != null) {
  31. onRevisionLoaded(pageRevision);
  32. }
  33. }
  34. }, [onRevisionLoaded, pageRevision]);
  35. useEffect(() => {
  36. if (error != null) {
  37. const isForbidden = error != null && error[0].code === 'forbidden-page';
  38. if (isForbidden) {
  39. setMarkdown(`<span className="material-symbols-outlined p-1">cancel</span>${t('not_allowed_to_see_this_page')}`);
  40. }
  41. else {
  42. const errorMessages = error.map((error) => {
  43. return `<span className="material-symbols-outlined p-1">cancel</span><span class="text-muted"><em>${error.message}</em></span>`;
  44. });
  45. setMarkdown(errorMessages.join('\n'));
  46. }
  47. }
  48. }, [error, t]);
  49. if (isLoading) {
  50. return (
  51. <div className="wiki">
  52. <div className="text-muted text-center">
  53. <LoadingSpinner className="me-1 fs-3" />
  54. </div>
  55. </div>
  56. );
  57. }
  58. return (
  59. <RevisionRenderer
  60. rendererOptions={rendererOptions}
  61. markdown={markdown}
  62. />
  63. );
  64. };