RevisionComparerContainer.js 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  1. import { Container } from 'unstated';
  2. import loggerFactory from '~/utils/logger';
  3. import { toastError } from '../util/apiNotification';
  4. import { apiv3Get } from '../util/apiv3-client';
  5. const logger = loggerFactory('growi:PageHistoryContainer');
  6. /**
  7. * Service container for personal settings page (RevisionCompare.jsx)
  8. * @extends {Container} unstated Container
  9. */
  10. export default class RevisionComparerContainer extends Container {
  11. constructor(appContainer, pageContainer) {
  12. super();
  13. this.appContainer = appContainer;
  14. this.pageContainer = pageContainer;
  15. this.state = {
  16. errMessage: null,
  17. sourceRevision: null,
  18. targetRevision: null,
  19. latestRevision: null,
  20. };
  21. this.initRevisions = this.initRevisions.bind(this);
  22. }
  23. /**
  24. * Workaround for the mangling in production build to break constructor.name
  25. */
  26. static getClassName() {
  27. return 'RevisionComparerContainer';
  28. }
  29. /**
  30. * Initialize the revisions
  31. */
  32. async initRevisions() {
  33. const latestRevision = await this.fetchLatestRevision();
  34. const [sourceRevisionId, targetRevisionId] = this.getRevisionIDsToCompareAsParam();
  35. const sourceRevision = sourceRevisionId ? await this.fetchRevision(sourceRevisionId) : latestRevision;
  36. const targetRevision = targetRevisionId ? await this.fetchRevision(targetRevisionId) : latestRevision;
  37. const compareWithLatest = targetRevisionId ? false : this.state.compareWithLatest;
  38. this.setState({
  39. sourceRevision, targetRevision, latestRevision, compareWithLatest,
  40. });
  41. }
  42. /**
  43. * Get the IDs of the comparison source and target from "window.location" as an array
  44. */
  45. getRevisionIDsToCompareAsParam() {
  46. const searchParams = {};
  47. for (const param of window.location.search?.substr(1)?.split('&')) {
  48. const [k, v] = param.split('=');
  49. searchParams[k] = v;
  50. }
  51. if (!searchParams.compare) {
  52. return [];
  53. }
  54. return searchParams.compare.split('...') || [];
  55. }
  56. /**
  57. * Fetch the latest revision
  58. */
  59. async fetchLatestRevision() {
  60. const { pageId, shareLinkId } = this.pageContainer.state;
  61. try {
  62. const res = await apiv3Get('/revisions/list', {
  63. pageId, shareLinkId, page: 1, limit: 1,
  64. });
  65. return res.data.docs[0];
  66. }
  67. catch (err) {
  68. toastError(err);
  69. this.setState({ errorMessage: err.message });
  70. logger.error(err);
  71. }
  72. return null;
  73. }
  74. /**
  75. * Fetch the revision of the specified ID
  76. * @param {string} revision ID
  77. */
  78. async fetchRevision(revisionId) {
  79. const { pageId, shareLinkId } = this.pageContainer.state;
  80. try {
  81. const res = await apiv3Get(`/revisions/${revisionId}`, {
  82. pageId, shareLinkId,
  83. });
  84. return res.data.revision;
  85. }
  86. catch (err) {
  87. toastError(err);
  88. this.setState({ errorMessage: err.message });
  89. logger.error(err);
  90. }
  91. return null;
  92. }
  93. }