Ver Fonte

refactor TagLabel

Yuki Takei há 7 anos atrás
pai
commit
442ab3323a

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

@@ -32,7 +32,7 @@ import CommentForm from './components/PageComment/CommentForm';
 import PageAttachment from './components/PageAttachment';
 import PageStatusAlert from './components/PageStatusAlert';
 import RevisionPath from './components/Page/RevisionPath';
-import TagLabel from './components/Page/TagLabel';
+import TagLabels from './components/Page/TagLabels';
 import RevisionUrl from './components/Page/RevisionUrl';
 import BookmarkButton from './components/BookmarkButton';
 import LikeButton from './components/LikeButton';
@@ -315,8 +315,8 @@ if (pagePath) {
   componentMappings.page = <Page crowi={crowi} crowiRenderer={crowiRenderer} markdown={markdown} pagePath={pagePath} onSaveWithShortcut={saveWithShortcut} />;
   componentMappings['revision-path'] = <RevisionPath pagePath={pagePath} crowi={crowi} />;
   // [TODO] there is a need to decide the destination of RevisionUrl
-  componentMappings['revision-url'] = <RevisionUrl crowi={crowi} pageId={pageId} pagePath={pagePath} sendTagData={setTagData} />;
-  componentMappings['tag-label'] = <I18nextProvider i18n={i18n}><TagLabel crowi={crowi} pageId={pageId} sendTagData={setTagData} /></I18nextProvider>;
+  componentMappings['revision-url'] = <RevisionUrl crowi={crowi} pageId={pageId} pagePath={pagePath} />;
+  componentMappings['tag-label'] = <I18nextProvider i18n={i18n}><TagLabels crowi={crowi} pageId={pageId} sendTagData={setTagData} /></I18nextProvider>;
 }
 
 Object.keys(componentMappings).forEach((key) => {

+ 111 - 0
src/client/js/components/Page/TagEditor.jsx

@@ -0,0 +1,111 @@
+import React from 'react';
+import PropTypes from 'prop-types';
+import * as toastr from 'toastr';
+import Button from 'react-bootstrap/es/Button';
+import Modal from 'react-bootstrap/es/Modal';
+import PageTagForm from '../PageTagForm';
+
+class TagEditor extends React.Component {
+
+  constructor(props) {
+    super(props);
+
+    this.state = {
+      tags: [],
+      isOpenModal: false,
+      isEditorMode: null,
+    };
+
+    this.show = this.show.bind(this);
+    this.onTagsUpdatedByFormHandler = this.onTagsUpdatedByFormHandler.bind(this);
+    this.closeModalHandler = this.closeModalHandler.bind(this);
+    this.handleSubmit = this.handleSubmit.bind(this);
+    this.apiSuccessHandler = this.apiSuccessHandler.bind(this);
+    this.apiErrorHandler = this.apiErrorHandler.bind(this);
+  }
+
+  async componentWillMount() {
+  }
+
+  show(tags) {
+    const isEditorMode = this.props.crowi.getCrowiForJquery().getCurrentEditorMode();
+    this.setState({ isOpenModal: true, isEditorMode, tags });
+  }
+
+  onTagsUpdatedByFormHandler(tags) {
+    this.setState({ tags });
+  }
+
+  closeModalHandler() {
+    this.setState({ isOpenModal: false });
+  }
+
+  async handleSubmit() {
+
+    if (!this.state.isEditorMode) {
+      try {
+        await this.props.crowi.apiPost('/tags.update', { pageId: this.props.pageId, tags: this.state.tags });
+        this.apiSuccessHandler();
+      }
+      catch (err) {
+        this.apiErrorHandler(err);
+        return;
+      }
+    }
+
+    this.props.onTagsUpdated(this.state.tags);
+
+    // close modal
+    this.setState({ isOpenModal: false });
+  }
+
+  apiSuccessHandler() {
+    toastr.success(undefined, 'updated tags successfully', {
+      closeButton: true,
+      progressBar: true,
+      newestOnTop: false,
+      showDuration: '100',
+      hideDuration: '100',
+      timeOut: '1200',
+      extendedTimeOut: '150',
+    });
+  }
+
+  apiErrorHandler(err) {
+    toastr.error(err.message, 'Error occured', {
+      closeButton: true,
+      progressBar: true,
+      newestOnTop: false,
+      showDuration: '100',
+      hideDuration: '100',
+      timeOut: '3000',
+    });
+  }
+
+  render() {
+    return (
+      <Modal show={this.state.isOpenModal} onHide={this.closeModalHandler} id="editTagModal">
+        <Modal.Header closeButton className="bg-primary">
+          <Modal.Title className="text-white">Edit Tags</Modal.Title>
+        </Modal.Header>
+        <Modal.Body>
+          <PageTagForm crowi={this.props.crowi} tags={this.state.tags} onTagsUpdated={this.onTagsUpdatedByFormHandler} />
+        </Modal.Body>
+        <Modal.Footer>
+          <Button variant="primary" onClick={this.handleSubmit}>
+            Done
+          </Button>
+        </Modal.Footer>
+      </Modal>
+    );
+  }
+
+}
+
+TagEditor.propTypes = {
+  crowi: PropTypes.object.isRequired,
+  pageId: PropTypes.string,
+  onTagsUpdated: PropTypes.func.isRequired,
+};
+
+export default TagEditor;

+ 0 - 144
src/client/js/components/Page/TagLabel.jsx

@@ -1,144 +0,0 @@
-import React from 'react';
-import PropTypes from 'prop-types';
-import { withTranslation } from 'react-i18next';
-import * as toastr from 'toastr';
-import Button from 'react-bootstrap/es/Button';
-import Modal from 'react-bootstrap/es/Modal';
-import PageTagForm from '../PageTagForm';
-
-class TagLabel extends React.Component {
-
-  constructor(props) {
-    super(props);
-
-    this.state = {
-      currentPageTags: [],
-      newPageTags: [],
-      isOpenModal: false,
-      isEditorMode: null,
-    };
-
-    this.addNewTag = this.addNewTag.bind(this);
-    this.handleShowModal = this.handleShowModal.bind(this);
-    this.handleCloseModal = this.handleCloseModal.bind(this);
-    this.handleSubmit = this.handleSubmit.bind(this);
-    this.apiSuccessHandler = this.apiSuccessHandler.bind(this);
-    this.apiErrorHandler = this.apiErrorHandler.bind(this);
-  }
-
-  async componentWillMount() {
-    // set pageTag on button
-    const pageId = this.props.pageId;
-    if (pageId) {
-      const res = await this.props.crowi.apiGet('/pages.getPageTag', { pageId });
-      this.setState({ currentPageTags: res.tags, newPageTags: res.tags });
-      this.props.sendTagData(res.tags);
-    }
-  }
-
-  addNewTag(newPageTags) {
-    this.setState({ newPageTags });
-  }
-
-  handleCloseModal() {
-    // reset state newPageTags when user close modal without push Done button
-    this.setState({ isOpenModal: false, newPageTags: this.state.currentPageTags });
-  }
-
-  handleShowModal() {
-    const isEditorMode = this.props.crowi.getCrowiForJquery().getCurrentEditorMode();
-    this.setState({ isOpenModal: true, isEditorMode });
-  }
-
-  async handleSubmit() {
-
-    if (this.state.isEditorMode) { // set tag on draft on edit
-      this.props.sendTagData(this.state.newPageTags);
-    }
-    else { // update tags without saving the page on view
-      try {
-        await this.props.crowi.apiPost('/tags.update', { pageId: this.props.pageId, tags: this.state.newPageTags });
-        this.apiSuccessHandler();
-      }
-      catch (err) {
-        this.apiErrorHandler(err);
-        return;
-      }
-    }
-    this.setState({ currentPageTags: this.state.newPageTags, isOpenModal: false });
-  }
-
-  apiSuccessHandler() {
-    toastr.success(undefined, 'updated tags successfully', {
-      closeButton: true,
-      progressBar: true,
-      newestOnTop: false,
-      showDuration: '100',
-      hideDuration: '100',
-      timeOut: '1200',
-      extendedTimeOut: '150',
-    });
-  }
-
-  apiErrorHandler(err) {
-    toastr.error(err.message, 'Error occured', {
-      closeButton: true,
-      progressBar: true,
-      newestOnTop: false,
-      showDuration: '100',
-      hideDuration: '100',
-      timeOut: '3000',
-    });
-  }
-
-  render() {
-    const tags = [];
-    const { t } = this.props;
-
-    for (let i = 0; i < this.state.currentPageTags.length; i++) {
-      tags.push(
-        <i className="tag-icon icon-tag"></i>,
-        <a className="tag-name text-muted" href={`/_search?q=tag:${this.state.currentPageTags[i]}`} key={i.toString()}>{this.state.currentPageTags[i]}</a>,
-      );
-
-    }
-
-    return (
-      <div className="tag-viewer text-muted">
-        {this.state.currentPageTags.length === 0 && (
-          <a className="display-of-notag text-muted" onClick={this.handleShowModal}>{ t('Add tags for this page') }</a>
-        )}
-        {tags}
-        <i
-          className="manage-tags ml-2 icon-plus"
-          onClick={this.handleShowModal}
-
-        >
-        </i>
-        <Modal show={this.state.isOpenModal} onHide={this.handleCloseModal} id="editTagModal">
-          <Modal.Header closeButton className="bg-primary">
-            <Modal.Title className="text-white">Page Tag</Modal.Title>
-          </Modal.Header>
-          <Modal.Body>
-            <PageTagForm crowi={this.props.crowi} currentPageTags={this.state.currentPageTags} addNewTag={this.addNewTag} />
-          </Modal.Body>
-          <Modal.Footer>
-            <Button variant="primary" onClick={this.handleSubmit}>
-              Done
-            </Button>
-          </Modal.Footer>
-        </Modal>
-      </div>
-    );
-  }
-
-}
-
-TagLabel.propTypes = {
-  t: PropTypes.func.isRequired, // i18next
-  crowi: PropTypes.object.isRequired,
-  pageId: PropTypes.string,
-  sendTagData: PropTypes.func.isRequired,
-};
-
-export default withTranslation()(TagLabel);

+ 85 - 0
src/client/js/components/Page/TagLabels.jsx

@@ -0,0 +1,85 @@
+import React from 'react';
+import PropTypes from 'prop-types';
+import { withTranslation } from 'react-i18next';
+
+import TagEditor from './TagEditor';
+
+class TagLabels extends React.Component {
+
+  constructor(props) {
+    super(props);
+
+    this.state = {
+      tags: [],
+    };
+
+    this.showEditor = this.showEditor.bind(this);
+    this.tagsUpdatedHandler = this.tagsUpdatedHandler.bind(this);
+  }
+
+  async componentWillMount() {
+    // set pageTag on button
+    const pageId = this.props.pageId;
+    if (pageId) {
+      const res = await this.props.crowi.apiGet('/pages.getPageTag', { pageId });
+      this.setState({ tags: res.tags });
+      this.props.sendTagData(res.tags);
+    }
+  }
+
+  showEditor() {
+    this.tagEditor.show(this.state.tags);
+  }
+
+  tagsUpdatedHandler(tags) {
+    this.setState({ tags });
+    this.props.sendTagData(tags);
+  }
+
+  render() {
+    const tagElements = [];
+    const { t, pageId } = this.props;
+
+    for (let i = 0; i < this.state.tags.length; i++) {
+      tagElements.push(
+        <span key={`${pageId}_${i}`}>
+          <i className="tag-icon icon-tag"></i>
+          <a className="tag-name text-muted ml-1" href={`/_search?q=tag:${this.state.tags[i]}`} key={i.toString()}>{this.state.tags[i]}</a>
+        </span>,
+      );
+
+    }
+
+    return (
+      <div className="tag-viewer text-muted">
+        {this.state.tags.length === 0 && (
+          <a className="display-of-notag text-muted" onClick={this.showEditor}>{ t('Add tags for this page') }</a>
+        )}
+        {tagElements}
+        <i
+          className="manage-tags ml-2 icon-plus"
+          onClick={this.showEditor}
+        >
+        </i>
+
+        <TagEditor
+          ref={(c) => { this.tagEditor = c }}
+          crowi={this.props.crowi}
+          pageId={this.props.pageId}
+          onTagsUpdated={this.tagsUpdatedHandler}
+        >
+        </TagEditor>
+      </div>
+    );
+  }
+
+}
+
+TagLabels.propTypes = {
+  t: PropTypes.func.isRequired, // i18next
+  crowi: PropTypes.object.isRequired,
+  pageId: PropTypes.string,
+  sendTagData: PropTypes.func.isRequired,
+};
+
+export default withTranslation()(TagLabels);

+ 5 - 5
src/client/js/components/PageTagForm.jsx

@@ -19,8 +19,8 @@ export default class PageTagForm extends React.Component {
     this.state = {
       resultTags: [],
       isLoading: false,
-      selected: this.props.currentPageTags,
-      defaultPageTags: this.props.currentPageTags,
+      selected: this.props.tags,
+      defaultPageTags: this.props.tags,
     };
     this.crowi = this.props.crowi;
 
@@ -32,7 +32,7 @@ export default class PageTagForm extends React.Component {
   handleChange(selected) {
     // send tags to TagLabel Component when user add tag to form everytime
     this.setState({ selected }, () => {
-      this.props.addNewTag(this.state.selected);
+      this.props.onTagsUpdated(this.state.selected);
     });
   }
 
@@ -85,8 +85,8 @@ export default class PageTagForm extends React.Component {
 
 PageTagForm.propTypes = {
   crowi: PropTypes.object.isRequired,
-  currentPageTags: PropTypes.array.isRequired,
-  addNewTag: PropTypes.func.isRequired,
+  tags: PropTypes.array.isRequired,
+  onTagsUpdated: PropTypes.func.isRequired,
 };
 
 PageTagForm.defaultProps = {