Fix merge conflict

This commit is contained in:
Preston Doman 2019-02-10 15:57:05 -08:00
commit ae743ffb1a
3 changed files with 185 additions and 58 deletions

View file

@ -62,7 +62,7 @@
</div> </div>
</div> </div>
</div> </div>
<div class="modal" id="editReportModal" tabindex="-1" role="dialog"> <div class="modal fade" id="editReportModal" tabindex="-1" role="dialog">
<div class="modal-dialog modal-lg" role="document"> <div class="modal-dialog modal-lg" role="document">
<div class="modal-content"> <div class="modal-content">
<div class="modal-header"> <div class="modal-header">
@ -71,7 +71,13 @@
<span aria-hidden="true">&times;</span> <span aria-hidden="true">&times;</span>
</button> </button>
</div> </div>
<div class="modal-body"> <div class="modal-body" id="editReportModalBody">
<div class="text-center">
<i class="fas fa-spinner fa-3x fa-spin"></i>
<br>
<br>
<h5>Loading Report ...</h5>
</div>
</div> </div>
<div class="modal-footer"> <div class="modal-footer">
<button type="button" class="btn btn-danger delete-report">Delete Report</button> <button type="button" class="btn btn-danger delete-report">Delete Report</button>
@ -81,7 +87,7 @@
</div> </div>
</div> </div>
</div> </div>
<div class="modal" id="viewReportModal" tabindex="-1" role="dialog"> <div class="modal fade" id="viewReportModal" tabindex="-1" role="dialog">
<div class="modal-dialog modal-lg" role="document"> <div class="modal-dialog modal-lg" role="document">
<div class="modal-content"> <div class="modal-content">
<div class="modal-header"> <div class="modal-header">
@ -91,6 +97,12 @@
</button> </button>
</div> </div>
<div class="modal-view"> <div class="modal-view">
<div class="text-center">
<i class="fas fa-spinner fa-3x fa-spin"></i>
<br>
<br>
<h5>Loading Report ...</h5>
</div>
</div> </div>
</div> </div>
</div> </div>

View file

@ -1,3 +1,9 @@
const reportType = {
NEW : 1,
EDIT : 2,
VIEW : 3
};
// Hack to change endpoint url // Hack to change endpoint url
function getEndpointDomain() { function getEndpointDomain() {
return "https://" + window.location.hostname + ":8444/"; return "https://" + window.location.hostname + ":8444/";
@ -35,13 +41,12 @@ function removeDataFromEndpoint(url) {
} }
// Make a GET request to url and pass response to callback function // Make a GET request to url and pass response to callback function
function getDataFromEndpoint(url, callback) { function getDataFromEndpoint(url, callback, optional) {
const token = localStorage.getItem("token"); const token = localStorage.getItem("token");
const xhr = new XMLHttpRequest(); const xhr = new XMLHttpRequest();
console.log("Attempting a connection to the following endpoint: " + url); console.log("Attempting a connection to the following endpoint: " + url);
xhr.open("GET", url, true); xhr.open("GET", url, true);
xhr.setRequestHeader("Authorization", "Bearer " + token); xhr.setRequestHeader("Authorization", "Bearer " + token);
xhr.onreadystatechange = function() { xhr.onreadystatechange = function() {
@ -49,8 +54,8 @@ function getDataFromEndpoint(url, callback) {
if (this.status === 200) { if (this.status === 200) {
console.log("GET SUCCESS!"); console.log("GET SUCCESS!");
console.log("Server response:\n" + this.response); console.log("Server response:\n" + this.response);
parsedData = JSON.parse(this.response); let parsedData = JSON.parse(this.response);
callback(parsedData); optional ? callback(parsedData, optional) : callback(parsedData);
} else { } else {
console.error("GET FAILURE!"); console.error("GET FAILURE!");
console.error("Server status: " + this.status); console.error("Server status: " + this.status);
@ -66,22 +71,55 @@ function getDataFromEndpoint(url, callback) {
xhr.send(); xhr.send();
} }
// Make a POST request to url and pass response to callback function
function postDataToEndpoint(url, payload, callback, optional) {
const token = localStorage.getItem("token");
const xhr = new XMLHttpRequest();
console.log("Attempting a connection to the following endpoint: " + url);
xhr.open("POST", url, true);
xhr.setRequestHeader("Authorization", "Bearer " + token);
xhr.setRequestHeader("Content-Type", "application/json");
xhr.onreadystatechange = function() {
if (this.readyState === 4) {
if (this.status === 200) {
console.log("POST SUCCESS!");
console.log("Server response:\n" + this.response);
let parsedData = JSON.parse(this.response);
optional ? callback(parsedData, optional) : callback(parsedData);
} else {
console.error("POST FAILURE!");
console.error("Server status: " + this.status);
console.error("Server response:\n" + this.response);
}
}
};
xhr.onerror = function() {
alert("Connection error!");
};
xhr.send(payload);
}
// Wraps a Bootstrap form group around a field // Wraps a Bootstrap form group around a field
function createFormGroup(key, field) { function createFormGroup(field) {
const formGroup = document.createElement("div") const formGroup = document.createElement("div")
formGroup.classList.add("form-group", "row"); formGroup.classList.add("form-group", "row");
const label = document.createElement("label"); const label = document.createElement("label");
label.classList.add("col-sm-4", "col-form"); label.classList.add("col-sm-4", "col-form");
label.innerHTML = field.label + ": "; label.innerHTML = field.label + ": ";
label.setAttribute("for", key); label.setAttribute("for", field.field_name);
const div = document.createElement("div"); const div = document.createElement("div");
div.classList.add("col-sm-6"); div.classList.add("col-sm-6");
const input = document.createElement("input"); const input = document.createElement("input");
input.name = key; input.name = field.field_name;
input.id = key; input.id = field.field_name;
switch(field.type) { switch(field.type) {
case "boolean": case "boolean":
@ -91,6 +129,7 @@ function createFormGroup(key, field) {
input.classList.add("form-check-input"); input.classList.add("form-check-input");
label.className = ""; label.className = "";
label.classList.add("form-check-label"); label.classList.add("form-check-label");
label.innerHTML = field.label;
outerLabel = document.createElement("div"); outerLabel = document.createElement("div");
outerLabel.classList.add("col-sm-4"); outerLabel.classList.add("col-sm-4");
outerLabel.innerHTML = "Flight type: "; outerLabel.innerHTML = "Flight type: ";
@ -103,10 +142,29 @@ function createFormGroup(key, field) {
formGroup.appendChild(div); formGroup.appendChild(div);
break; break;
case "date": case "date":
case "string":
input.type = "text";
input.value = field.value;
input.classList.add("form-control");
formGroup.appendChild(label);
div.appendChild(input)
formGroup.appendChild(div);
break;
case "decimal": case "decimal":
input.type = "text"; input.type = "text";
input.value = field.value; input.value = field.value;
input.classList.add("form-control"); input.classList.add("form-control");
input.pattern = "\\d+(\\.\\d{2})?";
formGroup.appendChild(label);
div.appendChild(input)
formGroup.appendChild(div);
break;
case "integer":
input.type = "number";
input.value = field.value;
input.classList.add("form-control");
input.step = 1;
input.min = 0;
formGroup.appendChild(label); formGroup.appendChild(label);
div.appendChild(input) div.appendChild(input)
formGroup.appendChild(div); formGroup.appendChild(div);
@ -151,10 +209,13 @@ function createCollapsibleCard(key, sectionTitle) {
return card; return card;
} }
function createCollapsibleCardBody(key, form, sectionDescription, sectionCompleted) { function createCollapsibleCardBody(key, form, type, sectionDescription, sectionCompleted) {
// Create wrapper div // Create wrapper div
const div = document.createElement("div"); const div = document.createElement("div");
div.id = "collapse" + key;
const sectionAlert = document.createElement("div"); const sectionAlert = document.createElement("div");
const cardBody = document.createElement("div");
cardBody.classList.add("card-body");
if (sectionCompleted) { if (sectionCompleted) {
div.classList.add("collapse"); div.classList.add("collapse");
@ -166,12 +227,13 @@ function createCollapsibleCardBody(key, form, sectionDescription, sectionComplet
sectionAlert.innerHTML = "This section is not complete"; sectionAlert.innerHTML = "This section is not complete";
} }
if (type === reportType.EDIT) {
div.setAttribute("data-parent", "#editReportAccordion"); div.setAttribute("data-parent", "#editReportAccordion");
div.id = "collapse" + key; } else {
div.setAttribute("data-parent", "#newReportAccordion");
}
// Create card body. Append form to body, body to wrapper div // Create card body. Append form to body, body to wrapper div
const cardBody = document.createElement("div");
cardBody.classList.add("card-body");
cardBody.appendChild(sectionAlert); cardBody.appendChild(sectionAlert);
cardBody.insertAdjacentHTML("beforeend", sectionDescription); cardBody.insertAdjacentHTML("beforeend", sectionDescription);
cardBody.appendChild(form); cardBody.appendChild(form);
@ -180,9 +242,25 @@ function createCollapsibleCardBody(key, form, sectionDescription, sectionComplet
return div; return div;
} }
function createEditReportForm(parsedData) { function createReportForm(parsedData, type) {
const modalBody = document.querySelector(".modal-body"); let modalBody;
const modalLabel = document.querySelector("#editReportModalLabel"); let modalLabl;
const accordion = document.createElement("div");
accordion.classList.add("accordion");
if (type === reportType.EDIT) {
console.log("reportType.EDIT");
modalBody = document.querySelector("#editReportModalBody");
modalLabel = document.querySelector("#editReportModalLabel");
accordion.id = "editReportAccordion";
} else if (type === reportType.NEW) {
console.log("reportType.NEW");
modalBody = document.querySelector("#newReportModalBody");
modalLabel = document.querySelector("#newReportModalLabel");
accordion.id = "newReportAccordion";
} else {
return;
}
while (modalBody.firstChild) { while (modalBody.firstChild) {
modalBody.removeChild(modalBody.firstChild); modalBody.removeChild(modalBody.firstChild);
@ -193,11 +271,6 @@ function createEditReportForm(parsedData) {
const dateCreated = new Date(parsedData.date_created).toLocaleDateString("en-US"); const dateCreated = new Date(parsedData.date_created).toLocaleDateString("en-US");
modalLabel.innerHTML = reportTitle + " " + dateCreated; modalLabel.innerHTML = reportTitle + " " + dateCreated;
// Create accordion
const accordion = document.createElement("div");
accordion.classList.add("accordion");
accordion.id = "editReportAccordion";
// Traverse the report's sections array // Traverse the report's sections array
const sections = parsedData.sections; const sections = parsedData.sections;
for (let key in sections) { for (let key in sections) {
@ -219,7 +292,7 @@ function createEditReportForm(parsedData) {
console.log("Field value: " + field.value); console.log("Field value: " + field.value);
// Create a form group for each field and add it to the form // Create a form group for each field and add it to the form
let formGroup = createFormGroup(key, field); let formGroup = createFormGroup(field);
form.appendChild(formGroup); form.appendChild(formGroup);
} }
@ -231,7 +304,7 @@ function createEditReportForm(parsedData) {
form.appendChild(saveButton); form.appendChild(saveButton);
// Create collapsible card body, append form to it, append card to accordion // Create collapsible card body, append form to it, append card to accordion
let cardBody = createCollapsibleCardBody(key, form, section.html_description, section.completed); let cardBody = createCollapsibleCardBody(key, form, type, section.html_description, section.completed);
collapsibleCard.appendChild(cardBody); collapsibleCard.appendChild(cardBody);
accordion.appendChild(collapsibleCard); accordion.appendChild(collapsibleCard);
} }
@ -357,29 +430,27 @@ function displayReport(parsedData){
} }
document.addEventListener("DOMContentLoaded", function(event) { document.addEventListener("DOMContentLoaded", function(event) {
if (window.location.pathname === "/edit_report.html") {
const url = getEndpointDomain() + "api/v1/reports"; const url = getEndpointDomain() + "api/v1/reports";
getDataFromEndpoint(url, displayListOfReports); getDataFromEndpoint(url, displayListOfReports);
}
}); });
document.addEventListener("click", function(event) { document.addEventListener("click", function(event) {
if (event.target && event.target.classList.contains("edit-report-button")) { if (event.target) {
console.log("Edit button clicked"); if (event.target.classList.contains("edit-report-button")) {
const url = getEndpointDomain() + "api/v1/report/" + event.target.dataset.rid; const url = getEndpointDomain() + "api/v1/report/" + event.target.dataset.rid;
const type = reportType.EDIT;
const deleteButton = document.querySelector(".delete-report"); const deleteButton = document.querySelector(".delete-report");
if (deleteButton) { if (deleteButton) {
deleteButton.setAttribute("data-rid", event.target.dataset.rid); deleteButton.setAttribute("data-rid", event.target.dataset.rid);
} }
getDataFromEndpoint(url, createEditReportForm); getDataFromEndpoint(url, createReportForm, type);
} } else if (event.target.classList.contains("view-report-button")) {
if(event.target && event.target.classList.contains("view-report-button"))
{
console.log("View button clicked"); console.log("View button clicked");
const url = getEndpointDomain() + "api/v1/report/" + event.target.dataset.rid; const url = getEndpointDomain() + "api/v1/report/" + event.target.dataset.rid;
getDataFromEndpoint(url, displayReport); getDataFromEndpoint(url, displayReport);
} } else if (event.target.classList.contains("delete-report")) {
// TODO: Add View Report
if(event.target && event.target.classList.contains("delete-report")) {
event.preventDefault(); event.preventDefault();
console.log("Delete report button clicked"); console.log("Delete report button clicked");
const result = confirm("Are you sure you want to delete this report?"); const result = confirm("Are you sure you want to delete this report?");
@ -388,4 +459,18 @@ document.addEventListener("click", function(event) {
removeDataFromEndpoint(url); removeDataFromEndpoint(url);
} }
} }
}
}); });
const newReportForm = document.querySelector(".new-report-form");
if (newReportForm) {
newReportForm.addEventListener("submit", function(event) {
event.preventDefault();
const url = getEndpointDomain() + "api/v1/report";
const payload = JSON.stringify({ "title": event.target.elements.title.value });
console.log("Payload:\n" + payload);
const type = reportType.NEW;
postDataToEndpoint(url, payload, createReportForm, type);
this.reset();
});
}

View file

@ -7,6 +7,7 @@
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.2.1/css/bootstrap.min.css" integrity="sha384-GJzZqFGwb1QTTN6wy59ffF1BuGJpLSa9DkKMp0DgiMDm4iYMj70gZWKYbI706tWS" crossorigin="anonymous"> <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.2.1/css/bootstrap.min.css" integrity="sha384-GJzZqFGwb1QTTN6wy59ffF1BuGJpLSa9DkKMp0DgiMDm4iYMj70gZWKYbI706tWS" crossorigin="anonymous">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.2.1/js/bootstrap.min.js" integrity="sha384-B0UglyR+jN6CkvvICOB2joaf5I4l3gm9GU6Hc1og6Ls7i6U/mkkaduKaBhlAXv9k" crossorigin="anonymous"></script> <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.2.1/js/bootstrap.min.js" integrity="sha384-B0UglyR+jN6CkvvICOB2joaf5I4l3gm9GU6Hc1og6Ls7i6U/mkkaduKaBhlAXv9k" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/classlist/1.2.20171210/classList.min.js"></script>
<link rel="shortcut icon" href="img/favicon.ico"> <link rel="shortcut icon" href="img/favicon.ico">
<title>Reimbursinator</title> <title>Reimbursinator</title>
</head> </head>
@ -41,16 +42,45 @@
<div class="card bg-light text-dark"> <div class="card bg-light text-dark">
<div class="card-header"> <div class="card-header">
<h3>Create a new report</h3> <h3>Create a new report</h3>
</div>
<div class="card-body">
<form class="form new-report-form" autocomplete="off">
<div class="form-group"> <div class="form-group">
<label for="title">Report title:</label> <label for="title">Report title:</label>
<input type="text" class="form-control" id="title"> <input type="text" class="form-control" name="title" id="title">
</div> </div>
<button type="button" class="btn btn-primary" herf="#Create">Create</button> <button type="submit" class="btn btn-primary" data-toggle="modal" data-target="#newReportModal">Create</button>
</form>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
<div class="modal fade" id="newReportModal" tabindex="-1" role="dialog">
<div class="modal-dialog modal-lg" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="newReportModalLabel"></h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">&times;</span>
</button>
</div>
<div class="modal-body" id="newReportModalBody">
<div class="text-center">
<i class="fas fa-spinner fa-3x fa-spin"></i>
<br>
<br>
<h5>Creating Report ...</h5>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
<button type="button" class="btn btn-primary">Submit Report</button>
</div>
</div>
</div>
</div>
<script src="js/logout.js"></script> <script src="js/logout.js"></script>
<script src="js/viewHistory.js"></script>
</body> </body>
</html> </html>