PageAccessoriesModal.jsx 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160
  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 { withUnstatedContainers } from './UnstatedUtils';
  12. import PageAccessoriesContainer from '../services/PageAccessoriesContainer';
  13. import PageAttachment from './PageAttachment';
  14. const PageAccessoriesModal = (props) => {
  15. const { t, pageAccessoriesContainer } = props;
  16. const { switchActiveTab } = pageAccessoriesContainer;
  17. const { activeTab } = pageAccessoriesContainer.state;
  18. function closeModalHandler() {
  19. if (props.onClose == null) {
  20. return;
  21. }
  22. props.onClose();
  23. }
  24. const menu = document.getElementsByClassName('nav'); // 上部に持ってきた
  25. // Values are set.
  26. // Might make this dynamic for px, %, pt, em
  27. function getPercentage(min, max) {
  28. return min / max * 100;
  29. }
  30. // Not using reduce, because IE8 doesn't supprt it
  31. function getArraySum(arr) {
  32. let sum = 0;
  33. [].forEach.call(arr, (el, index) => {
  34. sum += el;
  35. });
  36. return sum;
  37. }
  38. function navSlider(menu, callback) {
  39. const menuWidth = menu.offsetWidth;
  40. // We only want the <li> </li> tags
  41. const navTabs = document.querySelectorAll('li.nav-link');
  42. console.log(navTabs);
  43. if (menu.length > 0) {
  44. const marginLeft = [];
  45. // Loop through nav children i.e li
  46. [].forEach.call(navTabs, (el, index) => {
  47. // Dynamic width/margin calculation for hr
  48. const width = getPercentage(el.offsetWidth, menuWidth);
  49. let tempMarginLeft = 0;
  50. // We don't want to modify first elements positioning
  51. if (index !== 0) {
  52. tempMarginLeft = getArraySum(marginLeft);
  53. }
  54. // Set mouse event hover/click
  55. callback(el, width, tempMarginLeft);
  56. /* We store it in array because the later accumulated value is used for positioning */
  57. marginLeft.push(width);
  58. });
  59. }
  60. }
  61. if (menu) {
  62. // CLICK
  63. const menuSliderClick = document.getElementById('nav_slide_click');
  64. if (menuSliderClick) {
  65. navSlider(menu[1], (el, width, tempMarginLeft) => {
  66. el.onclick = () => {
  67. menuSliderClick.style.width = `${width}%`;
  68. menuSliderClick.style.marginLeft = `${tempMarginLeft}%`;
  69. };
  70. });
  71. }
  72. } // endif
  73. return (
  74. <React.Fragment>
  75. <Modal
  76. size="lg"
  77. isOpen={props.isOpen}
  78. toggle={closeModalHandler}
  79. className="grw-page-accessories-modal"
  80. >
  81. <ModalBody>
  82. <Nav className="nav-title border-bottom" id="nav_slide_click">
  83. <NavItem type="button" className={`nav-link ${activeTab === 'pagelist' && 'active'}`}>
  84. <NavLink
  85. onClick={() => { switchActiveTab('pagelist') }}
  86. >
  87. <PageListIcon />
  88. { t('page_list') }
  89. </NavLink>
  90. </NavItem>
  91. <NavItem type="button" className={`nav-link ${activeTab === 'timeline' && 'active'}`}>
  92. <NavLink
  93. onClick={() => { switchActiveTab('timeline') }}
  94. >
  95. <TimeLineIcon />
  96. { t('Timeline View') }
  97. </NavLink>
  98. </NavItem>
  99. <NavItem type="button" className={`nav-link ${activeTab === 'recent-changes' && 'active'}`}>
  100. <NavLink
  101. onClick={() => { switchActiveTab('recent-changes') }}
  102. >
  103. <RecentChangesIcon />
  104. { t('History') }
  105. </NavLink>
  106. </NavItem>
  107. <NavItem type="button" className={`nav-link ${activeTab === 'attachment' && 'active'}`}>
  108. <NavLink
  109. onClick={() => { switchActiveTab('attachment') }}
  110. >
  111. <AttachmentIcon />
  112. { t('attachment_data') }
  113. </NavLink>
  114. </NavItem>
  115. </Nav>
  116. <TabContent activeTab={activeTab}>
  117. <TabPane tabId="pagelist"></TabPane>
  118. <TabPane tabId="timeline"></TabPane>
  119. <TabPane tabId="recent-changes"></TabPane>
  120. <TabPane tabId="attachment" className="p-4">
  121. {pageAccessoriesContainer.state.activeComponents.has('attachment') && <PageAttachment /> }
  122. </TabPane>
  123. </TabContent>
  124. </ModalBody>
  125. </Modal>
  126. </React.Fragment>
  127. );
  128. };
  129. /**
  130. * Wrapper component for using unstated
  131. */
  132. const PageAccessoriesModalWrapper = withUnstatedContainers(PageAccessoriesModal, [PageAccessoriesContainer]);
  133. PageAccessoriesModal.propTypes = {
  134. t: PropTypes.func.isRequired, // i18next
  135. // pageContainer: PropTypes.instanceOf(PageContainer).isRequired,
  136. pageAccessoriesContainer: PropTypes.instanceOf(PageAccessoriesContainer).isRequired,
  137. isOpen: PropTypes.bool.isRequired,
  138. onClose: PropTypes.func,
  139. };
  140. export default withTranslation()(PageAccessoriesModalWrapper);