import React,{ Fragment } from 'react'; import { Popover } from 'reactstrap'; import PropTypes from 'prop-types'; import cookie from 'react-cookies'; import { gettext, siteRoot, username, canAddRepo } from '../../utils/constants'; import { Link } from '@reach/router'; import { seafileAPI } from '../../utils/seafile-api'; import { Utils } from '../../utils/utils'; import Loading from '../../components/loading'; import EmptyTip from '../../components/empty-tip'; import ModalPortal from '../../components/modal-portal'; import Group from '../../models/group'; import Repo from '../../models/repo'; import toaster from '../../components/toast'; import CommonToolbar from '../../components/toolbar/common-toolbar'; import CreateRepoDialog from '../../components/dialog/create-repo-dialog'; import CreateDepartmentRepoDialog from '../../components/dialog/create-department-repo-dialog'; import DismissGroupDialog from '../../components/dialog/dismiss-group-dialog'; import RenameGroupDialog from '../../components/dialog/rename-group-dialog'; import TransferGroupDialog from '../../components/dialog/transfer-group-dialog'; // import ImportMembersDialog from '../../components/dialog/import-members-dialog'; import ManageMembersDialog from '../../components/dialog/manage-members-dialog'; import LeaveGroupDialog from '../../components/dialog/leave-group-dialog'; import SharedRepoListView from '../../components/shared-repo-list-view/shared-repo-list-view'; import LibDetail from '../../components/dirent-detail/lib-details'; import SortOptionsDialog from '../../components/dialog/sort-options'; import '../../css/group-view.css'; const propTypes = { onShowSidePanel: PropTypes.func.isRequired, onSearchedClick: PropTypes.func.isRequired, onGroupChanged: PropTypes.func.isRequired, onTabNavClick: PropTypes.func.isRequired, groupID: PropTypes.string, }; class GroupView extends React.Component { constructor(props) { super(props); this.state = { isLoading: true, errMessage: '', emptyTip: null, currentGroup: null, currentRepo: null, isStaff: false, isOwner: false, sortBy: cookie.load('seafile-repo-dir-sort-by') || 'name', // 'name' or 'time' or 'size' sortOrder: cookie.load('seafile-repo-dir-sort-order') || 'asc', // 'asc' or 'desc' isSortOptionsDialogOpen: false, repoList: [], libraryType: 'group', isCreateRepoDialogShow: false, isDepartmentGroup: false, showGroupDropdown: false, showGroupMembersPopover: false, showRenameGroupDialog: false, showDismissGroupDialog: false, showTransferGroupDialog: false, // showImportMembersDialog: false, showManageMembersDialog: false, groupMembers: [], isShowDetails: false, isLeaveGroupDialogOpen: false, }; } componentDidMount() { let groupID = this.props.groupID; this.loadGroup(groupID); } componentWillReceiveProps(nextProps) { if (nextProps.groupID !== this.props.groupID) { this.loadGroup(nextProps.groupID); } } loadGroup = (groupID) => { seafileAPI.getGroup(groupID).then((res) => { let currentGroup = new Group(res.data); let emptyTip = this.getEmptyTip(currentGroup); let isStaff = currentGroup.admins.indexOf(username) > -1; //for item operations let isOwner = currentGroup.owner === username ? true : false; let isDepartmentGroup = currentGroup.parent_group_id !== 0; this.setState({ emptyTip: emptyTip, currentGroup: currentGroup, isStaff: isStaff, isDepartmentGroup: isDepartmentGroup, isOwner: isOwner, }); this.loadRepos(groupID); }).catch((error) => { this.setState({ isLoading: false, errMessage: Utils.getErrorMsg(error, true) // true: show login tip if 403 }); }); } loadRepos = (groupID) => { this.setState({isLoading: true}); seafileAPI.listGroupRepos(groupID).then((res) => { let repoList = res.data.map(item => { let repo = new Repo(item); return repo; }); this.setState({ isLoading: false, repoList: Utils.sortRepos(repoList, this.state.sortBy, this.state.sortOrder) }); }).catch((error) => { this.setState({ isLoading: false, errMessage: Utils.getErrorMsg(error, true) // true: show login tip if 403 }); }); } getEmptyTip = (currentGroup) => { let emptyTip = null; if (currentGroup) { if (currentGroup.parent_group_id === 0) { emptyTip = (

{gettext('No libraries shared with this group')}

{gettext('No libraries have been shared with this group yet. A library shared with a group can be accessed by all group members. You can share a library with a group in "My Libraries". You can also create a new library to be shared with this group by clicking the "New Library" button in the menu bar.')}

); } else { if (currentGroup.admins.indexOf(username) == -1) { // is a member of this group emptyTip = (

{gettext('No libraries')}

); } else { emptyTip = (

{gettext('No libraries')}

{gettext('You can create libraries by clicking the "New Library" button above.')}

); } } } return emptyTip; } onCreateRepoToggle = () => { this.setState({isCreateRepoDialogShow: !this.state.isCreateRepoDialogShow}); } onCreateRepo = (repo, groupOwnerType) => { let groupId = this.props.groupID; if (groupOwnerType && groupOwnerType === 'department') { seafileAPI.createGroupOwnedLibrary(groupId, repo).then(res => { //need modify endpoint api let object = { repo_id: res.data.id, repo_name: res.data.name, owner_name: res.data.group_name, owner_email: res.data.owner, permission: res.data.permission, mtime: res.data.mtime, size: res.data.size, encrypted: res.data.encrypted, }; let repo = new Repo(object); let repoList = this.addRepoItem(repo); this.setState({repoList: repoList}); }).catch(error => { let errMessage = Utils.getErrorMsg(error); toaster.danger(errMessage); }); } else { seafileAPI.createGroupRepo(groupId, repo).then(res => { let repo = new Repo(res.data); let repoList = this.addRepoItem(repo); this.setState({repoList: repoList}); }).catch(error => { let errMessage = Utils.getErrorMsg(error); toaster.danger(errMessage); }); } this.onCreateRepoToggle(); } onItemDelete = (repo) => { let groupID = this.props.groupID; seafileAPI.deleteGroupOwnedLibrary(groupID, repo.repo_id).then(() => { let repoList = this.state.repoList.filter(item => { return item.repo_id !== repo.repo_id; }); this.setState({repoList: repoList}); this.loadGroup(groupID); let name = repo.repo_name; var msg = gettext('Successfully deleted {name}.').replace('{name}', name); toaster.success(msg); }).catch((error) => { let errMessage = Utils.getErrorMsg(error); if (errMessage === gettext('Error')) { let name = repo.repo_name; errMessage = gettext('Failed to delete {name}.').replace('{name}', name); } toaster.danger(errMessage); }); } addRepoItem = (repo) => { let newRepoList = this.state.repoList.map(item => {return item;}); newRepoList.unshift(repo); return newRepoList; } onItemUnshare = (repo) => { let group = this.state.currentGroup; seafileAPI.unshareRepoToGroup(repo.repo_id, group.id).then(() => { let repoList = this.state.repoList.filter(item => { return item.repo_id !== repo.repo_id; }); this.setState({repoList: repoList}); this.loadGroup(group.id); }).catch(error => { let errMessage = Utils.getErrorMsg(error); toaster.danger(errMessage); }); } onItemRename = (repo, newName) => { seafileAPI.renameGroupOwnedLibrary(this.props.groupID, repo.repo_id, newName).then(res => { let repoList = this.state.repoList.map(item => { if (item.repo_id === repo.repo_id) { item.repo_name = newName; } return item; }); this.setState({repoList: repoList}); }).catch(error => { let errMessage = Utils.getErrorMsg(error); toaster.danger(errMessage); }); } onTabNavClick = (tabName) => { this.props.onTabNavClick(tabName); } toggleGroupDropdown = () => { this.setState({ showGroupDropdown: !this.state.showGroupDropdown }); } toggleDismissGroupDialog = () => { this.setState({ showDismissGroupDialog: !this.state.showDismissGroupDialog, showGroupDropdown: false, }); } toggleRenameGroupDialog = () => { this.setState({ showRenameGroupDialog: !this.state.showRenameGroupDialog, showGroupDropdown: false, }); } toggleTransferGroupDialog = () => { this.setState({ showTransferGroupDialog: !this.state.showTransferGroupDialog, showGroupDropdown: false, }); } // toggleImportMembersDialog= () => { // this.setState({ // showImportMembersDialog: !this.state.showImportMembersDialog // }); // } toggleManageMembersDialog = () => { this.setState({ showManageMembersDialog: !this.state.showManageMembersDialog, showGroupDropdown: false, }); } toggleLeaveGroupDialog = () => { this.setState({ isLeaveGroupDialogOpen: !this.state.isLeaveGroupDialogOpen, showGroupDropdown: false, }); } listGroupMembers = () => { seafileAPI.listGroupMembers(this.props.groupID).then((res) => { this.setState({ groupMembers: res.data }); }).catch(error => { let errMessage = Utils.getErrorMsg(error); toaster.danger(errMessage); }); } toggleGroupMembersPopover = (state) => { if (state === 'open') { this.listGroupMembers(); this.setState({ showGroupMembersPopover: true }); } else { this.setState({ showGroupMembersPopover: false }); } } onItemDetails = (repo) => { this.setState({ isShowDetails: true, currentRepo: repo, }); } closeDetails = () => { this.setState({isShowDetails: false}); } sortItems = (sortBy, sortOrder) => { cookie.save('seafile-repo-dir-sort-by', sortBy); cookie.save('seafile-repo-dir-sort-order', sortOrder); this.setState({ sortBy: sortBy, sortOrder: sortOrder, repoList: Utils.sortRepos(this.state.repoList, sortBy, sortOrder) }); } translateRole = (role) => { if (role === 'Admin') { return gettext('Admin'); } else if (role === 'Member') { return gettext('Member'); } else if (role === 'Owner') { return gettext('Owner'); } } toggleSortOptionsDialog = () => { this.setState({ isSortOptionsDialogOpen: !this.state.isSortOptionsDialogOpen }); } render() { let { errMessage, emptyTip, currentGroup, isDepartmentGroup, isStaff } = this.state; let isShowSettingIcon = false; if (currentGroup) { // group message is loaded if (currentGroup.parent_group_id === 0) { isShowSettingIcon = true; } else { if (currentGroup.admins.indexOf(username) > -1) { isShowSettingIcon = true; } } } let useRate = 0; if (isDepartmentGroup && currentGroup.group_quota) { useRate = currentGroup.group_quota_usage / currentGroup.group_quota * 100 + '%'; } return (
{((!isDepartmentGroup && canAddRepo) || (isDepartmentGroup && isStaff)) && ( Utils.isDesktop() ? ( ) : ( ) )}
{currentGroup && (
this.onTabNavClick('groups')}>{gettext('Groups')} / {currentGroup.name} {isDepartmentGroup && ( {currentGroup.group_quota > 0 &&
{Utils.bytesToSize(currentGroup.group_quota_usage)} / {Utils.bytesToSize(currentGroup.group_quota)}
}
)}
{ isShowSettingIcon &&
{gettext('Settings')}
{(this.state.isStaff || this.state.isOwner) && } {(this.state.isStaff || this.state.isOwner) && } { this.state.isOwner && } {/* gourp owner only can dissmiss group, admin could not quit, department member could not quit */} {(!this.state.isOwner && !this.state.isStaff && !isDepartmentGroup) && }
} this.toggleGroupMembersPopover('open')}>
{gettext('Members')}
{(!Utils.isDesktop() && this.state.repoList.length > 0) && } {this.state.isSortOptionsDialogOpen && }
)}
{this.state.isLoading && } {(!this.state.isLoading && errMessage) &&
{errMessage}
} {(!this.state.isLoading && this.state.repoList.length === 0) && emptyTip} {(!this.state.isLoading && this.state.repoList.length > 0) && }
{this.state.isShowDetails && (
)}
{this.state.isCreateRepoDialogShow && !this.state.isDepartmentGroup && ( )} {this.state.isCreateRepoDialogShow && this.state.isDepartmentGroup && } {this.state.showRenameGroupDialog && } {this.state.showDismissGroupDialog && } {this.state.showTransferGroupDialog && } {/* this.state.showImportMembersDialog && */} {this.state.showManageMembersDialog && } {this.state.isLeaveGroupDialogOpen && }
); } } GroupView.propTypes = propTypes; export default GroupView;