mizozobu 7 лет назад
Родитель
Сommit
9d3c5fa91f

+ 2 - 2
src/client/js/components/MyDraftList/MyDraftList.jsx

@@ -221,9 +221,9 @@ export default class MyDraftList extends React.Component {
     return (
     return (
       <div className="page-list-container-create">
       <div className="page-list-container-create">
         <button type="button" className="btn-danger mb-3" onClick={this.clearAllDrafts}>Delete All</button>
         <button type="button" className="btn-danger mb-3" onClick={this.clearAllDrafts}>Delete All</button>
-        <ul className="p-0 m-0">
+        <div className="tab-pane m-t-30 accordion" id="draft-list">
           {draftList}
           {draftList}
-        </ul>
+        </div>
         <Pagination bsSize="small">{paginationItems}</Pagination>
         <Pagination bsSize="small">{paginationItems}</Pagination>
       </div>
       </div>
     );
     );

+ 94 - 76
src/client/js/components/PageList/Draft.jsx

@@ -1,8 +1,6 @@
 import React, { Fragment } from 'react';
 import React, { Fragment } from 'react';
 import PropTypes from 'prop-types';
 import PropTypes from 'prop-types';
 
 
-import Popover from 'react-bootstrap/lib/Popover';
-import OverlayTrigger from 'react-bootstrap/lib/OverlayTrigger';
 import { withTranslation } from 'react-i18next';
 import { withTranslation } from 'react-i18next';
 
 
 import GrowiRenderer from '../../util/GrowiRenderer';
 import GrowiRenderer from '../../util/GrowiRenderer';
@@ -16,74 +14,46 @@ class Draft extends React.Component {
 
 
     this.state = {
     this.state = {
       html: '',
       html: '',
+      isOpen: false,
     };
     };
 
 
     this.growiRenderer = new GrowiRenderer(this.props.crowi, this.props.crowiOriginRenderer, { mode: 'draft' });
     this.growiRenderer = new GrowiRenderer(this.props.crowi, this.props.crowiOriginRenderer, { mode: 'draft' });
 
 
     this.renderHtml = this.renderHtml.bind(this);
     this.renderHtml = this.renderHtml.bind(this);
-    this.renderButton = this.renderButton.bind(this);
-    this.renderPopover = this.renderPopover.bind(this);
+    this.toggleContent = this.toggleContent.bind(this);
     this.copyMarkdownToClipboard = this.copyMarkdownToClipboard.bind(this);
     this.copyMarkdownToClipboard = this.copyMarkdownToClipboard.bind(this);
-  }
-
-  async componentDidMount() {
-    this.setState({ html: await this.renderHtml(this.props.markdown) });
-  }
-
-  renderButton(isExist, markdown) {
-    if (isExist) {
-      return (
-        <a
-          className="draft-copy"
-          data-toggle="tooltip"
-          data-placement="bottom"
-          title={this.props.t('Copy')}
-          onClick={this.copyMarkdownToClipboard}
-        >
-          <i className="icon-doc" />
-        </a>
-      );
-    }
-
-    return (
-      <Fragment>
-        <span className="label-draft label label-default">draft</span>
-        <a
-          href={`${this.props.path}#edit`}
-          target="_blank"
-          rel="noopener noreferrer"
-          className="draft-delete"
-          data-toggle="tooltip"
-          data-placement="bottom"
-          title={this.props.t('Edit')}
-          onClick={() => { return this.props.clearDraft(this.props.path) }}
-        >
-          <i className="icon-note" />
-        </a>
-      </Fragment>
-    );
+    this.renderAccordionTitle = this.renderAccordionTitle.bind(this);
   }
   }
 
 
   copyMarkdownToClipboard() {
   copyMarkdownToClipboard() {
     navigator.clipboard.writeText(this.props.markdown);
     navigator.clipboard.writeText(this.props.markdown);
   }
   }
 
 
-  renderPopover(id, markdown) {
-    return (
-      <Popover id={id}>
-        <RevisionBody html={this.state.html} />
-      </Popover>
-    );
+  async toggleContent(e) {
+    const target = e.currentTarget.getAttribute('data-target');
+
+    if (!this.state.html) {
+      await this.renderHtml();
+    }
+
+    if (this.state.isOpen) {
+      $(target).collapse('hide');
+      this.setState({ isOpen: false });
+    }
+    else {
+      $(target).collapse('show');
+      this.setState({ isOpen: true });
+    }
   }
   }
 
 
-  async renderHtml(markdown) {
+  async renderHtml() {
     const context = {
     const context = {
-      markdown,
+      markdown: this.props.markdown,
     };
     };
 
 
     const growiRenderer = this.growiRenderer;
     const growiRenderer = this.growiRenderer;
     const interceptorManager = this.props.crowi.interceptorManager;
     const interceptorManager = this.props.crowi.interceptorManager;
-    const html = await interceptorManager.process('prePreProcess', context)
+    await interceptorManager.process('prePreProcess', context)
       .then(() => {
       .then(() => {
         context.markdown = growiRenderer.preProcess(context.markdown);
         context.markdown = growiRenderer.preProcess(context.markdown);
       })
       })
@@ -97,38 +67,86 @@ class Draft extends React.Component {
         context.parsedHTML = growiRenderer.postProcess(context.parsedHTML);
         context.parsedHTML = growiRenderer.postProcess(context.parsedHTML);
       })
       })
       .then(() => { return interceptorManager.process('postPostProcess', context) })
       .then(() => { return interceptorManager.process('postPostProcess', context) })
-      .then(() => { return context.parsedHTML });
+      .then(() => {
+        this.setState({ html: context.parsedHTML });
+      });
+  }
 
 
-    return html;
+  renderAccordionTitle(isExist) {
+    if (isExist) {
+      return (
+        <Fragment>
+          <span>{this.props.path}</span>
+          <span className="mx-2">({this.props.t('page exists')})</span>
+        </Fragment>
+      );
+    }
+
+    return (
+      <Fragment>
+        <a href={`${this.props.path}#edit`} target="_blank" rel="noopener noreferrer">{this.props.path}</a>
+        <span className="mx-2">
+          <span className="label-draft label label-default">draft</span>
+        </span>
+      </Fragment>
+    );
   }
   }
 
 
   render() {
   render() {
     const { t } = this.props;
     const { t } = this.props;
+    const id = this.props.path.replace('/', '-');
 
 
     return (
     return (
-      <li className="d-flex align-items-center">
-        <OverlayTrigger placement="bottom" overlay={this.renderPopover(this.props.path, this.props.markdown)}>
-          <span
-            data-toggle="tooltip"
-            data-placement="bottom"
-            title={t('Click to copy')}
-            onClick={this.copyMarkdownToClipboard}
-          >
-            <i className="icon-doc"></i>
-            {this.props.path} {this.props.isExist ? `(${t('page exists')})` : ''}
-          </span>
-        </OverlayTrigger>
-        {this.renderButton(this.props.isExist, this.props.markdown)}
-        <a
-          className="text-danger draft-delete"
-          data-toggle="tooltip"
-          data-placement="top"
-          title={t('Delete')}
-          onClick={() => { return this.props.clearDraft(this.props.path) }}
-        >
-          <i className="icon-trash" />
-        </a>
-      </li>
+      <div className="timeline-body">
+        <div className="panel panel-timeline">
+          <div className="panel-heading d-flex justify-content-between">
+            <div className="panel-title" onClick={this.toggleContent} data-target={`#${id}`}>
+              {this.renderAccordionTitle(this.props.isExist)}
+            </div>
+            <div>
+              {this.props.isExist
+                ? null
+                : (
+                  <a
+                    href={`${this.props.path}#edit`}
+                    target="_blank"
+                    rel="noopener noreferrer"
+                    className="draft-edit"
+                    data-toggle="tooltip"
+                    data-placement="bottom"
+                    title={this.props.t('Edit')}
+                  >
+                    <i className="icon-note" />
+                  </a>
+                )
+              }
+              <a
+                className="draft-copy"
+                data-toggle="tooltip"
+                data-placement="bottom"
+                title={this.props.t('Copy')}
+                onClick={this.copyMarkdownToClipboard}
+              >
+                <i className="icon-doc" />
+              </a>
+              <a
+                className="text-danger draft-delete"
+                data-toggle="tooltip"
+                data-placement="top"
+                title={t('Delete')}
+                onClick={() => { return this.props.clearDraft(this.props.path) }}
+              >
+                <i className="icon-trash" />
+              </a>
+            </div>
+          </div>
+          <div className="panel-body collapse" id={id} aria-labelledby={id} data-parent="#draft-list">
+            <div className="revision-body wiki">
+              <RevisionBody html={this.state.html} />
+            </div>
+          </div>
+        </div>
+      </div>
     );
     );
   }
   }
 
 

+ 12 - 10
src/client/styles/scss/_user.scss

@@ -67,20 +67,22 @@
 
 
   .user-page-content {
   .user-page-content {
     #user-draft-list {
     #user-draft-list {
-      li {
-        .label-draft {
-          padding: 1px 5px;
-          margin: 0 0 0 4px;
-          font-weight: normal;
-        }
+      #draft-list {
+        .panel-title {
+          width: 100%;
 
 
-        a {
-          &.draft-copy {
+          .label-draft {
+            padding: 1px 5px;
             margin: 0 0 0 4px;
             margin: 0 0 0 4px;
-            cursor: pointer;
+            font-weight: normal;
           }
           }
+        }
+
+        a {
 
 
-          &.draft-delete {
+          .icon-copy,
+          .draft-delete,
+          .icon-edit {
             margin: 0 0 0 4px;
             margin: 0 0 0 4px;
             cursor: pointer;
             cursor: pointer;
           }
           }