RevisionLoader.tsx 2.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879
  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 RevisionRenderer from './RevisionRenderer';
  8. export const ROOT_ELEM_ID = 'revision-loader' as const;
  9. export type RevisionLoaderProps = {
  10. rendererOptions: RendererOptions,
  11. pageId: string,
  12. revisionId: Ref<IRevision>,
  13. onRevisionLoaded?: (revision: IRevisionHasId) => void,
  14. }
  15. const logger = loggerFactory('growi:Page:RevisionLoader');
  16. /**
  17. * Load data from server and render RevisionBody component
  18. */
  19. export const RevisionLoader = (props: RevisionLoaderProps): JSX.Element => {
  20. const { t } = useTranslation();
  21. const {
  22. rendererOptions, pageId, revisionId, onRevisionLoaded,
  23. } = props;
  24. const { data: pageRevision, isLoading, error } = useSWRxPageRevision(pageId, revisionId);
  25. const [markdown, setMarkdown] = useState<string>('');
  26. useEffect(() => {
  27. if (pageRevision != null) {
  28. setMarkdown(pageRevision?.body ?? '');
  29. if (onRevisionLoaded != null) {
  30. onRevisionLoaded(pageRevision);
  31. }
  32. }
  33. }, [onRevisionLoaded, pageRevision]);
  34. useEffect(() => {
  35. if (error != null) {
  36. const isForbidden = error != null && error[0].code === 'forbidden-page';
  37. if (isForbidden) {
  38. setMarkdown(`<i class="icon-exclamation p-1"></i>${t('not_allowed_to_see_this_page')}`);
  39. }
  40. else {
  41. const errorMessages = error.map((error) => {
  42. return `<i class="icon-exclamation p-1"></i><span class="text-muted"><em>${error.message}</em></span>`;
  43. });
  44. setMarkdown(errorMessages.join('\n'));
  45. }
  46. }
  47. }, [error, t]);
  48. if (isLoading) {
  49. return (
  50. <div className="wiki">
  51. <div className="text-muted text-center">
  52. <i className="fa fa-2x fa-spinner fa-pulse mr-1"></i>
  53. </div>
  54. </div>
  55. );
  56. }
  57. return (
  58. <RevisionRenderer
  59. rendererOptions={rendererOptions}
  60. markdown={markdown}
  61. />
  62. );
  63. };