diff --git a/frontend/src/components/dir-view-mode/dir-column-nav.js b/frontend/src/components/dir-view-mode/dir-column-nav.js
index fc35ae27c4..babbbbe9c1 100644
--- a/frontend/src/components/dir-view-mode/dir-column-nav.js
+++ b/frontend/src/components/dir-view-mode/dir-column-nav.js
@@ -265,6 +265,7 @@ class DirColumnNav extends React.Component {
currentRepoInfo={this.props.currentRepoInfo}
selectedDirentList={this.props.selectedDirentList}
onItemsMove={this.props.onItemsMove}
+ repoID={this.props.repoID}
/>)
}
diff --git a/frontend/src/components/metadata-manage/metadata-manage-view.js b/frontend/src/components/metadata-manage/metadata-manage-view.js
new file mode 100644
index 0000000000..3840360c46
--- /dev/null
+++ b/frontend/src/components/metadata-manage/metadata-manage-view.js
@@ -0,0 +1,100 @@
+import React from 'react';
+import PropTypes from 'prop-types';
+import { Utils } from '../../utils/utils';
+import { gettext } from '../../utils/constants';
+import toaster from '../../components/toast';
+import seahubManageAPI from './seahub-manage-api';
+
+const propTypes = {
+ repoID: PropTypes.string.isRequired,
+};
+
+class MetadataManageView extends React.Component {
+
+ constructor(props) {
+ super(props);
+ this.state = {
+ isHighlight: false,
+ isShowOperationMenu: false,
+ };
+ }
+
+ onMouseEnter = () => {
+ this.setState({
+ isShowOperationMenu: true,
+ isHighlight: true,
+ });
+ };
+
+ onMouseOver = () => {
+ this.setState({
+ isShowOperationMenu: true,
+ isHighlight: true,
+ });
+ };
+
+ onMouseLeave = () => {
+ this.setState({
+ isShowOperationMenu: false,
+ isHighlight: false,
+ });
+ };
+
+ onItemMouseDown = (event) => {
+ event.stopPropagation();
+ if (event.button === 2) {
+ return;
+ }
+ };
+
+ onClick = () => {
+ seahubManageAPI.getMetadataManagementEnabledStatus(this.props.repoID).then((res) => {
+ if (res.data.enabled){
+ this.viewMetadata();
+ } else if (confirm(gettext('Enable-Metadata-Manage?'))){
+ seahubManageAPI.enableMetadataManagement(this.props.repoID).then((res) => {
+ this.viewMetadata();
+ }).catch((error) => {
+ let errMessage = Utils.getErrorMsg(error);
+ toaster.danger(errMessage);
+ });
+ }
+ }).catch((error) => {
+ let errMessage = Utils.getErrorMsg(error);
+ toaster.danger(errMessage);
+ });
+ };
+
+ viewMetadata = () => {
+
+ };
+
+ render() {
+ let hlClass = this.state.isHighlight ? 'tree-node-inner-hover ' : '';
+ return (
+
+
+
{gettext('Metadata-View')}
+
+
+
+
+
+
+
+
+ );
+ }
+}
+
+MetadataManageView.propTypes = propTypes;
+
+export default MetadataManageView;
diff --git a/frontend/src/components/metadata-manage/seahub-manage-api.js b/frontend/src/components/metadata-manage/seahub-manage-api.js
new file mode 100644
index 0000000000..531b2c9f7c
--- /dev/null
+++ b/frontend/src/components/metadata-manage/seahub-manage-api.js
@@ -0,0 +1,98 @@
+import axios from 'axios';
+import cookie from 'react-cookies';
+import { siteRoot } from '../../utils/constants';
+
+class SeahubManageAPI {
+ init({ server, username, password, token }) {
+ this.server = server;
+ this.username = username;
+ this.password = password;
+ this.token = token; //none
+ if (this.token && this.server) {
+ this.req = axios.create({
+ baseURL: this.server,
+ headers: { 'Authorization': 'Token ' + this.token },
+ });
+ }
+ return this;
+ }
+
+ initForSeahubUsage({ siteRoot, xcsrfHeaders }) {
+ if (siteRoot && siteRoot.charAt(siteRoot.length-1) === '/') {
+ var server = siteRoot.substring(0, siteRoot.length-1);
+ this.server = server;
+ } else {
+ this.server = siteRoot;
+ }
+
+ this.req = axios.create({
+ headers: {
+ 'X-CSRFToken': xcsrfHeaders,
+ }
+ });
+ return this;
+ }
+
+ _sendPostRequest(url, form) {
+ if (form.getHeaders) {
+ return this.req.post(url, form, {
+ headers:form.getHeaders()
+ });
+ } else {
+ return this.req.post(url, form);
+ }
+ }
+
+ getMetadataManagementEnabledStatus(repoID) {
+ const url = this.server + '/api/v2.1/repos/' + repoID + '/metadata/';
+ return this.req.get(url);
+ }
+
+ enableMetadataManagement(repoID) {
+ const url = this.server + '/api/v2.1/repos/' + repoID + '/metadata/';
+ return this.req.post(url);
+ }
+
+ disableMetadataManagement(repoID) {
+ const url = this.server + '/api/v2.1/repos/' + repoID + '/metadata/';
+ return this.req.delete(url);
+ }
+
+ getMetadataRecords(repoID, params) {
+ const url = this.server + '/api/v2.1/repos/' + repoID + '/metadata/records/';
+ return this.req.get(url, {params: params});
+ }
+
+ addMetadataRecords(repoID, parentDir, name) {
+ const url = this.server + '/api/v2.1/repos/' + repoID + '/metadata/records/';
+ const data = {
+ 'parent_dir': parentDir,
+ 'name': name,
+ };
+ return this.req.post(url, data);
+ }
+
+ updateMetadataRecord(repoID, recordID, creator, createTime, modifier, modifyTime, parentDir, name) {
+ const url = this.server + '/api/v2.1/repos/' + repoID + '/metadata/records/' + recordID + '/';
+ const data = {
+ 'creator': creator,
+ 'create_time': createTime,
+ 'modifier': modifier,
+ 'modify_time': modifyTime,
+ 'current_dir': parentDir,
+ 'name': name,
+ };
+ return this.req.put(url, data);
+ }
+
+ deleteMetadataRecord(repoID, recordID) {
+ const url = this.server + '/api/v2.1/repos/' + repoID + '/metadata/records/' + recordID + '/';
+ return this.req.delete(url);
+ }
+}
+
+const seahubManageAPI = new SeahubManageAPI();
+const xcsrfHeaders = cookie.load('sfcsrftoken');
+seahubManageAPI.initForSeahubUsage({ siteRoot, xcsrfHeaders });
+
+export default seahubManageAPI;
\ No newline at end of file
diff --git a/frontend/src/components/tree-view/tree-view.js b/frontend/src/components/tree-view/tree-view.js
index 4812080d60..25612f021d 100644
--- a/frontend/src/components/tree-view/tree-view.js
+++ b/frontend/src/components/tree-view/tree-view.js
@@ -2,6 +2,7 @@ import React from 'react';
import PropTypes from 'prop-types';
import TextTranslation from '../../utils/text-translation';
import TreeNodeView from './tree-node-view';
+import MetadataManageView from '../metadata-manage/metadata-manage-view';
import ContextMenu from '../context-menu/context-menu';
import { hideMenu, showMenu } from '../context-menu/actions';
import { Utils } from '../../utils/utils';
@@ -19,6 +20,7 @@ const propTypes = {
currentRepoInfo: PropTypes.object,
selectedDirentList: PropTypes.array,
onItemsMove: PropTypes.func,
+ repoID: PropTypes.string.isRequired,
posX: PropTypes.number,
posY: PropTypes.number,
};
@@ -341,6 +343,9 @@ class TreeView extends React.Component {
onNodeDragLeave={this.onNodeDragLeave}
handleContextClick={this.handleContextClick}
/>
+ {window.app.pageOptions.enableMetadataManagement && }