PageAccessoriesModal.jsx 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193
  1. import React from 'react';
  2. import PropTypes from 'prop-types';
  3. import {
  4. Modal, ModalBody, Nav, NavItem, NavLink, 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 RecentChangesIcon from './Icons/RecentChangesIcon';
  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. const PageAccessoriesModal = (props) => {
  20. const { t, pageAccessoriesContainer } = props;
  21. const { switchActiveTab } = pageAccessoriesContainer;
  22. const { activeTab } = pageAccessoriesContainer.state;
  23. function closeModalHandler() {
  24. if (props.onClose == null) {
  25. return;
  26. }
  27. props.onClose();
  28. }
  29. const menu = document.getElementsByClassName('nav'); // 上部に持ってきた
  30. const navId = document.getElementById('nav-width');
  31. // Values are set.
  32. // Might make this dynamic for px, %, pt, em
  33. function getPercentage(min, max) {
  34. return min / max * 100;
  35. }
  36. // Not using reduce, because IE8 doesn't supprt it
  37. function getArraySum(arr) {
  38. let sum = 0;
  39. [].forEach.call(arr, (el, index) => {
  40. sum += el;
  41. });
  42. return sum;
  43. }
  44. function navSlider(menu, callback) { // ok
  45. const arrayMenu1 = Array.from(menu);
  46. const menuWidth = arrayMenu1.offsetWidth; // not ok
  47. // We only want the <li> </li> tags
  48. const navTabs = document.querySelectorAll('li.nav-link');
  49. if (menu.length > 0) {
  50. const marginLeft = [];
  51. // Loop through nav children i.e li
  52. [].forEach.call(navTabs, (el, index) => {
  53. // Dynamic width/margin calculation for hr
  54. const width = getPercentage(el.offsetWidth, navId.offsetWidth);
  55. let tempMarginLeft = 0;
  56. // We don't want to modify first elements positioning
  57. if (index !== 0) {
  58. tempMarginLeft = getArraySum(marginLeft);
  59. }
  60. // Set mouse event [click]
  61. callback(el, width, tempMarginLeft);
  62. /* We store it in array because the later accumulated value is used for positioning */
  63. marginLeft.push(width);
  64. });
  65. }
  66. }
  67. if (menu) {
  68. // CLICK
  69. const menuSliderClick = document.getElementById('nav_slide_click');
  70. console.log('menu clicked');
  71. if (menuSliderClick) {
  72. const arrayMenu = Array.from(menu); // 変換してみた
  73. navSlider(arrayMenu, (el, width, tempMarginLeft) => {
  74. el.onclick = () => {
  75. menuSliderClick.style.width = `${width}%`;
  76. menuSliderClick.style.marginLeft = `${tempMarginLeft}%`;
  77. };
  78. });
  79. }
  80. } // endif
  81. return (
  82. <React.Fragment>
  83. <Modal size="xl" isOpen={props.isOpen} toggle={closeModalHandler} className="grw-page-accessories-modal">
  84. <ModalBody>
  85. <Nav className="nav-title" id="nav-width">
  86. <NavItem type="button" className={`nav-link ${activeTab === 'pagelist' && 'active'}`}>
  87. <NavLink
  88. onClick={() => {
  89. switchActiveTab('pagelist');
  90. }}
  91. >
  92. <PageListIcon />
  93. {t('page_list')}
  94. </NavLink>
  95. </NavItem>
  96. <NavItem type="button" className={`nav-link ${activeTab === 'timeline' && 'active'}`}>
  97. <NavLink
  98. onClick={() => {
  99. switchActiveTab('timeline');
  100. }}
  101. >
  102. <TimeLineIcon />
  103. {t('Timeline View')}
  104. </NavLink>
  105. </NavItem>
  106. <NavItem type="button" className={`nav-link ${activeTab === 'page-history' && 'active'}`}>
  107. <NavLink
  108. onClick={() => {
  109. switchActiveTab('page-history');
  110. }}
  111. >
  112. <RecentChangesIcon />
  113. {t('History')}
  114. </NavLink>
  115. </NavItem>
  116. <NavItem type="button" className={`nav-link ${activeTab === 'attachment' && 'active'}`}>
  117. <NavLink
  118. onClick={() => {
  119. switchActiveTab('attachment');
  120. }}
  121. >
  122. <AttachmentIcon />
  123. {t('attachment_data')}
  124. </NavLink>
  125. </NavItem>
  126. <NavItem type="button" className={`nav-link ${activeTab === 'share-link' && 'active'}`}>
  127. <NavLink
  128. onClick={() => {
  129. switchActiveTab('share-link');
  130. }}
  131. >
  132. <ShareLinkIcon />
  133. {t('share_links.share_link_management')}
  134. </NavLink>
  135. </NavItem>
  136. </Nav>
  137. <hr id="nav_slide_click" className="my-0"></hr>
  138. <TabContent activeTab={activeTab}>
  139. <TabPane tabId="pagelist">
  140. {pageAccessoriesContainer.state.activeComponents.has('pagelist') && <PageList />}
  141. </TabPane>
  142. <TabPane tabId="timeline" className="p-4">
  143. {pageAccessoriesContainer.state.activeComponents.has('timeline') && <PageTimeline /> }
  144. </TabPane>
  145. <TabPane tabId="page-history">
  146. <div className="overflow-auto">
  147. {pageAccessoriesContainer.state.activeComponents.has('page-history') && <PageHistory /> }
  148. </div>
  149. </TabPane>
  150. <TabPane tabId="attachment" className="p-4">
  151. {pageAccessoriesContainer.state.activeComponents.has('attachment') && <PageAttachment />}
  152. </TabPane>
  153. <TabPane tabId="share-link" className="p-4">
  154. {pageAccessoriesContainer.state.activeComponents.has('share-link') && <ShareLink />}
  155. </TabPane>
  156. </TabContent>
  157. </ModalBody>
  158. </Modal>
  159. </React.Fragment>
  160. );
  161. };
  162. /**
  163. * Wrapper component for using unstated
  164. */
  165. const PageAccessoriesModalWrapper = withUnstatedContainers(PageAccessoriesModal, [PageAccessoriesContainer]);
  166. PageAccessoriesModal.propTypes = {
  167. t: PropTypes.func.isRequired, // i18next
  168. // pageContainer: PropTypes.instanceOf(PageContainer).isRequired,
  169. pageAccessoriesContainer: PropTypes.instanceOf(PageAccessoriesContainer).isRequired,
  170. isOpen: PropTypes.bool.isRequired,
  171. onClose: PropTypes.func,
  172. };
  173. export default withTranslation()(PageAccessoriesModalWrapper);