mirror of
https://github.com/haiwen/seahub.git
synced 2025-09-08 10:22:46 +00:00
add groups-view module
This commit is contained in:
@@ -6,7 +6,7 @@ import Loading from '../../components/loading';
|
|||||||
import CommonToolbar from '../../components/toolbar/common-toolbar';
|
import CommonToolbar from '../../components/toolbar/common-toolbar';
|
||||||
import RepoViewToolbar from '../../components/toolbar/repo-view-toobar';
|
import RepoViewToolbar from '../../components/toolbar/repo-view-toobar';
|
||||||
import CurRepoPath from '../../components/cur-repo-path/';
|
import CurRepoPath from '../../components/cur-repo-path/';
|
||||||
import ShareRepoListView from '../../components/shared-repo-list-view/shared-repo-list-view';
|
import ShareRepoListView from '../../components/share-repo-list-view/share-repo-list-view';
|
||||||
|
|
||||||
const propTypes = {
|
const propTypes = {
|
||||||
isLoading: PropTypes.bool.isRequired,
|
isLoading: PropTypes.bool.isRequired,
|
||||||
|
@@ -13,7 +13,7 @@ const propTypes = {
|
|||||||
onFreezedItem: PropTypes.func.isRequired,
|
onFreezedItem: PropTypes.func.isRequired,
|
||||||
};
|
};
|
||||||
|
|
||||||
class RepoListItem extends React.Component {
|
class SharedRepoListItem extends React.Component {
|
||||||
|
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
@@ -136,7 +136,8 @@ class RepoListItem extends React.Component {
|
|||||||
|
|
||||||
generatorOperations = () => {
|
generatorOperations = () => {
|
||||||
let { repo, currentGroup } = this.props;
|
let { repo, currentGroup } = this.props;
|
||||||
let isStaff = currentGroup.admins.indexOf(username) > -1; //for group repolist;
|
//todo this have a bug; use current api is not return admins param;
|
||||||
|
let isStaff = currentGroup.admins && currentGroup.admins.indexOf(username) > -1; //for group repolist;
|
||||||
let isRepoOwner = repo.owner_email === username;
|
let isRepoOwner = repo.owner_email === username;
|
||||||
let isAdmin = repo.is_admin;
|
let isAdmin = repo.is_admin;
|
||||||
let operations = [];
|
let operations = [];
|
||||||
@@ -293,6 +294,6 @@ class RepoListItem extends React.Component {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
RepoListItem.propTypes = propTypes;
|
SharedRepoListItem.propTypes = propTypes;
|
||||||
|
|
||||||
export default RepoListItem;
|
export default SharedRepoListItem;
|
@@ -1,15 +1,16 @@
|
|||||||
import React, {Fragment} from 'react';
|
import React, {Fragment} from 'react';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import { gettext } from '../../utils/constants';
|
import { gettext } from '../../utils/constants';
|
||||||
import SharedRepoListItem from './shared-repo-list-item';
|
import ShareRepoListItem from './share-repo-list-item';
|
||||||
|
|
||||||
const propTypes = {
|
const propTypes = {
|
||||||
currentGroup: PropTypes.object,
|
currentGroup: PropTypes.object,
|
||||||
repoList: PropTypes.array.isRequired,
|
repoList: PropTypes.array.isRequired,
|
||||||
isShowRepoOwner: PropTypes.bool.isRequired,
|
isShowRepoOwner: PropTypes.bool.isRequired,
|
||||||
|
isShowTableThread: PropTypes.bool,
|
||||||
};
|
};
|
||||||
|
|
||||||
class SharedRepoListView extends React.Component {
|
class ShareRepoListView extends React.Component {
|
||||||
|
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
@@ -29,7 +30,7 @@ class SharedRepoListView extends React.Component {
|
|||||||
<Fragment>
|
<Fragment>
|
||||||
{this.props.repoList.map(repo => {
|
{this.props.repoList.map(repo => {
|
||||||
return (
|
return (
|
||||||
<SharedRepoListItem
|
<ShareRepoListItem
|
||||||
key={repo.repo_id}
|
key={repo.repo_id}
|
||||||
repo={repo}
|
repo={repo}
|
||||||
isShowRepoOwner={this.props.isShowRepoOwner}
|
isShowRepoOwner={this.props.isShowRepoOwner}
|
||||||
@@ -45,9 +46,10 @@ class SharedRepoListView extends React.Component {
|
|||||||
|
|
||||||
renderPCUI = () => {
|
renderPCUI = () => {
|
||||||
let isShowRepoOwner = this.props.isShowRepoOwner;
|
let isShowRepoOwner = this.props.isShowRepoOwner;
|
||||||
|
let isShowTableThread = this.props.isShowTableThread !== undefined ? this.props.isShowTableThread : true;
|
||||||
return (
|
return (
|
||||||
<table>
|
<table>
|
||||||
<thead>
|
<thead className={isShowTableThread ? '' : 'vh'}>
|
||||||
<tr>
|
<tr>
|
||||||
<th width="4%"><span className="sr-only">{gettext("Library Type")}</span></th>
|
<th width="4%"><span className="sr-only">{gettext("Library Type")}</span></th>
|
||||||
<th width="40%">{gettext("Name")}
|
<th width="40%">{gettext("Name")}
|
||||||
@@ -70,9 +72,10 @@ class SharedRepoListView extends React.Component {
|
|||||||
|
|
||||||
renderMobileUI = () => {
|
renderMobileUI = () => {
|
||||||
let isShowRepoOwner = this.props.isShowRepoOwner;
|
let isShowRepoOwner = this.props.isShowRepoOwner;
|
||||||
|
let isShowTableThread = this.props.isShowTableThread !== undefined ? this.props.isShowTableThread : true;
|
||||||
return (
|
return (
|
||||||
<table>
|
<table>
|
||||||
<thead>
|
<thead className={isShowTableThread ? '' : 'vh'}>
|
||||||
<tr>
|
<tr>
|
||||||
<th width="18%"><span className="sr-only">{gettext("Library Type")}</span></th>
|
<th width="18%"><span className="sr-only">{gettext("Library Type")}</span></th>
|
||||||
<th width="68%">
|
<th width="68%">
|
||||||
@@ -105,6 +108,6 @@ class SharedRepoListView extends React.Component {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SharedRepoListView.propTypes = propTypes;
|
ShareRepoListView.propTypes = propTypes;
|
||||||
|
|
||||||
export default SharedRepoListView;
|
export default ShareRepoListView;
|
@@ -3,11 +3,14 @@ class Group {
|
|||||||
this.id= object.id;
|
this.id= object.id;
|
||||||
this.name = object.name;
|
this.name = object.name;
|
||||||
this.owner = object.owner;
|
this.owner = object.owner;
|
||||||
this.admins = object.admins;
|
this.admins = object.admins || [];
|
||||||
this.avatar_url = object.avatar_url;
|
this.avatar_url = object.avatar_url;
|
||||||
this.created_at = object.created_at;
|
this.created_at = object.created_at;
|
||||||
this.parent_group_id = object.parent_group_id;
|
this.parent_group_id = object.parent_group_id;
|
||||||
this.wiki_enabled = object.wiki_enabled;
|
this.wiki_enabled = object.wiki_enabled;
|
||||||
|
if (object.repos) {
|
||||||
|
this.repos = object.repos;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -1,19 +1,137 @@
|
|||||||
import React from 'react';
|
import React, { Fragment } from 'react';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
|
import { gettext, siteRoot, loginUrl } from '../../utils/constants';
|
||||||
|
import { seafileAPI } from '../../utils/seafile-api';
|
||||||
|
import Loading from '../../components/loading';
|
||||||
|
import Group from '../../models/group';
|
||||||
|
import RepoInfo from '../../models/repoInfo';
|
||||||
|
import GeneralToolbar from '../../components/toolbar/general-toolbar';
|
||||||
|
import ShareRepoListView from '../../components/share-repo-list-view/share-repo-list-view';
|
||||||
|
|
||||||
|
import '../../css/groups.css';
|
||||||
|
|
||||||
const propTypes = {
|
const propTypes = {
|
||||||
|
group: PropTypes.object.isRequired,
|
||||||
};
|
};
|
||||||
|
|
||||||
class Groups extends React.Component {
|
|
||||||
|
class RepoListViewPanel extends React.Component {
|
||||||
|
|
||||||
|
constructor(props) {
|
||||||
|
super(props);
|
||||||
|
this.state = {
|
||||||
|
repoList: [],
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
componentDidMount() {
|
||||||
|
let group = this.props.group;
|
||||||
|
seafileAPI.listGroupRepos(group.id).then(res => {
|
||||||
|
let repoList = res.data.map(item => {
|
||||||
|
let repo = new RepoInfo(item);
|
||||||
|
return repo;
|
||||||
|
});
|
||||||
|
this.setState({repoList: repoList});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
let group = this.props.group;
|
||||||
|
const emptyTip = <p className="group-item-empty-tip">{gettext('No libraries')}</p>;
|
||||||
|
return (
|
||||||
|
<Fragment>
|
||||||
|
<h4 className="group-item-heading ellipsis">
|
||||||
|
<a href={`${siteRoot}group/${group.id}/`} title={group.name}>{group.name}</a>
|
||||||
|
</h4>
|
||||||
|
{this.state.repoList.length === 0 ?
|
||||||
|
emptyTip :
|
||||||
|
<ShareRepoListView
|
||||||
|
isShowTableThread={false}
|
||||||
|
isShowRepoOwner={false}
|
||||||
|
currentGroup={this.props.group}
|
||||||
|
repoList={this.state.repoList}
|
||||||
|
/>
|
||||||
|
}
|
||||||
|
</Fragment>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
RepoListViewPanel.propTypes = propTypes;
|
||||||
|
|
||||||
|
class GroupsView extends React.Component {
|
||||||
|
|
||||||
|
constructor(props) {
|
||||||
|
super(props);
|
||||||
|
this.state = {
|
||||||
|
isLoading: true,
|
||||||
|
errorMsg: '',
|
||||||
|
groupList: [],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
componentDidMount() {
|
||||||
|
seafileAPI.listGroups().then((res) => { // TODO: api name
|
||||||
|
// `{'with_repos': 1}`: list repos of every group
|
||||||
|
// res: {data: [...], status: 200, statusText: "OK", headers: {…}, config: {…}, …}
|
||||||
|
let groupList = res.data.groups.map(item => {
|
||||||
|
let group = new Group(item);
|
||||||
|
return group;
|
||||||
|
})
|
||||||
|
this.setState({
|
||||||
|
isLoading: false,
|
||||||
|
groupList: groupList,
|
||||||
|
});
|
||||||
|
}).catch((error) => {
|
||||||
|
if (error.response) {
|
||||||
|
if (error.response.status == 403) {
|
||||||
|
this.setState({
|
||||||
|
isLoading: false,
|
||||||
|
errorMsg: gettext("Permission denied")
|
||||||
|
});
|
||||||
|
location.href = `${loginUrl}?next=${encodeURIComponent(location.href)}`;
|
||||||
|
} else {
|
||||||
|
this.setState({
|
||||||
|
isLoading: false,
|
||||||
|
errorMsg: gettext("Error")
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
this.setState({
|
||||||
|
isLoading: false,
|
||||||
|
errorMsg: gettext("Please check the network.")
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
return (
|
return (
|
||||||
<div>{placehodler}</div>
|
<Fragment>
|
||||||
|
<GeneralToolbar onShowSidePanel={this.props.onShowSidePanel} onSearchedClick={this.props.onSearchedClick}/>
|
||||||
|
<div className="main-panel-center">
|
||||||
|
<div className="cur-view-container">
|
||||||
|
<div className="cur-view-path">
|
||||||
|
<h3 className="sf-heading">{gettext("My Groups")}</h3>
|
||||||
|
</div>
|
||||||
|
<div className="cur-view-content">
|
||||||
|
{this.state.isLoading && <Loading />}
|
||||||
|
{(!this.state.isLoading && this.state.errorMsg !== '') && this.state.errorMsg}
|
||||||
|
{/* {(!this.state.isLoading && this.state.groupList.length === 0 ) && emptyTip} //todo */}
|
||||||
|
{!this.state.isLoading && this.state.groupList.map((group, index) => {
|
||||||
|
return (
|
||||||
|
<RepoListViewPanel key={index} group={group} />
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</Fragment>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Groups.propTypes = propTypes;
|
// Groups.propTypes = propTypes;
|
||||||
|
|
||||||
export default Groups;
|
export default GroupsView;
|
||||||
|
Reference in New Issue
Block a user