|
|
@@ -1,149 +1,87 @@
|
|
|
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 {
|
|
|
+import TagEditor from './TagEditor';
|
|
|
+
|
|
|
+class TagLabels extends React.Component {
|
|
|
|
|
|
constructor(props) {
|
|
|
super(props);
|
|
|
|
|
|
this.state = {
|
|
|
- currentPageTags: [],
|
|
|
- newPageTags: [],
|
|
|
- isOpenModal: false,
|
|
|
- isEditorMode: null,
|
|
|
+ tags: [],
|
|
|
};
|
|
|
|
|
|
- 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);
|
|
|
+ this.showEditor = this.showEditor.bind(this);
|
|
|
+ this.tagsUpdatedHandler = this.tagsUpdatedHandler.bind(this);
|
|
|
}
|
|
|
|
|
|
async componentWillMount() {
|
|
|
- // set default pageTag on button
|
|
|
- let tags = this.props.templateTags.split(',') || [];
|
|
|
-
|
|
|
- // tags of existed page override template tags
|
|
|
+ // set pageTag on button
|
|
|
const pageId = this.props.pageId;
|
|
|
if (pageId) {
|
|
|
const res = await this.props.crowi.apiGet('/pages.getPageTag', { pageId });
|
|
|
- tags = res.tags;
|
|
|
- }
|
|
|
-
|
|
|
- this.setState({ currentPageTags: tags });
|
|
|
- this.props.sendTagData(tags);
|
|
|
- }
|
|
|
-
|
|
|
- addNewTag(newPageTags) {
|
|
|
- this.setState({ newPageTags });
|
|
|
- }
|
|
|
-
|
|
|
- handleCloseModal() {
|
|
|
- this.setState({ isOpenModal: false });
|
|
|
- }
|
|
|
-
|
|
|
- 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);
|
|
|
+ this.setState({ tags: res.tags });
|
|
|
+ this.props.sendTagData(res.tags);
|
|
|
}
|
|
|
- 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',
|
|
|
- });
|
|
|
+ showEditor() {
|
|
|
+ this.tagEditor.show(this.state.tags);
|
|
|
}
|
|
|
|
|
|
- apiErrorHandler(err) {
|
|
|
- toastr.error(err.message, 'Error occured', {
|
|
|
- closeButton: true,
|
|
|
- progressBar: true,
|
|
|
- newestOnTop: false,
|
|
|
- showDuration: '100',
|
|
|
- hideDuration: '100',
|
|
|
- timeOut: '3000',
|
|
|
- });
|
|
|
+ tagsUpdatedHandler(tags) {
|
|
|
+ this.setState({ tags });
|
|
|
+ this.props.sendTagData(tags);
|
|
|
}
|
|
|
|
|
|
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>,
|
|
|
+ const tagElements = [];
|
|
|
+ const { t, pageId } = this.props;
|
|
|
+
|
|
|
+ for (let i = 0; i < this.state.tags.length; i++) {
|
|
|
+ tagElements.push(
|
|
|
+ <span key={`${pageId}_${i}`} className="text-muted">
|
|
|
+ <i className="tag-icon icon-tag mr-1"></i>
|
|
|
+ <a className="tag-name mr-2" 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.currentPageTags.length === 0 && (
|
|
|
- <a className="display-of-notag text-muted" onClick={this.handleShowModal}>{ t('Add tags for this page') }</a>
|
|
|
+ <div className="tag-viewer">
|
|
|
+ {this.state.tags.length === 0 && (
|
|
|
+ <a className="btn btn-link btn-edit-tags no-tags p-0" onClick={this.showEditor}>
|
|
|
+ {t('Add tags for this page')} <i className="manage-tags ml-2 icon-plus"></i>
|
|
|
+ </a>
|
|
|
+ )}
|
|
|
+ {tagElements}
|
|
|
+ {this.state.tags.length > 0 && (
|
|
|
+ <a className="btn btn-link btn-edit-tags p-0" onClick={this.showEditor}>
|
|
|
+ <i className="manage-tags ml-2 icon-plus"></i> {t('Edit tags for this page')}
|
|
|
+ </a>
|
|
|
)}
|
|
|
- {tags}
|
|
|
- <i
|
|
|
- className="manage-tags ml-2 icon-plus"
|
|
|
- onClick={this.handleShowModal}
|
|
|
|
|
|
+ <TagEditor
|
|
|
+ ref={(c) => { this.tagEditor = c }}
|
|
|
+ crowi={this.props.crowi}
|
|
|
+ pageId={this.props.pageId}
|
|
|
+ onTagsUpdated={this.tagsUpdatedHandler}
|
|
|
>
|
|
|
- </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>
|
|
|
+ </TagEditor>
|
|
|
</div>
|
|
|
);
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
-TagLabel.propTypes = {
|
|
|
+TagLabels.propTypes = {
|
|
|
t: PropTypes.func.isRequired, // i18next
|
|
|
crowi: PropTypes.object.isRequired,
|
|
|
pageId: PropTypes.string,
|
|
|
sendTagData: PropTypes.func.isRequired,
|
|
|
- templateTags: PropTypes.string,
|
|
|
};
|
|
|
|
|
|
-export default withTranslation()(TagLabel);
|
|
|
+export default withTranslation()(TagLabels);
|