diff --git a/accounts/forms.py b/accounts/forms.py index b037d0c..d772a28 100644 --- a/accounts/forms.py +++ b/accounts/forms.py @@ -9,7 +9,7 @@ __all__ = ['UserForm', 'GroupForm', 'TeamForm'] UserForm = modelform_factory(User, fields=['username', 'first_name', - 'last_name', 'password', 'email', 'is_superuser'], + 'last_name', 'email', 'is_superuser'], widgets={'password': PasswordInput}) GroupForm = modelform_factory(Group, fields=['name']) diff --git a/accounts/static/js/accounts.js b/accounts/static/js/accounts.js index d885039..bca8d21 100644 --- a/accounts/static/js/accounts.js +++ b/accounts/static/js/accounts.js @@ -8,19 +8,23 @@ $('a[role="remove"]').on("click", function () { a.html('removing...'); $.ajax(href) .done(function(data, textStatus) { - a.parents('li').remove(); - var counter = $('#' + type + '-counter'); - var empty = $('#' + type + '-empty'); - var count = parseInt(counter.html()); - count--; - counter.html(count); - if (count < 0) { - // should not happen - window.location.reload(); - } else if (count == 0) { - empty.removeClass('hidden'); + if (data) { + a.parents('span').html(data); } else { - empty.addClass('hidden'); + a.parents('li').remove(); + var counter = $('#' + type + '-counter'); + var empty = $('#' + type + '-empty'); + var count = parseInt(counter.html()); + count--; + counter.html(count); + if (count < 0) { + // should not happen + window.location.reload(); + } else if (count == 0) { + empty.removeClass('hidden'); + } else { + empty.addClass('hidden'); + } } }) .fail(function () { diff --git a/accounts/static/js/team.js b/accounts/static/js/tabswitch.js similarity index 66% rename from accounts/static/js/team.js rename to accounts/static/js/tabswitch.js index 8e4f0fc..67f60ff 100644 --- a/accounts/static/js/team.js +++ b/accounts/static/js/tabswitch.js @@ -1,13 +1,8 @@ /* This script switch the visible add form when we * change between user and group tab on team page. */ $('a[data-toggle="tab"]').on("show.bs.tab", function () { - var tab = $(this).data('tab'); - var hiddentab; - if (tab == 'user') { - hiddentab = 'group'; - } else { - hiddentab = 'user'; - } + var tab = $(this).data('showtab'); + var hiddentab = $(this).data('hidetab'); $('#add-' + hiddentab + '-form').addClass('hidden'); $('#add-' + tab + '-form').removeClass('hidden'); }); diff --git a/accounts/urls.py b/accounts/urls.py index a9ef55e..ec1aa86 100644 --- a/accounts/urls.py +++ b/accounts/urls.py @@ -7,10 +7,15 @@ urlpatterns = [ # Users url(r'^admin/users/$', 'accounts.views.user_list', name='list-user'), url(r'^admin/users/add/$', 'accounts.views.user_edit', name='add-user'), + url(r'^admin/users/(?P[0-9]+)/$', 'accounts.views.user_details', name='show-user'), url(r'^admin/users/(?P[0-9]+)/edit/$', 'accounts.views.user_edit', name='edit-user'), url(r'^admin/users/(?P[0-9]+)/delete/$', 'accounts.views.user_delete', name='delete-user'), url(r'^admin/users/(?P[0-9]+)/activate/$', 'accounts.views.user_activate', name='activate-user'), url(r'^admin/users/(?P[0-9]+)/disable/$', 'accounts.views.user_disable', name='disable-user'), + url(r'^admin/users/(?P[0-9]+)/add-group/$', 'accounts.views.user_add_group', name='add-group-to-user'), + url(r'^admin/users/(?P[0-9]+)/remove-group/(?P[0-9]+)/$', 'accounts.views.user_remove_group', name='remove-group-from-user'), + url(r'^admin/users/(?P[0-9]+)/add-team/$', 'accounts.views.user_add_team', name='add-team-to-user'), + url(r'^admin/users/(?P[0-9]+)/remove-team/(?P[0-9]+)/$', 'accounts.views.user_remove_team', name='remove-team-from-user'), # Groups url(r'^admin/groups/$', 'accounts.views.group_list', name='list-group'), url(r'^admin/groups/add/$', 'accounts.views.group_edit', name='add-group'), diff --git a/accounts/views.py b/accounts/views.py index 060339f..0333329 100644 --- a/accounts/views.py +++ b/accounts/views.py @@ -33,6 +33,16 @@ def user_list(request): }) +@project_perm_required('manage_user') +def user_details(request, user): + tab = request.session.pop('user-tab', 'group') + return render(request, 'accounts/user_details.html', { + 'user': get_object_or_404(User, id=user), + 'directteams': Team.objects.filter(users__id=user), + 'tab': tab, + }) + + @project_perm_required('manage_user') def user_edit(request, user=None): @@ -41,12 +51,12 @@ def user_edit(request, user=None): form = UserForm(request.POST or None, instance=user) if request.method == 'POST' and form.is_valid(): - form.save() + user = form.save() if user: messages.success(request, 'User modified successfully.') else: messages.success(request, 'User added successfully.') - return redirect('list-user') + return redirect('show-user', user.id) return render(request, 'accounts/user_edit.html', { 'user': user, @@ -63,7 +73,7 @@ def user_activate(request, user): user.is_active = True user.save() messages.success(request, 'Account activated successfully.') - return redirect('list-user') + return redirect('show-user', user.id) @project_perm_required('manage_user') @@ -75,7 +85,7 @@ def user_disable(request, user): messages.success(request, 'Account disabled successfully.') else: messages.info(request, 'Account already disabled.') - return redirect('list-user') + return redirect('show-user', user.id) @require_http_methods(["POST"]) @@ -87,6 +97,106 @@ def user_delete(request, user): return redirect('list-user') +@project_perm_required('manage_user') +def user_add_group(request, user): + user = get_object_or_404(User, id=user) + if request.method == 'POST': + group = request.POST.get('group') + if group: + try: + group = Group.objects.get(name=group) + except ObjectDoesNotExist: + messages.error(request, 'Group not found.') + else: + if user.groups.filter(id=group.id).exists(): + messages.info(request, 'User already in group.') + else: + user.groups.add(group) + user.save() + messages.success(request, + 'User added to group successfully.') + else: + messages.error(request, 'Group not found.') + request.session['user-tab'] = 'group' + return redirect('show-user', user.id) + else: + term = request.GET.get('term') + if not term: + return Http404() + groups = Group.objects \ + .exclude(id__in=user.groups.values('id')) \ + .filter(name__icontains=term)[:10] + response = [] + for group in groups: + response += [{ + 'label': group.name, + 'value': group.name, + }] + return JsonResponse(response, safe=False) + + +@project_perm_required('manage_user') +def user_remove_group(request, user, group): + user = get_object_or_404(User, pk=user) + group = get_object_or_404(Group, pk=group) + user.groups.remove(group) + user.save() + return HttpResponse() + + +@project_perm_required('manage_user') +def user_add_team(request, user): + user = get_object_or_404(User, id=user) + if request.method == 'POST': + team = request.POST.get('team') + if team: + try: + team = Team.objects.get(name=team) + except ObjectDoesNotExist: + messages.error(request, 'Team not found.') + else: + # We do not use user.teams because we want to be able to add an + # user to a team even if he is already a member through a group + if Team.objects.filter(users=user).exists(): + messages.info(request, 'User already in team.') + else: + team.users.add(user) + team.save() + messages.success(request, + 'User added to team successfully.') + else: + messages.error(request, 'Team not found.') + request.session['user-tab'] = 'team' + return redirect('show-user', user.id) + else: + term = request.GET.get('term') + if not term: + return Http404() + teams = Team.objects \ + .exclude(users=user) \ + .filter(name__icontains=term)[:10] + response = [] + for team in teams: + response += [{ + 'label': team.name, + 'value': team.name, + }] + return JsonResponse(response, safe=False) + + +@project_perm_required('manage_user') +def user_remove_team(request, user, team): + user = get_object_or_404(User, pk=user) + team = get_object_or_404(Team, pk=team) + team.users.remove(user) + team.save() + response = '' + if team.groups.filter(id__in=user.groups.values('id')).exists(): + # style a member throught a group + response = 'member throught group' + return HttpResponse(response) + + ########## # Groups # ########## diff --git a/templates/accounts/group_list.html b/templates/accounts/group_list.html index b6dbe77..00dc81d 100644 --- a/templates/accounts/group_list.html +++ b/templates/accounts/group_list.html @@ -14,16 +14,22 @@ diff --git a/templates/accounts/team_details.html b/templates/accounts/team_details.html index b600825..9773856 100644 --- a/templates/accounts/team_details.html +++ b/templates/accounts/team_details.html @@ -34,8 +34,8 @@