ExportPage.jsx 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169
  1. import React, { Fragment } from 'react';
  2. import PropTypes from 'prop-types';
  3. import { withTranslation } from 'react-i18next';
  4. import * as toastr from 'toastr';
  5. import { createSubscribedElement } from '../../UnstatedUtils';
  6. import AppContainer from '../../../services/AppContainer';
  7. import WebsocketContainer from '../../../services/WebsocketContainer';
  8. // import { toastSuccess, toastError } from '../../../util/apiNotification';
  9. import ExportZipFormModal from './ExportZipFormModal';
  10. import ZipFileTable from './ZipFileTable';
  11. class ExportPage extends React.Component {
  12. constructor(props) {
  13. super(props);
  14. this.state = {
  15. collections: [],
  16. zipFileStats: [],
  17. isExportModalOpen: false,
  18. isExporting: false,
  19. };
  20. this.onZipFileStatAdd = this.onZipFileStatAdd.bind(this);
  21. this.onZipFileStatRemove = this.onZipFileStatRemove.bind(this);
  22. this.openExportModal = this.openExportModal.bind(this);
  23. this.closeExportModal = this.closeExportModal.bind(this);
  24. }
  25. async componentWillMount() {
  26. // TODO:: use apiv3.get
  27. // eslint-disable-next-line no-unused-vars
  28. const [{ collections }, { zipFileStats, isExporting }] = await Promise.all([
  29. this.props.appContainer.apiGet('/v3/mongo/collections', {}),
  30. this.props.appContainer.apiGet('/v3/export/status', {}),
  31. ]);
  32. // TODO: toastSuccess, toastError
  33. this.setState({
  34. collections: ['pages', 'revisions'],
  35. zipFileStats,
  36. isExporting,
  37. }); // FIXME: delete this line and uncomment the line below
  38. // this.setState({ collections, zipFileStats, isExporting });
  39. this.setupWebsocketEventHandler();
  40. }
  41. setupWebsocketEventHandler() {
  42. const socket = this.props.websocketContainer.getWebSocket();
  43. socket.on('admin:onProgressForExport', (data) => {
  44. console.log(data);
  45. });
  46. socket.on('admin:onTerminateForExport', (data) => {
  47. console.log(data);
  48. });
  49. }
  50. onZipFileStatAdd(newStat) {
  51. this.setState((prevState) => {
  52. return {
  53. zipFileStats: [...prevState.zipFileStats, newStat],
  54. };
  55. });
  56. }
  57. async onZipFileStatRemove(fileName) {
  58. try {
  59. await this.props.appContainer.apiDelete(`/v3/export/${fileName}`, {});
  60. this.setState((prevState) => {
  61. return {
  62. zipFileStats: prevState.zipFileStats.filter(stat => stat.fileName !== fileName),
  63. };
  64. });
  65. // TODO: toastSuccess, toastError
  66. toastr.success(undefined, `Deleted ${fileName}`, {
  67. closeButton: true,
  68. progressBar: true,
  69. newestOnTop: false,
  70. showDuration: '100',
  71. hideDuration: '100',
  72. timeOut: '1200',
  73. extendedTimeOut: '150',
  74. });
  75. }
  76. catch (err) {
  77. // TODO: toastSuccess, toastError
  78. toastr.error(err, 'Error', {
  79. closeButton: true,
  80. progressBar: true,
  81. newestOnTop: false,
  82. showDuration: '100',
  83. hideDuration: '100',
  84. timeOut: '3000',
  85. });
  86. }
  87. }
  88. openExportModal() {
  89. this.setState({ isExportModalOpen: true });
  90. }
  91. closeExportModal() {
  92. this.setState({ isExportModalOpen: false });
  93. }
  94. render() {
  95. const { t } = this.props;
  96. return (
  97. <Fragment>
  98. <div className="alert alert-warning">
  99. <i className="icon-exclamation"></i> { t('export_management.beta_warning') }
  100. </div>
  101. <h2>{t('Export Data')}</h2>
  102. <button type="button" className="btn btn-default" onClick={this.openExportModal}>{t('export_management.create_new_exported_data')}</button>
  103. <div className="mt-5">
  104. <h3>{t('export_management.exported_data_list')}</h3>
  105. <ZipFileTable
  106. zipFileStats={this.state.zipFileStats}
  107. onZipFileStatRemove={this.onZipFileStatRemove}
  108. />
  109. </div>
  110. <div className="mt-5">
  111. <h3>{t('export_management.exported_data_list')}</h3>
  112. <ZipFileTable
  113. zipFileStats={this.state.zipFileStats}
  114. onZipFileStatRemove={this.onZipFileStatRemove}
  115. />
  116. </div>
  117. <ExportZipFormModal
  118. isOpen={this.state.isExportModalOpen}
  119. onClose={this.closeExportModal}
  120. collections={this.state.collections}
  121. zipFileStats={this.state.zipFileStats}
  122. onZipFileStatAdd={this.onZipFileStatAdd}
  123. />
  124. </Fragment>
  125. );
  126. }
  127. }
  128. ExportPage.propTypes = {
  129. t: PropTypes.func.isRequired, // i18next
  130. appContainer: PropTypes.instanceOf(AppContainer).isRequired,
  131. websocketContainer: PropTypes.instanceOf(WebsocketContainer).isRequired,
  132. };
  133. /**
  134. * Wrapper component for using unstated
  135. */
  136. const ExportPageFormWrapper = (props) => {
  137. return createSubscribedElement(ExportPage, props, [AppContainer, WebsocketContainer]);
  138. };
  139. export default withTranslation()(ExportPageFormWrapper);