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