PageAccessoriesModal.tsx 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136
  1. import React, { useEffect, useMemo, useState } from 'react';
  2. import { useTranslation } from 'next-i18next';
  3. import {
  4. Modal, ModalBody, ModalHeader,
  5. } from 'reactstrap';
  6. import AppContainer from '~/client/services/AppContainer';
  7. import { useIsGuestUser, useIsSharedUser } from '~/stores/context';
  8. import { usePageAccessoriesModal, PageAccessoriesModalContents } from '~/stores/modal';
  9. import { CustomNavTab } from './CustomNavigation/CustomNav';
  10. import CustomTabContent from './CustomNavigation/CustomTabContent';
  11. import ExpandOrContractButton from './ExpandOrContractButton';
  12. import AttachmentIcon from './Icons/AttachmentIcon';
  13. import HistoryIcon from './Icons/HistoryIcon';
  14. import ShareLinkIcon from './Icons/ShareLinkIcon';
  15. import PageAttachment from './PageAttachment';
  16. import PageHistory from './PageHistory';
  17. import ShareLink from './ShareLink/ShareLink';
  18. import { withUnstatedContainers } from './UnstatedUtils';
  19. import styles from './PageAccessoriesModal.module.scss';
  20. type Props = {
  21. appContainer: AppContainer,
  22. isLinkSharingDisabled: boolean,
  23. }
  24. const PageAccessoriesModal = (props: Props): JSX.Element => {
  25. const {
  26. appContainer,
  27. } = props;
  28. const isLinkSharingDisabled = appContainer.config.disableLinkSharing;
  29. const { t } = useTranslation();
  30. const [activeTab, setActiveTab] = useState<PageAccessoriesModalContents>(PageAccessoriesModalContents.PageHistory);
  31. const [isWindowExpanded, setIsWindowExpanded] = useState(false);
  32. const { data: isSharedUser } = useIsSharedUser();
  33. const { data: isGuestUser } = useIsGuestUser();
  34. const { data: status, mutate, close } = usePageAccessoriesModal();
  35. // add event handler when opened
  36. useEffect(() => {
  37. if (status == null || status.onOpened != null) {
  38. return;
  39. }
  40. mutate({
  41. ...status,
  42. onOpened: (activatedContents) => {
  43. setActiveTab(activatedContents);
  44. },
  45. }, false);
  46. }, [mutate, status]);
  47. const navTabMapping = useMemo(() => {
  48. return {
  49. [PageAccessoriesModalContents.PageHistory]: {
  50. Icon: HistoryIcon,
  51. Content: () => <PageHistory />,
  52. i18n: t('History'),
  53. index: 0,
  54. isLinkEnabled: () => !isGuestUser && !isSharedUser,
  55. },
  56. [PageAccessoriesModalContents.Attachment]: {
  57. Icon: AttachmentIcon,
  58. Content: () => <PageAttachment />,
  59. i18n: t('attachment_data'),
  60. index: 1,
  61. },
  62. [PageAccessoriesModalContents.ShareLink]: {
  63. Icon: ShareLinkIcon,
  64. Content: () => <ShareLink />,
  65. i18n: t('share_links.share_link_management'),
  66. index: 2,
  67. isLinkEnabled: () => !isGuestUser && !isSharedUser && !isLinkSharingDisabled,
  68. },
  69. };
  70. }, [t, isGuestUser, isSharedUser, isLinkSharingDisabled]);
  71. const buttons = useMemo(() => (
  72. <div className="d-flex flex-nowrap">
  73. <ExpandOrContractButton
  74. isWindowExpanded={isWindowExpanded}
  75. expandWindow={() => setIsWindowExpanded(true)}
  76. contractWindow={() => setIsWindowExpanded(false)}
  77. />
  78. <button type="button" className="close" onClick={close} aria-label="Close">
  79. <span aria-hidden="true">&times;</span>
  80. </button>
  81. </div>
  82. ), [close, isWindowExpanded]);
  83. if (status == null) {
  84. return <></>;
  85. }
  86. const { isOpened } = status;
  87. return (
  88. <Modal
  89. size="xl"
  90. isOpen={isOpened}
  91. toggle={close}
  92. data-testid="page-accessories-modal"
  93. className={`grw-page-accessories-modal ${styles['grw-page-accessories-modal']} ${isWindowExpanded ? 'grw-modal-expanded' : ''} `}
  94. >
  95. <ModalHeader className="p-0" toggle={close} close={buttons}>
  96. <CustomNavTab
  97. activeTab={activeTab}
  98. navTabMapping={navTabMapping}
  99. breakpointToHideInactiveTabsDown="md"
  100. onNavSelected={(v) => {
  101. setActiveTab(v);
  102. }}
  103. hideBorderBottom
  104. />
  105. </ModalHeader>
  106. <ModalBody className="overflow-auto grw-modal-body-style">
  107. <CustomTabContent activeTab={activeTab} navTabMapping={navTabMapping} />
  108. </ModalBody>
  109. </Modal>
  110. );
  111. };
  112. /**
  113. * Wrapper component for using unstated
  114. */
  115. const PageAccessoriesModalWrapper = withUnstatedContainers(PageAccessoriesModal, [AppContainer]);
  116. export default PageAccessoriesModalWrapper;