mirror of
https://github.com/documize/community.git
synced 2025-07-20 13:49:42 +02:00
join and leave group persistence
This commit is contained in:
parent
0680a72ee2
commit
e4d78904dc
6 changed files with 161 additions and 34 deletions
|
@ -243,3 +243,107 @@ func (h *Handler) GetGroupMembers(w http.ResponseWriter, r *http.Request) {
|
||||||
|
|
||||||
response.WriteJSON(w, m)
|
response.WriteJSON(w, m)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// JoinGroup adds user to group.
|
||||||
|
func (h *Handler) JoinGroup(w http.ResponseWriter, r *http.Request) {
|
||||||
|
method := "group.JoinGroup"
|
||||||
|
ctx := domain.GetRequestContext(r)
|
||||||
|
|
||||||
|
// Should be no reason for non-admin to see members
|
||||||
|
if !ctx.Administrator {
|
||||||
|
response.WriteForbiddenError(w)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
groupID := request.Param(r, "groupID")
|
||||||
|
if len(groupID) == 0 {
|
||||||
|
response.WriteMissingDataError(w, method, "groupID")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
userID := request.Param(r, "userID")
|
||||||
|
if len(userID) == 0 {
|
||||||
|
response.WriteMissingDataError(w, method, "userID")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
var err error
|
||||||
|
|
||||||
|
ctx.Transaction, err = h.Runtime.Db.Beginx()
|
||||||
|
if err != nil {
|
||||||
|
response.WriteServerError(w, method, err)
|
||||||
|
h.Runtime.Log.Error(method, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// safety first
|
||||||
|
err = h.Store.Group.LeaveGroup(ctx, groupID, userID)
|
||||||
|
if err != nil {
|
||||||
|
ctx.Transaction.Rollback()
|
||||||
|
response.WriteServerError(w, method, err)
|
||||||
|
h.Runtime.Log.Error(method, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// now we can join group
|
||||||
|
err = h.Store.Group.JoinGroup(ctx, groupID, userID)
|
||||||
|
if err != nil {
|
||||||
|
ctx.Transaction.Rollback()
|
||||||
|
response.WriteServerError(w, method, err)
|
||||||
|
h.Runtime.Log.Error(method, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx.Transaction.Commit()
|
||||||
|
|
||||||
|
h.Store.Audit.Record(ctx, audit.EventTypeGroupJoin)
|
||||||
|
|
||||||
|
response.WriteEmpty(w)
|
||||||
|
}
|
||||||
|
|
||||||
|
// LeaveGroup removes user to group.
|
||||||
|
func (h *Handler) LeaveGroup(w http.ResponseWriter, r *http.Request) {
|
||||||
|
method := "group.LeaveGroup"
|
||||||
|
ctx := domain.GetRequestContext(r)
|
||||||
|
|
||||||
|
// Should be no reason for non-admin to see members
|
||||||
|
if !ctx.Administrator {
|
||||||
|
response.WriteForbiddenError(w)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
groupID := request.Param(r, "groupID")
|
||||||
|
if len(groupID) == 0 {
|
||||||
|
response.WriteMissingDataError(w, method, "groupID")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
userID := request.Param(r, "userID")
|
||||||
|
if len(userID) == 0 {
|
||||||
|
response.WriteMissingDataError(w, method, "userID")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
var err error
|
||||||
|
|
||||||
|
ctx.Transaction, err = h.Runtime.Db.Beginx()
|
||||||
|
if err != nil {
|
||||||
|
response.WriteServerError(w, method, err)
|
||||||
|
h.Runtime.Log.Error(method, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
err = h.Store.Group.LeaveGroup(ctx, groupID, userID)
|
||||||
|
if err != nil {
|
||||||
|
ctx.Transaction.Rollback()
|
||||||
|
response.WriteServerError(w, method, err)
|
||||||
|
h.Runtime.Log.Error(method, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx.Transaction.Commit()
|
||||||
|
|
||||||
|
h.Store.Audit.Record(ctx, audit.EventTypeGroupLeave)
|
||||||
|
|
||||||
|
response.WriteEmpty(w)
|
||||||
|
}
|
||||||
|
|
|
@ -120,3 +120,24 @@ func (s Scope) GetGroupMembers(ctx domain.RequestContext, groupID string) (membe
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// JoinGroup adds user to group.
|
||||||
|
func (s Scope) JoinGroup(ctx domain.RequestContext, groupID, userID string) (err error) {
|
||||||
|
_, err = ctx.Transaction.Exec("INSERT INTO rolemember (orgid, roleid, userid) VALUES (?, ?, ?)", ctx.OrgID, groupID, userID)
|
||||||
|
if err != nil {
|
||||||
|
err = errors.Wrap(err, "insert group member")
|
||||||
|
}
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// LeaveGroup removes user from group.
|
||||||
|
func (s Scope) LeaveGroup(ctx domain.RequestContext, groupID, userID string) (err error) {
|
||||||
|
b := mysql.BaseQuery{}
|
||||||
|
_, err = b.DeleteWhere(ctx.Transaction, fmt.Sprintf("DELETE FROM rolemember WHERE orgid=\"%s\" AND roleid=\"%s\" AND userid=\"%s\"", ctx.OrgID, groupID, userID))
|
||||||
|
if err != nil {
|
||||||
|
err = errors.Wrap(err, "clear group member")
|
||||||
|
}
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
|
@ -277,4 +277,6 @@ type GroupStorer interface {
|
||||||
Update(ctx RequestContext, g group.Group) (err error)
|
Update(ctx RequestContext, g group.Group) (err error)
|
||||||
Delete(ctx RequestContext, refID string) (rows int64, err error)
|
Delete(ctx RequestContext, refID string) (rows int64, err error)
|
||||||
GetGroupMembers(ctx RequestContext, groupID string) (m []group.Member, err error)
|
GetGroupMembers(ctx RequestContext, groupID string) (m []group.Member, err error)
|
||||||
|
JoinGroup(ctx RequestContext, groupID, userID string) (err error)
|
||||||
|
LeaveGroup(ctx RequestContext, groupID, userID string) (err error)
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,11 +28,11 @@ export default Component.extend(AuthProvider, ModalMixin, {
|
||||||
|
|
||||||
didReceiveAttrs() {
|
didReceiveAttrs() {
|
||||||
this._super(...arguments);
|
this._super(...arguments);
|
||||||
this.load();
|
this.loadGroups();
|
||||||
this.setDefaults();
|
this.setDefaults();
|
||||||
},
|
},
|
||||||
|
|
||||||
load() {
|
loadGroups() {
|
||||||
this.get('groupSvc').getAll().then((groups) => {
|
this.get('groupSvc').getAll().then((groups) => {
|
||||||
this.set('groups', groups);
|
this.set('groups', groups);
|
||||||
});
|
});
|
||||||
|
@ -42,34 +42,26 @@ export default Component.extend(AuthProvider, ModalMixin, {
|
||||||
this.set('newGroup', { name: '', purpose: '' });
|
this.set('newGroup', { name: '', purpose: '' });
|
||||||
},
|
},
|
||||||
|
|
||||||
loadUsers(searchText) {
|
loadGroupInfo() {
|
||||||
this.get('userSvc').matchUsers(searchText).then((users) => {
|
let groupId = this.get('membersGroup.id');
|
||||||
let members = this.get('members');
|
let searchText = this.get('searchText');
|
||||||
|
|
||||||
if (members.length > 0) {
|
this.get('groupSvc').getGroupMembers(groupId).then((members) => {
|
||||||
|
this.set('members', members);
|
||||||
|
|
||||||
|
this.get('userSvc').matchUsers(searchText).then((users) => {
|
||||||
users.forEach((user) => {
|
users.forEach((user) => {
|
||||||
let m = members.findBy('userId', user.get('id'));
|
let m = members.findBy('userId', user.get('id'));
|
||||||
user.set('isMember', is.not.undefined(m));
|
user.set('isMember', is.not.undefined(m));
|
||||||
})
|
})
|
||||||
}
|
|
||||||
|
|
||||||
this.set('users', users);
|
if (this.get('showMembers') && members.length === 0) {
|
||||||
});
|
this.set('showMembers', false);
|
||||||
},
|
this.set('showUsers', true);
|
||||||
|
}
|
||||||
|
|
||||||
loadMembers(groupId) {
|
this.set('users', users);
|
||||||
this.get('groupSvc').getGroupMembers(groupId).then((members) => {
|
});
|
||||||
this.set('members', members);
|
|
||||||
|
|
||||||
// if we have no members, then prefetch users (server should limit to top 100 users)
|
|
||||||
if (members.length === 0) {
|
|
||||||
this.loadUsers('');
|
|
||||||
this.set('showMembers', false);
|
|
||||||
this.set('showUsers', true);
|
|
||||||
} else {
|
|
||||||
this.set('showMembers', true);
|
|
||||||
this.set('showUsers', false);
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -148,20 +140,20 @@ export default Component.extend(AuthProvider, ModalMixin, {
|
||||||
this.modalOpen("#group-members-modal", {"show": true}, '#group-members-search');
|
this.modalOpen("#group-members-modal", {"show": true}, '#group-members-search');
|
||||||
this.set('members', null);
|
this.set('members', null);
|
||||||
this.set('users', null);
|
this.set('users', null);
|
||||||
this.loadMembers(groupId);
|
this.set('showMembers', true);
|
||||||
|
this.set('showUsers', false);
|
||||||
|
this.loadGroupInfo();
|
||||||
},
|
},
|
||||||
|
|
||||||
onSearch() {
|
onSearch() {
|
||||||
debounce(this, function() {
|
debounce(this, function() {
|
||||||
let searchText = this.get('searchText');
|
let searchText = this.get('searchText');
|
||||||
let groupId = this.get('membersGroup.id');
|
this.loadGroupInfo();
|
||||||
|
|
||||||
if (is.not.empty(searchText)) {
|
if (is.not.empty(searchText)) {
|
||||||
this.loadUsers(searchText);
|
|
||||||
this.set('showMembers', false);
|
this.set('showMembers', false);
|
||||||
this.set('showUsers', true);
|
this.set('showUsers', true);
|
||||||
} else {
|
} else {
|
||||||
this.loadMembers(groupId);
|
|
||||||
this.set('showMembers', true);
|
this.set('showMembers', true);
|
||||||
this.set('showUsers', false);
|
this.set('showUsers', false);
|
||||||
}
|
}
|
||||||
|
@ -169,14 +161,20 @@ export default Component.extend(AuthProvider, ModalMixin, {
|
||||||
},
|
},
|
||||||
|
|
||||||
onLeaveGroup(userId) {
|
onLeaveGroup(userId) {
|
||||||
this.get('groupSvc').leave(this.get('membersGroup.id'), userId).then(() => {
|
let groupId = this.get('membersGroup.id');
|
||||||
this.load();
|
|
||||||
|
this.get('groupSvc').leave(groupId, userId).then(() => {
|
||||||
|
this.loadGroupInfo();
|
||||||
|
this.loadGroups();
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
onJoinGroup(userId) {
|
onJoinGroup(userId) {
|
||||||
this.get('groupSvc').join(this.get('membersGroup.id'), userId).then(() => {
|
let groupId = this.get('membersGroup.id');
|
||||||
this.load();
|
|
||||||
|
this.get('groupSvc').join(groupId, userId).then(() => {
|
||||||
|
this.loadGroupInfo();
|
||||||
|
this.loadGroups();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -110,7 +110,7 @@
|
||||||
<div id="group-members-modal" class="modal" tabindex="-1" role="dialog">
|
<div id="group-members-modal" class="modal" tabindex="-1" role="dialog">
|
||||||
<div class="modal-dialog modal-lg" role="document">
|
<div class="modal-dialog modal-lg" role="document">
|
||||||
<div class="modal-content">
|
<div class="modal-content">
|
||||||
<div class="modal-header">{{membersGroup.name}}</div>
|
<div class="modal-header">{{membersGroup.name}} ({{members.length}})</div>
|
||||||
<div class="modal-body">
|
<div class="modal-body">
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="group-members-search">Search for group members, non-members</label>
|
<label for="group-members-search">Search for group members, non-members</label>
|
||||||
|
|
|
@ -77,4 +77,6 @@ const (
|
||||||
EventTypeGroupAdd EventType = "added-group"
|
EventTypeGroupAdd EventType = "added-group"
|
||||||
EventTypeGroupDelete EventType = "removed-group"
|
EventTypeGroupDelete EventType = "removed-group"
|
||||||
EventTypeGroupUpdate EventType = "updated-group"
|
EventTypeGroupUpdate EventType = "updated-group"
|
||||||
|
EventTypeGroupJoin EventType = "joined-group"
|
||||||
|
EventTypeGroupLeave EventType = "left-group"
|
||||||
)
|
)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue