fixed merge conflicts FINALLYgit add .!
This commit is contained in:
commit
08033fc117
11 changed files with 80 additions and 75 deletions
|
@ -9,8 +9,8 @@ verify_ssl = true
|
||||||
django = "==2.1.5"
|
django = "==2.1.5"
|
||||||
django-cors-headers = "==2.4.0"
|
django-cors-headers = "==2.4.0"
|
||||||
djangorestframework = "==3.8.2"
|
djangorestframework = "==3.8.2"
|
||||||
|
|
||||||
gunicorn = "==19.6.0"
|
gunicorn = "==19.6.0"
|
||||||
|
django-rest-auth = "==0.9.3"
|
||||||
|
|
||||||
[requires]
|
[requires]
|
||||||
python_version = "3.5"
|
python_version = "3.5"
|
||||||
|
|
16
back/Pipfile.lock
generated
16
back/Pipfile.lock
generated
|
@ -1,7 +1,7 @@
|
||||||
{
|
{
|
||||||
"_meta": {
|
"_meta": {
|
||||||
"hash": {
|
"hash": {
|
||||||
"sha256": "b5222b4256c8f09a9b1b1d380285fa65c443f84d28dc03450684fca84b38a26b"
|
"sha256": "d3bf402a934e168cbdc04022effcdb9ff8d4fde5b83d79bb388ad2a4c547894a"
|
||||||
},
|
},
|
||||||
"pipfile-spec": 6,
|
"pipfile-spec": 6,
|
||||||
"requires": {
|
"requires": {
|
||||||
|
@ -32,6 +32,13 @@
|
||||||
"index": "pypi",
|
"index": "pypi",
|
||||||
"version": "==2.4.0"
|
"version": "==2.4.0"
|
||||||
},
|
},
|
||||||
|
"django-rest-auth": {
|
||||||
|
"hashes": [
|
||||||
|
"sha256:ad155a0ed1061b32e3e46c9b25686e397644fd6acfd35d5c03bc6b9d2fc6c82a"
|
||||||
|
],
|
||||||
|
"index": "pypi",
|
||||||
|
"version": "==0.9.3"
|
||||||
|
},
|
||||||
"djangorestframework": {
|
"djangorestframework": {
|
||||||
"hashes": [
|
"hashes": [
|
||||||
"sha256:b6714c3e4b0f8d524f193c91ecf5f5450092c2145439ac2769711f7eba89a9d9",
|
"sha256:b6714c3e4b0f8d524f193c91ecf5f5450092c2145439ac2769711f7eba89a9d9",
|
||||||
|
@ -54,6 +61,13 @@
|
||||||
"sha256:d5f05e487007e29e03409f9398d074e158d920d36eb82eaf66fb1136b0c5374c"
|
"sha256:d5f05e487007e29e03409f9398d074e158d920d36eb82eaf66fb1136b0c5374c"
|
||||||
],
|
],
|
||||||
"version": "==2018.9"
|
"version": "==2018.9"
|
||||||
|
},
|
||||||
|
"six": {
|
||||||
|
"hashes": [
|
||||||
|
"sha256:3350809f0555b11f552448330d0b52d5f24c91a322ea4a15ef22629740f3761c",
|
||||||
|
"sha256:d16a0141ec1a18405cd4ce8b4613101da75da0e9a7aec5bdd4fa804d0e0eba73"
|
||||||
|
],
|
||||||
|
"version": "==1.12.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"develop": {}
|
"develop": {}
|
||||||
|
|
0
back/backend/__init__.py
Normal file
0
back/backend/__init__.py
Normal file
|
@ -9,9 +9,6 @@ urlpatterns = [
|
||||||
path('reports', views.reports),
|
path('reports', views.reports),
|
||||||
path('report/<int:report_pk>', views.report_detail),
|
path('report/<int:report_pk>', views.report_detail),
|
||||||
path('report/<int:report_pk>/section/<int:section_pk>', views.section),
|
path('report/<int:report_pk>/section/<int:section_pk>', views.section),
|
||||||
path('account', views.account),
|
|
||||||
path('account/login', views.account_login),
|
|
||||||
path('account/logout', views.account_logout),
|
|
||||||
]
|
]
|
||||||
|
|
||||||
urlpatterns = format_suffix_patterns(urlpatterns)
|
urlpatterns = format_suffix_patterns(urlpatterns)
|
|
@ -174,24 +174,3 @@ def section(request, report_pk, section_pk):
|
||||||
}
|
}
|
||||||
|
|
||||||
return JsonResponse(data)
|
return JsonResponse(data)
|
||||||
|
|
||||||
@api_view(['POST'])
|
|
||||||
def account(request):
|
|
||||||
'''
|
|
||||||
Create a new user account
|
|
||||||
'''
|
|
||||||
return JsonResponse({"message": "Account creation successful."})
|
|
||||||
|
|
||||||
@api_view(['POST'])
|
|
||||||
def account_login(request):
|
|
||||||
'''
|
|
||||||
Log in to a user account
|
|
||||||
'''
|
|
||||||
return JsonResponse({"message": "Successfully logged in."})
|
|
||||||
|
|
||||||
@api_view(['DELETE'])
|
|
||||||
def account_logout(request):
|
|
||||||
'''
|
|
||||||
Log out from a user account
|
|
||||||
'''
|
|
||||||
return JsonResponse({"message": "User logged out."})
|
|
||||||
|
|
9
back/reimbursinator/custom_auth.py
Normal file
9
back/reimbursinator/custom_auth.py
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
from rest_framework.authentication import TokenAuthentication
|
||||||
|
|
||||||
|
class BearerAuthentication(TokenAuthentication):
|
||||||
|
"""
|
||||||
|
This class simply changes the expected token keyword to 'Bearer'
|
||||||
|
from the Django rest authentication default 'Token'. This allows
|
||||||
|
applications like Postman to work with token authentication.
|
||||||
|
"""
|
||||||
|
keyword = "Bearer"
|
|
@ -11,6 +11,7 @@ https://docs.djangoproject.com/en/2.1/ref/settings/
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import os
|
import os
|
||||||
|
#from reimbursinator.custom_auth import BearerAuthentication
|
||||||
|
|
||||||
# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
|
# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
|
||||||
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
|
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
|
||||||
|
@ -40,6 +41,8 @@ INSTALLED_APPS = [
|
||||||
'django.contrib.staticfiles',
|
'django.contrib.staticfiles',
|
||||||
# 3rd party
|
# 3rd party
|
||||||
'rest_framework',
|
'rest_framework',
|
||||||
|
'rest_framework.authtoken',
|
||||||
|
'rest_auth',
|
||||||
'corsheaders',
|
'corsheaders',
|
||||||
# local
|
# local
|
||||||
'users',
|
'users',
|
||||||
|
@ -48,8 +51,12 @@ INSTALLED_APPS = [
|
||||||
|
|
||||||
REST_FRAMEWORK = {
|
REST_FRAMEWORK = {
|
||||||
'DEFAULT_PERMISSION_CLASSES': [
|
'DEFAULT_PERMISSION_CLASSES': [
|
||||||
'rest_framework.permissions.AllowAny',
|
'rest_framework.permissions.IsAuthenticated',
|
||||||
]
|
],
|
||||||
|
'DEFAULT_AUTHENTICATION_CLASSES': [
|
||||||
|
'reimbursinator.custom_auth.BearerAuthentication',
|
||||||
|
'rest_framework.authentication.SessionAuthentication',
|
||||||
|
],
|
||||||
}
|
}
|
||||||
|
|
||||||
MIDDLEWARE = [
|
MIDDLEWARE = [
|
||||||
|
|
|
@ -12,4 +12,6 @@ from django.urls import path, include
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
path('admin/', admin.site.urls),
|
path('admin/', admin.site.urls),
|
||||||
path('api/v1/', include("backend.urls")),
|
path('api/v1/', include("backend.urls")),
|
||||||
|
path('api/v1/account/', include('rest_auth.urls')),
|
||||||
|
path('api-auth/', include('rest_framework.urls')),
|
||||||
]
|
]
|
0
back/users/__init__.py
Normal file
0
back/users/__init__.py
Normal file
|
@ -62,6 +62,25 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="modal" id="editReportModal" 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="editReportModalLabel"></h5>
|
||||||
|
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
|
||||||
|
<span aria-hidden="true">×</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<div class="modal-body">
|
||||||
|
</div>
|
||||||
|
<div class="modal-footer">
|
||||||
|
<button type="button" class="btn btn-danger">Delete Report</button>
|
||||||
|
<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>
|
<script src="js/viewHistory.js"></script>
|
||||||
</body>
|
</body>
|
||||||
|
|
|
@ -1,30 +1,6 @@
|
||||||
// Hack to change endpoint url for each OS
|
// Hack to change endpoint url
|
||||||
function getEndpointDomain() {
|
function getEndpointDomain() {
|
||||||
let OSName;
|
return "https://" + window.location.hostname + ":8444/";
|
||||||
let domain;
|
|
||||||
|
|
||||||
if (navigator.appVersion.indexOf("Win") !== -1)
|
|
||||||
OSName = "Windows";
|
|
||||||
else if (navigator.appVersion.indexOf("Mac") !== -1)
|
|
||||||
OSName = "MacOS";
|
|
||||||
else if (navigator.appVersion.indexOf("X11") !== -1)
|
|
||||||
OSName = "UNIX";
|
|
||||||
else if (navigator.appVersion.indexOf("Linux") !== -1)
|
|
||||||
OSName = "Linux";
|
|
||||||
else
|
|
||||||
OSName = "Unknown OS";
|
|
||||||
|
|
||||||
console.log("Detected operating system: " + OSName);
|
|
||||||
|
|
||||||
if (OSName === "Windows") {
|
|
||||||
domain = "https://192.168.99.100:8444/";
|
|
||||||
} else if (OSName === "MacOS" && navigator.userAgent.includes("Firefox")) {
|
|
||||||
domain = "https://192.168.99.100:8444/"; // That's Shuaiyi
|
|
||||||
} else {
|
|
||||||
domain = "https://localhost:8444/"; // Jack, Preston
|
|
||||||
}
|
|
||||||
|
|
||||||
return domain;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Make a GET request to url and pass response to callback function
|
// Make a GET request to url and pass response to callback function
|
||||||
|
@ -145,13 +121,25 @@ function createCollapsibleCard(key, sectionTitle) {
|
||||||
function createCollapsibleCardBody(key, form, sectionDescription, sectionCompleted) {
|
function createCollapsibleCardBody(key, form, sectionDescription, sectionCompleted) {
|
||||||
// Create wrapper div
|
// Create wrapper div
|
||||||
const div = document.createElement("div");
|
const div = document.createElement("div");
|
||||||
sectionCompleted ? div.classList.add("collapse") : div.classList.add("collapse", "show");
|
const sectionAlert = document.createElement("div");
|
||||||
|
|
||||||
|
if (sectionCompleted) {
|
||||||
|
div.classList.add("collapse");
|
||||||
|
sectionAlert.classList.add("alert", "alert-success");
|
||||||
|
sectionAlert.innerHTML = "This section is complete";
|
||||||
|
} else {
|
||||||
|
div.classList.add("collapse", "show");
|
||||||
|
sectionAlert.classList.add("alert", "alert-danger");
|
||||||
|
sectionAlert.innerHTML = "This section is not complete";
|
||||||
|
}
|
||||||
|
|
||||||
div.setAttribute("data-parent", "#editReportAccordion");
|
div.setAttribute("data-parent", "#editReportAccordion");
|
||||||
div.id = "collapse" + key;
|
div.id = "collapse" + key;
|
||||||
|
|
||||||
// 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");
|
const cardBody = document.createElement("div");
|
||||||
cardBody.classList.add("card-body");
|
cardBody.classList.add("card-body");
|
||||||
|
cardBody.appendChild(sectionAlert);
|
||||||
cardBody.insertAdjacentHTML("beforeend", sectionDescription);
|
cardBody.insertAdjacentHTML("beforeend", sectionDescription);
|
||||||
cardBody.appendChild(form);
|
cardBody.appendChild(form);
|
||||||
div.appendChild(cardBody);
|
div.appendChild(cardBody);
|
||||||
|
@ -160,20 +148,17 @@ function createCollapsibleCardBody(key, form, sectionDescription, sectionComplet
|
||||||
}
|
}
|
||||||
|
|
||||||
function createEditReportForm(parsedData) {
|
function createEditReportForm(parsedData) {
|
||||||
const col = document.querySelector(".col-sm-8");
|
const modalBody = document.querySelector(".modal-body");
|
||||||
const fragment = document.createDocumentFragment();
|
const modalLabel = document.querySelector("#editReportModalLabel");
|
||||||
|
|
||||||
while (col.firstChild) {
|
while (modalBody.firstChild) {
|
||||||
col.removeChild(col.firstChild)
|
modalBody.removeChild(modalBody.firstChild);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add report title and date
|
// Add report title and date
|
||||||
const reportTitle = parsedData.title;
|
const reportTitle = parsedData.title;
|
||||||
const dateCreated = new Date(parsedData.date_created).toLocaleDateString("en-US");
|
const dateCreated = new Date(parsedData.date_created).toLocaleDateString("en-US");
|
||||||
const h3 = document.createElement("h3");
|
modalLabel.innerHTML = reportTitle + " " + dateCreated;
|
||||||
h3.innerHTML = reportTitle + " " + dateCreated;
|
|
||||||
h3.classList.add("text-center");
|
|
||||||
fragment.appendChild(h3);
|
|
||||||
|
|
||||||
// Create accordion
|
// Create accordion
|
||||||
const accordion = document.createElement("div");
|
const accordion = document.createElement("div");
|
||||||
|
@ -218,15 +203,7 @@ function createEditReportForm(parsedData) {
|
||||||
accordion.appendChild(collapsibleCard);
|
accordion.appendChild(collapsibleCard);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add submit button to accordion
|
modalBody.appendChild(accordion);
|
||||||
let submitButton = document.createElement("button");
|
|
||||||
submitButton.innerHTML = "Submit Report";
|
|
||||||
submitButton.type = "submit";
|
|
||||||
submitButton.classList.add("btn", "btn-primary", "btn-lg", "btn-block"); // TODO: add eventListener
|
|
||||||
accordion.appendChild(submitButton);
|
|
||||||
|
|
||||||
fragment.appendChild(accordion)
|
|
||||||
col.appendChild(fragment);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function displayListOfReports(parsedData) {
|
function displayListOfReports(parsedData) {
|
||||||
|
@ -268,7 +245,8 @@ function displayListOfReports(parsedData) {
|
||||||
dateSubmitted = "TBD";
|
dateSubmitted = "TBD";
|
||||||
actionButton.classList.add("btn-primary", "edit-report-button"); // Add event listener class
|
actionButton.classList.add("btn-primary", "edit-report-button"); // Add event listener class
|
||||||
actionButton.innerHTML = "Edit";
|
actionButton.innerHTML = "Edit";
|
||||||
//actionButton.addEventListener("click", openEditReportForm);
|
actionButton.setAttribute("data-toggle", "modal");
|
||||||
|
actionButton.setAttribute("data-target", "#editReportModal");
|
||||||
} else {
|
} else {
|
||||||
// View button
|
// View button
|
||||||
dateSubmitted = new Date(reports[i].date_submitted).toLocaleDateString("en-US");
|
dateSubmitted = new Date(reports[i].date_submitted).toLocaleDateString("en-US");
|
||||||
|
|
Loading…
Reference in a new issue