diff --git a/wger/core/static/js/app.js b/wger/core/static/js/app.js new file mode 100644 index 0000000..67d8076 --- /dev/null +++ b/wger/core/static/js/app.js @@ -0,0 +1,8 @@ +$(document).ready( function () { + /* Make table sortable */ + $('#main_member_list').DataTable({ + paging: false, + bFilter: true, + bInfo : false + }); +}); diff --git a/wger/core/views/user.py b/wger/core/views/user.py index f335a81..896b574 100644 --- a/wger/core/views/user.py +++ b/wger/core/views/user.py @@ -526,6 +526,7 @@ def get_context_data(self, **kwargs): _('Username'), _('Name'), _('Last activity'), - _('Gym')], + _('Gym'), + _('Status')], 'users': context['object_list']['members']} return context diff --git a/wger/gym/templates/gym/active_gym_users_list.html b/wger/gym/templates/gym/active_gym_users_list.html new file mode 100644 index 0000000..f074035 --- /dev/null +++ b/wger/gym/templates/gym/active_gym_users_list.html @@ -0,0 +1,62 @@ +{% load i18n staticfiles %} + + + + + + + + + + {% for key in user_table.keys %} + + {% endfor %} + + + + + {% for current_user in user_table.users %} + {% if current_user.obj.is_active %} + + + + + + {% if show_gym %} + + {% endif %} + + + {% endif %} + {% endfor %} + +
{{ key }}
+ {{current_user.obj.pk}} + + {{current_user.obj}} + + {{current_user.obj.get_full_name}} + + {{current_user.last_log|default:'-/-'}} + + {% if current_user.obj.userprofile.gym_id %} + + {{ current_user.obj.userprofile.gym }} + + {% else %} + -/- + {% endif %} + + + + Active +
diff --git a/wger/gym/templates/gym/inactive_gym_users_list.html b/wger/gym/templates/gym/inactive_gym_users_list.html new file mode 100644 index 0000000..50840d9 --- /dev/null +++ b/wger/gym/templates/gym/inactive_gym_users_list.html @@ -0,0 +1,376 @@ +{% extends "base.html" %} +{% load i18n staticfiles wger_extras django_bootstrap_breadcrumbs %} + +{% block title %}{{gym}}{% endblock %} + +{% block breadcrumbs %} + {{ block.super }} + + {% if perms.gym.manage_gyms %} + {% breadcrumb "Gyms" "gym:gym:list" %} + {% breadcrumb_raw gym "gym:gym:user-list" gym.pk %} + {% breadcrumb_raw name "gym:gym:inactive-user-list" gym.pk %} + {% endif %} +{% endblock %} + +{% block content %} +{% if perms.gym.manage_gym or perms.gym.gym_trainer %} + + + + + + + + + + {% for key in user_table.keys %} + + {% endfor %} + + + + +{% for current_user in user_table.users %} +{% if not current_user.obj.is_active %} + + + + + + {% if show_gym %} + + {% endif %} + + +{% endif %} +{% endfor %} + +
{{ key }}
+ {{current_user.obj.pk}} + + {{current_user.obj}} + + {{current_user.obj.get_full_name}} + + {{current_user.last_log|default:'-/-'}} + + {% if current_user.obj.userprofile.gym_id %} + + {{ current_user.obj.userprofile.gym }} + + {% else %} + -/- + {% endif %} + + + + Inactive +
+{% endif %} + + +

{% trans "Administrators and trainers" %}

+ + + + + + + {% if perms.gym.manage_gym or perms.gym.manage_gyms %} + + {% endif %} + + + +{% for current_user in object_list.admins %} + + + + + + {% if perms.gym.manage_gym or perms.gym.manage_gyms %} + + {% endif %} + +{% empty %} + + + +{% endfor %} + +
{% trans "ID" %}{% trans "Username" %}{% trans "Name" %}{% trans "Roles" %}
+ {{current_user.obj.pk}} + + {{current_user.obj}} + + {% if current_user.perms.gym_trainer %} + {% trans "Trainer" %} + {% endif %} + + {% if current_user.perms.manage_gym %} + {% trans "Gym manager" %} + {% endif %} + + {% if current_user.perms.manage_gyms %} + {% trans "General manager" %} + {% endif %} + + {{current_user.obj.get_full_name}} + + + + +
{% trans "This gym has no administrators or trainers" %}
+{% endblock %} + + +{% block sidebar %} +{# #} +{# Gym details #} +{# #} +{% if perms.gym.change_gym %} +
+ + +
+{% endif %} + +

{% trans "Details" %}

+ + + + + + + + + + + + + + + + + + + + + + + + + +
{% trans "Name" %}{{gym.name}}
{% trans "Phone" %}{{gym.phone}}
{% trans "Email" %} + {% if gym.email %} + {{gym.email}} + {% else %} + -/- + {% endif %} +
{% trans "Owner" %}{{gym.owner}}
{% trans "Address" %} + {{gym.zip_code}} {{gym.city}}
+ {{gym.street}} +
{% trans "Members" %}{{user_count}}
+ + +{# #} +{# Gym configuration #} +{# #} +{% if perms.gym.change_gymconfig %} +
+ + +
+{% endif %} + +

{% trans "Gym configuration" %}

+ + + + + +
{% trans "Inactive members" %}{{gym.config.weeks_inactive}} {% trans 'weeks' %}
+ + + + +{# #} +{# Admin configuration #} +{# #} +{% if user.gymadminconfig and user.userprofile.gym_id == gym.id %} +
+ + +
+ +

{% trans "My configuration" %}

+ + + + + +
{% trans "Overview of inactive members" %} + {% if user.gymadminconfig.overview_inactive %} + + {% else %} + + {% endif %} +
+{% endif %} + + + +{# #} +{# Contract configuration #} +{# #} +{% if perms.gym.change_contracttype or perms.gym.change_contractoption %} +

{% trans "Contracts" %}

+{% endif %} +{% if perms.gym.change_contracttype %} +
+ + +
+ +
{% trans "Types" %}
+ + {% for contract_type in gym.contracttype_set.all %} + + + + + {% empty %} + + + + {% endfor %} +
+ {{ contract_type }} + + {{ contract_type.description|truncatewords:15 }} +
+ {% trans "Nothing found" %} +
+{% endif %} + + +{% if perms.gym.change_contractoption %} +
+ + +
+ +
{% trans "Options" %}
+ + {% for option in gym.contractoption_set.all %} + + + + + {% empty %} + + + + {% endfor %} +
+ {{ option }} + + {{ option.description|truncatewords:15 }} +
+ {% trans "Nothing found" %} +
+{% endif %} + + + +{# #} +{# Email lists #} +{# #} +{% if perms.email.change_log %} +
+ + +
+ +

{% trans "Emails" %}

+ + {% for email in gym.email_log.all %} + + + + + {% empty %} + + + + {% endfor %} +
+ {{ email.date }} + + {{ email.subject|truncatewords:15 }} +
+ {% trans "Nothing found" %} +
+{% endif %} +{% endblock %} + +{# #} +{# Options #} +{# #} +{% block options %} +{% if perms.gym.manage_gym or perms.gym.manage_gyms %} + + {% trans "Add member" %} + +{% endif %} + +{% endblock %} diff --git a/wger/gym/templates/gym/member_list.html b/wger/gym/templates/gym/member_list.html index 2d7e2ac..0774354 100644 --- a/wger/gym/templates/gym/member_list.html +++ b/wger/gym/templates/gym/member_list.html @@ -8,17 +8,21 @@ {% if perms.gym.manage_gyms %} {% breadcrumb "Gyms" "gym:gym:list" %} - {% breadcrumb_raw gym "gym:gym:user-list" gym.pk %} + {% breadcrumb_raw name "gym:gym:user-list" gym.pk %} {% endif %} {% endblock %} {% block content %} {% if perms.gym.manage_gym or perms.gym.gym_trainer %} - {% include 'gym/partial_user_list.html' %} +

Click here to view inactive users

+ + {% include 'gym/active_gym_users_list.html' %} + {% endif %} +

{% trans "Administrators and trainers" %}

@@ -312,8 +316,6 @@

{% trans "Emails" %}

{% endif %} {% endblock %} - - {# #} {# Options #} {# #} diff --git a/wger/gym/templates/gym/partial_user_list.html b/wger/gym/templates/gym/partial_user_list.html index fe0532f..676226e 100644 --- a/wger/gym/templates/gym/partial_user_list.html +++ b/wger/gym/templates/gym/partial_user_list.html @@ -20,6 +20,7 @@ {% for key in user_table.keys %} {% endfor %} + @@ -48,6 +49,15 @@ {% endif %} {% endif %} + {% endfor %} diff --git a/wger/gym/urls.py b/wger/gym/urls.py index 38c4394..122716b 100644 --- a/wger/gym/urls.py +++ b/wger/gym/urls.py @@ -33,7 +33,6 @@ export ) - # 'sub patterns' for gyms patterns_gym = [ url(r'^list$', @@ -48,6 +47,9 @@ url(r'^(?P\d+)/members$', gym.GymUserListView.as_view(), name='user-list'), + url(r'^(?P\d+)/inactive-users$', + gym.GymInactiveUserListView.as_view(), + name='inactive-user-list'), url(r'^(?P\d+)/add-member$', gym.GymAddUserView.as_view(), name='add-user'), diff --git a/wger/gym/views/gym.py b/wger/gym/views/gym.py index 9d75d8b..2c44bd5 100644 --- a/wger/gym/views/gym.py +++ b/wger/gym/views/gym.py @@ -124,10 +124,66 @@ def get_context_data(self, **kwargs): ''' context = super(GymUserListView, self).get_context_data(**kwargs) context['gym'] = Gym.objects.get(pk=self.kwargs['pk']) + context['name'] = 'Active users' context['admin_count'] = len(context['object_list']['admins']) context['user_count'] = len(context['object_list']['members']) - context['user_table'] = {'keys': [_('ID'), _('Username'), _('Name'), _('Last activity')], - 'users': context['object_list']['members']} + context['user_table'] = {'keys': [_('ID'), _('Username'), _('Name'), _('Last activity'), _('Status')], + 'users': context['object_list']['members'], + "route": "active"} + return context + +class GymInactiveUserListView(LoginRequiredMixin, WgerMultiplePermissionRequiredMixin, ListView): + ''' + Overview of all inactive users for a specific gym + ''' + model = User + permission_required = ('gym.manage_gym', 'gym.gym_trainer', 'gym.manage_gyms') + template_name = 'gym/inactive_gym_users_list.html' + + def dispatch(self, request, *args, **kwargs): + ''' + Only managers and trainers for this gym can access the members + ''' + if request.user.has_perm('gym.manage_gyms') \ + or ((request.user.has_perm('gym.manage_gym') + or request.user.has_perm('gym.gym_trainer')) + and request.user.userprofile.gym_id == int(self.kwargs['pk'])): + return super(GymInactiveUserListView, self).dispatch(request, *args, **kwargs) + return HttpResponseForbidden() + + def get_queryset(self): + ''' + Return a list with the users, not really a queryset. + ''' + out = {'admins': [], + 'members': []} + + for u in Gym.objects.get_members(self.kwargs['pk']).select_related('usercache'): + out['members'].append({'obj': u, + 'last_log': u.usercache.last_activity}) + + # admins list + for u in Gym.objects.get_admins(self.kwargs['pk']): + out['admins'].append({'obj': u, + 'perms': {'manage_gym': u.has_perm('gym.manage_gym'), + 'manage_gyms': u.has_perm('gym.manage_gyms'), + 'gym_trainer': u.has_perm('gym.gym_trainer'), + 'any_admin': is_any_gym_admin(u)} + }) + return out + + def get_context_data(self, **kwargs): + ''' + Pass other info to the template + ''' + context = super(GymInactiveUserListView, self).get_context_data(**kwargs) + context['gym'] = Gym.objects.get(pk=self.kwargs['pk']) + context['name'] = 'Inactive users' + context['admin_count'] = len(context['object_list']['admins']) + context['user_count'] = len(context['object_list']['members']) + context['user_table'] = {'keys': [_('ID'), _('Username'), _('Name'), _('Last activity'), _('Status')], + 'users': context['object_list']['members'], + "route": "inactive"} return context
{{ key }}
+ {% if current_user.obj.is_active %} + + + Active + {% else %} + inactive + {% endif %} +