Procházet zdrojové kódy

Merge pull request #2232 from weseek/support/reactify-templateModal

Support/reactify template modal
itizawa před 5 roky
rodič
revize
0aa162ebd7

+ 1 - 1
resource/locales/en-US/translation.json

@@ -338,7 +338,7 @@
   "template": {
     "modal_label": {
       "Create/Edit Template Page": "Create/Edit template page",
-      "Create template under": "Create template page under:"
+      "Create template under": "Create template page under this page"
     },
     "option_label": {
       "create/edit": "Create/Edit template page..",

+ 1 - 1
resource/locales/ja/translation.json

@@ -336,7 +336,7 @@
   "template": {
     "modal_label": {
       "Create/Edit Template Page": "テンプレートページの作成/編集",
-      "Create template under": "以下のパスにテンプレートページを作成"
+      "Create template under": "配下にテンプレートページを作成"
     },
     "option_label": {
       "select": "テンプレートタイプを選択してください",

+ 2 - 0
src/client/js/bootstrap.jsx

@@ -13,6 +13,7 @@ import AppContainer from './services/AppContainer';
 import WebsocketContainer from './services/WebsocketContainer';
 import PageCreateButton from './components/Navbar/PageCreateButton';
 import PageCreateModal from './components/PageCreateModal';
+import CreateTemplateModal from './components/CreateTemplateModal';
 
 const logger = loggerFactory('growi:app');
 
@@ -49,6 +50,7 @@ const componentMappings = {
   'create-page-button': <PageCreateButton />,
   'create-page-button-icon': <PageCreateButton isIcon />,
   'page-create-modal': <PageCreateModal />,
+  'create-template-modal': <CreateTemplateModal />,
 
   'grw-sidebar-wrapper': <Sidebar />,
 

+ 87 - 0
src/client/js/components/CreateTemplateModal.jsx

@@ -0,0 +1,87 @@
+import React from 'react';
+import PropTypes from 'prop-types';
+
+import { Modal, ModalHeader, ModalBody } from 'reactstrap';
+
+import { withTranslation } from 'react-i18next';
+import { pathUtils } from 'growi-commons';
+import urljoin from 'url-join';
+import { createSubscribedElement } from './UnstatedUtils';
+
+import PageContainer from '../services/PageContainer';
+
+const CreateTemplateModal = (props) => {
+  const { t, pageContainer } = props;
+
+  const { path, isCreateTemplatePageModalShown } = pageContainer.state;
+  const parentPath = pathUtils.addTrailingSlash(path);
+
+  function generateUrl(label) {
+    return encodeURI(urljoin(parentPath, label, '#edit'));
+  }
+
+  /**
+   * @param {string} target Which hierarchy to create [children, decendants]
+   */
+  function renderTemplateCard(target, label) {
+    return (
+      <div className="card card-select-template">
+        <div className="card-header">{ t(`template.${target}.label`) }</div>
+        <div className="card-body">
+          <p className="text-center"><code>{label}</code></p>
+          <p className="form-text text-muted text-center"><small>{t(`template.${target}.desc`) }</small></p>
+        </div>
+        <div className="card-footer text-center">
+          <a
+            href={generateUrl(label)}
+            className="btn btn-sm btn-primary"
+            id={`template-button-${target}`}
+          >
+            { t('Edit') }
+          </a>
+        </div>
+      </div>
+    );
+  }
+
+  return (
+    <Modal isOpen={isCreateTemplatePageModalShown} toggle={pageContainer.closeCreateTemplatePageModal} className="grw-create-page">
+      <ModalHeader tag="h4" toggle={pageContainer.closeCreateTemplatePageModal} className="bg-primary text-light">
+        {t('template.modal_label.Create/Edit Template Page')}
+      </ModalHeader>
+      <ModalBody>
+        <div className="form-group">
+          <label className="mb-4">
+            <code>{parentPath}</code><br />
+            { t('template.modal_label.Create template under') }
+          </label>
+          <div className="row">
+            <div className="col-md-6">
+              {renderTemplateCard('children', '_template')}
+            </div>
+            <div className="col-md-6">
+              {renderTemplateCard('decendants', '__template')}
+            </div>
+          </div>
+        </div>
+      </ModalBody>
+    </Modal>
+
+  );
+};
+
+
+/**
+ * Wrapper component for using unstated
+ */
+const CreateTemplateModalWrapper = (props) => {
+  return createSubscribedElement(CreateTemplateModal, props, [PageContainer]);
+};
+
+
+CreateTemplateModal.propTypes = {
+  t: PropTypes.func.isRequired, //  i18next
+  pageContainer: PropTypes.instanceOf(PageContainer).isRequired,
+};
+
+export default withTranslation()(CreateTemplateModalWrapper);

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

@@ -55,7 +55,7 @@ const PageManagement = (props) => {
       </a>
       <div className="dropdown-menu dropdown-menu-right">
         {!isTopPagePath && renderDropdownItemForNotTopPage()}
-        <a className="dropdown-item" href="#" data-target="#create-template" data-toggle="modal">
+        <a className="dropdown-item" onClick={pageContainer.openCreateTemplatePageModal}>
           <i className="icon-fw icon-magic-wand"></i> { t('template.option_label.create/edit') }
         </a>
         {(!isTopPagePath && !isUserPagePath) && renderDropdownItemForDeletablePage()}

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

@@ -63,6 +63,7 @@ export default class PageContainer extends Container {
       isHackmdDraftUpdatingInRealtime: false,
 
       isPageDuplicateModalShown: false,
+      isCreateTemplatePageModalShown: false,
 
       isHeaderSticky: false,
       isSubnavCompact: false,
@@ -105,6 +106,8 @@ export default class PageContainer extends Container {
 
     this.openPageDuplicateModal = this.openPageDuplicateModal.bind(this);
     this.closePageDuplicateModal = this.closePageDuplicateModal.bind(this);
+    this.openCreateTemplatePageModal = this.openCreateTemplatePageModal.bind(this);
+    this.closeCreateTemplatePageModal = this.closeCreateTemplatePageModal.bind(this);
   }
 
   /**
@@ -414,4 +417,12 @@ export default class PageContainer extends Container {
     this.setState({ isPageDuplicateModalShown: false });
   }
 
+  openCreateTemplatePageModal() {
+    this.setState({ isCreateTemplatePageModalShown: true });
+  }
+
+  closeCreateTemplatePageModal() {
+    this.setState({ isCreateTemplatePageModalShown: false });
+  }
+
 }

+ 1 - 50
src/server/views/modal/create_template.html

@@ -1,50 +1 @@
-{% set templateParentPath = parentPath(page.path | preventXss | escape) %}
-
-<div class="modal create-template" id="create-template">
-  <div class="modal-dialog">
-    <div class="modal-content">
-
-      <div class="modal-header bg-primary text-light">
-        <div class="modal-title">{{ t('template.modal_label.Create/Edit Template Page') }}</div>
-        <button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
-      </div>
-      <div class="modal-body">
-        <div class="form-group">
-          <label class="mb-4">{{ t('template.modal_label.Create template under', templateParentPath ) }}</label>
-          <div class="row">
-            <div class="col-md-6">
-              <div class="card card-select-template">
-                <div class="card-header">{{ t('template.children.label') }}</div>
-                <div class="card-body">
-                  <p class="text-center"><code>_template</code></p>
-                  <p class="form-text text-muted text-center"><small>{{ t('template.children.desc') }}</small></p>
-                </div>
-                <div class="card-footer text-center">
-                  <a href="{{templateParentPath}}_template#edit"
-                      class="btn btn-sm btn-primary" id="template-button-children">
-                      {{ t("Edit") }}
-                  </a>
-                </div>
-              </div>
-            </div>
-            <div class="col-md-6">
-              <div class="card card-select-template">
-                <div class="card-header">{{ t('template.decendants.label') }}</div>
-                <div class="card-body">
-                  <p class="text-center"><code>__template</code></p>
-                  <p class="form-text text-muted text-center"><small>{{ t('template.decendants.desc') }}</small></p>
-                </div>
-                <div class="card-footer text-center">
-                  <a href="{{templateParentPath}}__template#edit"
-                      class="btn btn-sm btn-primary" id="template-button-decendants">
-                      {{ t("Edit") }}
-                  </a>
-                </div>
-              </div>
-            </div>
-          </div>
-        </div>
-      </div>
-    </div><!-- /.modal-content -->
-  </div><!-- /.modal-dialog -->
-</div><!-- /.modal -->
+<div id ="create-template-modal"></div>