Skip to content
Permalink
6e8b329e06
Switch branches/tags

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?
Go to file
 
 
Cannot retrieve contributors at this time
341 lines (311 sloc) 14 KB
<%@ 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">&times;</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>