DrawioViewerWithEditButton.tsx 2.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
  1. import React, { type JSX, useCallback, useState } from 'react';
  2. import { globalEventTarget } from '@growi/core/dist/utils';
  3. import {
  4. type DrawioEditByViewerProps,
  5. DrawioViewer,
  6. type DrawioViewerProps,
  7. } from '@growi/remark-drawio';
  8. import { useTranslation } from 'next-i18next';
  9. import { useCurrentPageYjsData } from '~/features/collaborative-editor/states';
  10. import {
  11. useIsGuestUser,
  12. useIsReadOnlyUser,
  13. useIsSharedUser,
  14. } from '~/states/context';
  15. import { useShareLinkId } from '~/states/page/hooks';
  16. import { useIsRevisionOutdated } from '~/stores/page';
  17. import styles from './DrawioViewerWithEditButton.module.scss';
  18. import './DrawioViewerWithEditButton.vendor-styles.prebuilt';
  19. export const DrawioViewerWithEditButton = React.memo(
  20. (props: DrawioViewerProps): JSX.Element => {
  21. const { t } = useTranslation();
  22. const { bol, eol } = props;
  23. const isGuestUser = useIsGuestUser();
  24. const isReadOnlyUser = useIsReadOnlyUser();
  25. const isSharedUser = useIsSharedUser();
  26. const shareLinkId = useShareLinkId();
  27. const isRevisionOutdated = useIsRevisionOutdated();
  28. const currentPageYjsData = useCurrentPageYjsData();
  29. const [isRendered, setRendered] = useState(false);
  30. const [mxfile, setMxfile] = useState('');
  31. const editButtonClickHandler = useCallback(() => {
  32. globalEventTarget.dispatchEvent(
  33. new CustomEvent<DrawioEditByViewerProps>('launchDrawioModal', {
  34. detail: {
  35. bol,
  36. eol,
  37. drawioMxFile: mxfile,
  38. },
  39. }),
  40. );
  41. }, [bol, eol, mxfile]);
  42. const renderingStartHandler = useCallback(() => {
  43. setRendered(false);
  44. }, []);
  45. const renderingUpdatedHandler = useCallback((mxfile: string | null) => {
  46. setRendered(mxfile != null);
  47. if (mxfile != null) {
  48. setMxfile(mxfile);
  49. }
  50. }, []);
  51. const isNoEditingUsers =
  52. currentPageYjsData?.awarenessStateSize == null ||
  53. currentPageYjsData?.awarenessStateSize === 0;
  54. const showEditButton =
  55. isNoEditingUsers &&
  56. !isRevisionOutdated &&
  57. isRendered &&
  58. !isGuestUser &&
  59. !isReadOnlyUser &&
  60. !isSharedUser &&
  61. shareLinkId == null;
  62. return (
  63. <div
  64. className={`drawio-viewer-with-edit-button ${styles['drawio-viewer-with-edit-button']}`}
  65. >
  66. {showEditButton && (
  67. <button
  68. type="button"
  69. className="btn btn-sm btn-outline-secondary btn-edit-drawio"
  70. onClick={editButtonClickHandler}
  71. >
  72. <span className="material-symbols-outlined me-1">edit_square</span>
  73. {t('Edit')}
  74. </button>
  75. )}
  76. <DrawioViewer
  77. {...props}
  78. onRenderingStart={renderingStartHandler}
  79. onRenderingUpdated={renderingUpdatedHandler}
  80. />
  81. </div>
  82. );
  83. },
  84. );
  85. DrawioViewerWithEditButton.displayName = 'DrawioViewerWithEditButton';