PageAccessoriesModal.jsx 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156
  1. import React, { useCallback, useMemo, useState } from 'react';
  2. import PropTypes from 'prop-types';
  3. import {
  4. Modal, ModalBody, ModalHeader, TabContent, TabPane,
  5. } from 'reactstrap';
  6. import { withTranslation } from 'react-i18next';
  7. import PageListIcon from './Icons/PageListIcon';
  8. import TimeLineIcon from './Icons/TimeLineIcon';
  9. import HistoryIcon from './Icons/HistoryIcon';
  10. import AttachmentIcon from './Icons/AttachmentIcon';
  11. import ShareLinkIcon from './Icons/ShareLinkIcon';
  12. import { withUnstatedContainers } from './UnstatedUtils';
  13. import PageAccessoriesContainer from '../services/PageAccessoriesContainer';
  14. import PageAttachment from './PageAttachment';
  15. import PageTimeline from './PageTimeline';
  16. import PageList from './PageList';
  17. import PageHistory from './PageHistory';
  18. import ShareLink from './ShareLink/ShareLink';
  19. import { CustomNavTab } from './CustomNavigation/CustomNav';
  20. import ExpandOrContractButton from './ExpandOrContractButton';
  21. const PageAccessoriesModal = (props) => {
  22. const {
  23. t, pageAccessoriesContainer, onClose, isGuestUser, isSharedUser,
  24. } = props;
  25. const { switchActiveTab } = pageAccessoriesContainer;
  26. const { activeTab, activeComponents } = pageAccessoriesContainer.state;
  27. const [isWindowExpanded, setIsWindowExpanded] = useState(false);
  28. const navTabMapping = useMemo(() => {
  29. return {
  30. pagelist: {
  31. Icon: PageListIcon,
  32. i18n: t('page_list'),
  33. index: 0,
  34. isLinkEnabled: v => !isSharedUser,
  35. },
  36. timeline: {
  37. Icon: TimeLineIcon,
  38. i18n: t('Timeline View'),
  39. index: 1,
  40. isLinkEnabled: v => !isSharedUser,
  41. },
  42. pageHistory: {
  43. Icon: HistoryIcon,
  44. i18n: t('History'),
  45. index: 2,
  46. isLinkEnabled: v => !isGuestUser && !isSharedUser,
  47. },
  48. attachment: {
  49. Icon: AttachmentIcon,
  50. i18n: t('attachment_data'),
  51. index: 3,
  52. },
  53. shareLink: {
  54. Icon: ShareLinkIcon,
  55. i18n: t('share_links.share_link_management'),
  56. index: 4,
  57. isLinkEnabled: v => !isGuestUser && !isSharedUser,
  58. },
  59. };
  60. }, [t, isGuestUser, isSharedUser]);
  61. const closeModalHandler = useCallback(() => {
  62. if (onClose == null) {
  63. return;
  64. }
  65. onClose();
  66. }, [onClose]);
  67. const expandWindow = () => {
  68. setIsWindowExpanded(true);
  69. };
  70. const contractWindow = () => {
  71. setIsWindowExpanded(false);
  72. };
  73. const buttons = (
  74. <div className="d-flex flex-nowrap">
  75. <ExpandOrContractButton
  76. isWindowExpanded={isWindowExpanded}
  77. expandWindow={expandWindow}
  78. contractWindow={contractWindow}
  79. />
  80. <button type="button" className="close" onClick={closeModalHandler} aria-label="Close">
  81. <span aria-hidden="true">&times;</span>
  82. </button>
  83. </div>
  84. );
  85. return (
  86. <React.Fragment>
  87. <Modal
  88. size="xl"
  89. isOpen={props.isOpen}
  90. toggle={closeModalHandler}
  91. className={`grw-page-accessories-modal ${isWindowExpanded ? 'grw-modal-expanded' : ''} `}
  92. >
  93. <ModalHeader className="p-0" toggle={closeModalHandler} close={buttons}>
  94. <CustomNavTab
  95. activeTab={activeTab}
  96. navTabMapping={navTabMapping}
  97. onNavSelected={switchActiveTab}
  98. breakpointToHideInactiveTabsDown="md"
  99. hideBorderBottom
  100. />
  101. </ModalHeader>
  102. <ModalBody className="overflow-auto grw-modal-body-style p-0">
  103. {/* Do not use CustomTabContent because of performance problem:
  104. the 'navTabMapping[tabId].Content' for PageAccessoriesModal depends on activeComponents */}
  105. <TabContent activeTab={activeTab} className="p-5">
  106. <TabPane tabId="pagelist">
  107. {activeComponents.has('pagelist') && <PageList />}
  108. </TabPane>
  109. <TabPane tabId="timeline">
  110. {activeComponents.has('timeline') && <PageTimeline /> }
  111. </TabPane>
  112. {!isGuestUser && (
  113. <TabPane tabId="pageHistory">
  114. {activeComponents.has('pageHistory') && <PageHistory /> }
  115. </TabPane>
  116. )}
  117. <TabPane tabId="attachment">
  118. {activeComponents.has('attachment') && <PageAttachment />}
  119. </TabPane>
  120. {!isGuestUser && (
  121. <TabPane tabId="shareLink">
  122. {activeComponents.has('shareLink') && <ShareLink />}
  123. </TabPane>
  124. )}
  125. </TabContent>
  126. </ModalBody>
  127. </Modal>
  128. </React.Fragment>
  129. );
  130. };
  131. /**
  132. * Wrapper component for using unstated
  133. */
  134. const PageAccessoriesModalWrapper = withUnstatedContainers(PageAccessoriesModal, [PageAccessoriesContainer]);
  135. PageAccessoriesModal.propTypes = {
  136. t: PropTypes.func.isRequired, // i18next
  137. pageAccessoriesContainer: PropTypes.instanceOf(PageAccessoriesContainer).isRequired,
  138. isGuestUser: PropTypes.bool.isRequired,
  139. isSharedUser: PropTypes.bool.isRequired,
  140. isOpen: PropTypes.bool.isRequired,
  141. onClose: PropTypes.func,
  142. };
  143. export default withTranslation()(PageAccessoriesModalWrapper);