App/client/root.js

368 lines
14 KiB
JavaScript

class Root
{
static instance = null;
constructor() {
// Init values / parse cookies
if (Root.instance!==null) {
return;
}
Root.instance = this;
this.jwt = this.getCookie("jwt");
this.secToken = this.getCookie("secToken");
this.loggedIn = false;
this.url = "https://app.fw-innenstadt.de/index_new.php/";
this.scanner = new Scanner(this);
this.page = "Start";
this.routesChecksum = "";
const _this = this;
Root.AddEventListenerIfButtonExists("loginButton", function (event) {_this.Login();});
Root.AddEventListenerIfButtonExists("nav_start", function (event) {_this.Open("Start");});
Root.AddEventListenerIfButtonExists("nav_termine", function (event) {_this.Open("Termine");});
Root.AddEventListenerIfButtonExists("nav_dienstpläne", function (event) {_this.Open("Dienstpläne");});
Root.AddEventListenerIfButtonExists("nav_personal", function (event) {_this.Open("Personal");});
Root.AddEventListenerIfButtonExists("nav_prozesse", function (event) {_this.Open("Prozesse");});
Root.AddEventListenerIfButtonExists("nav_spinde", function (event) {_this.Open("Spinde");});
Root.AddEventListenerIfButtonExists("nav_einsätze", function (event) {_this.Open("Einsätze");});
Root.AddEventListenerIfButtonExists("nav_anwesenheiten", function (event) {_this.Open("Anwesenheiten");});
Root.AddEventListenerIfButtonExists("nav_fahrzeuge", function (event) {_this.Open("Fahrzeuge");});
Root.AddEventListenerIfButtonExists("nav_logout", function (event) {_this.Logout();});
document.getElementById("navigation_select").addEventListener("change", function (event) {_this.Open(document.getElementById("navigation_select").value);});
this.FetchRoutes(true);
}
Open(page) {
if ("_LOGOUT_"==page) {
this.Logout();
return;
}
this.setCookie("page", page);
switch (page) {
case "Termine":
//TerminePage.Open();
break;
case "Dienstpläne":
//DienstplänePage.Open();
break;
case "Personal":
PersonalPage.Open();
break;
case "Prozesse":
//ProzessePage.Open();
break;
case "Spinde":
//SpindePage.Open();
break;
case "Einsätze":
//EinsätzePage.Open();
break;
case "Anwesenheiten":
//AnwesenheitenPage.Open();
break;
case "Fahrzeuge":
FahrzeugePage.Open();
break;
default:
//StartPage.Open();
this.setCookie("page", "Start");
}
}
Login() {
var button = document.getElementById("loginButton");
button.disabled = true;
button.className = "login disabled";
const json = {
"login": document.getElementById("loginUser").value,
"password": document.getElementById("loginPassword").value/*,
"secToken": typeof(this.secToken)!="undefined" ? this.secToken : ""*/
};
const _this = this;
Root.SetLoadAnimation(true);
let request = new XMLHttpRequest();
request.open("POST", this.url, true);
request.setRequestHeader("Content-Type", "application/json");
request.setRequestHeader("Accept", "application/json");
request.onreadystatechange = function() {
if (request.readyState != 4) return;
Root.SetLoadAnimation(false);
const {ok, json, etag} = _this.FinishResponse(request);
_this.changeLoginScreen(ok);
if (ok) {
_this.updatePages(etag, json);
_this.Open(_this.getCookie("page"));
setTimeout(Root.instance.FetchPages, 10000, false);
}
};
request.send(JSON.stringify(json));
}
Logout() {
const _this = this;
let request = new XMLHttpRequest();
Root.SetLoadAnimation(true);
request.open("DELETE", this.url, true);
request.setRequestHeader("Content-Type", "application/json");
request.setRequestHeader("Accept", "application/json");
request.onreadystatechange = function() {
if (request.readyState != 4) return;
Root.SetLoadAnimation(false);
_this.FinishResponse(request);
_this.changeLoginScreen(false);
};
request.send({secToken: this.secToken});
}
FetchRoutes(callOpenAfterOk = false) {
if (this.jwt!="") {
Root.SetLoadAnimation(true);
const _this = this;
let request = new XMLHttpRequest();
request.open("OPTIONS", this.url);
request.setRequestHeader("Authorization", "Bearer " + this.jwt);
request.setRequestHeader("Accept", "application/json");
request.onreadystatechange = function() {
if (request.readyState != 4) return;
Root.SetLoadAnimation(false);
const {ok, json, etag} = _this.FinishResponse(request);
if (ok) {
_this.updatePages(etag, json);
if (callOpenAfterOk) {
_this.Open(_this.getCookie("page"));
}
setTimeout(Root.instance.FetchPages, 10000, false);
} }
request.send();
} else {
this.changeLoginScreen(false);
}
}
FinishResponse(request, isHead = false) {
const {ok, json} = isHead ? {ok: true, json: {}} : Root.ParseJson(request.responseText);
if (!ok) {
return {ok: false, json: {}, etag: null};
}
if (typeof(json.messages)!="undefined") {
Root.ShowMessages(json.messages);
}
if (typeof(json.secToken)!="undefined") {
this.secToken = json.secToken;
this.setCookie("secToken", json.secToken);
}
if (typeof(json.jwt)!="undefined") {
this.jwt = json.jwt;
this.setCookie("jwt", json.jwt);
}
if (request.status>=300) {
let statusString = "";
switch (request.status) {
//case 200: statusString = "OK"; break;
//case 201: statusString = "Erstellt"; break;
case 400: statusString = "Fehlerhafte Anfrage"; break;
case 401: statusString = "Anmeldung erforderlich"; this.changeLoginScreen(false); break;
case 403: statusString = "Keine Berechtigung"; break;
case 404: statusString = "Nicht gefunden"; break;
case 500: statusString = "Fehler auf Server"; break;
default: statusString = "" + request.status + " = Unbekannt";
}
Root.ShowMessages(["Anfrage wurde mit Code " + request.status + " abgelehnt.<br />(" + statusString + ")"]);
} else {
const etag = typeof(request.getResponseHeader) === 'function' ? request.getResponseHeader("ETag") : null;
return {ok: true, json: json, etag: etag};
}
return {ok: false, json: {}, etag: null};
}
/* "Private" functions */
updatePages(etag, json) {
if (etag!=this.routesChecksum) {
//StartPage.SetVisibility(true);
//TerminePage.SetVisibility(json.pages.includes("Termine"));
//DienstplänePage.SetVisibility(json.pages.includes("Dienstpläne"));
PersonalPage.SetVisibility(json);
//ProzessePage.SetVisibility(json.pages.includes("Prozesse"));
//SpindePage.SetVisibility(json.pages.includes("Spinde"));
//EinsätzePage.SetVisibility(json.pages.includes("Einsätze"));
//AnwesenheitenPage.SetVisibility(json.pages.includes("Anwesenheiten"));
FahrzeugePage.SetVisibility(json);
this.pagesChecksum = etag;
} }
changeLoginScreen(newStatus) {
var s = document.getElementById('header').style;
if (this.loggedIn==null) {
if (!newStatus) {
s.display = "block";
s.opacity = 1;
}
} else if (newStatus) {
(function fadeOut() {(s.opacity-=0.1)<0 ? s.display="none" : setTimeout(fadeOut, 40)})();
} else {
var button = document.getElementById("loginButton");
button.disabled = false;
button.className = "login";
s.display = "block";
(function fadeIn(){(s.opacity-=-0.1)>1 ? s.opacity=1 : setTimeout(fadeIn, 40)})();
}
this.loggedIn = newStatus;
}
/*updateLoginStatus(loggedIn) {
if (loggedIn) {
if (loggedIn!=this.loggedIn) {
this.changeLoginScreen(true);
}
return true;
} else {
this.changeLoginScreen(false);
}
return false;
}*/
setCookie(cname, cvalue, exdays) {
var d = new Date();
d.setTime(d.getTime() + (exdays*24*60*60*1000));
var expires = "expires="+ d.toUTCString();
document.cookie = cname + "=" + cvalue + ";" + expires + ";path=/;SameSite=Strict;Secure";
}
getCookie(cname){
var name = cname + "=";
var decodedCookie = decodeURIComponent(document.cookie);
var ca = decodedCookie.split(';');
for(var i = 0; i <ca.length; i++) {
var c = ca[i];
while (c.charAt(0) == ' ') {
c = c.substring(1);
}
if (c.indexOf(name) == 0) {
return c.substring(name.length, c.length);
} }
return "";
}
/* Static functions */
static ShowMessages(messages) {
for (var i in messages) {
Toastify({
text: messages[i],
duration: 3000,
close: true,
gravity: "top", // `top` or `bottom`
position: "right", // `left`, `center` or `right`
backgroundColor: "linear-gradient(to right, #00b09b, #96c93d)",
stopOnFocus: true, // Prevents dismissing of toast on hover
}).showToast();
} }
static ToggleVisibility(idImg, idDiv) {
let div = document.getElementById(idDiv);
let img = document.getElementById(idImg);
if (div.style.display === "none") {
div.style.display = "flex";
img.src = "res/dark/hide.png";
} else {
div.style.display = "none";
img.src = "res/dark/show.png";
}
}
static AddEventListenerIfButtonExists(button, func) {
let buttonElement = document.getElementById(button);
if (buttonElement!==null) {
buttonElement.addEventListener('click', func);
}
}
static ParseJson(responseText) {
let json = {};
try {
json = JSON.parse(responseText);
} catch (SyntaxError) {
Root.ShowMessages(["Parsen der Antwort gescheitert. Es folgt die Antwort!", responseText]);
return {ok: false, json: {}};
}
return {ok: true, json: json};
}
static SetLoadAnimation(isLoading) {
var loadElement = document.getElementById("loadImage");
if (null!=loadElement) {
if (isLoading) {
loadElement.innerHTML = "<img src='/res/loading.gif' />";
} else {
loadElement.innerHTML = "";
}
}
}
/*RenderMain(root) {
var html = "<table class='moneyplanner_accounts'>";
html+= "<tr><th>" + (this.viewFrom>0 ? "<button id='view_both_left'><</button>" : "") + (this.viewTo<this.view.length-1 ? "<button id='view_both_right'>></button>" : "") + "</th>";
for (var v=this.viewFrom; v<=this.viewTo; v++) {
html+= "<th>"
+ (v==this.viewFrom && this.viewFrom>0 ? "<button id='view_from_left'><</button>" : "")
+ (v==this.viewTo && this.viewTo>this.viewFrom ? "<button id='view_to_left'><</button>" : "")
+ this.view[v].title
+ (v==this.viewFrom && this.viewFrom<this.viewTo ? "<button id='view_from_right'>></button>" : "")
+ (v==this.viewTo && this.viewTo<this.view.length-1 ? "<button id='view_to_right'>></button>" : "")
+ "</th>";
}
html+= "</tr>";
for (let a in Account.byOrdering) {
html+= Account.byOrdering[a].Render();
}
this.contentContainer.innerHTML = html+"</table>";
const _this = this;
addEventListenerIfButtonExists('view_from_left', function (event) {if (_this.viewFrom>0) {--_this.viewFrom; _this.RenderMain();}});
addEventListenerIfButtonExists('view_from_right', function (event) {if (_this.viewFrom<_this.viewTo) {++_this.viewFrom; _this.RenderMain();}});
addEventListenerIfButtonExists('view_to_left', function (event) {if (_this.viewTo>_this.viewFrom) {--_this.viewTo; _this.RenderMain();}});
addEventListenerIfButtonExists('view_to_right', function (event) {if (_this.viewTo<_this.view.length-1) {++_this.viewTo; _this.RenderMain();}});
addEventListenerIfButtonExists('view_both_left', function (event) {if (_this.viewFrom>0) {--_this.viewFrom; --_this.viewTo; _this.RenderMain();}});
addEventListenerIfButtonExists('view_both_right', function (event) {if (_this.viewTo<_this.view.length-1) {++_this.viewFrom; ++_this.viewTo; _this.RenderMain();}});
for (let a in Account.array) {
let accountId = Account.array[a].id;
addEventListenerIfButtonExists('balances_add_' + accountId, function (event) {Balance.Add(_this, _this.RenderMain, accountId);});
}
}*/
}
/*function ToggleEntryView(id) {api.activeRoute.ToggleEntryView(id);}
function Open(path) {api.Open(path);}
function OpenSelected() {
let s = document.getElementById("navigation_select").value;
if (s=="_LOGOUT_") {Logout();} else {api.Open(s);}
}
function Logout() {api.Open("/index.php/Logout");}
function FilterAdd() {api.activeRoute.FilterAdd();}
function FilterDelete(id) {api.activeRoute.FilterDelete(id);}
function FilterChange(id) {api.activeRoute.FilterChange(id);}
function Add() {api.activeRoute.Add();}
function Delete(id, data = {}) {api.Request("DELETE", data, id);}
function Edit(id) {api.activeRoute.Edit(id);}
function Cancel(id) {api.activeRoute.Cancel(id);}
function Save(id) {api.activeRoute.Save(id);}
function SubShowAdd(id, markers) {api.activeRoute.SubShowAdd(id, markers);}
function SubShowScan(id, subroute, parsers) {api.activeRoute.SubShowScan(id, subroute, parsers);}
function HideScanner() {api.scanner.Stop(); document.getElementById("qrscanner").style.display = "none";}
function SwitchCamera() {api.scanner.SwitchCamera();}
function SubAdd(id, markers, subroute) {api.activeRoute.SubAdd(id, markers, subroute);}
function SubDelete(id, subroute, subid = null) {api.Request("DELETE", {}, id, subroute, subid);}
function Request(method, data, id = null, subroute = null, subid = null) {api.Request(method, data, id, subroute, subid);}
function Print(printID, printName) {api.Request("GET", {Print: printID, PrintName: printName});}
function SelectChange(id, state) {api.activeRoute.SelectChange(id, state);}*/
document.addEventListener ("DOMContentLoaded", () => {
var root = new Root();
});