diff --git a/frontend/src/components/cur-repo-path/index.js b/frontend/src/components/cur-repo-path/index.js
index e0469620ff..2c7f023d93 100644
--- a/frontend/src/components/cur-repo-path/index.js
+++ b/frontend/src/components/cur-repo-path/index.js
@@ -4,18 +4,18 @@ import RepoPath from './repo-path';
import RepoTool from './repo-tool';
const propTypes = {
- currentTab: PropTypes.string.isRequired,
+ libraryType: PropTypes.string.isRequired,
currentGroup: PropTypes.object,
};
class CurGroupPath extends React.Component {
render() {
- let { currentTab, currentGroup } = this.props;
+ let { libraryType, currentGroup } = this.props;
return (
-
-
+
+
);
}
diff --git a/frontend/src/components/cur-repo-path/repo-path.js b/frontend/src/components/cur-repo-path/repo-path.js
index 0d15095446..f19deceefd 100644
--- a/frontend/src/components/cur-repo-path/repo-path.js
+++ b/frontend/src/components/cur-repo-path/repo-path.js
@@ -4,14 +4,14 @@ import {gettext, siteRoot} from '../../utils/constants';
const propTypes = {
currentGroup: PropTypes.object, // for group
- currentTab: PropTypes.string.isRequired, //for my-library, shared width me, shared whith all, groups
+ libraryType: PropTypes.string.isRequired, //for my-library, shared width me, shared whith all, groups
};
class RepoPath extends React.Component {
render() {
- let { currentTab, currentGroup } = this.props;
- if (currentTab === 'group' && currentGroup) {
+ let { libraryType, currentGroup } = this.props;
+ if (libraryType === 'group' && currentGroup) {
return (
{gettext("Groups")}
@@ -26,7 +26,7 @@ class RepoPath extends React.Component {
return (
- {currentTab}
+ {libraryType}
);
}
diff --git a/frontend/src/components/cur-repo-path/repo-tool.js b/frontend/src/components/cur-repo-path/repo-tool.js
index 07ca1c42a7..0e3205946f 100644
--- a/frontend/src/components/cur-repo-path/repo-tool.js
+++ b/frontend/src/components/cur-repo-path/repo-tool.js
@@ -4,13 +4,13 @@ import { gettext, username } from '../../utils/constants';
const propTypes = {
currentGroup: PropTypes.object, // for group
- currentTab: PropTypes.string.isRequired, //for my-library, shared width me, shared whith all, groups
+ libraryType: PropTypes.string.isRequired, //for my-library, shared width me, shared whith all, groups
};
class RepoTool extends React.Component {
render() {
- if (this.props.currentTab === 'group' && this.props.currentGroup) {
+ if (this.props.libraryType === 'group' && this.props.currentGroup) {
let currentGroup = this.props.currentGroup;
let isShowSettingIcon = !(currentGroup.parent_group_id !== 0 && currentGroup.admins.indexOf(username) === -1);
return (
diff --git a/frontend/src/components/dialog/create-department-repo-dialog.js b/frontend/src/components/dialog/create-department-repo-dialog.js
new file mode 100644
index 0000000000..b320cdae46
--- /dev/null
+++ b/frontend/src/components/dialog/create-department-repo-dialog.js
@@ -0,0 +1,106 @@
+import React from 'react';
+import PropTypes from 'prop-types';
+import { Button, Modal, ModalHeader, Input, ModalBody, ModalFooter, Form, FormGroup, Label, Col, FormText } from 'reactstrap';
+import { gettext, maxFileName } from '../../utils/constants';
+
+const propTypes = {
+ onCreateRepo: PropTypes.func.isRequired,
+ onCreateToggle: PropTypes.func.isRequired
+};
+
+class CreateDepartmentRepoDialog extends React.Component {
+ constructor(props) {
+ super(props);
+ this.state = {
+ repoName: '',
+ errMessage: '',
+ };
+ this.newInput = React.createRef();
+ }
+
+ handleChange = (e) => {
+ this.setState({
+ repoName: e.target.value,
+ });
+ }
+
+ handleSubmit = () => {
+ let isValid = this.validateRepoName();
+ if (isValid) {
+ let repo = this.createRepo(this.state.repoName);
+ this.props.onCreateRepo(repo);
+ }
+
+ }
+
+ handleKeyPress = (e) => {
+ if (e.key === 'Enter') {
+ this.handleSubmit();
+ }
+ }
+
+ toggle = () => {
+ this.props.onCreateToggle();
+ }
+
+ componentDidMount = () => {
+ this.newInput.focus();
+ }
+
+ validateRepoName = () => {
+ let errMessage = '';
+ let repoName = this.state.repoName.trim();
+ if (!repoName.length) {
+ errMessage = 'Name is required';
+ this.setState({errMessage: errMessage});
+ return false;
+ }
+ if (repoName.indexOf('/') > -1) {
+ errMessage = 'Name should not include \'/\'.';
+ this.setState({errMessage: errMessage});
+ return false;
+ }
+ if (repoName.length > maxFileName) {
+ errMessage = 'RepoName\'s length is must little than ' + maxFileName;
+ this.setState({errMessage: errMessage});
+ return false;
+ }
+ return true;
+ }
+
+ createRepo = (repoName) => {
+ let repo = { repo_name: repoName };
+ return repo;
+ }
+
+ render() {
+ return (
+
+ {gettext('New Department Library')}
+
+
+
+
+
+
+
+
+ );
+ }
+}
+
+CreateDepartmentRepoDialog.propTypes = propTypes;
+
+export default CreateDepartmentRepoDialog;
diff --git a/frontend/src/components/share-repo-list-view/share-repo-list-item.js b/frontend/src/components/share-repo-list-view/share-repo-list-item.js
index 1473acb60d..3f854fccc8 100644
--- a/frontend/src/components/share-repo-list-view/share-repo-list-item.js
+++ b/frontend/src/components/share-repo-list-view/share-repo-list-item.js
@@ -9,8 +9,8 @@ const propTypes = {
currentGroup: PropTypes.object,
repo: PropTypes.object.isRequired,
isItemFreezed: PropTypes.bool.isRequired,
- isShowRepoOwner: PropTypes.bool.isRequired,
onFreezedItem: PropTypes.func.isRequired,
+ onItemUnshared: PropTypes.func.isRequired,
};
class SharedRepoListItem extends React.Component {
@@ -33,6 +33,15 @@ class SharedRepoListItem extends React.Component {
});
}
}
+
+ onMouseOver = () => {
+ if (!this.props.isItemFreezed) {
+ this.setState({
+ highlight: true,
+ isOperationShow: true,
+ });
+ }
+ }
onMouseLeave = () => {
if (!this.props.isItemFreezed) {
@@ -128,6 +137,7 @@ class SharedRepoListItem extends React.Component {
onItemUnshared = () => {
// todo
+ this.props.onItemUnshared(this.props.repo);
}
onItemDelete = () => {
@@ -208,7 +218,7 @@ class SharedRepoListItem extends React.Component {
// scene two: (share, unshare), (share), (unshare)
let operations = this.generatorOperations();
const shareOperation =
;
- const unshareOperation =
+ const unshareOperation =
const deleteOperation =
;
if (this.isDeparementOnwerGroupMember) {
@@ -255,28 +265,28 @@ class SharedRepoListItem extends React.Component {
renderPCUI = () => {
let { iconUrl, iconTitle, libPath } = this.getRepoComputeParams();
- let { repo, isShowRepoOwner } = this.props;
+ let { repo } = this.props;
return (
-
+
 |
{repo.repo_name} |
{this.state.isOperationShow && this.generatorPCMenu()} |
{repo.size} |
{moment(repo.last_modified).fromNow()} |
- {isShowRepoOwner && {repo.owner_name} | }
+ {repo.owner_name} |
);
}
renderMobileUI = () => {
let { iconUrl, iconTitle, libPath } = this.getRepoComputeParams();
- let { repo, isShowRepoOwner } = this.props;
+ let { repo } = this.props;
return (
-
+
 |
{repo.repo_name}
- {isShowRepoOwner ? {repo.owner_name} : null}
+ {repo.owner_name}
{repo.size}
{moment(repo.last_modified).fromNow()}
|
diff --git a/frontend/src/components/share-repo-list-view/share-repo-list-view.js b/frontend/src/components/share-repo-list-view/share-repo-list-view.js
index caa9104157..d0da0b4167 100644
--- a/frontend/src/components/share-repo-list-view/share-repo-list-view.js
+++ b/frontend/src/components/share-repo-list-view/share-repo-list-view.js
@@ -6,8 +6,8 @@ import ShareRepoListItem from './share-repo-list-item';
const propTypes = {
currentGroup: PropTypes.object,
repoList: PropTypes.array.isRequired,
- isShowRepoOwner: PropTypes.bool.isRequired,
isShowTableThread: PropTypes.bool,
+ onItemUnshared: PropTypes.func.isRequired,
};
class ShareRepoListView extends React.Component {
@@ -33,10 +33,10 @@ class ShareRepoListView extends React.Component {
);
})}
@@ -45,7 +45,6 @@ class ShareRepoListView extends React.Component {
}
renderPCUI = () => {
- let isShowRepoOwner = this.props.isShowRepoOwner;
let isShowTableThread = this.props.isShowTableThread !== undefined ? this.props.isShowTableThread : true;
return (
@@ -56,11 +55,11 @@ class ShareRepoListView extends React.Component {
{/*TODO: sort*/}
{gettext("Actions")} |
- {gettext("Size")} |
- {gettext("Last Update")}
+ | {gettext("Size")} |
+ {gettext("Last Update")}
{/*TODO: sort*/}
|
- {isShowRepoOwner && {gettext("Owner")} | }
+ {gettext("Owner")} |
@@ -71,7 +70,6 @@ class ShareRepoListView extends React.Component {
}
renderMobileUI = () => {
- let isShowRepoOwner = this.props.isShowRepoOwner;
let isShowTableThread = this.props.isShowTableThread !== undefined ? this.props.isShowTableThread : true;
return (
@@ -79,15 +77,11 @@ class ShareRepoListView extends React.Component {
{gettext("Library Type")} |
- {isShowRepoOwner ? (
-
- {gettext("Sort:")} {/* TODO: sort */}
- {gettext("name")}
- {gettext("last update")}
-
- ) :
- (gettext('name'))
- }
+
+ {gettext("Sort:")} {/* TODO: sort */}
+ {gettext("name")}
+ {gettext("last update")}
+
|
{gettext("Actions")} |
diff --git a/frontend/src/pages/groups/group-view.js b/frontend/src/pages/groups/group-view.js
index 496a2013c4..c2bf04ed05 100644
--- a/frontend/src/pages/groups/group-view.js
+++ b/frontend/src/pages/groups/group-view.js
@@ -3,11 +3,13 @@ import PropTypes from 'prop-types';
import { gettext, username, loginUrl } from '../../utils/constants';
import { seafileAPI } from '../../utils/seafile-api';
import Loading from '../../components/loading';
+import ModalPortal from '../../components/modal-portal';
import Group from '../../models/group';
import RepoInfo from '../../models/repoInfo';
import CommonToolbar from '../../components/toolbar/common-toolbar';
-import RepoViewToolbar from '../../components/toolbar/repo-view-toobar';
import CurRepoPath from '../../components/cur-repo-path/';
+import CreateRepoDialog from '../../components/dialog/create-repo-dialog';
+import CreateDepartmentRepoDialog from '../../components/dialog/create-department-repo-dialog';
import ShareRepoListView from '../../components/share-repo-list-view/share-repo-list-view';
const propTypes = {
@@ -15,6 +17,8 @@ const propTypes = {
onSearchedClick: PropTypes.func.isRequired,
};
+const DEPARETMENT_GROUP_ONWER_NAME = 'system admin';
+
class GroupView extends React.Component {
constructor(props) {
@@ -26,8 +30,9 @@ class GroupView extends React.Component {
currentGroup: null,
isStaff: false,
repoList: [],
- currentTab: 'group',
- isShowRepoOwner: true,
+ libraryType: 'group',
+ isCreateRepoDialogShow: false,
+ isDepartmentGroup: false,
}
}
@@ -47,10 +52,12 @@ class GroupView extends React.Component {
let currentGroup = new Group(res.data);
let emptyTip = this.getEmptyTip(currentGroup);
let isStaff = currentGroup.admins.indexOf(username) > -1; //for item operations
+ let isDepartmentGroup = currentGroup.owner === DEPARETMENT_GROUP_ONWER_NAME;
this.setState({
emptyTip: emptyTip,
currentGroup: currentGroup,
isStaff: isStaff,
+ isDepartmentGroup: isDepartmentGroup,
});
this.loadRepos(groupID);
}).catch((error) => {
@@ -141,6 +148,10 @@ class GroupView extends React.Component {
return emptyTip;
}
+ onCreateRepoToggle = () => {
+ this.setState({isCreateRepoDialogShow: !this.state.isCreateRepoDialogShow});
+ }
+
onCreateRepo = (repo) => {
let groupId = this.props.groupID;
seafileAPI.createGroupRepo(groupId, repo).then(res => {
@@ -150,6 +161,7 @@ class GroupView extends React.Component {
}).catch(() => {
//todo
});
+ this.onCreateRepoToggle();
}
addRepoItem = (repo) => {
@@ -158,22 +170,36 @@ class GroupView extends React.Component {
return newRepoList;
}
+ onItemUnshared = (repo) => {
+ let group = this.state.currentGroup;
+ seafileAPI.unshareRepo(repo.repo_id, {share_type: 'group', group_id: group.id}).then(() => {
+ let repoList = this.state.repoList.filter(item => {
+ return item.repo_id !== repo.repo_id;
+ });
+ this.setState({repoList: repoList});
+ });
+ }
+
render() {
let { errMessage, emptyTip } = this.state;
return (
-
+
+
+
+
+
+
-
+
{this.state.isLoading && }
@@ -183,12 +209,29 @@ class GroupView extends React.Component {
}
+ {this.state.isCreateRepoDialogShow && !this.state.isDepartmentGroup && (
+
+
+
+ )}
+ {this.state.isCreateRepoDialogShow && this.state.isDepartmentGroup &&
+
+ }
);
}
diff --git a/frontend/src/utils/constants.js b/frontend/src/utils/constants.js
index e3c808ed31..e7acdb2347 100644
--- a/frontend/src/utils/constants.js
+++ b/frontend/src/utils/constants.js
@@ -27,6 +27,7 @@ export const storages = window.app.pageOptions.storages; // storage backends
export const enableRepoSnapshotLabel = window.app.pageOptions.enableRepoSnapshotLabel;
export const shareLinkExpireDaysMin = window.app.pageOptions.shareLinkExpireDaysMin;
export const shareLinkExpireDaysMax = window.app.pageOptions.shareLinkExpireDaysMax;
+export const maxFileName = window.app.pageOptions.maxFileName;
// wiki
export const slug = window.wiki ? window.wiki.config.slug : '';
diff --git a/seahub/templates/base_for_react.html b/seahub/templates/base_for_react.html
index 7c52d81dd6..3aeb0fb049 100644
--- a/seahub/templates/base_for_react.html
+++ b/seahub/templates/base_for_react.html
@@ -61,6 +61,7 @@
enableRepoSnapshotLabel: {% if enable_repo_snapshot_label %} true {% else %} false {% endif %},
shareLinkExpireDaysMin: "{{ share_link_expire_days_min }}",
shareLinkExpireDaysMax: "{{ share_link_expire_days_max }}",
+ maxFileName: "{{ max_file_name }}"
}
};