PageAttachment.jsx 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176
  1. /* eslint-disable react/no-access-state-in-setstate */
  2. import React from 'react';
  3. import PropTypes from 'prop-types';
  4. import PageAttachmentList from './PageAttachment/PageAttachmentList';
  5. import DeleteAttachmentModal from './PageAttachment/DeleteAttachmentModal';
  6. import PaginationWrapper from './PaginationWrapper';
  7. import { withUnstatedContainers } from './UnstatedUtils';
  8. import AppContainer from '../services/AppContainer';
  9. import PageContainer from '../services/PageContainer';
  10. class PageAttachment extends React.Component {
  11. constructor(props) {
  12. super(props);
  13. this.state = {
  14. activePage: 1,
  15. limit: 10,
  16. totalAttachments: 0,
  17. attachments: [],
  18. inUse: {},
  19. attachmentToDelete: null,
  20. deleting: false,
  21. deleteError: '',
  22. };
  23. this.handlePage = this.handlePage.bind(this);
  24. this.onAttachmentDeleteClicked = this.onAttachmentDeleteClicked.bind(this);
  25. this.onAttachmentDeleteClickedConfirm = this.onAttachmentDeleteClickedConfirm.bind(this);
  26. }
  27. async handlePage(selectedPage) {
  28. const { pageId } = this.props.pageContainer.state;
  29. const { limit } = this.state;
  30. const offset = (selectedPage - 1) * limit;
  31. const activePage = selectedPage;
  32. if (!pageId) { return }
  33. const res = await this.props.appContainer.apiv3Get('/attachment/list', {
  34. pageId, limit, offset,
  35. });
  36. const attachments = res.data.paginateResult.docs;
  37. const totalAttachments = res.data.paginateResult.totalDocs;
  38. const inUse = {};
  39. for (const attachment of attachments) {
  40. inUse[attachment._id] = this.checkIfFileInUse(attachment);
  41. }
  42. this.setState({
  43. activePage,
  44. totalAttachments,
  45. attachments,
  46. inUse,
  47. });
  48. }
  49. async componentDidMount() {
  50. await this.handlePage(1);
  51. }
  52. checkIfFileInUse(attachment) {
  53. const { markdown } = this.props.pageContainer.state;
  54. if (markdown.match(attachment._id)) {
  55. return true;
  56. }
  57. return false;
  58. }
  59. onAttachmentDeleteClicked(attachment) {
  60. this.setState({
  61. attachmentToDelete: attachment,
  62. });
  63. }
  64. onAttachmentDeleteClickedConfirm(attachment) {
  65. const attachmentId = attachment._id;
  66. this.setState({
  67. deleting: true,
  68. });
  69. this.props.appContainer.apiPost('/attachments.remove', { attachment_id: attachmentId })
  70. .then((res) => {
  71. this.setState({
  72. attachments: this.state.attachments.filter((at) => {
  73. // comparing ObjectId
  74. // eslint-disable-next-line eqeqeq
  75. return at._id != attachmentId;
  76. }),
  77. attachmentToDelete: null,
  78. deleting: false,
  79. });
  80. }).catch((err) => {
  81. this.setState({
  82. deleteError: 'Something went wrong.',
  83. deleting: false,
  84. });
  85. });
  86. }
  87. isUserLoggedIn() {
  88. return this.props.appContainer.currentUser != null;
  89. }
  90. render() {
  91. let deleteAttachmentModal = '';
  92. if (this.isUserLoggedIn()) {
  93. const attachmentToDelete = this.state.attachmentToDelete;
  94. const deleteModalClose = () => {
  95. this.setState({ attachmentToDelete: null, deleteError: '' });
  96. };
  97. const showModal = attachmentToDelete !== null;
  98. let deleteInUse = null;
  99. if (attachmentToDelete !== null) {
  100. deleteInUse = this.state.inUse[attachmentToDelete._id] || false;
  101. }
  102. deleteAttachmentModal = (
  103. <DeleteAttachmentModal
  104. isOpen={showModal}
  105. animation={false}
  106. toggle={deleteModalClose}
  107. attachmentToDelete={attachmentToDelete}
  108. inUse={deleteInUse}
  109. deleting={this.state.deleting}
  110. deleteError={this.state.deleteError}
  111. onAttachmentDeleteClickedConfirm={this.onAttachmentDeleteClickedConfirm}
  112. />
  113. );
  114. }
  115. return (
  116. <div>
  117. <PageAttachmentList
  118. attachments={this.state.attachments}
  119. inUse={this.state.inUse}
  120. onAttachmentDeleteClicked={this.onAttachmentDeleteClicked}
  121. isUserLoggedIn={this.isUserLoggedIn()}
  122. />
  123. {deleteAttachmentModal}
  124. <PaginationWrapper
  125. activePage={this.state.activePage}
  126. changePage={this.handlePage}
  127. totalItemsCount={this.state.totalAttachments}
  128. pagingLimit={this.state.limit}
  129. />
  130. </div>
  131. );
  132. }
  133. }
  134. /**
  135. * Wrapper component for using unstated
  136. */
  137. const PageAttachmentWrapper = withUnstatedContainers(PageAttachment, [AppContainer, PageContainer]);
  138. PageAttachment.propTypes = {
  139. appContainer: PropTypes.instanceOf(AppContainer).isRequired,
  140. pageContainer: PropTypes.instanceOf(PageContainer).isRequired,
  141. };
  142. export default PageAttachmentWrapper;