|
|
@@ -2,6 +2,12 @@ import React from 'react';
|
|
|
import PropTypes from 'prop-types';
|
|
|
import { withTranslation } from 'react-i18next';
|
|
|
|
|
|
+import * as toastr from 'toastr';
|
|
|
+
|
|
|
+import { createSubscribedElement } from '../UnstatedUtils';
|
|
|
+import AppContainer from '../../services/AppContainer';
|
|
|
+import PageContainer from '../../services/PageContainer';
|
|
|
+
|
|
|
import TagEditor from './TagEditor';
|
|
|
|
|
|
class TagLabels extends React.Component {
|
|
|
@@ -10,61 +16,86 @@ class TagLabels extends React.Component {
|
|
|
super(props);
|
|
|
|
|
|
this.state = {
|
|
|
- tags: [],
|
|
|
+ showTagEditor: false,
|
|
|
};
|
|
|
|
|
|
this.showEditor = this.showEditor.bind(this);
|
|
|
this.tagsUpdatedHandler = this.tagsUpdatedHandler.bind(this);
|
|
|
}
|
|
|
|
|
|
- async componentWillMount() {
|
|
|
- // set pageTag on button
|
|
|
- const pageId = this.props.pageId;
|
|
|
+ showEditor() {
|
|
|
+ const { tags } = this.props.pageContainer.state;
|
|
|
+ this.tagEditor.show(tags);
|
|
|
+ }
|
|
|
+
|
|
|
+ async tagsUpdatedHandler(tags) {
|
|
|
+ // TODO
|
|
|
+ // if (currentEditorMode == null) {
|
|
|
+ try {
|
|
|
+ const { pageContainer } = this.props;
|
|
|
+ const { pageId } = this.props.pageContainer.state;
|
|
|
+ await this.props.appContainer.apiPost('/tags.update', { pageId, tags });
|
|
|
+
|
|
|
+ // update pageContainer.state
|
|
|
+ pageContainer.setState({ tags });
|
|
|
|
|
|
- if (pageId) {
|
|
|
- const res = await this.props.crowi.apiGet('/pages.getPageTag', { pageId });
|
|
|
- this.setState({ tags: res.tags });
|
|
|
- this.props.sendTagData(res.tags);
|
|
|
+ this.apiSuccessHandler();
|
|
|
}
|
|
|
- else if (this.props.templateTagData) {
|
|
|
- const templateTags = this.props.templateTagData.split(',');
|
|
|
- this.setState({ tags: templateTags });
|
|
|
- this.props.sendTagData(templateTags);
|
|
|
+ catch (err) {
|
|
|
+ this.apiErrorHandler(err);
|
|
|
+ return;
|
|
|
}
|
|
|
+ // else {
|
|
|
+ // update editorContainer.tags
|
|
|
+ // }
|
|
|
}
|
|
|
|
|
|
- showEditor() {
|
|
|
- this.tagEditor.show(this.state.tags);
|
|
|
+ apiSuccessHandler() {
|
|
|
+ toastr.success(undefined, 'updated tags successfully', {
|
|
|
+ closeButton: true,
|
|
|
+ progressBar: true,
|
|
|
+ newestOnTop: false,
|
|
|
+ showDuration: '100',
|
|
|
+ hideDuration: '100',
|
|
|
+ timeOut: '1200',
|
|
|
+ extendedTimeOut: '150',
|
|
|
+ });
|
|
|
}
|
|
|
|
|
|
- tagsUpdatedHandler(tags) {
|
|
|
- this.setState({ tags });
|
|
|
- this.props.sendTagData(tags);
|
|
|
+ apiErrorHandler(err) {
|
|
|
+ toastr.error(err.message, 'Error occured', {
|
|
|
+ closeButton: true,
|
|
|
+ progressBar: true,
|
|
|
+ newestOnTop: false,
|
|
|
+ showDuration: '100',
|
|
|
+ hideDuration: '100',
|
|
|
+ timeOut: '3000',
|
|
|
+ });
|
|
|
}
|
|
|
|
|
|
render() {
|
|
|
- const tagElements = [];
|
|
|
- const { t, pageId } = this.props;
|
|
|
+ const { t } = this.props;
|
|
|
+ const { pageId } = this.props.pageContainer.state;
|
|
|
+ const { tags } = this.props.pageContainer.state;
|
|
|
|
|
|
- for (let i = 0; i < this.state.tags.length; i++) {
|
|
|
- tagElements.push(
|
|
|
- <span key={`${pageId}_${i}`} className="text-muted">
|
|
|
+ const tagElements = tags.map((tag) => {
|
|
|
+ return (
|
|
|
+ <span key={`${pageId}_${tag}`} 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>,
|
|
|
+ <a className="tag-name mr-2" href={`/_search?q=tag:${tag}`} key={`${pageId}_${tag}_link`}>{tag}</a>
|
|
|
+ </span>
|
|
|
);
|
|
|
-
|
|
|
- }
|
|
|
+ });
|
|
|
|
|
|
return (
|
|
|
- <div className={`tag-viewer ${this.props.pageId ? 'existed-page' : 'new-page'}`}>
|
|
|
- {this.state.tags.length === 0 && (
|
|
|
+ <div className={`tag-viewer ${pageId ? 'existed-page' : 'new-page'}`}>
|
|
|
+ {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 && (
|
|
|
+ {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>
|
|
|
@@ -72,8 +103,8 @@ class TagLabels extends React.Component {
|
|
|
|
|
|
<TagEditor
|
|
|
ref={(c) => { this.tagEditor = c }}
|
|
|
- crowi={this.props.crowi}
|
|
|
- pageId={this.props.pageId}
|
|
|
+ appContainer={this.props.appContainer}
|
|
|
+ show={this.state.showTagEditor}
|
|
|
onTagsUpdated={this.tagsUpdatedHandler}
|
|
|
>
|
|
|
</TagEditor>
|
|
|
@@ -83,12 +114,18 @@ class TagLabels extends React.Component {
|
|
|
|
|
|
}
|
|
|
|
|
|
+/**
|
|
|
+ * Wrapper component for using unstated
|
|
|
+ */
|
|
|
+const TagLabelsWrapper = (props) => {
|
|
|
+ return createSubscribedElement(TagLabels, props, [AppContainer, PageContainer]);
|
|
|
+};
|
|
|
+
|
|
|
+
|
|
|
TagLabels.propTypes = {
|
|
|
t: PropTypes.func.isRequired, // i18next
|
|
|
- crowi: PropTypes.object.isRequired,
|
|
|
- pageId: PropTypes.string,
|
|
|
- sendTagData: PropTypes.func.isRequired,
|
|
|
- templateTagData: PropTypes.string,
|
|
|
+ appContainer: PropTypes.instanceOf(AppContainer).isRequired,
|
|
|
+ pageContainer: PropTypes.instanceOf(PageContainer).isRequired,
|
|
|
};
|
|
|
|
|
|
-export default withTranslation()(TagLabels);
|
|
|
+export default withTranslation()(TagLabelsWrapper);
|