ulrich@undisclosed
2020-05-16 d0af4cc92d521aee62d8c83bedee5b61c245be4a
commit | author | age
3d5fe0 1 function NutzerApp() {
002c44 2   var self = this;
U 3   var vorlagen;
4   var userid;
5   var loc;
eefd25 6
U 7   this.init = function () {
8     self.vorlagen = new Vorlagen();
9     var dlg = document.querySelector(".dialog");
10     dlg.style.flexBasis = '0em';
f57e84 11     document.querySelector('#top-neu-btn').addEventListener('click', self.nutzer_neu_dialog_zeigen);
eefd25 12     document.querySelector('.west').style.flexBasis = '0em';
U 13     document.querySelector('.ost').style.flexBasis = '0em';
14     self.get_login();
15     self.get_user_list();
16     self.loc = window.location.protocol + '//' + window.location.host;
17   };
002c44 18
f9d0c4 19   /* Nutzerverwaltung */
U 20   
eefd25 21   this.nutzer_neu_dialog_zeigen = function () {
U 22     self.dialog_zeigen('data/tpl/dlg-nutzer-neu.tpl', '', function(){
23       var btn = document.getElementById('nutzer-speichern-btn');
24       if(btn !== null) {
25         btn.addEventListener('click', self.nutzer_speichern);                         
26       }                      
27     });
28   };
29
f9d0c4 30   this.nutzerliste_klick = function(event) {
U 31     var target = event.target;
32     var gewaehlterNutzer = document.querySelector(".nutzer-gewaehlt");
33     if(gewaehlterNutzer !== null) {
34       gewaehlterNutzer.classList.remove("nutzer-gewaehlt");
35     }
36     target.classList.add("nutzer-gewaehlt");
c995b7 37     var nutzerId = target.innerHTML;
d9858d 38     self.rollen_zeigen(nutzerId);
f9d0c4 39   };
d1b8b2 40   
U 41   this.nutzer_speichern = function() {
42     var user = self.nutzer_dialog_lesen();
43     var kww = document.getElementById('nutzer-wkw').value;
44     if(user.pw !== kww) {
45       self.meldung_mit_timeout("Kennworte stimmen nicht ueberein.", 1500);
46     } else {
47       self.neuen_nutzer_speichern('p=' + self.serialisieren(user));
48     }
49   };
50   
51   this.nutzer_dialog_lesen = function() {
52     var id = document.getElementById('nutzer-id').value;
53     var vname = document.getElementById('nutzer-vorname').value;
54     var nname = document.getElementById('nutzer-name').value;
55     var email = document.getElementById('nutzer-email').value;
56     var kw = document.getElementById('nutzer-kw').value;
57     var user = new User(id, kw, vname, nname, email);
58     return user;
59   };
002c44 60
eefd25 61   /* Rollen erteilen und entziehen */
002c44 62   
d9858d 63   this.rollen_zeigen = function(nutzerId) {
f57e84 64     var topBtn = document.querySelector('#top-neu-btn');
U 65     topBtn.removeEventListener('click', self.nutzer_neu_dialog_zeigen);
66     topBtn.addEventListener('click', self.rolle_neu_dialog_zeigen);
67     topBtn.title = "Neue Rolle";
68     
c995b7 69     var m = 'getUserRoleNames';
U 70     var u = '../svc/' + m + '?p=' + nutzerId;
71     self.http_get(u, function (antwort) {
d9858d 72       var jsonAntwort = JSON.parse(antwort);
U 73       var rollen = jsonAntwort.List[0];
74       if(typeof rollen === 'object') {
75         rollen = jsonAntwort;
76       } else {
77         rollen = 'keine';
78       }
c995b7 79       self.vorlagen.html_erzeugen(
U 80         'data/tpl/nutzer-rollen-dlg.tpl',
d9858d 81         rollen,
c995b7 82         function (html) {
U 83           document.querySelector("#nutzer").innerHTML = html;
ab2b54 84           document.querySelector("#nutzer-id").textContent = nutzerId;          
U 85           self.addEvtListener('.granted-role-btn', 'click', self.revoke_role_klick);
d9858d 86           self.alle_rollen_zeigen();
c995b7 87         });
045d48 88     });
U 89     document.querySelector('.zurueck-btn').style.color = 'black';
ab2b54 90   };
U 91   
d9858d 92   this.alle_rollen_zeigen = function() {
U 93     var m = 'getRoleNamesGranted';
94     var u = '../svc/' + m;
95     self.http_get(u, function (antwort2) {
96       self.vorlagen.html_erzeugen(
97         'data/tpl/alle-rollen.tpl',
98         JSON.parse(antwort2),
99         function (html) {
100           document.querySelector(".alle-rollen-behaelter").innerHTML = html;
101           document.querySelector('.zurueck-btn').addEventListener('click', function (e) {
102             self.get_user_list();
103           });
104           self.addEvtListener('.avl-role-btn', 'click', self.grant_role_klick);
105         });
106     });
107   };
108   
ab2b54 109   this.grant_role_klick = function(event) {
U 110     self.alter_role(event, 'grantRole', function(roleId) {
f57e84 111       self.add_role_to_user_roles(roleId);
ab2b54 112     });
f57e84 113   };
U 114   
115   this.add_role_to_user_roles = function(roleId) {
116     var btn = document.createElement("button");
117     btn.type = "button";
118     btn.classList.add("granted-role-btn");
119     btn.id = roleId;
120     btn.textContent = roleId;
121     document.querySelector('.rollen-behaelter').appendChild(btn);
ab2b54 122   };
U 123   
124   this.revoke_role_klick = function(event) {
125     self.alter_role(event, 'revokeRole', function(roleId) {
126       var btn = document.querySelector("#" + roleId);
127       btn.parentNode.removeChild(btn);
128     });
129   };
130   
131   this.alter_role = function(event, method, updateCallback) {
132     var target = event.target;
133     var nutzerId = document.querySelector("#nutzer-id").textContent;
134     var roleId = target.textContent;
f57e84 135     self.alter_role_call(method, nutzerId, roleId, updateCallback);
c995b7 136   };
U 137   
f57e84 138   this.rolle_neu_dialog_zeigen = function () {
U 139     self.dialog_zeigen('data/tpl/dlg-rolle-neu.tpl', '', function(){
140       var btn = document.getElementById('rolle-speichern-btn');
141       if(btn !== null) {
142         btn.addEventListener('click', function() {
143           var nutzerId = document.querySelector("#nutzer-id").textContent;
144           var rolle = document.getElementById('rollen-id').value;
145           self.alter_role_call('grantRole', nutzerId, rolle, function(roleId) {
146             self.add_role_to_user_roles(roleId);
147             self.dialog_schliessen();
148           });
149         });                         
150       }                      
151     });
152   };
eefd25 153
U 154   /* Funktionen aus App-Vorlage */
155
156   this.login_zeigen = function() {
157     self.meldung_mit_timeout("Benutzer: " + self.userid, 1500);
158   };
159   
160   
002c44 161   this.info_dialog_zeigen = function () {
14cc29 162     self.dialog_zeigen('data/tpl/dlg-info.tpl', '');
002c44 163   };
U 164
165   this.seitenleiste_umschalten = function () {
166     var ostDiv = document.querySelector('.ost');
167     if (ostDiv.classList.contains('ost-open')) {
168       ostDiv.classList.remove('ost-open');
169       ostDiv.style.flexBasis = '0em';
170     } else {
171       ostDiv.classList.add('ost-open');
172       ostDiv.style.flexBasis = '6em';
173     }
174   };
175
176   this.fusszeile_umschalten = function () {
177     var suedDiv = document.querySelector('.sued');
178     if (suedDiv.classList.contains('sued-open')) {
179       suedDiv.classList.remove('sued-open');
180       suedDiv.style.height = '0';
181     } else {
182       suedDiv.classList.add('sued-open');
183       suedDiv.style.height = '1.5em';
184     }
185   };
186
187   this.meldung_mit_timeout = function (meldung, timeout) {
188     var s = document.querySelector('.sued');
189     s.textContent = meldung;
d1b8b2 190     if (!s.classList.contains('sued-open')) {
U 191       s.classList.add('sued-open');
192       s.style.height = '1.5em';
193     }
002c44 194     setTimeout(function () {
U 195       s.textContent = 'Bereit.';
196       setTimeout(function () {
197         var suedDiv = document.querySelector('.sued');
198         if (suedDiv.classList.contains('sued-open')) {
199           suedDiv.classList.remove('sued-open');
200           suedDiv.style.height = '0';
201         }
202       }, 500);
203     }, timeout);
204   };
205
206   /* Dialog-Funktionen */
207
208   /*
14cc29 209    * Einen Dialog erzeugen
U 210    * 
211    * Die Vorlage, auf die im Parameter vurl verwiesen wird, wird geladen, 
212    * wenn sie noch nicht benutzt wurde
213    * 
214    * @param {String} vurl - der URL mit der Dialogvorlage
215    * @param {JSON-Objekt} inhalt - was im Dialog an dynamischem Inhalt angezeigt werden soll
216    * @param {function} renderCallback - 
217    *     Funktion, die aufgerufen wird nachdem der Dialog gerendert wurde 
218    * @returns {undefined}
002c44 219    */
14cc29 220   this.dialog_zeigen = function (vurl, inhalt, renderCallback) {
002c44 221     var dlg = document.querySelector(".dialog");
U 222     self.vorlagen.html_erzeugen(
223             vurl,
224             inhalt,
225             function (html) {
3d5fe0 226               dlg.style.flexBasis = '14em';
e86f3c 227               setTimeout(function () {
U 228                 dlg.innerHTML = html;
14cc29 229                 document.querySelector('.close-btn').addEventListener(
U 230                         'click', self.dialog_schliessen);
231                 if(renderCallback !== undefined) {
232                   renderCallback();
233                 }
e86f3c 234               }, 300);
002c44 235             });
U 236   };
237
238   this.dialog_schliessen = function () {
14cc29 239     document.querySelector('.close-btn').removeEventListener(
U 240             'click', self.dialog_schliessen);
002c44 241     var dlg = document.querySelector('.dialog');
U 242     dlg.innerHTML = '';
e86f3c 243     dlg.style.flexBasis = '0em';
002c44 244   };
U 245
246   /* API functions */
247   
d1b8b2 248   this.get_user_list = function() {
002c44 249     var m = 'getUserNameList';
U 250     var u = '../svc/' + m;
d1b8b2 251     self.http_get(u, function (antwort) {
045d48 252       self.vorlagen.html_erzeugen(
U 253         'data/tpl/inhalt.tpl',
254         JSON.parse(antwort),
255         function (h) {
256           var elem = document.getElementById('nutzer');
257           elem.innerHTML = h;
258           self.addEvtListener('p.nutzer-liste-eintrag', 'click', self.nutzerliste_klick);
259           document.querySelector('.zurueck-btn').style.color = '#eee';
d65863 260           self.removeAllListeners('top-neu-btn'); 
U 261           var topBtn = document.querySelector('#top-neu-btn');
262           topBtn.title = "Neuer Benutzer";
263           topBtn.addEventListener('click', self.nutzer_neu_dialog_zeigen);
045d48 264         });
b73bb6 265       });
U 266   };
d1b8b2 267   
U 268   this.neuen_nutzer_speichern = function(u) {
269     var url = '../svc/createUser';
270     self.http_post(url, u, function (antwort) {
271       self.get_user_list();
14cc29 272       document.getElementById('nutzer-speichern-btn').removeEventListener(
U 273         'click', self.nutzer_speichern);
d1b8b2 274       self.dialog_schliessen();
U 275     });
276   };
002c44 277
f57e84 278   this.alter_role_call = function(method, nutzerId, roleId, updateCallback) {
U 279     var u = '../svc/' + method;
280     var data = "p=" + self.serialisieren(new UserRole(nutzerId, roleId));
281     self.http_post(u, data, function (antwort) {  
282       updateCallback(roleId);
283     });            
284   };
285   
002c44 286   /* -------- An- und Abmelden ------------- */
U 287
d1b8b2 288   this.get_login = function() {
002c44 289     var m = '?c=de.uhilger.um.pub.SessionManager&m=getSessionUser';
U 290     var u = '../pub' + m;
d1b8b2 291     self.http_get(u, function (resp) {
002c44 292       self.userid = resp;
U 293       self.login_zeigen();
294       //document.querySelector("#userMenu").textContent = resp;
295     });
296   };
297
298   this.um_logout = function() {
299     var m = '?c=de.uhilger.um.pub.SessionManager&m=expireSession';
300     var u = '../pub' + m;
d1b8b2 301     self.http_get(u, function (resp) {
002c44 302       //$('#userMenu').text('nicht angemeldet');
U 303       window.location.href = '../logout.html';
304     });
305   };
306
307   /* -------- ajax helper functions ----------- */
308
d1b8b2 309   this.http_get = function (u, scallback) {    
002c44 310     var xmlhttp = new XMLHttpRequest();
U 311     var url = u;
312     xmlhttp.onreadystatechange = function() {
d1b8b2 313       if (this.readyState === 4 && this.status === 200) {
002c44 314         scallback(this.responseText);
U 315       }
316     };
317     xmlhttp.open("GET", url, true);
318     xmlhttp.send();
319   };
3d5fe0 320   
d1b8b2 321   this.http_post = function (url, data, callback) {
U 322     var xhr = new XMLHttpRequest();
323     xhr.onreadystatechange = function() {
324       if (this.readyState === 4 && this.status === 200) {
325         callback(this.responseText);
326       }
327     };
328     xhr.open("POST", url, true);
329     xhr.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
330     xhr.send(data);
331   };
332   
3d5fe0 333 /* ----- Hilfsfunktionen ----- */
U 334
335   this.serialisieren = function(obj) {
336     return '{"' + obj.constructor.name + '":' + JSON.stringify(obj) + '}';
337   };
ab2b54 338   
U 339   this.addEvtListener = function(selector, eventName, func) {
340     var elems = document.querySelectorAll(selector);
341     var index;
342     for (index = 0; index < elems.length; index++) {
343       elems[index].addEventListener(eventName, func);
344     }
345   };
d65863 346   
U 347   this.removeAllListeners = function(elementId) {
348     var el = document.getElementById(elementId);
349     elClone = el.cloneNode(true);
350     el.parentNode.replaceChild(elClone, el);
351   };
002c44 352
U 353 }
3d5fe0 354
70d6da 355 /* ----- Vorlagen ----- */
U 356
357 function Vorlagen() {
358   var self = this;
359   this.cache = {}; // mustache templates
360
361   /*
362     Das HTML erzeugen, das entsteht, wenn eine Vorlage mit Inhalt
363     gefüllt wird
364
365     Das Füllen erfolgt asynchron, d.h. der Programmlauf geht nach dem
366     Aufruf weiter ohne auf das Laden und Füllen der Vorlage zu warten.
367     Das fertige HTML wird der Callback-Funktion übergeben
368     sobald die Vorlage geladen und gefüllt ist, unabhängig davon, wo der
369     Programmlauf zu diesem Zeitpunkt mittlerweile ist.
370
371     vurl - URL zur Vorlagendatei
372     inhalt - die JSON-Struktur, deren Inhalt in die
373               Vorlage gefüllt werden soll
374     cb - Callback-Funktion, die gerufen wird, wenn die Vorlage gefüllt ist.
375           Dieser Callback-Funktion wird das fertige HTML übergeben
376   */
377   this.html_erzeugen = function(vurl, inhalt, cb) {
378     var vorlage = self.cache[vurl];
379     if(vorlage === undefined) {
380       self.vorlage_laden_und_fuellen(vurl, inhalt, cb);
381     } else {
382       self.vorlage_fuellen(vurl, inhalt, cb);
383     }
384   };
385
386   this.vorlage_fuellen = function(vurl, inhalt, cb) {
387     cb(Mustache.render(self.cache[vurl], inhalt));
388   };
389
390   /*
391     Eine Vorlage vom Server in den lokalen Speicher laden
392     vurl - der URL unter dem die Vorlage zu finden ist
393     inhalt - die JSON-Struktur, deren Inhalt in die
394               Vorlage gefüllt werden soll
395     cb - callback: Diese Funktion wird gerufen, wenn die Vorlage mit dem
396             Inhalt gefüllt ist
397   */
398   this.vorlage_laden_und_fuellen = function(vurl, inhalt, cb) {
399     var xmlhttp = new XMLHttpRequest();
400     xmlhttp.onreadystatechange = function() {
401       if (this.readyState == 4 && this.status == 200) {
402         self.cache[vurl] = this.responseText;
403         self.vorlage_fuellen(vurl, inhalt, cb);
404       }
405     };
406     xmlhttp.open("GET", vurl, true);
407     xmlhttp.send();
408   };
409
410 }
411
3d5fe0 412
U 413 /* ----- Objekte ----- */
414
415 function User(i, p, fn, ln, em) {
416   this.id = i;
417   this.pw = p;
418   this.firstName = fn;
419   this.lastName = ln;
420   this.email = em;
421 }
422
ab2b54 423 function UserRole(u, r) {
U 424   this.userId = u;
425   this.role = r;
426 }