1
0
mirror of https://github.com/haiwen/seahub.git synced 2025-09-05 08:53:14 +00:00

search group member

This commit is contained in:
lian
2021-10-14 14:55:23 +08:00
parent 9ded919a2f
commit 23dc12f6b0
4 changed files with 102 additions and 26 deletions

View File

@@ -1,6 +1,6 @@
import React, { Fragment } from 'react'; import React, { Fragment } from 'react';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import { Button, Modal, ModalHeader, ModalBody, ModalFooter, Table } from 'reactstrap'; import { Button, Modal, ModalHeader, ModalBody, ModalFooter, Table, Input, Label, FormGroup } from 'reactstrap';
import { Utils } from '../../utils/utils'; import { Utils } from '../../utils/utils';
import { gettext } from '../../utils/constants'; import { gettext } from '../../utils/constants';
import { seafileAPI } from '../../utils/seafile-api'; import { seafileAPI } from '../../utils/seafile-api';
@@ -31,7 +31,8 @@ class ManageMembersDialog extends React.Component {
hasNextPage: false, hasNextPage: false,
selectedOption: null, selectedOption: null,
errMessage: [], errMessage: [],
isItemFreezed: false isItemFreezed: false,
searchGroupMemberInputValue: '',
}; };
} }
@@ -49,7 +50,7 @@ class ManageMembersDialog extends React.Component {
isLoadingMore: false, isLoadingMore: false,
page: page, page: page,
hasNextPage: members.length < perPage ? false : true, hasNextPage: members.length < perPage ? false : true,
groupMembers: groupMembers.concat(members) groupMembers: groupMembers.concat(members)
}); });
}).catch(error => { }).catch(error => {
let errMessage = Utils.getErrorMsg(error); let errMessage = Utils.getErrorMsg(error);
@@ -92,6 +93,24 @@ class ManageMembersDialog extends React.Component {
}); });
} }
handleSearchGroupMemberInputChange = (e) => {
this.setState({
searchGroupMemberInputValue: e.target.value
});
}
searchGroupMember = () => {
seafileAPI.searchGroupMember(this.props.groupID, this.state.searchGroupMemberInputValue).then((res) => {
this.setState({
groupMembers: res.data,
});
}).catch(error => {
let errMessage = Utils.getErrorMsg(error);
toaster.danger(errMessage);
});
}
toggleItemFreezed = (isFreezed) => { toggleItemFreezed = (isFreezed) => {
this.setState({ this.setState({
isItemFreezed: isFreezed isItemFreezed: isFreezed
@@ -112,10 +131,10 @@ class ManageMembersDialog extends React.Component {
const isBottom = (clientHeight + scrollTop + 1 >= scrollHeight); const isBottom = (clientHeight + scrollTop + 1 >= scrollHeight);
if (isBottom) { // scroll to the bottom if (isBottom) { // scroll to the bottom
this.setState({isLoadingMore: true}, () => { this.setState({isLoadingMore: true}, () => {
this.listGroupMembers(page + 1); this.listGroupMembers(page + 1);
}); });
} }
} }
} }
changeMember = (targetMember) => { changeMember = (targetMember) => {
@@ -143,20 +162,39 @@ class ManageMembersDialog extends React.Component {
<Modal isOpen={true} toggle={this.toggle}> <Modal isOpen={true} toggle={this.toggle}>
<ModalHeader toggle={this.toggle}>{gettext('Manage group members')}</ModalHeader> <ModalHeader toggle={this.toggle}>{gettext('Manage group members')}</ModalHeader>
<ModalBody> <ModalBody>
<p>{gettext('Add group member')}</p> <FormGroup>
<div className='add-members'> <p>{gettext('Add group member')}</p>
<UserSelect <div className='add-members'>
placeholder={gettext('Search users...')} <UserSelect
onSelectChange={this.onSelectChange} placeholder={gettext('Search users...')}
ref="userSelect" onSelectChange={this.onSelectChange}
isMulti={true} ref="userSelect"
className="add-members-select" isMulti={true}
/> className="add-members-select"
{this.state.selectedOption ? />
<Button color="secondary" onClick={this.addGroupMember}>{gettext('Submit')}</Button> : {this.state.selectedOption ?
<Button color="secondary" disabled>{gettext('Submit')}</Button> <Button color="secondary" onClick={this.addGroupMember}>{gettext('Submit')}</Button> :
} <Button color="secondary" disabled>{gettext('Submit')}</Button>
</div> }
</div>
</FormGroup>
<FormGroup>
<p>{gettext('Search group member')}</p>
<div className="search-members">
<Input
type="text"
id="search-member"
className="form-control search-members-input"
value={this.state.searchGroupMemberInputValue}
onChange={this.handleSearchGroupMemberInputChange}
placeholder={gettext('Search users...')}
/>
{this.state.searchGroupMemberInputValue ?
<Button color="secondary" onClick={this.searchGroupMember}>{gettext('Search')}</Button> :
<Button color="secondary" disabled>{gettext('Search')}</Button>
}
</div>
</FormGroup>
{ {
this.state.errMessage.length > 0 && this.state.errMessage.length > 0 &&
this.state.errMessage.map((item, index = 0) => { this.state.errMessage.map((item, index = 0) => {

View File

@@ -33,17 +33,22 @@
display: none; display: none;
} }
.add-members { .add-members,
.search-members {
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;
} }
.add-members .add-members-select { .add-members .add-members-select,
.search-members .search-members-input {
width: 385px; width: 385px;
} }
.add-members .btn {
.add-members .btn,
.search-members .btn {
width: 75px; width: 75px;
} }
.group-error { .group-error {
margin-top: 10px; margin-top: 10px;
} }

View File

@@ -133,10 +133,42 @@ class GroupMembers(APIView):
return Response(member_info, status=status.HTTP_201_CREATED) return Response(member_info, status=status.HTTP_201_CREATED)
class GroupSearchMember(APIView):
authentication_classes = (TokenAuthentication, SessionAuthentication)
permission_classes = (IsAuthenticated,)
throttle_classes = (UserRateThrottle,)
@api_check_group
def get(self, request, group_id, format=None):
"""
Search group member by email.
"""
q = request.GET.get('q', '')
if not q:
error_msg = 'q invalid.'
return api_error(status.HTTP_400_BAD_REQUEST, error_msg)
if not is_group_member(group_id, request.user.username):
error_msg = 'Permission denied.'
return api_error(status.HTTP_403_FORBIDDEN, error_msg)
group_members = []
members = ccnet_api.search_group_members(group_id, q)
for member in members:
member_info = get_group_member_info(request, group_id, member.user_name)
group_members.append(member_info)
return Response(group_members)
class GroupMember(APIView): class GroupMember(APIView):
authentication_classes = (TokenAuthentication, SessionAuthentication) authentication_classes = (TokenAuthentication, SessionAuthentication)
permission_classes = (IsAuthenticated,) permission_classes = (IsAuthenticated,)
throttle_classes = (UserRateThrottle, ) throttle_classes = (UserRateThrottle,)
@api_check_group @api_check_group
def get(self, request, group_id, email): def get(self, request, group_id, email):

View File

@@ -36,7 +36,7 @@ from seahub.api2.endpoints.group_owned_libraries import GroupOwnedLibraries, \
from seahub.api2.endpoints.address_book.groups import AddressBookGroupsSubGroups from seahub.api2.endpoints.address_book.groups import AddressBookGroupsSubGroups
from seahub.api2.endpoints.address_book.members import AddressBookGroupsSearchMember from seahub.api2.endpoints.address_book.members import AddressBookGroupsSearchMember
from seahub.api2.endpoints.group_members import GroupMembers, GroupMember, \ from seahub.api2.endpoints.group_members import GroupMembers, GroupSearchMember, GroupMember, \
GroupMembersBulk, GroupMembersImport, GroupMembersImportExample GroupMembersBulk, GroupMembersImport, GroupMembersImportExample
from seahub.api2.endpoints.search_group import SearchGroup from seahub.api2.endpoints.search_group import SearchGroup
from seahub.api2.endpoints.share_links import ShareLinks, ShareLink, \ from seahub.api2.endpoints.share_links import ShareLinks, ShareLink, \
@@ -307,6 +307,7 @@ urlpatterns = [
url(r'^api/v2.1/groups/(?P<group_id>\d+)/group-owned-libraries/$', GroupOwnedLibraries.as_view(), name='api-v2.1-group-owned-libraries'), url(r'^api/v2.1/groups/(?P<group_id>\d+)/group-owned-libraries/$', GroupOwnedLibraries.as_view(), name='api-v2.1-group-owned-libraries'),
url(r'^api/v2.1/groups/(?P<group_id>\d+)/group-owned-libraries/(?P<repo_id>[-0-9a-f]{36})/$', GroupOwnedLibrary.as_view(), name='api-v2.1-owned-group-library'), url(r'^api/v2.1/groups/(?P<group_id>\d+)/group-owned-libraries/(?P<repo_id>[-0-9a-f]{36})/$', GroupOwnedLibrary.as_view(), name='api-v2.1-owned-group-library'),
url(r'^api/v2.1/groups/(?P<group_id>\d+)/members/$', GroupMembers.as_view(), name='api-v2.1-group-members'), url(r'^api/v2.1/groups/(?P<group_id>\d+)/members/$', GroupMembers.as_view(), name='api-v2.1-group-members'),
url(r'^api/v2.1/groups/(?P<group_id>\d+)/search-member/$', GroupSearchMember.as_view(), name='api-v2.1-group-search-member'),
url(r'^api/v2.1/groups/(?P<group_id>\d+)/members/bulk/$', GroupMembersBulk.as_view(), name='api-v2.1-group-members-bulk'), url(r'^api/v2.1/groups/(?P<group_id>\d+)/members/bulk/$', GroupMembersBulk.as_view(), name='api-v2.1-group-members-bulk'),
url(r'^api/v2.1/groups/(?P<group_id>\d+)/members/import/$', GroupMembersImport.as_view(), name='api-v2.1-group-members-import'), url(r'^api/v2.1/groups/(?P<group_id>\d+)/members/import/$', GroupMembersImport.as_view(), name='api-v2.1-group-members-import'),
url(r'^api/v2.1/group-members-import-example/$', GroupMembersImportExample.as_view(), name='api-v2.1-group-members-import-example'), url(r'^api/v2.1/group-members-import-example/$', GroupMembersImportExample.as_view(), name='api-v2.1-group-members-import-example'),