Skip to content

Commit

Permalink
Merge pull request #5201 from dimagi/paginate-web-users
Browse files Browse the repository at this point in the history
Paginate web users
  • Loading branch information
esoergel committed Jan 8, 2015
2 parents dcde360 + c1c0249 commit b5e7cd9
Show file tree
Hide file tree
Showing 9 changed files with 351 additions and 112 deletions.
10 changes: 7 additions & 3 deletions corehq/apps/hqwebapp/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -1028,10 +1028,14 @@ def web_username(request=None, couch_user=None, **context):
else:
return None

from corehq.apps.users.views import (EditWebUserView, EditMyAccountDomainView, ListWebUsersView)
from corehq.apps.users.views import (
EditWebUserView,
EditMyAccountDomainView,
get_web_user_list_view,
)
items.append((_('Project Users'), [
{'title': ListWebUsersView.page_title,
'url': reverse(ListWebUsersView.urlname, args=[self.domain]),
{'title': get_web_user_list_view(self._request).page_title,
'url': reverse(get_web_user_list_view(self._request).urlname, args=[self.domain]),
'description': _("Grant other CommCare HQ users access to your project and manage user roles."),
'subpages': [
{
Expand Down
1 change: 1 addition & 0 deletions corehq/apps/style/static/style/js/layout.js
Original file line number Diff line number Diff line change
Expand Up @@ -97,5 +97,6 @@ $(window).resize(function () {
});

$(window).scroll(function () {
hqLayout.actions.balanceSidebar();
hqLayout.actions.recheckFooterStatus();
});
66 changes: 52 additions & 14 deletions corehq/apps/users/static/users/js/web_users_list.ng.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,36 +9,74 @@
'ng.django.rmi'
]);

users.constant('webUsersConfig', {

});

var WebUser = function (data) {
var self = {};
var self = this;
self.email = data.email;
self.name = data.name;
self.role = data.role;
self.phoneNumbers = data.phoneNumbers;
self.removeMembershipUrl = data.removeMembershipUrl;
self.removeUrl = data.removeUrl;
self.editUrl = data.editUrl;
self.domain = data.domain;
};

var usersControllers = {};
usersControllers.paginatedListController = function($scope, djangoRMI) {
var self = this;
$scope.paginatedItems = [new WebUser({
email: 'foo@bar.com',
name: "Foo Bar",
role: "Admin",
phoneNumbers: ["+16175005454"],
removeMembershipUrl: null
})];
$scope.paginatedItems = [];

$scope.limit = 10;
$scope.total = 1;
$scope.maxSize = 8;
$scope.currentPage = 1;

$scope.query = '';

$scope.error = null;
$scope.notLoaded = true;

self.retries = 0;

self.updateUserList = function (data) {
if (data.success) {
$scope.paginatedItems = _.map(data.response.users, function (user_data) {
return new WebUser(user_data);
});
$scope.total = data.response.total;
$scope.currentPage = data.response.page;
$scope.query = data.response.query;
if ($scope.notLoaded) {
$scope.notLoaded = false;
}
}
};

self.retry = function () {
if (self.retries < 10) {
self.retries ++;
self.getUsers();
} else {
// show error
}
};

self.getUsers = function () {
djangoRMI.get_users({
limit: $scope.limit,
page: $scope.currentPage,
query: $scope.query
})
.success(self.updateUserList)
.error(self.retry);
};
self.getUsers();

$scope.pageChanged = function () {
console.log('change page');
self.getUsers();
};

$scope.filterUsers = function () {
self.getUsers();
};
};
users.controller(usersControllers);
Expand Down
210 changes: 150 additions & 60 deletions corehq/apps/users/templates/users/web_users.b3.html
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,6 @@
usersApp.config(["djangoRMIProvider", function(djangoRMIProvider) {
djangoRMIProvider.configure({% djng_current_rmi %});
}]);
usersApp.constant('dashboardConfig', {
staticRoot: '{{ STATIC_URL }}'
});
}(window.angular));
</script>
<script>
Expand Down Expand Up @@ -54,14 +51,27 @@
</script>
<script>
$(function () {
$('#save_restrict_option').click(function() {
$('#restrict_users').on('change', function () {
var $saveButton = $('#save_restrict_option');
$saveButton
.removeAttr('disabled')
.removeClass('disabled btn-default')
.addClass('btn-success')
.text('{% trans "Save" %}');
});
$('#save_restrict_option').click(function(e) {
var post_url = '{% url "location_restriction_for_users" domain %}';
$(this).text('Saving ...');
$.post(post_url,
{restrict_users: $('#restrict_users')[0].checked},
function(data, status) {
$('#save_restrict_option').text('Saved');
})
$('#save_restrict_option')
.text('{% trans "Saved" %}')
.removeClass('btn-success')
.attr('disabled', 'disabled')
.addClass('disabled btn-default');
});
e.preventDefault();
});

$('.resend-invite').click(function (e) {
Expand Down Expand Up @@ -121,65 +131,145 @@
using the CommCare Application.
{% endblocktrans %}
<div class="btn-toolbar">
<a class="btn btn-success" href="{% url "invite_web_user" domain %}">
<i class="fa fa-plus"></i> {% trans 'Invite Web User' %}</a>
<a class="btn btn-success"
href="{% url "invite_web_user" domain %}">
<i class="fa fa-plus"></i> {% trans 'Invite Web User' %}
</a>
</div>
</p>
<div ng-app="usersApp">
<div class="panel panel-default" ng-controller="paginatedListController">
<div class="panel-heading">
<div class="row">
<div class="col-sm-6">
<h3 class="panel-title" style="padding-top: 7px;">{% trans 'Current Users' %}</h3>
</div>
<div class="col-sm-6">
<div class="input-group">
<input type="text"
class="form-control"
ng-model="query"
placeholder="{% trans "Filter Users..." %}">
<span class="input-group-btn">
<button class="btn btn-default"
ng-click="filterUsers()"
type="button">
<i class="fa fa-search"></i>
</button>
</span>
</div><!-- /input-group -->
</div>
</div>
</div>
<div class="panel-body">
<table class="table table-striped table-responsive"
style="margin-bottom: 0;">
<thead>
<tr>
<th>{% trans "E-mail" %}</th>
<th>{% trans "Role" %}</th>
<th>{% trans "Name" %}</th>
<th>{% trans "Phone Numbers" %}</th>
<th>{% trans "Remove" %}</th>
</tr>
</thead>
<tbody>
<tr ng-show="notLoaded">
<td colspan="5">{% trans "Loading Users..." %}</td>
</tr>
<tr ng-repeat="user in paginatedItems">
{% angularjs %}
<td><a href="{{ user.editUrl }}">{{ user.email }}</a></td>
<td>{{ user.role }}</td>
<td>{{ user.name }}</td>
<td>
<ul>
<li ng-repeat="number in user.phoneNumbers">{{ number }}</li>
</ul>
</td>
<td>
<div ng-show="user.removeUrl">
<button type="button"
class="btn btn-danger"
data-toggle="modal"
data-target="#remove_membership_{{ user.id }}">
<i class="fa fa-remove"></i> {% trans "Remove Membership" %}
</button>
<div id="remove_membership_{{ user.id }}"
class="modal fade">
<div class="modal-dialog">
<form class="modal-content"
action="{{ user.removeUrl }}"
method="post">
<div class="modal-header">
<button type="button" class="close">
<span aria-hidden="true">&times;</span>
<span class="sr-only">{% trans "Close" %}</span>
</button>
<h4 class="modal-title">{% trans "Remove User Membership" %}: {{ user.name }}</h4>
</div>
<div class="modal-body">
<p class="lead">{% trans "Are you sure you want to remove this users's membership?" %}</p>
<ul class="dl-horizontal">
<dt>{% trans "E-mail" %}</dt>
<dd>{{ user.email }}</dd>
<dt>{% trans "Name" %}</dt>
<dd>{{ user.name }}</dd>
<dt>{% trans "Membership" %}</dt>
<dd>{{ user.domain }}</dd>
<dt>{% trans "Role" %}</dt>
<dd>{{ user.role }}</dd>
</ul>
</div>
<div class="modal-footer">
<button type="button"
class="btn btn-default"
data-dismiss="modal">
{% trans "Cancel" %}
</button>
<button type="submit"
class="btn btn-danger">
{% trans "Remove Membership" %}
</button>
</div>
</form>
</div>
</div>
</div>
</td>
{% endangularjs %}
</tr>
</tbody>
</table>
<pagination direction-links="true"
total-items="total"
items-per-page="limit"
previous-text="&laquo;"
next-text="&raquo;"
max-size="maxSize"
ng-model="currentPage"
ng-change="pageChanged()"></pagination>

<div ng-app="usersApp" class="panel panel-default">
<div class="panel-heading">
<h3 class="panel-title">{% trans 'Current Users' %}</h3>
</div>
<div ng-controller="paginatedListController" class="panel-body">
<table class="table table-striped table-responsive"
style="margin-bottom: 0;">
<thead>
<tr>
<th>{% trans "E-mail" %}</th>
{% block extra_headers %}
{% endblock %}
<th>{% trans "Role" %}</th>
<th>{% trans "Name" %}</th>
<th>{% trans "Phone Numbers" %}</th>
{% if remove_included %}<th>{% trans "Remove" %}</th>{% endif %}
</tr>
</thead>
<tbody>
<tr ng-repeat="user in paginatedItems">
<td>email</td>
<td>role</td>
<td>name</td>
<td>numbers</td>
{% if remove_included %}<td>Remove</td>{% endif %}
</tr>
</tbody>
</table>
<pagination direction-links="true"
total-items="total"
items-per-page="limit"
previous-text="&laquo;"
next-text="&raquo;"
max-size="maxSize"
ng-model="currentPage"
ng-change="pageChanged()"></pagination>
{% if domain_object.commtrack_enabled %}
<div class="checkbox">
<label>
<input type="checkbox"
id="restrict_users"
name="restrict_users"
value="True" {% if domain_object.location_restriction_for_users %}checked{% endif %}/>
{% trans "Restrict Web User access based on location" %}
</label>
<button type="button"
class="btn btn-sm btn-default disabled"
id="save_restrict_option">
{% trans "Saved" %}
</button>
</div>
{% endif %}
</div>
</div>
</div>

{% if domain_object.commtrack_enabled %}
<label class="checkbox">
<input id="restrict_users"
type="checkbox"
name="restrict_users"
value="True" {% if domain_object.location_restriction_for_users %}checked{% endif %}>
{% trans "Restrict Web User access based on location" %}
<button type="button"
class="btn btn-success"
id="save_restrict_option">
{% trans "Save" %}
</button>
</label>
{% endif %}

{% if invitations %}
<div class="panel panel-info">
<div class="panel-heading">
Expand Down Expand Up @@ -250,7 +340,7 @@ <h3 class="panel-title">
<h4 class="modal-title">{% trans "Delete invitation" %}</h4>
</div>
<div class="modal-body">
<h4> {% trans "Are you sure you want to delete this invitation?" %}</h4>
<p>{% trans "Are you sure you want to delete this invitation?" %}</p>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">{% trans "Cancel" %}</button>
Expand Down
16 changes: 16 additions & 0 deletions corehq/apps/users/util.py
Original file line number Diff line number Diff line change
Expand Up @@ -137,3 +137,19 @@ def can_add_extra_mobile_workers(request):
if account is None or account.date_confirmed_extra_charges is None:
return False
return True


def smart_query_string(query):
"""
If query does not use the ES query string syntax,
default to doing an infix search for each term.
returns (is_simple, query)
"""
special_chars = ['&&', '||', '!', '(', ')', '{', '}', '[', ']', '^', '"',
'~', '*', '?', ':', '\\', '/']
for char in special_chars:
if char in query:
return False, query
r = re.compile(r'\w+')
tokens = r.findall(query)
return True, "*{}*".format("* *".join(tokens))

0 comments on commit b5e7cd9

Please sign in to comment.