// ---------------------------------------------------------------------- // VARS // ---------------------------------------------------------------------- // current winbox instances var aWinBoxes = {}; // default frame border color for winboxes var WINBOX_data = false; var WINBOX_lsvariable = "winbox_data"; var WINBOX_defaults = { background: "#456", border: 5, class: ["no-min", "no-max", "no-full", "ciwinboxinfos"], // viewport top: 70, right: 20, bottom: 20, left: 20 }; /** * get data of all winboxes - or of a single winbox only - from localstorage * @param {string} sId optional: id of a winbox * @returns */ function wb_getdata(sId) { WINBOX_data = WINBOX_data ? WINBOX_data : (localStorage.getItem(WINBOX_lsvariable) ? JSON.parse(localStorage.getItem(WINBOX_lsvariable)) : {} ); return sId ? (WINBOX_data[sId] ? WINBOX_data[sId] : {}) : WINBOX_data; } /** * get data of all winboxes - or of a single winbox only - from localstorage * @param {string} sId optional: id of a winbox * @returns */ function wb_getdefaults(sId, aOverrides) { var _aReturn = Object.assign({}, WINBOX_defaults); for (var key in aOverrides) { _aReturn[key] = aOverrides[key]; } var _aData = wb_getdata(sId); for (var key in _aData) { _aReturn[key] = _aData[key]; } if (_aReturn['x']<_aReturn['left']){ _aReturn['x']=_aReturn['left']; } if (_aReturn['y']<_aReturn['top']){ _aReturn['y']=_aReturn['top']; } return _aReturn; } /** * save data for a given winbox * @param {string} sId id of a winbox * @param {array} _aNewvalues properties to store as key+value */ function wb_savedata(sId, _aNewvalues) { WINBOX_data = WINBOX_data ? WINBOX_data : wb_getdata(); if (!WINBOX_data[sId]) { WINBOX_data[sId] = {}; } for (var key in _aNewvalues) { WINBOX_data[sId][key] = _aNewvalues[key]; } localStorage.setItem(WINBOX_lsvariable, JSON.stringify(WINBOX_data)); } // ---------------------------------------------------------------------- // FUNCTIONS // ---------------------------------------------------------------------- /** * initialize soft scrolling for links with css class "scroll-link" * @see http://css-tricks.com/snippets/jquery/smooth-scrolling/ * @returns {undefined} */ function initSoftscroll() { $(function () { // $('a[href*=#]:not([href=#])').click(function() { $('a.scroll-link').click(function () { if (location.pathname.replace(/^\//, '') == this.pathname.replace(/^\//, '') && location.hostname == this.hostname) { var target = $(this.hash); target = target.length ? target : $('[name=' + this.hash.slice(1) + ']'); if (target.length) { $('html,body').animate({ scrollTop: target.offset().top - 70 }, 300); return false; } } }); }); } /** * Shows a modal message by setting the inner HTML of div#divmodalmessage * to the given message, and showing div#divmodal. * * @param {string} sMessage - The message to display in the modal */ function showModalMessage(sMessage) { $('#divmodalmessage').html(sMessage); $('#divmodal').show(); } /** * Hide modal message box */ function hideModalMessage() { $('#divmodal').hide(); return false; } /** * show a window displaying the content of a given dom id using Winbox * * @param {string} sId dom id of a div to show * @param {string} sTitle title for the winbox window * @returns */ function showIdAsModalMessage(sId, sTitle) { if (aWinBoxes[sId]) { return true; } var oWrapper = document.getElementById(sId); var aOptions = wb_getdefaults(sId, { title: sTitle, id: 'winbox-' + sId, // position + size x: "center", y: "center", width: 700, height: 500, // take content from existing div // mount: oWrapper // mount: document.getElementById(sId).cloneNode(true), html: oWrapper.innerHTML, onmove: function (x, y) { wb_savedata(sId, { x: x, y: y }); }, onresize: function (x, y) { wb_savedata(sId, { width: x, height: y }); }, onclose: function () { delete aWinBoxes[sId]; } }); aWinBoxes[sId] = WinBox(aOptions); return false; } /** * shellcmd plugin ... toggle output window * @param {string} sId id of the wrapper * @param {object} oLink a tag in the navbar with link for toggling window */ function toggleShellWindow(sId, oLink) { if (aWinBoxes[sId]) { aWinBoxes[sId].close(); } else { var oWrapper = document.getElementById(sId); var aOptions = wb_getdefaults(sId, { title: oLink.innerText, id: 'winbox-' + sId, class: ["no-min", "no-max", /* "no-full", "no-resize", "no-move"*/ "ciwinbox"], // position + size x: "center", y: "center", width: 10, height: 10, // take content from existing div mount: oWrapper, onmove: function (x, y) { wb_savedata(sId, { x: x, y: y }); }, onresize: function (x, y) { wb_savedata(sId, { width: x, height: y }); }, onclose: function () { delete aWinBoxes[sId]; $(oLink).removeClass('active'); } }); aWinBoxes[sId] = WinBox(aOptions); if (oLink) { $(oLink).addClass('active'); } if(aOptions['width']==10){ window.setTimeout("aWinBoxes['" + sId + "'].resize(" + (oWrapper.clientWidth + 25) + ", " + (oWrapper.clientHeight + 150) + ").move('center', 'center')", 10); } } } // ---------------------------------------------------------------------- // general init in each page // ---------------------------------------------------------------------- $(document).ready(function () { initSoftscroll(); }); // ---------------------------------------------------------------------- // action log // ---------------------------------------------------------------------- /** * get filtered action log table * @returns {undefined} */ function updateActionlog() { var sUrlBase = "/webservice/?class=Actionlog&action=getLogs&type=json&args="; // columns in output table var aTableitems = ["id", "time", "loglevel", "ip", "user", "project", "action", "message"]; var aArgs = { 'project': $('#selectproject').val(), 'from': $('#selectfrom').val(), 'to': $('#selectto').val(), 'limit': $('#selectlimit').val(), } // --- get data var sUrl = sUrlBase + '[' + JSON.stringify(aArgs) + ']'; $.post(sUrl, function (aData) { var sHtml = ''; // --- generate output if (aData.length && aData[0]["id"]) { for (i = 0; i < aData.length; i++) { sHtml += '<tr class="tractionlogs loglevel-' + aData[i]["loglevel"] + ' ' + aData[i]["project"] + '">'; for (j = 0; j < aTableitems.length; j++) { sHtml += '<td>' + aData[i][aTableitems[j]] + '</td>'; } sHtml += '</tr>'; } } drawTimeline(aData); if (!sHtml) { sHtml = sMsgNolog; // variable is set in actionlog.class.php } else { sHead = ''; for (j = 0; j < aTableitems.length; j++) { sHead += '<th>' + aTableitems[j] + '</th>'; } sHead = '<thead><tr>' + sHead + '</tr></thead>'; sHtml = '<table class="table table-condensed">' + sHead + '<tbody>' + sHtml + '</tbody></table>'; } $('#tableLogactions').html(sHtml); filterLogTable(); }); } /** * render timeline with Visjs * * @param {array} aData * @returns {undefined} */ function drawTimeline(aData) { var sDataset = ''; var container = document.getElementById('divTimeline'); if (!container) { return false; } container.innerHTML = ''; // empty the div if (aData.length && aData[0]["id"]) { for (i = 0; i < aData.length; i++) { // keys are // var aTableitems=["id", "time", "loglevel", "ip", "user", "project", "action", "message"]; sLabel = aData[i]["project"] + '<br>' + aData[i]["action"]; sTitle = aData[i]["time"] + '<br>' + aData[i]["loglevel"] + '<br><br>Projekt: ' + aData[i]["project"] + '<br>User: ' + aData[i]["user"] + ' (' + aData[i]["ip"] + ')<br>' + aData[i]["message"]; sDataset += (sDataset ? ', ' : '') + '{"id": ' + i + ', "content": "' + sLabel + '", "start": "' + aData[i]["time"].replace(/\ /, "T") + '", "title": "' + sTitle + '", "group": "' + aData[i]["project"] + '", "className": "loglevel-' + aData[i]["loglevel"] + '" }'; } aDataset = JSON.parse('[' + sDataset + ']'); var items = new vis.DataSet(aDataset); // Configuration for the Timeline var options = { // verticalScroll: false, clickToUse: true }; // Create a Timeline var timeline = new vis.Timeline(container, items, options); } } /** * filter table with action logs by filtertext (input field) */ function filterLogTable() { var sSearch = $("#efilterlogs").val(); var Regex = new RegExp(sSearch, "i"); $(".tractionlogs").each(function () { sVisible = "none"; if (Regex.exec(this.innerHTML)) { sVisible = ""; } $(this).css("display", sVisible); }); return false; } // ---------------------------------------------------------------------- // tables // ---------------------------------------------------------------------- var localStoreTablefilter = "tblvalue" + location.pathname; // http://blog.mastykarz.nl/jquery-regex-filter/ jQuery.extend( jQuery.expr[':'], { regex: function (a, i, m) { var r = new RegExp(m[3], 'i'); return r.test(jQuery(a).text()); } } ); /* highlight v4 Highlights arbitrary terms. <http://johannburkard.de/blog/programming/javascript/highlight-javascript-text-higlighting-jquery-plugin.html> MIT license. Johann Burkard <http://johannburkard.de> <mailto:jb@eaio.com> */ jQuery.fn.highlight = function (pat) { function innerHighlight(node, pat) { var skip = 0; if (node.nodeType == 3) { var pos = node.data.toUpperCase().indexOf(pat); if (pos >= 0) { var spannode = document.createElement('span'); spannode.className = 'highlight'; var middlebit = node.splitText(pos); var endbit = middlebit.splitText(pat.length); var middleclone = middlebit.cloneNode(true); spannode.appendChild(middleclone); middlebit.parentNode.replaceChild(spannode, middlebit); skip = 1; } } else if (node.nodeType == 1 && node.childNodes && !/(script|style)/i.test(node.tagName)) { for (var i = 0; i < node.childNodes.length; ++i) { i += innerHighlight(node.childNodes[i], pat); } } return skip; } return this.length && pat && pat.length ? this.each(function () { innerHighlight(this, pat.toUpperCase()); }) : this; }; jQuery.fn.removeHighlight = function () { return this.find("span.highlight").each(function () { this.parentNode.firstChild.nodeName; with (this.parentNode) { replaceChild(this.firstChild, this); normalize(); } }).end(); }; /** * add a filter form to a table * @returns {undefined} */ function addFilterToTable() { var sValue = localStorage.getItem(localStoreTablefilter) ? localStorage.getItem(localStoreTablefilter) : ''; var sForm = '<form class="pure-form">\n\ <fieldset>\n\ <label for="eFilter">\n\ <i class="fa fa-filter"></i> Tabelle filtern\n\ </label>\n\ <input type="text" id="eFilter" size="40" name="q" placeholder="Suchbegriff..." value="'+ sValue + '" onkeypress="filterTable(this);" onkeyup="filterTable(this);" onchange="filterTable(this);">\n\ <button class="pure-button" onclick="$(\'#eFilter\').val(\'\'); filterTable(); return false;"><i class="fa fa-times"></i> </button>\n\ <span id="filterinfo"></span>\n\ </fieldset>\n\ </form><div style="clear: both;"></div>'; $(sForm).insertBefore($("table").first()); } /** * callback ... filter the table * use addFilterToTable() before. * @returns {undefined} */ function filterTable() { var filter = $('#eFilter').val(); localStorage.setItem(localStoreTablefilter, filter); $("table").removeHighlight(); if (filter) { $("tr:regex('" + filter + "')").show(); $("tr:not(:regex('" + filter + "'))").hide(); $("tr").first().show(); $("td").highlight(filter); } else { $("td").removeHighlight(); $('tr').show(); } var sInfo = ''; var iVisible = -1; // 1 abziehen wg. tr der ersten Zeile $("tr").each(function () { if ($(this).css('display') != 'none') { iVisible++; } }); sInfo = (iVisible == ($("tr").length - 1)) ? "ges.: <strong>" + ($("tr").length - 1) + "</strong> Einträge" : "<strong>" + iVisible + "</strong> von " + ($("tr").length - 1) + " Einträgen" ; $('#filterinfo').html(sInfo); } // ---------------------------------------------------------------------- // API secret // ---------------------------------------------------------------------- function generateSecret(length) { var result = ''; var characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'; var charactersLength = characters.length; for (var i = 0; i < length; i++) { result += characters.charAt(Math.floor(Math.random() * charactersLength)); } return result; } // ----------------------------------------------------------------------