added pagination to the repository GetUser method.

added pagesixe to userlist object.
added total user count to enable PageCount to work correctly.
added GET_TOTAL_USER_COUNT and GET_ALL_USERS_PAGINATE sqlite procedures to support pagination.
updated methods in SQLiteRepository to support pagination procedures and pagination properties of UserList.
updated UsersController to support pagination parameters.
tidied html script tags.
added pagination buttons at the bottom of user page. including drop down to select PageSize
added setPageSize, goToUserPage and setPagination methods to the viewmodel.
updated other methods for sammy etc to work with pagesize and PageNumber params.
#11
This commit is contained in:
chris.watts90@outlook.com 2017-02-12 22:26:00 +00:00
parent 159c0a7625
commit cdac61b18d
7 changed files with 161 additions and 41 deletions

View File

@ -11,7 +11,17 @@ namespace Interfaces
/// Returns <see cref="UserList"/> with full list of users,
/// plus a total user count. Pagination options are supported.
/// </returns>
UserList GetUsers();
UserList GetUsers(int pageNumber=-1, int pageSize=-1);
///// <summary>
///// Get a paginated list of users
///// </summary>
///// <param name="pageNumber">The number of the page to retrieve</param>
///// <param name="pageSize">The size of the pages</param>
///// <returns>
///// Returns <see cref="UserList"/> with full list of users,
///// plus a total user count. Pagination options are supported.
///// </returns>
//UserList GetUsers(int pageNumber, int pageSize);
/// <summary>
/// Search the user list for the following string
/// </summary>

View File

@ -7,10 +7,23 @@ namespace Interfaces
public UserList()
{
Users = new List<User>();
PageSize = 10;
}
public string Query { get; set; }
public int UserCount { get { return Users.Count; } }
public int TotalUserCount { get; set; }
public List<User> Users { get; set; }
public int PageCount
{
get
{
if (TotalUserCount < PageSize)
return 1;
return (TotalUserCount / PageSize);
}
}
public int PageSize { get; set; }
public int PageNumber { get; set; }
}

View File

@ -18,5 +18,9 @@ namespace SQLiteRepository
public const string SEARCH_USER_LIST = "SELECT * FROM " + nameof(UserIdentity) + " where(" + nameof(UserIdentity.FirstName) + " Like ? OR " + nameof(UserIdentity.LastName) + " Like ?)";
public const string GET_LAST_TIMELOG_DIRECTION = "SELECT * FROM " + nameof(TimeLogDb) + " where " + nameof(TimeLogDb.UserId_FK) + " = ? order by " + nameof(TimeLogDb.SwipeEventDateTime) + " LIMIT 1";
public const string GET_ALL_USERS_PAGINATE = "select * from "+ nameof(UserIdentity)+" limit ? offset ?";
public const string GET_TOTAL_USER_COUNT = "select Max("+nameof(UserIdentity.Id)+") from " + nameof(UserIdentity);
}
}

View File

@ -23,16 +23,35 @@ namespace SQLiteRepository
_connection.CreateTable<TimeLogDb>();
}
public UserList GetUsers()
public UserList GetUsers(int pageNumber=-1, int pageSize=-1)
{
var ret = new UserList();
var users = _connection.Query<UserIdentity>(SQLiteProcedures.GET_ALL_USERS);
List<UserIdentity> users;
int userCount = -1;
if (pageNumber == -1 && pageSize == -1)
{
users = _connection.Query<UserIdentity>(SQLiteProcedures.GET_ALL_USERS);
userCount = users.Count;
}
else
{
users = _connection.Query<UserIdentity>(SQLiteProcedures.GET_ALL_USERS_PAGINATE,
pageSize, (pageNumber-1)*pageSize);
userCount = _connection.ExecuteScalar<int>(SQLiteProcedures.GET_TOTAL_USER_COUNT);
}
if (!users.Any())
{
ret.PageNumber = 1;
ret.PageSize = 20;
if (pageNumber == -1 && pageSize == -1)
{
ret.PageNumber = 1;
ret.PageSize = 20;
}
else
{
ret.PageNumber = pageNumber;
ret.PageSize = pageSize;
}
return ret;
}
@ -54,9 +73,17 @@ namespace SQLiteRepository
}
ret.Users.Add(userObj);
}
ret.PageSize = 20;
ret.PageNumber = 1;
if (pageNumber == -1 && pageSize == -1)
{
ret.PageSize = 1; //TODO: switch to ret.UserCount
ret.PageNumber = 1;
}
else
{
ret.PageSize = pageSize;
ret.PageNumber = pageNumber;
}
ret.TotalUserCount = userCount;
return ret;
}

View File

@ -24,8 +24,21 @@ namespace WindowsDataCenter
[CacheControl(MaxAge = 0)]
public IHttpActionResult GetUsers([FromUri] string query = "",[FromUri] int pageSize = -1, [FromUri] int pageNumber =-1)
{
var userList = query == string.Empty ? _repo.GetUsers() : _repo.Search(query);
userList.Query = query == string.Empty ? null : query;
UserList userList = new UserList();
pageNumber = pageNumber == -1 ? 1 : pageNumber;
pageSize = pageSize == -1 ? 1 : pageSize;
userList = query == string.Empty ? _repo.GetUsers(pageNumber, pageSize) : _repo.Search(query);
if (query != string.Empty)
{
userList.Query = query;
userList.PageNumber = 1;
userList.PageSize = userList.UserCount;
}
else
userList.Query = null;
userList.PageNumber = pageNumber;
userList.PageSize = pageSize;
var msg = Request.CreateResponse(HttpStatusCode.OK, userList);
return ResponseMessage(msg);

View File

@ -1,9 +1,7 @@
<html>
<head>
<title>Flexi Time Data Viewer</title>
<link rel="shortcut icon" href="/favicon.ico" />
<!--<script src="https://code.jquery.com/jquery-3.1.0.min.js" type="text/javascript"></script>
<script src="https://code.jquery.com/jquery-1.9.1.min.js"></script>-->
<link rel="shortcut icon" href="favicon.ico" />
<link rel="stylesheet preload" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
<link rel="stylesheet preload" href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-datepicker/1.6.1/css/bootstrap-datepicker3.min.css">
@ -61,28 +59,46 @@
<div>
<table class="table table-striped">
<thead>
<tr>
<th>ID</th>
<th>UserId</th>
<th class="col-md-1">firstName</th>
<th class="col-md-1">lastName</th>
<th />
<th />
</tr>
<tr>
<th>ID</th>
<th>UserId</th>
<th class="col-md-1">firstName</th>
<th class="col-md-1">lastName</th>
<th />
<th />
</tr>
</thead>
<tbody data-bind="foreach: Users">
<tr>
<td class="valign" data-bind="text: UserId"></td>
<td class="valign" data-bind="text: UserId"></td>
<td class="valign" data-bind="text: LastName"></td>
<td class="valign" data-bind="text: FirstName"></td>
<td class="fit"><button data-bind="click: $root.goToUserDetails" class="btn btn-default">Details</button></td>
<td class="fit hidden-md-down"><button data-bind="click: $root.goToTimeLogs" class="btn btn-default">View Logs</button></td>
</tr>
<tr>
<td class="valign" data-bind="text: UserId"></td>
<td class="valign" data-bind="text: UserId"></td>
<td class="valign" data-bind="text: LastName"></td>
<td class="valign" data-bind="text: FirstName"></td>
<td class="fit"><button data-bind="click: $root.goToUserDetails" class="btn btn-default">Details</button></td>
<td class="fit hidden-md-down"><button data-bind="click: $root.goToTimeLogs" class="btn btn-default">View Logs</button></td>
</tr>
</tbody>
</table>
<label>Total User Count: <span data-bind="text: UserCount"></span></label>
</div>
<div class="row">
<ul class="pagination" data-bind="foreach: new Array(PageCount)">
<li data-bind="css:{ active: $parent.PageNumber==($index()+1)}"><a data-bind="text: $index()+1, click: function(){$root.goToUserPage($index()+1);}"></a></li>
</ul>
<div class="dropdown">
<button class="btn btn-default dropdown-toggle" type="button" id="dropdownMenu1" data-toggle="dropdown" aria-haspopup="true" aria-expanded="true">
Page Size
<span class="caret"></span>
</button>
<ul class="dropdown-menu" aria-labelledby="dropdownMenu1">
<li data-bind="css:{disabled:$root.userList().PageSize===-1}"><a data-bind="click: function(){$root.setPageSize(-1);}">All</a></li>
<li data-bind="css:{disabled:$root.userList().PageSize===1}"><a data-bind="click: function(){$root.setPageSize(1);}">1</a></li>
<li data-bind="css:{disabled:$root.userList().PageSize===10}"><a data-bind="click: function(){$root.setPageSize(10);}">10</a></li>
<li data-bind="css:{disabled:$root.userList().PageSize===20}"><a data-bind="click: function(){$root.setPageSize(20);}">20</a></li>
<li data-bind="css:{disabled:$root.userList().PageSize===50}"><a data-bind="click: function(){$root.setPageSize(50);}">50</a></li>
</ul>
</div>
</div>
</div>
</div>

View File

@ -35,11 +35,7 @@
}
var url = "timelogs" + "/" + userId;
if (args) {
var appender = "?";
args.forEach(function(arg) {
url += appender + arg.key + "=" + arg.value;
appender = "&";
});
url = self.createRequestUrl(url, args, false, true);
}
location.hash = url;
};
@ -80,16 +76,16 @@
* @param {string} routePath
* @param {Array<Object<string>} params - Key, Value object detailing the param name (key) and value (value).
* @param {boolean} requiresCallback - True - add callback function for JSONP/CORS.
* @param {boolean} isRelativePath - True, create a relative URL (without root).
* @param {boolean} isAbsolutePath - True, create a relative URL (without root).
* @returns {string} the url generated
* @example
* createRequestUrl("/api/endpoint", [{key:"param", value:"value"}], true, false);
* returns: "http://192.168.2.2/api/endpoint?param=value&callback=?"
*/
self.createRequestUrl = function (routePath, params, requiresCallback, isRelativePath) {
self.createRequestUrl = function (routePath, params, requiresCallback, isAbsoluteUrl) {
var appender = "?";
var url = "";
if (isRelativePath) {
if (isAbsoluteUrl) {
url = self.apiEndpoints.root;
}
url = url + routePath;
@ -136,6 +132,32 @@
self.dismissAlert = function(data, event) {
self.errorData(null);
};
self.setPageSize = function(data) {
if (self.userList().PageSize !== data && self.userList().PageSize !== -1) {
self.setPagination(data, 1);
}
};
self.goToUserPage = function (data) {
if (self.userList().PageNumber !== data && self.userList().PageNumber !== -1) {
self.setPagination(self.userList().PageSize, data);
}
};
self.setPagination = function(pageSize, pageNumber) {
var args = [
{
key: "pageSize",
value: pageSize
},
{
key: "pageNumber",
value: pageNumber
}
];
var url = self.createRequestUrl("users", args, false, false);
location.hash = url;
console.log(url);
};
self.initDatePicker = function (selectedDate) {
$("#weeklyDatePicker").datepicker({
weekStart: 1,
@ -170,8 +192,21 @@
});
}
}
self.getUserList = function () {
var url = self.createRequestUrl(self.apiEndpoints.getUserList, null, false);
self.getUserList = function (pageSize, pageNumber) {
var args = null;
if (pageSize && pageNumber) {
args = [
{
key: "pageSize",
value: pageSize
},
{
key: "pageNumber",
value: pageNumber
}
];
}
var url = self.createRequestUrl(self.apiEndpoints.getUserList, args, false);
$.getJSON(url, function (res) {
self.userList(res);
}).fail(function (response, status, error) {
@ -251,6 +286,8 @@
Sammy(function () {
this.get("#users", function () {
var query = this.params.query;
var pageSize = this.params.pageSize;
var pageNumber = this.params.pageNumber;
self.chosenMenuItemId("Users");
self.chosenUserDetails(null);
self.userList(null);
@ -258,7 +295,7 @@
if (query)
self.searchUsers(query);
else
self.getUserList();
self.getUserList(pageSize, pageNumber);
self.assignErrorObject(101, "An Error has occurred.. run away!!!", "test");
//$.get("http://localhost:3000", { menu: this.params.menu }, self.chosenMenuData);
});