itizawa 5 лет назад
Родитель
Сommit
47fe9c5c60

+ 3 - 0
src/client/js/app.jsx

@@ -22,6 +22,7 @@ import PageComments from './components/PageComments';
 import PageTimeline from './components/PageTimeline';
 import CommentEditorLazyRenderer from './components/PageComment/CommentEditorLazyRenderer';
 import PageManagement from './components/Page/PageManagement';
+import PageDuplicateModal from './components/PageDuplicateModal';
 import PageAttachment from './components/PageAttachment';
 import PageStatusAlert from './components/PageStatusAlert';
 import PagePathAutoComplete from './components/PagePathAutoComplete';
@@ -90,6 +91,8 @@ if (pageContainer.state.pageId != null) {
     'page-attachment': <PageAttachment />,
     'page-comment-write': <CommentEditorLazyRenderer />,
     'page-management': <PageManagement />,
+    'page-duplicate-modal': <PageDuplicateModal />,
+
     'revision-toc': <TableOfContents />,
     'seen-user-list': <UserPictureList userIds={pageContainer.state.seenUserIds} />,
     'liker-list': <UserPictureList userIds={pageContainer.state.likerUserIds} />,

+ 1 - 1
src/client/js/components/Page/PageManagement.jsx

@@ -21,7 +21,7 @@ const PageManagement = (props) => {
         <a className="dropdown-item" href="#" data-target="#renamePage" data-toggle="modal">
           <i className="icon-fw icon-action-redo"></i> { t('Move/Rename') }
         </a>
-        <a className="dropdown-item" href="#" data-target="#duplicatePage" data-toggle="modal">
+        <a className="dropdown-item" type="button" onClick={pageContainer.openPageDuplicateModal}>
           <i className="icon-fw icon-docs"></i> { t('Duplicate') }
         </a>
         <div className="dropdown-divider"></div>

+ 62 - 0
src/client/js/components/PageDuplicateModal.jsx

@@ -0,0 +1,62 @@
+
+import React, { useState } from 'react';
+import PropTypes from 'prop-types';
+
+import { Modal, ModalHeader, ModalBody } from 'reactstrap';
+
+import { withTranslation } from 'react-i18next';
+import { format } from 'date-fns';
+import urljoin from 'url-join';
+
+import { userPageRoot } from '@commons/util/path-utils';
+import { pathUtils } from 'growi-commons';
+import { createSubscribedElement } from './UnstatedUtils';
+
+import AppContainer from '../services/AppContainer';
+import PageContainer from '../services/PageContainer';
+import PagePathAutoComplete from './PagePathAutoComplete';
+
+const PageDuplicateModal = (props) => {
+  const { t, appContainer, pageContainer } = props;
+
+  const config = appContainer.getConfig();
+  const isReachable = config.isSearchServiceReachable;
+  const { path } = pageContainer.state;
+  const userPageRootPath = userPageRoot(appContainer.currentUser);
+  const parentPath = pathUtils.addTrailingSlash(path);
+  const now = format(new Date(), 'yyyy/MM/dd');
+
+  const [todayInput1, setTodayInput1] = useState(t('Memo'));
+  const [todayInput2, setTodayInput2] = useState('');
+  const [pageNameInput, setPageNameInput] = useState(parentPath);
+  const [template, setTemplate] = useState(null);
+
+  return (
+    <Modal size="lg" isOpen={pageContainer.state.isPageDuplicateModalShown} toggle={pageContainer.closePageDuplicateModal} className="grw-duplicate-page">
+      <ModalHeader tag="h4" toggle={pageContainer.closePageDuplicateModal} className="bg-primary text-light">
+        { t('New Page') }
+      </ModalHeader>
+      <ModalBody>
+
+      </ModalBody>
+    </Modal>
+
+  );
+};
+
+
+/**
+ * Wrapper component for using unstated
+ */
+const PageDuplicateModallWrapper = (props) => {
+  return createSubscribedElement(PageDuplicateModal, props, [AppContainer, PageContainer]);
+};
+
+
+PageDuplicateModal.propTypes = {
+  t: PropTypes.func.isRequired, //  i18next
+  appContainer: PropTypes.instanceOf(AppContainer).isRequired,
+  pageContainer: PropTypes.instanceOf(PageContainer).isRequired,
+};
+
+export default withTranslation()(PageDuplicateModallWrapper);

+ 13 - 0
src/client/js/services/PageContainer.js

@@ -60,6 +60,8 @@ export default class PageContainer extends Container {
       hasDraftOnHackmd: !!mainContent.getAttribute('data-page-has-draft-on-hackmd'),
       isHackmdDraftUpdatingInRealtime: false,
 
+      isPageDuplicateModalShown: false,
+
       isHeaderSticky: false,
       isSubnavCompact: false,
     };
@@ -85,6 +87,9 @@ export default class PageContainer extends Container {
         isSubnavCompact: scrollThresForCompact < currentYOffset,
       });
     });
+
+    this.openPageDuplicateModal = this.openPageDuplicateModal.bind(this);
+    this.closePageDuplicateModal = this.closePageDuplicateModal.bind(this);
   }
 
   /**
@@ -386,4 +391,12 @@ export default class PageContainer extends Container {
 
   }
 
+  openPageDuplicateModal() {
+    this.setState({ isPageDuplicateModalShown: true });
+  }
+
+  closePageDuplicateModal() {
+    this.setState({ isPageDuplicateModalShown: false });
+  }
+
 }

+ 3 - 1
src/server/views/modal/duplicate.html

@@ -1,4 +1,6 @@
-  <div class="modal" id="duplicatePage">
+<div id ="page-duplicate-modal"></div>
+
+<div class="modal" id="duplicatePage">
     <div class="modal-dialog">
       <div class="modal-content">