Permalink
Cannot retrieve contributors at this time
Name already in use
A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch?
2017-CSE-Senior-Project-Team-2/WebContent/html/webpages/administration/adminApprove.jsp
Go to fileThis commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
341 lines (311 sloc)
14 KB
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<%@ page import = "database.*,entities.*" %> | |
<%@ page language="java" contentType="text/html; charset=ISO-8859-1" | |
pageEncoding="ISO-8859-1"%> | |
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> | |
<html lang="en"> | |
<head> | |
<meta charset="utf-8"> | |
<meta http-equiv="X-UA-Compatible" content="IE=edge"> | |
<meta name="viewport" content="width=device-width, initial-scale=1"> | |
<!-- The above 3 meta tags *must* come first in the head; any other head content must come *after* these tags --> | |
<meta name="description" content=""> | |
<meta name="author" content=""> | |
<title>Innovation Hub</title> | |
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css"> | |
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script> | |
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script> | |
<!-- Latest compiled and minified CSS --> | |
<link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/bootstrap-table/1.11.1/bootstrap-table.min.css"> | |
<!-- Latest compiled and minified JavaScript --> | |
<script src="//cdnjs.cloudflare.com/ajax/libs/bootstrap-table/1.11.1/bootstrap-table.min.js"></script> | |
<!-- Latest compiled and minified Locales --> | |
<script src="//cdnjs.cloudflare.com/ajax/libs/bootstrap-table/1.11.1/locale/bootstrap-table-zh-CN.min.js"></script> | |
<link rel = "stylesheet" type = "text/css" href = "../../css/stylesheet.css"> | |
<link rel = "shortcut icon" href = "../../imgs/synchrony-financial-logo-dlpx_1.ico"> | |
<style> | |
.form-control{ | |
margin: auto; | |
text-align: center; | |
} | |
tr.entry{ | |
cursor: pointer; | |
} | |
.table{ | |
width: auto; | |
background-color: #E9EAEB; | |
} | |
tbody{ | |
text-align: left; | |
} | |
.btn{ | |
margin-top: 15px; | |
} | |
body{ | |
overflow: visible; | |
} | |
div.displayDevice{ | |
padding-right: 30px; | |
padding-bottom: 30px; | |
} | |
</style> | |
</head> | |
<body> | |
<nav class="navbar navbar-inverse navbar-fixed-top" id = "navbaruniversal"> | |
<%@ include file="../components/adminnavbar.jsp"%> | |
</nav> | |
<div class="col-sm-3 col-md-2 sidebar"> | |
<%@ include file="../components/adminsidebar.jsp" %> | |
</div> | |
<!-- Modal for choosing ticket action. --> | |
<div id="Modal" class="modal"> | |
<div class="modal-content"> | |
<div class="modal-head"> | |
<span id="closeForm" class="close">×</span> | |
<h4>View Ticket Below</h4> | |
</div><br> | |
<div class="modal-body"> | |
<!-- Where new information is added. --> | |
<form ACTION = "../redirect/ticketAdminRedirect.jsp" METHOD = "POST"> | |
<table style = 'margin: 0 auto;' class="table table-bordered table-hover"> | |
<thead> | |
<tr> | |
<th>Ticket ID</th> | |
<th>Requestor Name</th> | |
<th>Location Name</th> | |
<th>Device Name</th> | |
<th>Status</th> | |
<th>Permanent?</th> | |
<th>Return Date</th> | |
</tr> | |
</thead> | |
<tbody id="tablemodal"> | |
</tbody> | |
</table> | |
<button type = "submit" name = "approve" value = "Approve" class="btn btn-primary">Approve</button> | |
<button type = "submit" name = "reject" value = "Reject" class="btn btn-primary">Reject</button> | |
<input type = "text" id = "ticketIDfield" name = "ticketid" style = "display: none;"> | |
<input type = "text" id = "deviceIDfield" name = "deviceid" style = "display: none;"> | |
<input type = "text" id = "locationIDfield" name = "locationid" style = "display: none;"> | |
<input type = "text" id = "permField" name = "permField" style = "display: none;"> | |
</form> | |
</div> | |
</div> | |
</div> | |
<div class = "displayDevice"> | |
<h2>Admin View Approvals</h2> | |
<form onsubmit="return false;" class="form-inline"> | |
<input type="search" class="form-control" name="searchBar" placeholder=" search tickets" autocomplete="off" style="width: 50%; text-align: left; margin: 1%;" /> | |
</form> | |
<table id = "tabledisplay" class="table table-bordered table-hover" data-toggle="table" data-sort-name="id" data-sort-order="asc"> | |
<thead> | |
<tr> | |
<th data-name = "id" data-sortable = "true">Ticket ID</th> | |
<th data-name = "renter" data-sortable = "true">Requestor Name</th> | |
<th data-name = "loc" data-sortable = "true">Location Name</th> | |
<th data-name = "dev" data-sortable = "true">Device Name</th> | |
<th data-name = "status" data-sortable = "true">Status</th> | |
<th data-name = "perm" data-sortable = "true">Permanent?</th> | |
<th data-name = "return" data-sortable = "true">Return Date</th> | |
</tr> | |
</thead> | |
<tbody id="tablebodymain"> | |
</tbody> | |
</table> | |
</div> | |
<% | |
/* | |
Get all tickets that need to be reviewed for approval from the server. | |
*/ | |
Ticket[] tickets = TicketQueries.getRequestedTickets(); | |
String ticketStr = Ticket.arrayToString(tickets); | |
%> | |
<script> | |
/* | |
Turn tickets into strings that can be displayable in the ticket hub menu. | |
*/ | |
window.json = '<%=ticketStr%>'; | |
var ticks = JSON.parse(window.json); | |
/* | |
This displays the tickets. | |
*/ | |
populateTickets(ticks); | |
/* | |
Managing the event listeners on the page. | |
*/ | |
// Exits modal when x is clicked. | |
$("#closeForm").click(closeModal); | |
// Event listener exits modal when esc key pressed. | |
window.onkeydown = function(e){if (e.keyCode == 27){closeModal();}} | |
// Event listener exits modal when click outside modal. | |
window.onclick = function(e){var modal = document.getElementById('Modal'); if(e.target == modal) {closeModal();}} | |
// Search bar listener | |
var searchbar = document.getElementsByName('searchBar'); | |
searchbar[0].onkeyup = refresh; | |
// Set up table record event listeners | |
$('#tabledisplay').bootstrapTable({onClickRow: function(row,$element){ | |
var id = $element[0].getAttribute('id'); | |
var html = "<tr><td>" + ticks[id].id + "</td><td>" + ticks[id].username + "</td><td>" + ticks[id].locationname + "</td><td>" + ticks[id].devicename + "</td><td>" + ticks[id].status + "</td><td>" + ticks[id].permanent + "</td><td>" + ticks[id].return + "</td></tr>"; | |
document.getElementById("tablemodal").innerHTML = html; | |
$("#ticketIDfield").val(ticks[id].id); | |
$("#deviceIDfield").val(ticks[id].deviceID); | |
$("#locationIDfield").val(ticks[id].location); | |
$("#permField").val(ticks[id].permanent); | |
$("#Modal").show(); | |
}}); | |
$(".no-records-found").html("<td colspan='7'>No tickets found!</td>"); | |
/* | |
Params: tickets - array of objects, formatted as tickets. | |
This function will display tickets in a table on the webpage. | |
*/ | |
function populateTickets(tickets){ | |
var html = ""; | |
for(var i = 0; i < tickets.length; i++){ | |
// Iteratively, a string of HTML tags is built that will later be placed | |
// inside of a table block, formatted in a way so all the proper information | |
// is displayed. | |
// TODO : NEED TO ADD IN RETURN DATE AT END BUT THAT WOULD BREAK THINGS AT THE MOMENT | |
html += "<tr class = 'entry' id = '" + i + "'><td>" + tickets[i].id + "</td><td>" + tickets[i].username + "</td><td>" + tickets[i].locationname + "</td><td>" + tickets[i].devicename + "</td><td>" + tickets[i].status + "</td><td>" + tickets[i].permanent + "</td><td>" + tickets[i].return + "</td></tr>"; | |
} | |
document.getElementById("tablebodymain").innerHTML = html; | |
} | |
/* | |
This function is executed by the ticket record event listener. | |
When a ticket record is selected, we want a modal to display and autofill | |
with information pertaining to the ticket that should be reviewed. | |
From there, the ticket can be approved or rejected from the modal. | |
*/ | |
function ticketAction(){ | |
var id = this.id; | |
var html = "<tr><td>" + ticks[id].id + "</td><td>" + ticks[id].username + "</td><td>" + ticks[id].locationname + "</td><td>" + ticks[id].devicename + "</td><td>" + ticks[id].status + "</td><td>" + ticks[id].permanent + "</td><td>" + ticks[id].return + "</td></tr>"; | |
document.getElementById("tablemodal").innerHTML = html; | |
$("#ticketIDfield").val(ticks[id].id); | |
$("#deviceIDfield").val(ticks[id].deviceID); | |
$("#locationIDfield").val(ticks[id].location); | |
$("#permField").val(ticks[id].permanent); | |
$("#Modal").show(); | |
} | |
/* | |
This function is executed when a user is attempting to close out | |
the modal, whether that is clicking x, clicking outside of the modal, | |
or clicking esc. | |
*/ | |
function closeModal(){ | |
$("#Modal").hide(); | |
} | |
/* | |
This function "refreshes" the page while search query is performed. | |
It essentially filters the tickets based on search criteria, | |
and redisplays them, while adding back their event listeners. | |
*/ | |
function refresh() { | |
populateTickets(fuzzyFilter(JSON.parse(window.json))); | |
//adds event listeners to all table records | |
$("tr.entry").click(ticketAction); | |
} | |
/* | |
Params: ticketArray - Array of objects, formatted as tickets. | |
Output: finalResults - Array of objects, formatted as tickets, but filtered by search text. | |
This function is executed on the search bar's key-up event listener, and based on the input text, | |
will filter what is currently displayed in the table based on user input. It implements a scoring system | |
that determines how "matching" a table string is to the user input. | |
*/ | |
function fuzzyFilter(ticketArray) { | |
// Pass #1: filter by id | |
var searchText = document.getElementsByName('searchBar')[0].value; | |
var options = { | |
pre: "<span style='color: darkmagenta; font-size: 115%'><b>", | |
post: '</b></span>', | |
extract: function(arg) {return ''+arg.id;} | |
} | |
var idFilterResults = fuzzy.filter(searchText, ticketArray, options); | |
for (var i = idFilterResults.length - 1; i >= 0; i--) { | |
idFilterResults[i].original.id=idFilterResults[i].string; | |
} | |
// Pass #2: filter by status | |
options.extract=function(arg) {return arg.status;} | |
var statusFilterResults = fuzzy.filter(searchText, ticketArray, options) | |
for (var i = statusFilterResults.length-1;i >=0; i--) { | |
statusFilterResults[i].original.status=statusFilterResults[i].string; | |
} | |
// Pass #3: filter by username | |
options.extract=function(arg) {return arg.username;} | |
var usernameFilterResults = fuzzy.filter(searchText, ticketArray, options) | |
for (var i = usernameFilterResults.length-1;i >=0; i--) { | |
usernameFilterResults[i].original.username=usernameFilterResults[i].string; | |
} | |
// Pass #4: filter by locationname | |
options.extract=function(arg) {return arg.locationname;} | |
var locationnameFilterResults = fuzzy.filter(searchText, ticketArray, options) | |
for (var i = locationnameFilterResults.length-1;i >=0; i--) { | |
locationnameFilterResults[i].original.locationname=locationnameFilterResults[i].string; | |
} | |
// Pass #5: filter by devicename | |
options.extract=function(arg) {return arg.devicename;} | |
var devicenameFilterResults = fuzzy.filter(searchText, ticketArray, options) | |
for (var i = devicenameFilterResults.length-1;i >=0; i--) { | |
devicenameFilterResults[i].original.devicename=devicenameFilterResults[i].string; | |
} | |
// Pass #6: filter by return | |
options.extract=function(arg) {return arg.return;} | |
var returnFilterResults = fuzzy.filter(searchText, ticketArray, options) | |
for (var i = returnFilterResults.length-1;i >=0; i--) { | |
returnFilterResults[i].original.return=returnFilterResults[i].string; | |
} | |
var filteredResults = union([idFilterResults, statusFilterResults, usernameFilterResults, locationnameFilterResults, devicenameFilterResults, returnFilterResults]); | |
// this returns a filtered array of objects with attributes 'index', 'original', 'score', and 'string' | |
// I am interested in the 'original' attribute, which is the relevant object exactly as it was submitted, | |
// and the 'string' attribute, which is the attribute that was compared against with matching characters conveniantly bolded | |
var finalResults = new Array(filteredResults.length); | |
for (var i = 0; i < finalResults.length; i++) { | |
finalResults[i]= { | |
id:filteredResults[i].original.id, | |
status:filteredResults[i].original.status, | |
username:filteredResults[i].original.username, | |
locationname:filteredResults[i].original.locationname, | |
devicename:filteredResults[i].original.devicename, | |
return:filteredResults[i].original.return, | |
permanent:filteredResults[i].original.permanent, | |
}; | |
} | |
return finalResults; | |
} | |
/* | |
Params: arrays - a set of arrays that will be unioned together. | |
Output: One array, union of the input | |
Unions array results and removes duplicates. This is needed to support | |
fuzzy filter search. | |
*/ | |
function union(arrays) { | |
if(arrays.length == 2) | |
return(unionBaseCase(arrays[0],arrays[1])) | |
if(arrays.length == 1) | |
return(arrays[0]) | |
else{ | |
var pivot = Math.floor(arrays.length/2); | |
var arrayA=arrays.slice(0,pivot); | |
var arrayB=arrays.slice(pivot); | |
return union([union(arrayA),union(arrayB)]); | |
} | |
} | |
/* | |
Params: array1 - first array we are unioning, array2 - second array we are unioning | |
Output: results - One array, the union of the two inputs. | |
This is where tha magic happens and the actual union occurs between two arrays. | |
*/ | |
function unionBaseCase(array1,array2) { | |
var results = new Array(); | |
while(array1.length>0 && array2.length>0) { | |
if(array1[0].index == array2[0].index){ | |
array1.splice(0,1); | |
} | |
else | |
results.push((array1[0].index > array2[0].index ? array2.splice(0,1)[0] : array1.splice(0,1)[0])) | |
} | |
results = results.concat(array1); | |
results = results.concat(array2); | |
return results; | |
} | |
</script> | |
<script src="../../javascript/lib/fuzzy.js"></script> | |
</body> | |
</html> |