From 002c445416c96ec3af57df02e86ac8d5aaecf38b Mon Sep 17 00:00:00 2001 From: ulrich@undisclosed Date: Fri, 08 May 2020 15:36:26 +0000 Subject: [PATCH] ui2 begonnen --- web/ui2/data/menu/edit.json | 27 + web/ui2/data/tpl/app-menu.tpl | 20 + web/ui2/data/tpl/inhalt.tpl | 3 web/ui2/js/app-menu.js | 137 +++++++ web/ui2/stile.css | 322 ++++++++++++++++ web/ui2/data/menu/untermenue-1.json | 27 + web/ui2/js/data.js | 148 +++++++ web/ui2/js/vorlagen.js | 66 +++ web/ui2/js/app.js | 186 +++++++++ web/ui2/data/menu/datei.json | 27 + web/ui2/data/menu/nutzer.json | 27 + web/ui2/data/menu/hauptmenue.json | 27 + web/ui2/data/tpl/dlg-info.tpl | 8 web/ui2/font/pikto.ttf | 0 web/ui2/index.html | 75 +++ web/ui2/data/menu/untermenue-2.json | 27 + 16 files changed, 1,127 insertions(+), 0 deletions(-) diff --git a/web/ui2/data/menu/datei.json b/web/ui2/data/menu/datei.json new file mode 100644 index 0000000..7cbedb9 --- /dev/null +++ b/web/ui2/data/menu/datei.json @@ -0,0 +1,27 @@ +{ + "menue": { + "menuetitel": "Datei", + "wurzel": false, + "vorgaenger": { + "vtitel": "Hauptmenü", + "vverweis": "hauptmenue.json" + }, + "inhalt": [ + { + "titel": "Neuer Text", + "umenue": false, + "funktion": "app.datei_neuer_text" + }, + { + "titel": "noch mehr", + "umenue": true, + "verweis": "untermenue-2.json" + }, + { + "titel": "Benachrichtigung 2", + "umenue": false, + "funktion": "app.message_2" + } + ] + } +} diff --git a/web/ui2/data/menu/edit.json b/web/ui2/data/menu/edit.json new file mode 100644 index 0000000..24f547c --- /dev/null +++ b/web/ui2/data/menu/edit.json @@ -0,0 +1,27 @@ +{ + "menue": { + "menuetitel": "Untermenü 1", + "wurzel": false, + "vorgaenger": { + "vtitel": "Hauptmenü", + "vverweis": "hauptmenue.json" + }, + "inhalt": [ + { + "titel": "Benachrichtigung 1", + "umenue": false, + "funktion": "app.message_1" + }, + { + "titel": "noch mehr", + "umenue": true, + "verweis": "untermenue-2.json" + }, + { + "titel": "Benachrichtigung 2", + "umenue": false, + "funktion": "app.message_2" + } + ] + } +} diff --git a/web/ui2/data/menu/hauptmenue.json b/web/ui2/data/menu/hauptmenue.json new file mode 100644 index 0000000..da2c9e5 --- /dev/null +++ b/web/ui2/data/menu/hauptmenue.json @@ -0,0 +1,27 @@ +{ + "menue": { + "menuetitel": "Hauptmenü", + "wurzel": true, + "vorgaenger": { + "vtitel": "", + "vverweis": "" + }, + "inhalt": [ + { + "titel": "Datei", + "umenue": true, + "verweis": "datei.json" + }, + { + "titel": "Bearbeiten", + "umenue": true, + "verweis": "edit.json" + }, + { + "titel": "Nutzer", + "umenue": true, + "verweis": "nutzer.json" + } + ] + } +} diff --git a/web/ui2/data/menu/nutzer.json b/web/ui2/data/menu/nutzer.json new file mode 100644 index 0000000..deec071 --- /dev/null +++ b/web/ui2/data/menu/nutzer.json @@ -0,0 +1,27 @@ +{ + "menue": { + "menuetitel": "Untermenü 1", + "wurzel": false, + "vorgaenger": { + "vtitel": "Hauptmenü", + "vverweis": "hauptmenue.json" + }, + "inhalt": [ + { + "titel": "Benachrichtigung 1", + "umenue": false, + "funktion": "app.message_1" + }, + { + "titel": "noch mehr", + "umenue": true, + "verweis": "untermenue-2.json" + }, + { + "titel": "Abmelden", + "umenue": false, + "funktion": "app.fm_logout" + } + ] + } +} diff --git a/web/ui2/data/menu/untermenue-1.json b/web/ui2/data/menu/untermenue-1.json new file mode 100644 index 0000000..24f547c --- /dev/null +++ b/web/ui2/data/menu/untermenue-1.json @@ -0,0 +1,27 @@ +{ + "menue": { + "menuetitel": "Untermenü 1", + "wurzel": false, + "vorgaenger": { + "vtitel": "Hauptmenü", + "vverweis": "hauptmenue.json" + }, + "inhalt": [ + { + "titel": "Benachrichtigung 1", + "umenue": false, + "funktion": "app.message_1" + }, + { + "titel": "noch mehr", + "umenue": true, + "verweis": "untermenue-2.json" + }, + { + "titel": "Benachrichtigung 2", + "umenue": false, + "funktion": "app.message_2" + } + ] + } +} diff --git a/web/ui2/data/menu/untermenue-2.json b/web/ui2/data/menu/untermenue-2.json new file mode 100644 index 0000000..00c0268 --- /dev/null +++ b/web/ui2/data/menu/untermenue-2.json @@ -0,0 +1,27 @@ +{ + "menue": { + "menuetitel": "Untermenü 2", + "wurzel": false, + "vorgaenger": { + "vtitel": "Untermenü 1", + "vverweis": "untermenue-1.json" + }, + "inhalt": [ + { + "titel": "Funktion U2.1", + "umenue": false, + "funktion": "app.message_3('U2.1')" + }, + { + "titel": "Funktion U2.2", + "umenue": false, + "funktion": "app.message_3('U2.2')" + }, + { + "titel": "Funktion U2.3", + "umenue": false, + "funktion": "app.message_3('U2.3')" + } + ] + } +} diff --git a/web/ui2/data/tpl/app-menu.tpl b/web/ui2/data/tpl/app-menu.tpl new file mode 100644 index 0000000..de9b1e4 --- /dev/null +++ b/web/ui2/data/tpl/app-menu.tpl @@ -0,0 +1,20 @@ +{{#menue}} + <p class="app-menu-kopf"> + {{menuetitel}} + </p> + <ul class="app-menu"> + {{^wurzel}} + <li class="app-menu-item-back bitem" data-verweis="{{vorgaenger.vverweis}}"> + ❮ {{vorgaenger.vtitel}}</i> + </li> + {{/wurzel}} + {{#inhalt}} + {{#umenue}} + <li class="app-menu-item smenu" data-verweis="{{verweis}}">{{titel}} ❯</li> + {{/umenue}} + {{^umenue}} + <li class="app-menu-item mitem" data-verweis="{{funktion}}" >{{titel}} <span class="app-menu-item-submark">❯</span></i></li> + {{/umenue}} + {{/inhalt}} + </ul> +{{/menue}} \ No newline at end of file diff --git a/web/ui2/data/tpl/dlg-info.tpl b/web/ui2/data/tpl/dlg-info.tpl new file mode 100644 index 0000000..692ace2 --- /dev/null +++ b/web/ui2/data/tpl/dlg-info.tpl @@ -0,0 +1,8 @@ +<div class="dlg-info"> + <span class="close-btn pointer-cursor">✖</span> + <div class="dlg-behaelter"> + <div class="dlg-info-app-titel">app-vorlage</div> + <div class="dlg-info-app-info">Eine Vorlage für Apps von <a href='https://uhilger.de'>Ulrich Hilger</a>.</div> + <div class="dlg-info-app-info">Weitere Infos im <a href='/gitblit/docs/web!app-vorlage.git'>Code-Repository</a>.</div> + </div> +</div> diff --git a/web/ui2/data/tpl/inhalt.tpl b/web/ui2/data/tpl/inhalt.tpl new file mode 100644 index 0000000..56f553e --- /dev/null +++ b/web/ui2/data/tpl/inhalt.tpl @@ -0,0 +1,3 @@ +<div> + +</div> diff --git a/web/ui2/font/pikto.ttf b/web/ui2/font/pikto.ttf new file mode 100644 index 0000000..175b3f4 --- /dev/null +++ b/web/ui2/font/pikto.ttf Binary files differ diff --git a/web/ui2/index.html b/web/ui2/index.html new file mode 100644 index 0000000..65e9f32 --- /dev/null +++ b/web/ui2/index.html @@ -0,0 +1,75 @@ +<!DOCTYPE html> +<html> + <head> + <title>Nutzerverwaltung</title> + <meta charset="UTF-8"> + <meta name="viewport" content="width=device-width, initial-scale=1.0"> + <meta name="apple-mobile-web-app-capable" content="yes" /> + <link href="https://fonts.googleapis.com/css?family=Roboto+Condensed" rel="stylesheet"> + <link rel="stylesheet" type="text/css" href="stile.css"> + </head> + <body> + <!-- Kopfzeile --> + <div class="nord"> + <div id="nav-menu"> + <div id="nav-toggle" class="hamburger hamburger--elastic"> + <div class="hamburger-box"> + <div class="hamburger-inner"></div> + </div> + </div> + </div> + <div class="app-titel"> + <span id="app-titel">Nutzerverwaltung</span> + </div> + </div> + <div class="inhalt"> + <!-- westliche Seitenleiste --> + <div class="west"> + westliche Seitenleiste + </div> + <div class="zentrum-behaelter"> + <!-- Einblendbereich --> + <div class="dialog"></div> + <!-- Breadcrumb --> + <div class="breadcrumb"> + <a class="bc-link">Ordner 1</a> / + <a class="bc-link">Ordner 2</a> + </div> + <!-- zentraler Inhaltsbereich --> + <div class="zentrum"> + <div class="zentraler-inhalt"> + <div class="zentrum-liste" id="nutzer"> + <figure> + <i class="demo-icon icon-folder"></i> + <figcaption class="i-name">icon-folder</figcaption> + </figure> + </div> + </div> + </div> + </div> + <!-- oestliche Seitenleiste --> + <div class="ost ost-open"> + östliche Seitenleiste + </div> + </div> + <!-- Fusszeile --> + <div class="sued sued-open"> + Fußzeile + </div> + <!-- Skripte --> + <script src="/jslib/mustache/mustache.min.js"></script> + <script src="/jslib/moment/moment-with-locales.min.js"></script> + <script src="/jslib/numeral/numeral.min.js"></script> + <script src="js/app-menu.js"></script> + <script src="js/vorlagen.js"></script> + <script src="js/data.js"></script> + <script src="js/app.js"></script> + <script> + var app; + document.addEventListener('DOMContentLoaded', function () { + app = new AppVorlage(); + app.init(); + }); + </script> + </body> +</html> diff --git a/web/ui2/js/app-menu.js b/web/ui2/js/app-menu.js new file mode 100644 index 0000000..6a3b11e --- /dev/null +++ b/web/ui2/js/app-menu.js @@ -0,0 +1,137 @@ +function AppMenu() { + var self = this; + var _app_menu_selector; + var _app_menu_mbreite; + var _app_menu_url_prefix = ""; + var _app_menu_template; + + /* + * die nachfolgenden Funktionen steuern das ein- und + * ausblenden des menues + */ + this.init = function (url_prefix, mdesc, mtpl, mselector, mbreite) { + self._app_menu_selector = mselector; + self._app_menu_mbreite = mbreite; + var menu = document.querySelector(self._app_menu_selector); + menu.style.flexBasis = '0em'; + self._app_menu_url_prefix = url_prefix; + /* + Die Menue-Vorlage wird einmal zu Beginn geladen und + waehrend dem Programmlauf immer wieder neu zum Rendern + einer dynamisch gelandenen Menuebeschreibung verwendet + */ + var request = new XMLHttpRequest(); + request.open("GET", mtpl); + request.addEventListener('load', function(event) { + if (request.status >= 200 && request.status < 300) { + self._app_menu_template = request.responseText; + Mustache.parse(self._app_menu_template); // optional, speeds up future uses + self.app_menu_laden(mdesc); + } else { + console.warn(request.statusText, request.responseText); + } + }); + request.send(); + }; + + this.app_menu_do_toggle = function(elem) { + self.toggle(); + }; + + this.toggle = function() { + var menuDiv = document.querySelector(self._app_menu_selector); + if(menuDiv.classList.contains('app-menu-open')) { + menuDiv.classList.remove('app-menu-open'); + menuDiv.style.flexBasis = '0em'; + } else { + menuDiv.classList.add('app-menu-open'); + menuDiv.style.flexBasis = self._app_menu_mbreite; + } + }; + + /* + * ab hier Steuerung des Menueinhalts + */ + + + /* + * Menuebeschreibung als JSON-Datei laden + * mdesc: der URL einer JSON-Datei mit einer Menuebeschreibung + * richtung: z.Zt. unbenutzt: Animationsrichtung + */ + this.app_menu_laden = function(mdesc, richtung) { + var xmlhttp = new XMLHttpRequest(); + var url = self._app_menu_url_prefix + mdesc; + xmlhttp.onreadystatechange = function() { + if (this.readyState == 4 && this.status == 200) { + self.app_menu_bauen(JSON.parse(this.responseText), richtung); + } + }; + xmlhttp.open("GET", url, true); + xmlhttp.send(); + }; + + /* + Aus einer Menuebeschreibung im JSON-Format mit Hilfe + von Mustache und der zu Beginn geladenen HTML-Vorlage + ein div-Element zusammenbauen, das als Menue eingeblendet + werden kann und dem Element _app_menu_selector hinzufuegen + */ + this.app_menu_bauen = function(menuejs, richtung) { + + // neues Menue als div-Element zusammensetzen + var menuDiv = document.createElement("div"); + menuDiv.classList.add('app-menu-content'); + menuDiv.style.position = 'relative'; + menuDiv.innerHTML = Mustache.render(self._app_menu_template, menuejs); + + // altes Menue loeschen + self.app_menu_remove_event_listener_multi('.smenu', 'click', self.app_menu_klick_herunter); + self.app_menu_remove_event_listener_multi('.bitem', 'click', self.app_menu_klick_herauf); + self.app_menu_remove_event_listener_multi('.mitem', 'click', self.app_menu_ausfuehren); + var menu = document.querySelector(self._app_menu_selector); + menu.innerHTML = ''; + + // neues Menue hinzufuegen + menu.append(menuDiv); + self.app_menu_add_event_listener_multi('.smenu', 'click', self.app_menu_klick_herunter); + self.app_menu_add_event_listener_multi('.bitem', 'click', self.app_menu_klick_herauf); + self.app_menu_add_event_listener_multi('.mitem', 'click', self.app_menu_ausfuehren); + + menuDiv = document.querySelector('.app-menu-content'); + menuDiv.classList.add('slidein-from-right'); + }; + + this.app_menu_klick_herunter = function() { + self.app_menu_laden(this.getAttribute('data-verweis'), 'herunter'); + }; + + this.app_menu_klick_herauf = function() { + self.app_menu_laden(this.getAttribute('data-verweis'), 'herauf'); + }; + + this.app_menu_ausfuehren = function() { + var functionName = this.getAttribute('data-verweis'); + eval(functionName + "(this)"); + }; + + /* --- Helferlein ---*/ + /* + sel - '.smenu' + evt - 'click' fuer onclick + func - der verweis auf die funktion + */ + this.app_menu_remove_event_listener_multi = function(sel, evt, func) { + var elem = document.querySelectorAll(sel); + for (var index = 0; index < elem.length; index++) { + elem[index].removeEventListener(evt, func); + } + }; + + this.app_menu_add_event_listener_multi = function(sel, evt, func) { + var elem = document.querySelectorAll(sel); + for (var index = 0; index < elem.length; index++) { + elem[index].addEventListener(evt, func); + } + }; +} diff --git a/web/ui2/js/app.js b/web/ui2/js/app.js new file mode 100644 index 0000000..ad224ea --- /dev/null +++ b/web/ui2/js/app.js @@ -0,0 +1,186 @@ +function AppVorlage() { + var self = this; + var appMenu; + var vorlagen; + var api; + var userid; + var pfad = ''; + var loc; + var modus = 'kacheln'; + var PERS_DIR = "Persoenlich"; + var PUB_DIR = "Oeffentlich"; + var DAV_DIR = "Austausch"; + var BASE_DIR = "$basis"; + var DATA_DIR = "$daten"; + var WWW_DIR = "www"; + + this.datei_neuer_text = function () { + self.meldung_mit_timeout("Neuer Text", 1500); + }; + + /* Funktionen aus App-Vorlage */ + + this.init = function () { + self.vorlagen = new Vorlagen(); + self.appMenu = new AppMenu(); + self.appMenu.init( + "data/menu/", + "hauptmenue.json", + "data/tpl/app-menu.tpl", + ".west", + "8em"); + document.querySelector('.hamburger').addEventListener('click', function (e) { + self.menue_umschalten(); + }); + self.um_get_login(); + self.um_get_user_list(); + self.loc = window.location.protocol + '//' + window.location.host; + }; + + this.login_zeigen = function() { + self.meldung_mit_timeout("Benutzer: " + self.userid, 1500); + }; + + this.menue_umschalten = function () { + var ham = document.querySelector(".hamburger"); + ham.classList.toggle("is-active"); // hamburger-icon umschalten + self.appMenu.toggle(); // menue oeffnen/schliessen + }; + + this.info_dialog_zeigen = function () { + self.dialog_laden_und_zeigen('data/tpl/dlg-info.tpl', ''); + self.menue_umschalten(); + }; + + this.seitenleiste_umschalten = function () { + var ostDiv = document.querySelector('.ost'); + if (ostDiv.classList.contains('ost-open')) { + ostDiv.classList.remove('ost-open'); + ostDiv.style.flexBasis = '0em'; + } else { + ostDiv.classList.add('ost-open'); + ostDiv.style.flexBasis = '6em'; + } + self.menue_umschalten(); + }; + + this.fusszeile_umschalten = function () { + var suedDiv = document.querySelector('.sued'); + if (suedDiv.classList.contains('sued-open')) { + suedDiv.classList.remove('sued-open'); + suedDiv.style.height = '0'; + } else { + suedDiv.classList.add('sued-open'); + suedDiv.style.height = '1.5em'; + } + self.menue_umschalten(); + }; + + this.meldung_mit_timeout = function (meldung, timeout) { + var s = document.querySelector('.sued'); + s.textContent = meldung; + setTimeout(function () { + s.textContent = 'Bereit.'; + setTimeout(function () { + var suedDiv = document.querySelector('.sued'); + if (suedDiv.classList.contains('sued-open')) { + suedDiv.classList.remove('sued-open'); + suedDiv.style.height = '0'; + } + }, 500); + }, timeout); + }; + + /* Dialog-Funktionen */ + + /* + Einen Dialog aus Vorlagen erzeugen + + vurl - URL zur Dialogvorlage + msgTpl - URL mit einer Vorlage eines Mitteilungstextes (optional) + */ + this.dialog_laden_und_zeigen = function (vurl, msgTpl) { + if (msgTpl !== '') { + fetch(msgTpl) + .then(data => { + // Handle data + self.dialog_zeigen(vurl, data); + }).catch(error => { + // Handle error + }); + } else { + self.dialog_zeigen(vurl, ''); + } + }; + + this.dialog_zeigen = function (vurl, inhalt) { + var dlg = document.querySelector(".dialog"); + self.vorlagen.html_erzeugen( + vurl, + inhalt, + function (html) { + //dlg.html(html); + dlg.style.height = '5em'; + dlg.innerHTML = html; + document.querySelector('.close-btn').addEventListener('click', self.dialog_schliessen); + //dlg.slideDown(300); + }); + }; + + this.dialog_schliessen = function () { + document.querySelector('.close-btn').removeEventListener('click', self.dialog_schliessen); + //$('.dialog').slideUp(300); + var dlg = document.querySelector('.dialog'); + //dlg.style.display = "none"; + dlg.style.height = '0'; + dlg.innerHTML = ''; + }; + + /* API functions */ + + this.um_get_user_list = function() { + var m = 'getUserNameList'; + var u = '../svc/' + m; + self.fm_get(u, "json", function (antwort) { + var elem = document.getElementById('nutzer'); + elem.textContent = antwort; + }); + } + + + /* -------- An- und Abmelden ------------- */ + + this.um_get_login = function() { + var m = '?c=de.uhilger.um.pub.SessionManager&m=getSessionUser'; + var u = '../pub' + m; + self.fm_get(u, "text", function (resp) { + self.userid = resp; + self.login_zeigen(); + //document.querySelector("#userMenu").textContent = resp; + }); + }; + + this.um_logout = function() { + var m = '?c=de.uhilger.um.pub.SessionManager&m=expireSession'; + var u = '../pub' + m; + self.fm_get(u, "text", function (resp) { + //$('#userMenu').text('nicht angemeldet'); + window.location.href = '../logout.html'; + }); + }; + + /* -------- ajax helper functions ----------- */ + + this.fm_get = function (u, dtype, scallback) { + var xmlhttp = new XMLHttpRequest(); + var url = u; + xmlhttp.onreadystatechange = function() { + if (this.readyState == 4 && this.status == 200) { + scallback(this.responseText); + } + }; + xmlhttp.open("GET", url, true); + xmlhttp.send(); + }; + +} diff --git a/web/ui2/js/data.js b/web/ui2/js/data.js new file mode 100644 index 0000000..821ba31 --- /dev/null +++ b/web/ui2/js/data.js @@ -0,0 +1,148 @@ +/* + Dateiverwaltung - File management in your browser + Copyright (C) 2017 Ulrich Hilger, http://uhilger.de + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as + published by the Free Software Foundation, either version 3 of the + License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + + + +/* + * In data.js finden sich die Objekte vom Browser-Client + * der Dateiverwaltung + */ + + + +/* ----- Objekte ----- */ + +function IssueList(il) { + this.issues = il; +} + +function CompilerIssue(sn, ms, ki, ln) { + var self = this; + this.sourceName = sn; + this.message = ms; + this.kind = ki; + this.lineNumber = ln; +} + +function FileList(fl) { + this.files = fl; +} + +function FileRef(obj) { + var self = this; + this.fr = obj; + this.fnx; + this.fext = ''; + + this.typeClass = function () { + if (modus == 'kacheln') { + if (self.fr.isDirectory) { + return 'fa-folder ordner'; + } else { + return 'fa-file datei'; + } + } else { + if (self.fr.isDirectory) { + return 'fa-folder ordner'; + } else { + return 'fa-file-o datei'; + } + } + }; + + this.mini = function () { + var miniatur = false; + var namen = self.fr.absolutePath.split('/'); + if (namen.length > 0) { + self.fnx = decodeURIComponent(namen[namen.length - 1]); + } else { + self.fnx = decodeURIComponent(self.fr.absolutePath); + } + if (self.fnx.indexOf('.jpg') > -1 || self.fnx.indexOf('.png') > -1 || + self.fnx.indexOf('.gif') > -1 || self.fnx.indexOf('.jpeg') > -1) { + miniatur = true; + } + return miniatur; + }; + + this.dia = function () { + return fm_slideshow; + }; + + this.miniurl = function () { + // var userid = $('#userMenu').text(); + if (self.fext === '') { + //self.fext = ''; + var dotpos = self.fnx.indexOf('.'); + if (dotpos > -1) { + var fny = self.fnx; + self.fnx = self.fnx.substring(0, dotpos); + self.fext = fny.substr(dotpos); + } + } + var path = fm_get_path(app.userid); + var imgurl = loc + path + '/' + self.fnx + '_tn' + self.fext; + return imgurl; + + }; + + this.bildurl = function () { + // var userid = $('#userMenu').text(); + if (self.fext === '') { + //self.fext = ''; + var dotpos = self.fnx.indexOf('.'); + if (dotpos > -1) { + var fny = self.fnx; + self.fnx = self.fnx.substring(0, dotpos); + self.fext = fny.substr(dotpos); + } + } + var path = fm_get_path(app.userid); + var imgurl = loc + path + '/' + self.fnx + self.fext; + return imgurl; + }; + + this.fileName = function () { + + var namen = self.fr.absolutePath.split('/'); + if (namen.length > 0) { + return decodeURIComponent(namen[namen.length - 1]); + } else { + return decodeURIComponent(self.fr.absolutePath); + } + + }; + + this.fileDate = function () { + return moment(self.fr.lastModified).format("YYYY-MM-DD-hh-mm-ss-SSS"); + }; + + this.fileSize = function () { + return numeral(self.fr.length).format("0.00 b"); + }; +} + +function BcrFiles(fl) { + this.files = fl; +} + +function BcrFile(rp, n) { + this.relPath = rp; + this.fName = n; +} + diff --git a/web/ui2/js/vorlagen.js b/web/ui2/js/vorlagen.js new file mode 100644 index 0000000..d76cd94 --- /dev/null +++ b/web/ui2/js/vorlagen.js @@ -0,0 +1,66 @@ + + +function Vorlagen() { + var self = this; + this.cache = {}; // mustache templates + + /* + Das HTML erzeugen, das entsteht, wenn eine Vorlage mit Inhalt + gefüllt wird + + Das Füllen erfolgt asynchron, d.h. der Programmlauf geht nach dem + Aufruf weiter ohne auf das Laden und Füllen der Vorlage zu warten. + Das fertige HTML wird der Callback-Funktion übergeben + sobald die Vorlage geladen und gefüllt ist, unabhängig davon, wo der + Programmlauf zu diesem Zeitpunkt mittlerweile ist. + + vurl - URL zur Vorlagendatei + inhalt - die JSON-Struktur, deren Inhalt in die + Vorlage gefüllt werden soll + cb - Callback-Funktion, die gerufen wird, wenn die Vorlage gefüllt ist. + Dieser Callback-Funktion wird das fertige HTML übergeben + */ + this.html_erzeugen = function(vurl, inhalt, cb) { + var vorlage = self.cache[vurl]; + if(vorlage === undefined) { + self.vorlage_laden_und_fuellen(vurl, inhalt, cb); + } else { + self.vorlage_fuellen(vurl, inhalt, cb); + } + }; + + this.vorlage_fuellen = function(vurl, inhalt, cb) { + cb(Mustache.render(self.cache[vurl], inhalt)); + }; + + /* + Eine Vorlage vom Server in den lokalen Speicher laden + vurl - der URL unter dem die Vorlage zu finden ist + inhalt - die JSON-Struktur, deren Inhalt in die + Vorlage gefüllt werden soll + cb - callback: Diese Funktion wird gerufen, wenn die Vorlage mit dem + Inhalt gefüllt ist + */ + this.vorlage_laden_und_fuellen = function(vurl, inhalt, cb) { + /* + $.ajax({ + url: vurl, + type: "GET", + dataType : "text" + }).done(function( vorlage ) { + self.cache[vurl] = vorlage; + self.vorlage_fuellen(vurl, inhalt, cb); + }); + */ + var xmlhttp = new XMLHttpRequest(); + xmlhttp.onreadystatechange = function() { + if (this.readyState == 4 && this.status == 200) { + self.cache[vurl] = this.responseText; + self.vorlage_fuellen(vurl, inhalt, cb); + } + }; + xmlhttp.open("GET", vurl, true); + xmlhttp.send(); + }; + +} diff --git a/web/ui2/stile.css b/web/ui2/stile.css new file mode 100644 index 0000000..e3ee310 --- /dev/null +++ b/web/ui2/stile.css @@ -0,0 +1,322 @@ +/* + Created on : 24.01.2020, 09:08:45 + Author : ulrich +*/ + + + + + + +/* aus App-Vorlage */ + +html, body { + margin: 0; + padding: 0; + height: 100%; /* Anmerkung 2 */ + font-size: larger; + font-family: 'Roboto Condensed'; +} +body { + min-height: 0; /* Anmerkung 1 */ + display: flex; + flex-flow: column; +} +.inhalt { + display: flex; + flex-flow: row; + height: 100%; /* Anmerkung 2 */ + min-height: 0; /* Anmerkung 1 */ + background-color: #ededed; + overflow: hidden; +} +.nord { + background-color: black; + display: flex; + flex-flow: row; + height: 2em; + align-items: center; +} +.sued { + height: 1.5em; + overflow: hidden; + transition: all 0.3s ease-in; + background-color: lightgray; +} +.west { + flex-grow: 0; + flex-shrink: 0; + flex-basis: 4em; + background-color: white; + transition: all 0.3s ease-in; + overflow: hidden; + white-space: nowrap; +} +.ost { + flex-grow: 0; + flex-shrink: 0; + flex-basis: 6em; + transition: all 0.3s ease-in; + background-color: antiquewhite; + overflow: hidden; +} +.zentrum-behaelter { + display: flex; + flex-flow: column; + /* background-color: #eaeaea; */ + width: 100%; +} + +.zentrum { + width: 100%; + height: 100%; + overflow-x: hidden; + overflow-y: auto; + -webkit-overflow-scrolling: touch; +} + +.zentraler-inhalt { + padding: 0.5em; +} + +/* + Anmerkungen: + 1.) min.height: 0 fuer body und inhalt ist gegen einen Bug, vgl. + http://stackoverflow.com/questions/33859811/understanding-flexbox-and-overflowauto + 2.) height 100% fuer html, body und inhalt sorgt dafuer, dass sich alles + immer ueber das gesamte Browserfenster ausdehnt. +*/ + +.app-titel { + margin-left: 0.6em; + color: white; +} + +.pointer-cursor { + cursor: pointer; +} + +.breadcrumb { + background-color: beige; + padding: 0.2em; + font-size: medium; +} + +.dialog { + position: relative; + /* height: 0.1em; */ + transition: all 0.3s ease-in; +} + +.dlg-behaelter { + line-height: 1.6; + padding: 0.4em; +} + +.dlg-info { + background-color: #dcf2fb; /* blau */ + padding: 0.4em; +} + +/* + Close Button + + <div> + <span class="close-btn">✖</span> + </div> +*/ + +.close-btn { + position: absolute; + top: 0px; + right: 0.4em; + margin: 0; + padding: 0; + font-size: 1.3em; + color: #b8b8b8; +} + +/* für app-menu */ + + +.app-menu { + margin: 0; + padding: 0; +} + +.app-menu-kopf { + text-align: center; +} + +ul.app-menu { + list-style: none; +} + +.app-menu-item-back { + margin-bottom: 0.3em; + cursor: pointer; +} + +.app-menu-item { + text-align: right; + cursor: pointer; +} + +.app-menu-item-submark { + color: transparent; + cursor: pointer; +} + +/* + Das div-Element, das das Menue aufnimmt erhaelt + die Klasse app-menu-content +*/ +.app-menu-content { + overflow: hidden; +} + +/* für Hamburger Icon */ + +.hamburger { + display: inline-block; + cursor: pointer; + transition-property: opacity, filter; + transition-duration: 0.15s; + transition-timing-function: linear; + font: inherit; + color: inherit; + text-transform: none; + background-color: transparent; + border: 0; + margin: 0; + overflow: visible; +} + +.hamburger:hover { + opacity: 0.7; +} + +.hamburger-box { + width: 40px; + height: 24px; + display: inline-block; + position: relative; +} + +.hamburger-inner { + display: block; + top: 50%; + margin: 0; +} + +.hamburger-inner, .hamburger-inner::before, .hamburger-inner::after { + width: 30px; + height: 4px; + background-color: white; /* #000; */ + border-radius: 4px; + position: absolute; + transition-property: transform; + transition-duration: 0.15s; + transition-timing-function: ease; +} + +.hamburger-inner::before, .hamburger-inner::after { + content: ""; + display: block; +} + +.hamburger-inner::before { + top: -10px; +} + +.hamburger-inner::after { + bottom: -10px; +} + +/* + * Elastic + */ +.hamburger--elastic .hamburger-inner { + top: 2px; + transition-duration: 0.275s; + transition-timing-function: cubic-bezier(0.68, -0.55, 0.265, 1.55); +} + +.hamburger--elastic .hamburger-inner::before { + top: 10px; + transition: opacity 0.125s 0.275s ease; +} + +.hamburger--elastic .hamburger-inner::after { + top: 20px; + transition: transform 0.275s cubic-bezier(0.68, -0.55, 0.265, 1.55); +} + +.hamburger--elastic.is-active .hamburger-inner { + transform: translate3d(0, 10px, 0) rotate(135deg); + transition-delay: 0.075s; +} + +.hamburger--elastic.is-active .hamburger-inner::before { + transition-delay: 0s; + opacity: 0; +} + +.hamburger--elastic.is-active .hamburger-inner::after { + transform: translate3d(0, -20px, 0) rotate(-270deg); + transition-delay: 0.075s; +} + +/* Font für Piktogramme mit Fontello aus FontAwesome erzeugt */ + +@font-face { + font-family: 'pikto'; + src: url('font/pikto.ttf?37040783') format('truetype'); + font-weight: normal; + font-style: normal; +} + + [class^="icon-"]:before, [class*=" icon-"]:before { + font-family: "pikto"; + font-style: normal; + font-weight: normal; + speak: none; + + display: inline-block; + text-decoration: inherit; + width: 1em; + margin-right: .2em; + text-align: center; + /* opacity: .8; */ + + /* For safety - reset parent styles, that can break glyph codes*/ + font-variant: normal; + text-transform: none; + + /* fix buttons height, for twitter bootstrap */ + line-height: 1em; + + /* Animation center compensation - margins should be symmetric */ + /* remove if not needed */ + margin-left: .2em; + + /* you can be more comfortable with increased icons size */ + /* font-size: 120%; */ + + /* Font smoothing. That was taken from TWBS */ + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; + + /* Uncomment for 3D effect */ + /* text-shadow: 1px 1px 1px rgba(127, 127, 127, 0.3); */ +} + +.icon-folder:before { content: '\e800'; } /* '' */ +.icon-folder-open:before { content: '\e801'; } /* '' */ +.icon-th-large:before { content: '\e802'; } /* '' */ +.icon-th-list:before { content: '\e803'; } /* '' */ +.icon-doc-text:before { content: '\f0f6'; } /* '' */ +.icon-folder-empty:before { content: '\f114'; } /* '' */ +.icon-folder-open-empty:before { content: '\f115'; } /* '' */ +.icon-doc-inv:before { content: '\f15b'; } /* '' */ +.icon-doc-text-inv:before { content: '\f15c'; } /* '' */ \ No newline at end of file -- Gitblit v1.9.3