Merge branch 'pr/FreddleSpl0it/4527' into feature/bootstrap5

This commit is contained in:
DerLinkman
2022-06-15 11:22:59 +02:00
160 changed files with 339944 additions and 5883 deletions

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

13269
data/web/js/build/008-chart.js Normal file

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

View File

@@ -1,778 +0,0 @@
//Copyright 2014-2015 Google Inc. All rights reserved.
//Use of this source code is governed by a BSD-style
//license that can be found in the LICENSE file or at
//https://developers.google.com/open-source/licenses/bsd
// ref: https://github.com/google/u2f-ref-code/blob/master/u2f-gae-demo/war/js/u2f-api.js
/**
* @fileoverview The U2F api.
*/
'use strict';
/**
* Modification:
* Wrap implementation so that we can exit if window.u2f is already supplied by the browser (see below).
*/
(function (root) {
/**
* Modification:
* Only continue load this library if window.u2f is not already supplied by the browser.
*/
var browserImplementsU2f = !!((typeof root.u2f !== 'undefined') && root.u2f.register);
if (browserImplementsU2f) {
root.u2f.isSupported = true;
return;
}
/**
* Namespace for the U2F api.
* @type {Object}
*/
var u2f = root.u2f || {};
/**
* Modification:
* Check if browser supports U2F API before this wrapper was added.
*/
u2f.isSupported = !!(((typeof u2f !== 'undefined') && u2f.register) || ((typeof chrome !== 'undefined') && chrome.runtime));
/**
* FIDO U2F Javascript API Version
* @number
*/
var js_api_version;
/**
* The U2F extension id
* @const {string}
*/
// The Chrome packaged app extension ID.
// Uncomment this if you want to deploy a server instance that uses
// the package Chrome app and does not require installing the U2F Chrome extension.
u2f.EXTENSION_ID = 'kmendfapggjehodndflmmgagdbamhnfd';
// The U2F Chrome extension ID.
// Uncomment this if you want to deploy a server instance that uses
// the U2F Chrome extension to authenticate.
// u2f.EXTENSION_ID = 'pfboblefjcgdjicmnffhdgionmgcdmne';
/**
* Message types for messsages to/from the extension
* @const
* @enum {string}
*/
u2f.MessageTypes = {
'U2F_REGISTER_REQUEST': 'u2f_register_request',
'U2F_REGISTER_RESPONSE': 'u2f_register_response',
'U2F_SIGN_REQUEST': 'u2f_sign_request',
'U2F_SIGN_RESPONSE': 'u2f_sign_response',
'U2F_GET_API_VERSION_REQUEST': 'u2f_get_api_version_request',
'U2F_GET_API_VERSION_RESPONSE': 'u2f_get_api_version_response'
};
/**
* Response status codes
* @const
* @enum {number}
*/
u2f.ErrorCodes = {
'OK': 0,
'OTHER_ERROR': 1,
'BAD_REQUEST': 2,
'CONFIGURATION_UNSUPPORTED': 3,
'DEVICE_INELIGIBLE': 4,
'TIMEOUT': 5
};
/**
* A message for registration requests
* @typedef {{
* type: u2f.MessageTypes,
* appId: ?string,
* timeoutSeconds: ?number,
* requestId: ?number
* }}
*/
u2f.U2fRequest;
/**
* A message for registration responses
* @typedef {{
* type: u2f.MessageTypes,
* responseData: (u2f.Error | u2f.RegisterResponse | u2f.SignResponse),
* requestId: ?number
* }}
*/
u2f.U2fResponse;
/**
* An error object for responses
* @typedef {{
* errorCode: u2f.ErrorCodes,
* errorMessage: ?string
* }}
*/
u2f.Error;
/**
* Data object for a single sign request.
* @typedef {enum {BLUETOOTH_RADIO, BLUETOOTH_LOW_ENERGY, USB, NFC}}
*/
u2f.Transport;
/**
* Data object for a single sign request.
* @typedef {Array<u2f.Transport>}
*/
u2f.Transports;
/**
* Data object for a single sign request.
* @typedef {{
* version: string,
* challenge: string,
* keyHandle: string,
* appId: string
* }}
*/
u2f.SignRequest;
/**
* Data object for a sign response.
* @typedef {{
* keyHandle: string,
* signatureData: string,
* clientData: string
* }}
*/
u2f.SignResponse;
/**
* Data object for a registration request.
* @typedef {{
* version: string,
* challenge: string
* }}
*/
u2f.RegisterRequest;
/**
* Data object for a registration response.
* @typedef {{
* version: string,
* keyHandle: string,
* transports: Transports,
* appId: string
* }}
*/
u2f.RegisterResponse;
/**
* Data object for a registered key.
* @typedef {{
* version: string,
* keyHandle: string,
* transports: ?Transports,
* appId: ?string
* }}
*/
u2f.RegisteredKey;
/**
* Data object for a get API register response.
* @typedef {{
* js_api_version: number
* }}
*/
u2f.GetJsApiVersionResponse;
//Low level MessagePort API support
/**
* Sets up a MessagePort to the U2F extension using the
* available mechanisms.
* @param {function((MessagePort|u2f.WrappedChromeRuntimePort_))} callback
*/
u2f.getMessagePort = function (callback) {
if (typeof chrome != 'undefined' && chrome.runtime) {
// The actual message here does not matter, but we need to get a reply
// for the callback to run. Thus, send an empty signature request
// in order to get a failure response.
var msg = {
type: u2f.MessageTypes.U2F_SIGN_REQUEST,
signRequests: []
};
chrome.runtime.sendMessage(u2f.EXTENSION_ID, msg, function () {
if (!chrome.runtime.lastError) {
// We are on a whitelisted origin and can talk directly
// with the extension.
u2f.getChromeRuntimePort_(callback);
} else {
// chrome.runtime was available, but we couldn't message
// the extension directly, use iframe
u2f.getIframePort_(callback);
}
});
} else if (u2f.isAndroidChrome_()) {
u2f.getAuthenticatorPort_(callback);
} else if (u2f.isIosChrome_()) {
u2f.getIosPort_(callback);
} else {
// chrome.runtime was not available at all, which is normal
// when this origin doesn't have access to any extensions.
u2f.getIframePort_(callback);
}
};
/**
* Detect chrome running on android based on the browser's useragent.
* @private
*/
u2f.isAndroidChrome_ = function () {
var userAgent = navigator.userAgent;
return userAgent.indexOf('Chrome') != -1 &&
userAgent.indexOf('Android') != -1;
};
/**
* Detect chrome running on iOS based on the browser's platform.
* @private
*/
u2f.isIosChrome_ = function () {
return ["iPhone", "iPad", "iPod"].indexOf(navigator.platform) > -1;
};
/**
* Connects directly to the extension via chrome.runtime.connect.
* @param {function(u2f.WrappedChromeRuntimePort_)} callback
* @private
*/
u2f.getChromeRuntimePort_ = function (callback) {
var port = chrome.runtime.connect(u2f.EXTENSION_ID,
{ 'includeTlsChannelId': true });
setTimeout(function () {
callback(new u2f.WrappedChromeRuntimePort_(port));
}, 0);
};
/**
* Return a 'port' abstraction to the Authenticator app.
* @param {function(u2f.WrappedAuthenticatorPort_)} callback
* @private
*/
u2f.getAuthenticatorPort_ = function (callback) {
setTimeout(function () {
callback(new u2f.WrappedAuthenticatorPort_());
}, 0);
};
/**
* Return a 'port' abstraction to the iOS client app.
* @param {function(u2f.WrappedIosPort_)} callback
* @private
*/
u2f.getIosPort_ = function (callback) {
setTimeout(function () {
callback(new u2f.WrappedIosPort_());
}, 0);
};
/**
* A wrapper for chrome.runtime.Port that is compatible with MessagePort.
* @param {Port} port
* @constructor
* @private
*/
u2f.WrappedChromeRuntimePort_ = function (port) {
this.port_ = port;
};
/**
* Format and return a sign request compliant with the JS API version supported by the extension.
* @param {Array<u2f.SignRequest>} signRequests
* @param {number} timeoutSeconds
* @param {number} reqId
* @return {Object}
*/
u2f.formatSignRequest_ =
function (appId, challenge, registeredKeys, timeoutSeconds, reqId) {
if (js_api_version === undefined || js_api_version < 1.1) {
// Adapt request to the 1.0 JS API
var signRequests = [];
for (var i = 0; i < registeredKeys.length; i++) {
signRequests[i] = {
version: registeredKeys[i].version,
challenge: challenge,
keyHandle: registeredKeys[i].keyHandle,
appId: appId
};
}
return {
type: u2f.MessageTypes.U2F_SIGN_REQUEST,
signRequests: signRequests,
timeoutSeconds: timeoutSeconds,
requestId: reqId
};
}
// JS 1.1 API
return {
type: u2f.MessageTypes.U2F_SIGN_REQUEST,
appId: appId,
challenge: challenge,
registeredKeys: registeredKeys,
timeoutSeconds: timeoutSeconds,
requestId: reqId
};
};
/**
* Format and return a register request compliant with the JS API version supported by the extension..
* @param {Array<u2f.SignRequest>} signRequests
* @param {Array<u2f.RegisterRequest>} signRequests
* @param {number} timeoutSeconds
* @param {number} reqId
* @return {Object}
*/
u2f.formatRegisterRequest_ =
function (appId, registeredKeys, registerRequests, timeoutSeconds, reqId) {
if (js_api_version === undefined || js_api_version < 1.1) {
// Adapt request to the 1.0 JS API
for (var i = 0; i < registerRequests.length; i++) {
registerRequests[i].appId = appId;
}
var signRequests = [];
for (var i = 0; i < registeredKeys.length; i++) {
signRequests[i] = {
version: registeredKeys[i].version,
challenge: registerRequests[0],
keyHandle: registeredKeys[i].keyHandle,
appId: appId
};
}
return {
type: u2f.MessageTypes.U2F_REGISTER_REQUEST,
signRequests: signRequests,
registerRequests: registerRequests,
timeoutSeconds: timeoutSeconds,
requestId: reqId
};
}
// JS 1.1 API
return {
type: u2f.MessageTypes.U2F_REGISTER_REQUEST,
appId: appId,
registerRequests: registerRequests,
registeredKeys: registeredKeys,
timeoutSeconds: timeoutSeconds,
requestId: reqId
};
};
/**
* Posts a message on the underlying channel.
* @param {Object} message
*/
u2f.WrappedChromeRuntimePort_.prototype.postMessage = function (message) {
this.port_.postMessage(message);
};
/**
* Emulates the HTML 5 addEventListener interface. Works only for the
* onmessage event, which is hooked up to the chrome.runtime.Port.onMessage.
* @param {string} eventName
* @param {function({data: Object})} handler
*/
u2f.WrappedChromeRuntimePort_.prototype.addEventListener =
function (eventName, handler) {
var name = eventName.toLowerCase();
if (name == 'message' || name == 'onmessage') {
this.port_.onMessage.addListener(function (message) {
// Emulate a minimal MessageEvent object
handler({ 'data': message });
});
} else {
console.error('WrappedChromeRuntimePort only supports onMessage');
}
};
/**
* Wrap the Authenticator app with a MessagePort interface.
* @constructor
* @private
*/
u2f.WrappedAuthenticatorPort_ = function () {
this.requestId_ = -1;
this.requestObject_ = null;
}
/**
* Launch the Authenticator intent.
* @param {Object} message
*/
u2f.WrappedAuthenticatorPort_.prototype.postMessage = function (message) {
var intentUrl =
u2f.WrappedAuthenticatorPort_.INTENT_URL_BASE_ +
';S.request=' + encodeURIComponent(JSON.stringify(message)) +
';end';
document.location = intentUrl;
};
/**
* Tells what type of port this is.
* @return {String} port type
*/
u2f.WrappedAuthenticatorPort_.prototype.getPortType = function () {
return "WrappedAuthenticatorPort_";
};
/**
* Emulates the HTML 5 addEventListener interface.
* @param {string} eventName
* @param {function({data: Object})} handler
*/
u2f.WrappedAuthenticatorPort_.prototype.addEventListener = function (eventName, handler) {
var name = eventName.toLowerCase();
if (name == 'message') {
var self = this;
/* Register a callback to that executes when
* chrome injects the response. */
window.addEventListener(
'message', self.onRequestUpdate_.bind(self, handler), false);
} else {
console.error('WrappedAuthenticatorPort only supports message');
}
};
/**
* Callback invoked when a response is received from the Authenticator.
* @param function({data: Object}) callback
* @param {Object} message message Object
*/
u2f.WrappedAuthenticatorPort_.prototype.onRequestUpdate_ =
function (callback, message) {
var messageObject = JSON.parse(message.data);
var intentUrl = messageObject['intentURL'];
var errorCode = messageObject['errorCode'];
var responseObject = null;
if (messageObject.hasOwnProperty('data')) {
responseObject = /** @type {Object} */ (
JSON.parse(messageObject['data']));
}
callback({ 'data': responseObject });
};
/**
* Base URL for intents to Authenticator.
* @const
* @private
*/
u2f.WrappedAuthenticatorPort_.INTENT_URL_BASE_ =
'intent:#Intent;action=com.google.android.apps.authenticator.AUTHENTICATE';
/**
* Wrap the iOS client app with a MessagePort interface.
* @constructor
* @private
*/
u2f.WrappedIosPort_ = function () { };
/**
* Launch the iOS client app request
* @param {Object} message
*/
u2f.WrappedIosPort_.prototype.postMessage = function (message) {
var str = JSON.stringify(message);
var url = "u2f://auth?" + encodeURI(str);
location.replace(url);
};
/**
* Tells what type of port this is.
* @return {String} port type
*/
u2f.WrappedIosPort_.prototype.getPortType = function () {
return "WrappedIosPort_";
};
/**
* Emulates the HTML 5 addEventListener interface.
* @param {string} eventName
* @param {function({data: Object})} handler
*/
u2f.WrappedIosPort_.prototype.addEventListener = function (eventName, handler) {
var name = eventName.toLowerCase();
if (name !== 'message') {
console.error('WrappedIosPort only supports message');
}
};
/**
* Sets up an embedded trampoline iframe, sourced from the extension.
* @param {function(MessagePort)} callback
* @private
*/
u2f.getIframePort_ = function (callback) {
// Create the iframe
var iframeOrigin = 'chrome-extension://' + u2f.EXTENSION_ID;
var iframe = document.createElement('iframe');
iframe.src = iframeOrigin + '/u2f-comms.html';
iframe.setAttribute('style', 'display:none');
document.body.appendChild(iframe);
var channel = new MessageChannel();
var ready = function (message) {
if (message.data == 'ready') {
channel.port1.removeEventListener('message', ready);
callback(channel.port1);
} else {
console.error('First event on iframe port was not "ready"');
}
};
channel.port1.addEventListener('message', ready);
channel.port1.start();
iframe.addEventListener('load', function () {
// Deliver the port to the iframe and initialize
iframe.contentWindow.postMessage('init', iframeOrigin, [channel.port2]);
});
};
//High-level JS API
/**
* Default extension response timeout in seconds.
* @const
*/
u2f.EXTENSION_TIMEOUT_SEC = 30;
/**
* A singleton instance for a MessagePort to the extension.
* @type {MessagePort|u2f.WrappedChromeRuntimePort_}
* @private
*/
u2f.port_ = null;
/**
* Callbacks waiting for a port
* @type {Array<function((MessagePort|u2f.WrappedChromeRuntimePort_))>}
* @private
*/
u2f.waitingForPort_ = [];
/**
* A counter for requestIds.
* @type {number}
* @private
*/
u2f.reqCounter_ = 0;
/**
* A map from requestIds to client callbacks
* @type {Object.<number,(function((u2f.Error|u2f.RegisterResponse))
* |function((u2f.Error|u2f.SignResponse)))>}
* @private
*/
u2f.callbackMap_ = {};
/**
* Creates or retrieves the MessagePort singleton to use.
* @param {function((MessagePort|u2f.WrappedChromeRuntimePort_))} callback
* @private
*/
u2f.getPortSingleton_ = function (callback) {
if (u2f.port_) {
callback(u2f.port_);
} else {
if (u2f.waitingForPort_.length == 0) {
u2f.getMessagePort(function (port) {
u2f.port_ = port;
u2f.port_.addEventListener('message',
/** @type {function(Event)} */(u2f.responseHandler_));
// Careful, here be async callbacks. Maybe.
while (u2f.waitingForPort_.length)
u2f.waitingForPort_.shift()(u2f.port_);
});
}
u2f.waitingForPort_.push(callback);
}
};
/**
* Handles response messages from the extension.
* @param {MessageEvent.<u2f.Response>} message
* @private
*/
u2f.responseHandler_ = function (message) {
var response = message.data;
var reqId = response['requestId'];
if (!reqId || !u2f.callbackMap_[reqId]) {
console.error('Unknown or missing requestId in response.');
return;
}
var cb = u2f.callbackMap_[reqId];
delete u2f.callbackMap_[reqId];
cb(response['responseData']);
};
/**
* Dispatches an array of sign requests to available U2F tokens.
* If the JS API version supported by the extension is unknown, it first sends a
* message to the extension to find out the supported API version and then it sends
* the sign request.
* @param {string=} appId
* @param {string=} challenge
* @param {Array<u2f.RegisteredKey>} registeredKeys
* @param {function((u2f.Error|u2f.SignResponse))} callback
* @param {number=} opt_timeoutSeconds
*/
u2f.sign = function (appId, challenge, registeredKeys, callback, opt_timeoutSeconds) {
if (js_api_version === undefined) {
// Send a message to get the extension to JS API version, then send the actual sign request.
u2f.getApiVersion(
function (response) {
js_api_version = response['js_api_version'] === undefined ? 0 : response['js_api_version'];
console.log("Extension JS API Version: ", js_api_version);
u2f.sendSignRequest(appId, challenge, registeredKeys, callback, opt_timeoutSeconds);
});
} else {
// We know the JS API version. Send the actual sign request in the supported API version.
u2f.sendSignRequest(appId, challenge, registeredKeys, callback, opt_timeoutSeconds);
}
};
/**
* Dispatches an array of sign requests to available U2F tokens.
* @param {string=} appId
* @param {string=} challenge
* @param {Array<u2f.RegisteredKey>} registeredKeys
* @param {function((u2f.Error|u2f.SignResponse))} callback
* @param {number=} opt_timeoutSeconds
*/
u2f.sendSignRequest = function (appId, challenge, registeredKeys, callback, opt_timeoutSeconds) {
u2f.getPortSingleton_(function (port) {
var reqId = ++u2f.reqCounter_;
u2f.callbackMap_[reqId] = callback;
var timeoutSeconds = (typeof opt_timeoutSeconds !== 'undefined' ?
opt_timeoutSeconds : u2f.EXTENSION_TIMEOUT_SEC);
var req = u2f.formatSignRequest_(appId, challenge, registeredKeys, timeoutSeconds, reqId);
port.postMessage(req);
});
};
/**
* Dispatches register requests to available U2F tokens. An array of sign
* requests identifies already registered tokens.
* If the JS API version supported by the extension is unknown, it first sends a
* message to the extension to find out the supported API version and then it sends
* the register request.
* @param {string=} appId
* @param {Array<u2f.RegisterRequest>} registerRequests
* @param {Array<u2f.RegisteredKey>} registeredKeys
* @param {function((u2f.Error|u2f.RegisterResponse))} callback
* @param {number=} opt_timeoutSeconds
*/
u2f.register = function (appId, registerRequests, registeredKeys, callback, opt_timeoutSeconds) {
if (js_api_version === undefined) {
// Send a message to get the extension to JS API version, then send the actual register request.
u2f.getApiVersion(
function (response) {
js_api_version = response['js_api_version'] === undefined ? 0 : response['js_api_version'];
console.log("Extension JS API Version: ", js_api_version);
u2f.sendRegisterRequest(appId, registerRequests, registeredKeys,
callback, opt_timeoutSeconds);
});
} else {
// We know the JS API version. Send the actual register request in the supported API version.
u2f.sendRegisterRequest(appId, registerRequests, registeredKeys,
callback, opt_timeoutSeconds);
}
};
/**
* Dispatches register requests to available U2F tokens. An array of sign
* requests identifies already registered tokens.
* @param {string=} appId
* @param {Array<u2f.RegisterRequest>} registerRequests
* @param {Array<u2f.RegisteredKey>} registeredKeys
* @param {function((u2f.Error|u2f.RegisterResponse))} callback
* @param {number=} opt_timeoutSeconds
*/
u2f.sendRegisterRequest = function (appId, registerRequests, registeredKeys, callback, opt_timeoutSeconds) {
u2f.getPortSingleton_(function (port) {
var reqId = ++u2f.reqCounter_;
u2f.callbackMap_[reqId] = callback;
var timeoutSeconds = (typeof opt_timeoutSeconds !== 'undefined' ?
opt_timeoutSeconds : u2f.EXTENSION_TIMEOUT_SEC);
var req = u2f.formatRegisterRequest_(
appId, registeredKeys, registerRequests, timeoutSeconds, reqId);
port.postMessage(req);
});
};
/**
* Dispatches a message to the extension to find out the supported
* JS API version.
* If the user is on a mobile phone and is thus using Google Authenticator instead
* of the Chrome extension, don't send the request and simply return 0.
* @param {function((u2f.Error|u2f.GetJsApiVersionResponse))} callback
* @param {number=} opt_timeoutSeconds
*/
u2f.getApiVersion = function (callback, opt_timeoutSeconds) {
u2f.getPortSingleton_(function (port) {
// If we are using Android Google Authenticator or iOS client app,
// do not fire an intent to ask which JS API version to use.
if (port.getPortType) {
var apiVersion;
switch (port.getPortType()) {
case 'WrappedIosPort_':
case 'WrappedAuthenticatorPort_':
apiVersion = 1.1;
break;
default:
apiVersion = 0;
break;
}
callback({ 'js_api_version': apiVersion });
return;
}
var reqId = ++u2f.reqCounter_;
u2f.callbackMap_[reqId] = callback;
var req = {
type: u2f.MessageTypes.U2F_GET_API_VERSION_REQUEST,
timeoutSeconds: (typeof opt_timeoutSeconds !== 'undefined' ?
opt_timeoutSeconds : u2f.EXTENSION_TIMEOUT_SEC),
requestId: reqId
};
port.postMessage(req);
});
};
/**
* Modification:
* Assign u2f back to window (root) scope.
*/
root.u2f = u2f;
}(this));

View File

@@ -355,11 +355,8 @@ $(document).ready(function() {
data_array[i] = decodeURIComponent(data_array[i]);
$("#ItemsToDelete").append("<li>" + escapeHtml(data_array[i]) + "</li>");
}
});
$('#ConfirmDeleteModal').modal({
backdrop: 'static',
keyboard: false
})
})
$('#ConfirmDeleteModal').modal('show')
.one('click', '#IsConfirmed', function(e) {
if (is_active($('#IsConfirmed'))) { return false; }
$.ajax({

View File

@@ -1,239 +0,0 @@
!function ($) {
"use strict";
// TABCOLLAPSE CLASS DEFINITION
// ======================
var TabCollapse = function (el, options) {
this.options = options;
this.$tabs = $(el);
this._accordionVisible = false; //content is attached to tabs at first
this._initAccordion();
this._checkStateOnResize();
// checkState() has gone to setTimeout for making it possible to attach listeners to
// shown-accordion.bs.tabcollapse event on page load.
// See https://github.com/flatlogic/bootstrap-tabcollapse/issues/23
var that = this;
setTimeout(function() {
that.checkState();
}, 0);
};
TabCollapse.DEFAULTS = {
accordionClass: 'visible-xs',
tabsClass: 'hidden-xs',
accordionTemplate: function(heading, groupId, parentId, active) {
return '<div class="panel panel-default">' +
' <div class="panel-heading">' +
' <h4 class="panel-title">' +
' </h4>' +
' </div>' +
' <div id="' + groupId + '" class="panel-collapse collapse ' + (active ? 'in' : '') + '">' +
' <div class="panel-body js-tabcollapse-panel-body">' +
' </div>' +
' </div>' +
'</div>'
}
};
TabCollapse.prototype.checkState = function(){
if (this.$tabs.is(':visible') && this._accordionVisible){
this.showTabs();
this._accordionVisible = false;
} else if (this.$accordion.is(':visible') && !this._accordionVisible){
this.showAccordion();
this._accordionVisible = true;
}
};
TabCollapse.prototype.showTabs = function(){
var view = this;
this.$tabs.trigger($.Event('show-tabs.bs.tabcollapse'));
var $panelHeadings = this.$accordion.find('.js-tabcollapse-panel-heading').detach();
$panelHeadings.each(function() {
var $panelHeading = $(this),
$parentLi = $panelHeading.data('bs.tabcollapse.parentLi');
var $oldHeading = view._panelHeadingToTabHeading($panelHeading);
$parentLi.removeClass('active');
if ($parentLi.parent().hasClass('dropdown-menu') && !$parentLi.siblings('li').hasClass('active')) {
$parentLi.parent().parent().removeClass('active');
}
if (!$oldHeading.hasClass('collapsed')) {
$parentLi.addClass('active');
$('.tab-pane').removeClass('active');
$($panelHeading.attr('href')).addClass('active');
if ($parentLi.parent().hasClass('dropdown-menu')) {
$parentLi.parent().parent().addClass('active');
}
} else {
$oldHeading.removeClass('collapsed');
}
$parentLi.append($panelHeading);
});
if (!$('li').hasClass('active')) {
$('li').first().addClass('active')
}
var $panelBodies = this.$accordion.find('.js-tabcollapse-panel-body');
$panelBodies.each(function(){
var $panelBody = $(this),
$tabPane = $panelBody.data('bs.tabcollapse.tabpane');
$tabPane.append($panelBody.contents().detach());
});
this.$accordion.html('');
if(this.options.updateLinks) {
var $tabContents = this.getTabContentElement();
$tabContents.find('[data-toggle-was="tab"], [data-toggle-was="pill"]').each(function() {
var $el = $(this);
var href = $el.attr('href').replace(/-collapse$/g, '');
$el.attr({
'data-toggle': $el.attr('data-toggle-was'),
'data-toggle-was': '',
'data-parent': '',
href: href
});
});
}
this.$tabs.trigger($.Event('shown-tabs.bs.tabcollapse'));
};
TabCollapse.prototype.getTabContentElement = function(){
var $tabContents = $(this.options.tabContentSelector);
if($tabContents.length === 0) {
$tabContents = this.$tabs.siblings('.tab-content');
}
return $tabContents;
};
TabCollapse.prototype.showAccordion = function(){
this.$tabs.trigger($.Event('show-accordion.bs.tabcollapse'));
var $headings = this.$tabs.find('li:not(.dropdown) [data-toggle="tab"], li:not(.dropdown) [data-toggle="pill"]'),
view = this;
$headings.each(function(){
var $heading = $(this),
$parentLi = $heading.parent();
$heading.data('bs.tabcollapse.parentLi', $parentLi);
view.$accordion.append(view._createAccordionGroup(view.$accordion.attr('id'), $heading.detach()));
});
if(this.options.updateLinks) {
var parentId = this.$accordion.attr('id');
var $selector = this.$accordion.find('.js-tabcollapse-panel-body');
$selector.find('[data-toggle="tab"], [data-toggle="pill"]').each(function() {
var $el = $(this);
var href = $el.attr('href') + '-collapse';
$el.attr({
'data-toggle-was': $el.attr('data-toggle'),
'data-toggle': 'collapse',
'data-parent': '#' + parentId,
href: href
});
});
}
this.$tabs.trigger($.Event('shown-accordion.bs.tabcollapse'));
};
TabCollapse.prototype._panelHeadingToTabHeading = function($heading) {
var href = $heading.attr('href').replace(/-collapse$/g, '');
$heading.attr({
'data-toggle': 'tab',
'href': href,
'data-parent': ''
});
return $heading;
};
TabCollapse.prototype._tabHeadingToPanelHeading = function($heading, groupId, parentId, active) {
$heading.addClass('js-tabcollapse-panel-heading ' + (active ? '' : 'collapsed'));
$heading.attr({
'data-toggle': 'collapse',
'data-parent': '#' + parentId,
'href': '#' + groupId
});
return $heading;
};
TabCollapse.prototype._checkStateOnResize = function(){
var view = this;
$(window).resize(function(){
clearTimeout(view._resizeTimeout);
view._resizeTimeout = setTimeout(function(){
view.checkState();
}, 100);
});
};
TabCollapse.prototype._initAccordion = function(){
var randomString = function() {
var result = "",
possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
for( var i=0; i < 5; i++ ) {
result += possible.charAt(Math.floor(Math.random() * possible.length));
}
return result;
};
var srcId = this.$tabs.attr('id'),
accordionId = (srcId ? srcId : randomString()) + '-accordion';
this.$accordion = $('<div class="panel-group ' + this.options.accordionClass + '" id="' + accordionId +'"></div>');
this.$tabs.after(this.$accordion);
this.$tabs.addClass(this.options.tabsClass);
this.getTabContentElement().addClass(this.options.tabsClass);
};
TabCollapse.prototype._createAccordionGroup = function(parentId, $heading){
var tabSelector = $heading.attr('data-target'),
active = $heading.data('bs.tabcollapse.parentLi').is('.active');
if (!tabSelector) {
tabSelector = $heading.attr('href');
tabSelector = tabSelector && tabSelector.replace(/.*(?=#[^\s]*$)/, ''); //strip for ie7
}
var $tabPane = $(tabSelector),
groupId = $tabPane.attr('id') + '-collapse',
$panel = $(this.options.accordionTemplate($heading, groupId, parentId, active));
$panel.find('.panel-heading > .panel-title').append(this._tabHeadingToPanelHeading($heading, groupId, parentId, active));
$panel.find('.panel-body').append($tabPane.contents().detach())
.data('bs.tabcollapse.tabpane', $tabPane);
return $panel;
};
// TABCOLLAPSE PLUGIN DEFINITION
// =======================
$.fn.tabCollapse = function (option) {
return this.each(function () {
var $this = $(this);
var data = $this.data('bs.tabcollapse');
var options = $.extend({}, TabCollapse.DEFAULTS, $this.data(), typeof option === 'object' && option);
if (!data) $this.data('bs.tabcollapse', new TabCollapse(this, options));
});
};
$.fn.tabCollapse.Constructor = TabCollapse;
}(window.jQuery);

File diff suppressed because one or more lines are too long

View File

@@ -55,14 +55,14 @@ $(document).ready(function() {
// tooltips
$(function () {
$('[data-toggle="tooltip"]').tooltip()
$('[data-bs-toggle="tooltip"]').tooltip()
});
// remember last navigation pill
(function () {
'use strict';
if ($('a[data-toggle="tab"]').length) {
$('a[data-toggle="tab"]').on('shown.bs.tab', function (e) {
// remember desktop tabs
$('button[data-bs-toggle="tab"]').on('click', function (e) {
if ($(this).data('dont-remember') == 1) {
return true;
}
@@ -71,8 +71,28 @@ $(document).ready(function() {
if (id) {
key += ':' + id;
}
localStorage.setItem(key, $(e.target).attr('href'));
var tab_id = $(e.target).attr('data-bs-target').substring(1);
localStorage.setItem(key, tab_id);
});
// remember mobile tabs
$('button[data-bs-target^="#collapse-tab-"]').on('click', function (e) {
// only remember tab if its being opened
if ($(this).hasClass('collapsed')) return false;
var tab_id = $(this).closest('div[role="tabpanel"]').attr('id');
if ($(this).data('dont-remember') == 1) {
return true;
}
var id = $(this).parents('[role="tablist"]').attr('id');;
var key = 'lastTag';
if (id) {
key += ':' + id;
}
localStorage.setItem(key, tab_id);
});
// open last tab
$('[role="tablist"]').each(function (idx, elem) {
var id = $(elem).attr('id');
var key = 'lastTag';
@@ -81,10 +101,11 @@ $(document).ready(function() {
}
var lastTab = localStorage.getItem(key);
if (lastTab) {
$('[href="' + lastTab + '"]').tab('show');
$('[data-bs-target="#' + lastTab + '"]').click();
var tab = $('[id^="' + lastTab + '"]');
$(tab).find('.card-body.collapse').collapse('show');
}
});
}
})();
// IE fix to hide scrollbars when table body is empty
@@ -119,7 +140,7 @@ $(document).ready(function() {
shake(password_field);
}
else {
$(hibp_result).attr('class', 'hibp-out label label-info');
$(hibp_result).attr('class', 'hibp-out badge fs-5 bg-info');
$(hibp_result).text(lang_footer.loading);
var password_digest = $.sha1($(password_field).val())
var digest_five = password_digest.substring(0, 5).toUpperCase();
@@ -130,16 +151,16 @@ $(document).ready(function() {
type: 'GET',
success: function(res) {
if (res.search(compl_digest) > -1){
$(hibp_result).removeClass('label label-info').addClass('label label-danger');
$(hibp_result).removeClass('badge fs-5 bg-info').addClass('badge fs-5 bg-danger');
$(hibp_result).text(lang_footer.hibp_nok)
} else {
$(hibp_result).removeClass('label label-info').addClass('label label-success');
$(hibp_result).removeClass('badge fs-5 bg-info').addClass('badge fs-5 bg-success');
$(hibp_result).text(lang_footer.hibp_ok)
}
$(hibp_field).removeClass('task-running');
},
error: function(xhr, status, error) {
$(hibp_result).removeClass('label label-info').addClass('label label-warning');
$(hibp_result).removeClass('badge fs-5 bg-info').addClass('badge fs-5 bg-warning');
$(hibp_result).text('API error: ' + xhr.responseText)
$(hibp_field).removeClass('task-running');
}
@@ -150,8 +171,8 @@ $(document).ready(function() {
// Disable disallowed inputs
$('[data-acl="0"]').each(function(event){
if ($(this).is("a")) {
$(this).removeAttr("data-toggle");
$(this).removeAttr("data-target");
$(this).removeAttr("data-bs-toggle");
$(this).removeAttr("data-bs-target");
$(this).removeAttr("data-action");
$(this).click(function(event) {
event.preventDefault();
@@ -166,8 +187,8 @@ $(document).ready(function() {
if ($(this).hasClass('btn-group')) {
$(this).find('a').each(function(){
$(this).removeClass('dropdown-toggle')
.removeAttr('data-toggle')
.removeAttr('data-target')
.removeAttr('data-bs-toggle')
.removeAttr('data-bs-target')
.removeAttr('data-action')
.removeAttr('id')
.attr("disabled", true);
@@ -182,7 +203,7 @@ $(document).ready(function() {
} else if ($(this).hasClass('input-group')) {
$(this).find('input').each(function() {
$(this).removeClass('dropdown-toggle')
.removeAttr('data-toggle')
.removeAttr('data-bs-toggle')
.attr("disabled", true);
$(this).click(function(event) {
event.preventDefault();
@@ -226,7 +247,7 @@ $(document).ready(function() {
$('#containerName').text(container);
$('#triggerRestartContainer').click(function(){
$(this).prop("disabled",true);
$(this).html('<i class="bi bi-arrow-repeat icon-spin"></i> ');
$(this).html('<div class="spinner-border text-secondary" role="status"><span class="visually-hidden">Loading...</span></div>');
$('#statusTriggerRestartContainer').html(lang_footer.restarting_container);
$.ajax({
method: 'get',
@@ -253,25 +274,9 @@ $(document).ready(function() {
});
})
// responsive tabs
$('.responsive-tabs').tabCollapse({
tabsClass: 'hidden-xs',
accordionClass: 'js-tabcollapse-panel-group visible-xs'
});
$(document).on("shown.bs.collapse shown.bs.tab", function (e) {
var target = $(e.target);
if($(window).width() <= 767) {
var offset = target.offset().top - 112;
$("html, body").stop().animate({
scrollTop: offset
}, 100);
}
if(target.hasClass('panel-collapse')){
var id = e.target.id.replace(/-collapse$/g, '');
if(id){
localStorage.setItem('lastTag', '#'+id);
}
}
// Jquery Datatables, enable responsive plugin
$.extend($.fn.dataTable.defaults, {
responsive: true
});
// tag boxes

View File

@@ -53,237 +53,422 @@ jQuery(function($){
$("#show_rspamd_global_filters").click(function() {
$.get("inc/ajax/show_rspamd_global_filters.php");
$("#confirm_show_rspamd_global_filters").hide();
$("#rspamd_global_filters").removeClass("hidden");
$("#rspamd_global_filters").removeClass("d-none");
});
$("#super_delete").click(function() { return confirm(lang.queue_ays); });
$(".refresh_table").on('click', function(e) {
e.preventDefault();
var table_name = $(this).data('table');
$('#' + table_name).find("tr.footable-empty").remove();
draw_table = $(this).data('draw');
eval(draw_table + '()');
$('#' + table_name).DataTable().ajax.reload();
});
function table_admin_ready(ft, name) {
heading = ft.$el.parents('.panel').find('.panel-heading')
var ft_paging = ft.use(FooTable.Paging)
$(heading).children('.table-lines').text(function(){
return ft_paging.totalRows;
})
}
function draw_domain_admins() {
ft_domainadmins = FooTable.init('#domainadminstable', {
"columns": [
{"name":"chkbox","title":"","style":{"maxWidth":"60px","width":"60px"},"filterable": false,"sortable": false,"type":"html"},
{"sorted": true,"name":"username","title":lang.username,"style":{"width":"250px"}},
{"name":"selected_domains","title":lang.admin_domains,"breakpoints":"xs sm"},
{"name":"tfa_active","title":"TFA", "filterable": false,"style":{"maxWidth":"80px","width":"80px"},"formatter": function(value){return 1==value?'<i class="bi bi-check-lg"></i>':0==value&&'<i class="bi bi-x-lg"></i>';}},
{"name":"active","filterable": false,"style":{"maxWidth":"80px","width":"80px"},"title":lang.active,"formatter": function(value){return 1==value?'<i class="bi bi-check-lg"></i>':0==value&&'<i class="bi bi-x-lg"></i>';}},
{"name":"action","filterable": false,"sortable": false,"style":{"text-align":"right","maxWidth":"250px","width":"250px"},"type":"html","title":lang.action,"breakpoints":"xs sm"}
],
"rows": $.ajax({
dataType: 'json',
url: '/api/v1/get/domain-admin/all',
jsonp: false,
error: function () {
console.log('Cannot draw domain admin table');
},
success: function (data) {
$('#domainadminstable').DataTable({
processing: true,
serverSide: false,
language: lang_datatables,
ajax: {
type: "GET",
url: "/api/v1/get/domain-admin/all",
dataSrc: function(data){
return process_table_data(data, 'domainadminstable');
}
}),
"empty": lang.empty,
"paging": {"enabled": true,"limit": 5,"size": log_pagination_size},
"state": {"enabled": true},
"filtering": {"enabled": true,"delay": 1200,"position": "left","connectors": false,"placeholder": lang.filter_table},
"sorting": {"enabled": true},
"toggleSelector": "table tbody span.footable-toggle"
},
columns: [
{
// placeholder, so checkbox will not block child row toggle
title: '',
data: null,
searchable: false,
orderable: false,
defaultContent: ''
},
{
title: '',
data: 'chkbox',
searchable: false,
orderable: false,
defaultContent: ''
},
{
title: lang.username,
data: 'username',
},
{
title: "TFA",
data: 'tfa_active',
render: function (data, type) {
if(data == 1) return '<i class="bi bi-check-lg"></i>';
else return '<i class="bi bi-x-lg"></i>'
}
},
{
title: lang.admin_domains,
data: 'tfa_active',
render: function (data, type) {
return data;
}
},
{
title: lang.active,
data: 'active',
render: function (data, type) {
if(data == 1) return '<i class="bi bi-check-lg"></i>';
else return '<i class="bi bi-x-lg"></i>'
}
},
{
title: lang.action,
data: 'action',
className: 'text-md-end dt-sm-head-hidden dt-body-right'
},
],
initComplete: function(settings, json){
console.log(settings.aoColumns);
}
});
}
function draw_oauth2_clients() {
ft_oauth2clientstable = FooTable.init('#oauth2clientstable', {
"columns": [
{"name":"chkbox","title":"","style":{"maxWidth":"40px","width":"40px"},"filterable": false,"sortable": false,"type":"html"},
{"name":"id","type":"text","title":"ID","style":{"width":"50px"}},
{"name":"client_id","type":"text","title":lang.oauth2_client_id,"style":{"width":"200px"}},
{"name":"client_secret","title":lang.oauth2_client_secret,"breakpoints":"xs sm md","style":{"width":"200px"}},
{"name":"redirect_uri","title":lang.oauth2_redirect_uri, "type": "text"},
{"name":"action","filterable": false,"sortable": false,"style":{"text-align":"right","maxWidth":"180px","width":"180px"},"type":"html","title":lang.action,"breakpoints":"xs sm"}
],
"rows": $.ajax({
dataType: 'json',
url: '/api/v1/get/oauth2-client/all',
jsonp: false,
error: function () {
console.log('Cannot draw oauth2 clients table');
},
success: function (data) {
$('#oauth2clientstable').DataTable({
processing: true,
serverSide: false,
language: lang_datatables,
ajax: {
type: "GET",
url: "/api/v1/get/oauth2-client/all",
dataSrc: function(data){
return process_table_data(data, 'oauth2clientstable');
}
}),
"empty": lang.empty,
"paging": {"enabled": true,"limit": 5,"size": log_pagination_size},
"sorting": {"enabled": true},
"toggleSelector": "table tbody span.footable-toggle"
},
columns: [
{
// placeholder, so checkbox will not block child row toggle
title: '',
data: null,
searchable: false,
orderable: false,
defaultContent: ''
},
{
title: '',
data: 'chkbox',
searchable: false,
orderable: false,
defaultContent: ''
},
{
title: 'ID',
data: 'id',
},
{
title: lang.oauth2_client_id,
data: 'client_id'
},
{
title: lang.oauth2_client_secret,
data: 'client_secret'
},
{
title: lang.oauth2_redirect_uri,
data: 'redirect_uri'
},
{
title: lang.action,
data: 'action',
className: 'text-md-end dt-sm-head-hidden dt-body-right'
},
]
});
}
function draw_admins() {
ft_admins = FooTable.init('#adminstable', {
"columns": [
{"name":"chkbox","title":"","style":{"maxWidth":"60px","width":"60px"},"filterable": false,"sortable": false,"type":"html"},
{"sorted": true,"name":"usr","title":lang.username,"style":{"width":"250px"}},
{"name":"tfa_active","title":"TFA", "filterable": false,"style":{"maxWidth":"80px","width":"80px"},"formatter": function(value){return 1==value?'<i class="bi bi-check-lg"></i>':0==value&&'<i class="bi bi-x-lg"></i>';}},
{"name":"active","filterable": false,"style":{"maxWidth":"80px","width":"80px"},"title":lang.active,"formatter": function(value){return 1==value?'<i class="bi bi-check-lg"></i>':0==value&&'<i class="bi bi-x-lg"></i>';}},
{"name":"action","filterable": false,"sortable": false,"style":{"text-align":"right","maxWidth":"250px","width":"250px"},"type":"html","title":lang.action,"breakpoints":"xs sm"}
],
"rows": $.ajax({
dataType: 'json',
url: '/api/v1/get/admin/all',
jsonp: false,
error: function () {
console.log('Cannot draw admin table');
},
success: function (data) {
$('#adminstable').DataTable({
processing: true,
serverSide: false,
language: lang_datatables,
ajax: {
type: "GET",
url: "/api/v1/get/admin/all",
dataSrc: function(data){
return process_table_data(data, 'adminstable');
}
}),
"empty": lang.empty,
"paging": {"enabled": true,"limit": 5,"size": log_pagination_size},
"filtering": {"enabled": false},
"state": {"enabled": true},
"sorting": {"enabled": true},
"toggleSelector": "table tbody span.footable-toggle"
},
columns: [
{
// placeholder, so checkbox will not block child row toggle
title: '',
data: null,
searchable: false,
orderable: false,
defaultContent: ''
},
{
title: '',
data: 'chkbox',
searchable: false,
orderable: false,
defaultContent: ''
},
{
title: lang.username,
data: 'username',
},
{
title: "TFA",
data: 'tfa_active',
render: function (data, type) {
if(data == 1) return '<i class="bi bi-check-lg"></i>';
else return '<i class="bi bi-x-lg"></i>'
}
},
{
title: lang.active,
data: 'active',
render: function (data, type) {
if(data == 1) return '<i class="bi bi-check-lg"></i>';
else return '<i class="bi bi-x-lg"></i>'
}
},
{
title: lang.action,
data: 'action',
className: 'text-md-end dt-sm-head-hidden dt-body-right'
},
]
});
}
function draw_fwd_hosts() {
ft_forwardinghoststable = FooTable.init('#forwardinghoststable', {
"columns": [
{"name":"chkbox","title":"","style":{"maxWidth":"60px","width":"60px"},"filterable": false,"sortable": false,"type":"html"},
{"name":"host","type":"text","title":lang.host,"style":{"width":"250px"}},
{"name":"source","title":lang.source,"breakpoints":"xs sm"},
{"name":"keep_spam","title":lang.spamfilter, "type": "text","style":{"maxWidth":"80px","width":"80px"},"formatter": function(value){return 'yes'==value?'<i class="bi bi-x-lg"></i>':'no'==value&&'<i class="bi bi-check-lg"></i>';}},
{"name":"action","filterable": false,"sortable": false,"style":{"text-align":"right","maxWidth":"180px","width":"180px"},"type":"html","title":lang.action,"breakpoints":"xs sm"}
],
"rows": $.ajax({
dataType: 'json',
url: '/api/v1/get/fwdhost/all',
jsonp: false,
error: function () {
console.log('Cannot draw forwarding hosts table');
},
success: function (data) {
$('#forwardinghoststable').DataTable({
processing: true,
serverSide: false,
language: lang_datatables,
ajax: {
type: "GET",
url: "/api/v1/get/fwdhost/all",
dataSrc: function(data){
return process_table_data(data, 'forwardinghoststable');
}
}),
"empty": lang.empty,
"paging": {"enabled": true,"limit": 5,"size": log_pagination_size},
"sorting": {"enabled": true},
"toggleSelector": "table tbody span.footable-toggle"
},
columns: [
{
// placeholder, so checkbox will not block child row toggle
title: '',
data: null,
searchable: false,
orderable: false,
defaultContent: ''
},
{
title: '',
data: 'chkbox',
searchable: false,
orderable: false,
defaultContent: ''
},
{
title: lang.host,
data: 'host',
},
{
title: lang.source,
data: 'source'
},
{
title: lang.spamfilter,
data: 'keep_spam'
},
{
title: lang.action,
data: 'action',
className: 'text-md-end dt-sm-head-hidden dt-body-right'
},
]
});
}
function draw_relayhosts() {
ft_relayhoststable = FooTable.init('#relayhoststable', {
"columns": [
{"name":"chkbox","title":"","style":{"maxWidth":"60px","width":"60px"},"filterable": false,"sortable": false,"type":"html"},
{"name":"id","type":"text","title":"ID","style":{"width":"50px"}},
{"name":"hostname","type":"text","title":lang.host,"style":{"width":"250px"}},
{"name":"username","title":lang.username,"breakpoints":"xs sm"},
{"name":"in_use_by","title":lang.in_use_by,"style":{"min-width":"200px","width":"200px"}, "type": "text","breakpoints":"xs sm"},
{"name":"active","filterable": false,"style":{"maxWidth":"80px","width":"80px"},"title":lang.active,"formatter": function(value){return 1==value?'<i class="bi bi-check-lg"></i>':0==value&&'<i class="bi bi-x-lg"></i>';}},
{"name":"action","filterable": false,"sortable": false,"style":{"text-align":"right","min-width":"250px","width":"250px"},"type":"html","title":lang.action,"breakpoints":"xs sm md"}
],
"rows": $.ajax({
dataType: 'json',
url: '/api/v1/get/relayhost/all',
jsonp: false,
error: function () {
console.log('Cannot draw forwarding hosts table');
},
success: function (data) {
$('#relayhoststable').DataTable({
processing: true,
serverSide: false,
language: lang_datatables,
ajax: {
type: "GET",
url: "/api/v1/get/relayhost/all",
dataSrc: function(data){
return process_table_data(data, 'relayhoststable');
}
}),
"empty": lang.empty,
"paging": {"enabled": true,"limit": 5,"size": log_pagination_size},
"sorting": {"enabled": true},
"toggleSelector": "table tbody span.footable-toggle"
},
columns: [
{
// placeholder, so checkbox will not block child row toggle
title: '',
data: null,
searchable: false,
orderable: false,
defaultContent: ''
},
{
title: '',
data: 'chkbox',
searchable: false,
orderable: false,
defaultContent: ''
},
{
title: 'ID',
data: 'id',
},
{
title: lang.host,
data: 'hostname'
},
{
title: lang.username,
data: 'username'
},
{
title: lang.in_use_by,
data: 'in_use_by'
},
{
title: lang.active,
data: 'active'
},
{
title: lang.action,
data: 'action',
className: 'text-md-end dt-sm-head-hidden dt-body-right'
},
]
});
}
function draw_transport_maps() {
ft_transportstable = FooTable.init('#transportstable', {
"columns": [
{"name":"chkbox","title":"","style":{"maxWidth":"60px","width":"60px"},"filterable": false,"sortable": false,"type":"html"},
{"name":"id","type":"text","title":"ID","style":{"width":"50px"}},
{"name":"destination","type":"text","title":lang.destination,"style":{"min-width":"300px","width":"300px"}},
{"name":"nexthop","type":"text","title":lang.nexthop,"style":{"min-width":"200px","width":"200px"}},
{"name":"username","title":lang.username,"breakpoints":"xs sm"},
{"name":"active","filterable": false,"style":{"maxWidth":"80px","width":"80px"},"title":lang.active,"formatter": function(value){return 1==value?'<i class="bi bi-check-lg"></i>':0==value&&'<i class="bi bi-x-lg"></i>';}},
{"name":"action","filterable": false,"sortable": false,"style":{"text-align":"right","min-width":"250px","width":"250px"},"type":"html","title":lang.action,"breakpoints":"xs sm md"}
],
"rows": $.ajax({
dataType: 'json',
url: '/api/v1/get/transport/all',
jsonp: false,
error: function () {
console.log('Cannot draw transports table');
},
success: function (data) {
$('#transportstable').DataTable({
processing: true,
serverSide: false,
language: lang_datatables,
ajax: {
type: "GET",
url: "/api/v1/get/transport/all",
dataSrc: function(data){
return process_table_data(data, 'transportstable');
}
}),
"empty": lang.empty,
"paging": {"enabled": true,"limit": 5,"size": log_pagination_size},
"sorting": {"enabled": true},
"toggleSelector": "table tbody span.footable-toggle",
"on": {
"ready.ft.table": function(e, ft){
$('.mx-info').tooltip();
}
}
},
columns: [
{
// placeholder, so checkbox will not block child row toggle
title: '',
data: null,
searchable: false,
orderable: false,
defaultContent: ''
},
{
title: '',
data: 'chkbox',
searchable: false,
orderable: false,
defaultContent: ''
},
{
title: 'ID',
data: 'id',
},
{
title: lang.destination,
data: 'destination'
},
{
title: lang.nexthop,
data: 'nexthop'
},
{
title: lang.username,
data: 'username'
},
{
title: lang.active,
data: 'active'
},
{
title: lang.action,
data: 'action',
className: 'text-md-end dt-sm-head-hidden dt-body-right'
},
]
});
}
function draw_queue() {
ft_queuetable = FooTable.init('#queuetable', {
"columns": [
{"name":"chkbox","title":"","style":{"maxWidth":"60px","width":"60px"},"filterable": false,"sortable": false,"type":"html"},
{"name":"queue_id","type":"text","title":"QID","style":{"width":"50px"}},
{"name":"queue_name","type":"text","title":"Queue","style":{"width":"120px"}},
{"name":"arrival_time","sorted": true,"direction": "DESC","formatter":function unix_time_format(tm) { var date = new Date(tm ? tm * 1000 : 0); return date.toLocaleDateString(undefined, {year: "numeric", month: "2-digit", day: "2-digit", hour: "2-digit", minute: "2-digit", second: "2-digit"});},"title":lang.arrival_time,"style":{"width":"170px"}},
{"name":"message_size","style":{"whiteSpace":"nowrap"},"title":lang.message_size,"formatter": function(value){
return humanFileSize(value);
}},
{"name":"sender","title":lang.sender, "type": "text","breakpoints":"xs sm"},
{"name":"recipients","title":lang.recipients, "type": "text","style":{"word-break":"break-all","min-width":"300px"},"breakpoints":"xs sm md"},
{"name":"action","filterable": false,"sortable": false,"style":{"text-align":"right","maxWidth":"220px","width":"220px"},"type":"html","title":lang.action,"breakpoints":"xs sm md"}
],
"rows": $.ajax({
dataType: 'json',
url: '/api/v1/get/mailq/all',
jsonp: false,
error: function () {
console.log('Cannot draw forwarding hosts table');
},
success: function (data) {
$('#queuetable').DataTable({
processing: true,
serverSide: false,
language: lang_datatables,
ajax: {
type: "GET",
url: "/api/v1/get/mailq/all",
dataSrc: function(data){
return process_table_data(data, 'queuetable');
}
}),
"empty": lang.empty,
"paging": {"enabled": true,"limit": 5,"size": log_pagination_size},
"sorting": {"enabled": true},
"toggleSelector": "table tbody span.footable-toggle",
"on": {
"ready.ft.table": function(e, ft){
table_admin_ready(ft, 'queuetable');
}
}
},
columns: [
{
// placeholder, so checkbox will not block child row toggle
title: '',
data: null,
searchable: false,
orderable: false,
defaultContent: ''
},
{
title: '',
data: 'chkbox',
searchable: false,
orderable: false,
defaultContent: ''
},
{
title: 'QID',
data: 'queue_id',
},
{
title: 'Queue',
data: 'queue_name'
},
{
title: lang.arrival_time,
data: 'arrival_time',
render: function (data, type){
var date = new Date(data ? data * 1000 : 0);
return date.toLocaleDateString(undefined, {year: "numeric", month: "2-digit", day: "2-digit", hour: "2-digit", minute: "2-digit", second: "2-digit"});
}
},
{
title: lang.message_size,
data: 'message_size',
render: function (data, type){
return humanFileSize(data);
}
},
{
title: lang.sender,
data: 'sender'
},
{
title: lang.recipients,
data: 'recipients'
},
{
title: lang.action,
data: 'action',
className: 'text-md-end dt-sm-head-hidden dt-body-right'
},
]
});
}
function process_table_data(data, table) {
if (table == 'relayhoststable') {
$.each(data, function (i, item) {
item.action = '<div class="btn-group footable-actions">' +
'<a href="#" data-toggle="modal" data-target="#testTransportModal" data-transport-id="' + encodeURI(item.id) + '" data-transport-type="sender-dependent" class="btn btn-xs btn-xs-third btn-default"><i class="bi bi-caret-right-fill"></i> Test</a>' +
'<a href="/edit/relayhost/' + encodeURI(item.id) + '" class="btn btn-xs btn-xs-third btn-default"><i class="bi bi-pencil-fill"></i> ' + lang.edit + '</a>' +
item.action = '<div class="btn-group">' +
'<a href="#" data-bs-toggle="modal" data-bs-target="#testTransportModal" data-transport-id="' + encodeURI(item.id) + '" data-transport-type="sender-dependent" class="btn btn-xs btn-xs-third btn-secondary"><i class="bi bi-caret-right-fill"></i> Test</a>' +
'<a href="/edit/relayhost/' + encodeURI(item.id) + '" class="btn btn-xs btn-xs-third btn-secondary"><i class="bi bi-pencil-fill"></i> ' + lang.edit + '</a>' +
'<a href="#" data-action="delete_selected" data-id="single-rlyhost" data-api-url="delete/relayhost" data-item="' + encodeURI(item.id) + '" class="btn btn-xs btn-xs-third btn-danger"><i class="bi bi-trash"></i> ' + lang.remove + '</a>' +
'</div>';
if (item.used_by_mailboxes == '') { item.in_use_by = item.used_by_domains; }
@@ -294,14 +479,14 @@ jQuery(function($){
} else if (table == 'transportstable') {
$.each(data, function (i, item) {
if (item.is_mx_based) {
item.destination = '<i class="bi bi-info-circle-fill text-info mx-info" data-toggle="tooltip" title="' + lang.is_mx_based + '"></i> <code>' + item.destination + '</code>';
item.destination = '<i class="bi bi-info-circle-fill text-info mx-info" data-bs-toggle="tooltip" title="' + lang.is_mx_based + '"></i> <code>' + item.destination + '</code>';
}
if (item.username) {
item.username = '<i style="color:#' + intToRGB(hashCode(item.nexthop)) + ';" class="bi bi-square-fill"></i> ' + item.username;
}
item.action = '<div class="btn-group footable-actions">' +
'<a href="#" data-toggle="modal" data-target="#testTransportModal" data-transport-id="' + encodeURI(item.id) + '" data-transport-type="transport-map" class="btn btn-xs btn-xs-third btn-default"><i class="bi bi-caret-right-fill"></i> Test</a>' +
'<a href="/edit/transport/' + encodeURI(item.id) + '" class="btn btn-xs btn-xs-third btn-default"><i class="bi bi-pencil-fill"></i> ' + lang.edit + '</a>' +
item.action = '<div class="btn-group">' +
'<a href="#" data-bs-toggle="modal" data-bs-target="#testTransportModal" data-transport-id="' + encodeURI(item.id) + '" data-transport-type="transport-map" class="btn btn-xs btn-xs-third btn-secondary"><i class="bi bi-caret-right-fill"></i> Test</a>' +
'<a href="/edit/transport/' + encodeURI(item.id) + '" class="btn btn-xs btn-xs-third btn-secondary"><i class="bi bi-pencil-fill"></i> ' + lang.edit + '</a>' +
'<a href="#" data-action="delete_selected" data-id="single-transport" data-api-url="delete/transport" data-item="' + encodeURI(item.id) + '" class="btn btn-xs btn-xs-third btn-danger"><i class="bi bi-trash"></i> ' + lang.remove + '</a>' +
'</div>';
item.chkbox = '<input type="checkbox" data-id="transports" name="multi_select" value="' + item.id + '" />';
@@ -313,21 +498,21 @@ jQuery(function($){
return escapeHtml(i);
});
item.recipients = rcpts.join('<hr style="margin:1px!important">');
item.action = '<div class="btn-group footable-actions">' +
'<a href="#" data-toggle="modal" data-target="#showQueuedMsg" data-queue-id="' + encodeURI(item.queue_id) + '" class="btn btn-xs btn-default">' + lang.queue_show_message + '</a>' +
item.action = '<div class="btn-group">' +
'<a href="#" data-bs-toggle="modal" data-bs-target="#showQueuedMsg" data-queue-id="' + encodeURI(item.queue_id) + '" class="btn btn-xs btn-secondary">' + lang.queue_show_message + '</a>' +
'</div>';
});
} else if (table == 'forwardinghoststable') {
$.each(data, function (i, item) {
item.action = '<div class="btn-group footable-actions">' +
item.action = '<div class="btn-group">' +
'<a href="#" data-action="delete_selected" data-id="single-fwdhost" data-api-url="delete/fwdhost" data-item="' + encodeURI(item.host) + '" class="btn btn-xs btn-danger"><i class="bi bi-trash"></i> ' + lang.remove + '</a>' +
'</div>';
item.chkbox = '<input type="checkbox" data-id="fwdhosts" name="multi_select" value="' + item.host + '" />';
});
} else if (table == 'oauth2clientstable') {
$.each(data, function (i, item) {
item.action = '<div class="btn-group footable-actions">' +
'<a href="/edit.php?oauth2client=' + encodeURI(item.id) + '" class="btn btn-xs btn-xs-half btn-default"><i class="bi bi-pencil-fill"></i> ' + lang.edit + '</a>' +
item.action = '<div class="btn-group">' +
'<a href="/edit.php?oauth2client=' + encodeURI(item.id) + '" class="btn btn-xs btn-xs-half btn-secondary"><i class="bi bi-pencil-fill"></i> ' + lang.edit + '</a>' +
'<a href="#" data-action="delete_selected" data-id="single-oauth2-client" data-api-url="delete/oauth2-client" data-item="' + encodeURI(item.id) + '" class="btn btn-xs btn-xs-half btn-danger"><i class="bi bi-trash"></i> ' + lang.remove + '</a>' +
'</div>';
item.scope = "profile";
@@ -339,8 +524,8 @@ jQuery(function($){
item.selected_domains = escapeHtml(item.selected_domains);
item.selected_domains = item.selected_domains.toString().replace(/,/g, "<br>");
item.chkbox = '<input type="checkbox" data-id="domain_admins" name="multi_select" value="' + item.username + '" />';
item.action = '<div class="btn-group footable-actions">' +
'<a href="/edit/domainadmin/' + encodeURI(item.username) + '" class="btn btn-xs btn-xs-third btn-default"><i class="bi bi-pencil-fill"></i> ' + lang.edit + '</a>' +
item.action = '<div class="btn-group">' +
'<a href="/edit/domainadmin/' + encodeURI(item.username) + '" class="btn btn-xs btn-xs-third btn-secondary"><i class="bi bi-pencil-fill"></i> ' + lang.edit + '</a>' +
'<a href="#" data-action="delete_selected" data-id="single-domain-admin" data-api-url="delete/domain-admin" data-item="' + encodeURI(item.username) + '" class="btn btn-xs btn-xs-third btn-danger"><i class="bi bi-trash"></i> ' + lang.remove + '</a>' +
'<a href="/index.php?duallogin=' + encodeURIComponent(item.username) + '" class="btn btn-xs btn-xs-third btn-success"><i class="bi bi-person-fill"></i> Login</a>' +
'</div>';
@@ -353,22 +538,38 @@ jQuery(function($){
item.usr = item.username;
}
item.chkbox = '<input type="checkbox" data-id="admins" name="multi_select" value="' + item.username + '" />';
item.action = '<div class="btn-group footable-actions">' +
'<a href="/edit/admin/' + encodeURI(item.username) + '" class="btn btn-xs btn-xs-half btn-default"><i class="bi bi-pencil-fill"></i> ' + lang.edit + '</a>' +
item.action = '<div class="btn-group">' +
'<a href="/edit/admin/' + encodeURI(item.username) + '" class="btn btn-xs btn-xs-half btn-secondary"><i class="bi bi-pencil-fill"></i> ' + lang.edit + '</a>' +
'<a href="#" data-action="delete_selected" data-id="single-admin" data-api-url="delete/admin" data-item="' + encodeURI(item.username) + '" class="btn btn-xs btn-xs-half btn-danger"><i class="bi bi-trash"></i> ' + lang.remove + '</a>' +
'</div>';
});
}
return data
};
// Initial table drawings
draw_domain_admins();
draw_admins();
draw_fwd_hosts();
draw_relayhosts();
draw_oauth2_clients();
draw_transport_maps();
draw_queue();
// detect element visibility changes
function onVisible(element, callback) {
$(element).ready(function() {
element_object = document.querySelector(element)
new IntersectionObserver((entries, observer) => {
entries.forEach(entry => {
if(entry.intersectionRatio > 0) {
callback(element_object);
observer.disconnect();
}
});
}).observe(element_object);
});
}
// Draw Table if tab is active
onVisible("[id^=adminstable]", () => draw_admins());
onVisible("[id^=domainadminstable]", () => draw_domain_admins());
onVisible("[id^=oauth2clientstable]", () => draw_oauth2_clients());
onVisible("[id^=forwardinghoststable]", () => draw_fwd_hosts());
onVisible("[id^=relayhoststable]", () => draw_relayhosts());
onVisible("[id^=transportstable]", () => draw_transport_maps());
onVisible("[id^=queuetable]", () => draw_queue());
$('body').on('click', 'span.footable-toggle', function () {
event.stopPropagation();
@@ -483,11 +684,11 @@ jQuery(function($){
if (type == "app_link") {
cols = '<td><input class="input-sm input-xs-lg form-control" data-id="app_links" type="text" name="app" required></td>';
cols += '<td><input class="input-sm input-xs-lg form-control" data-id="app_links" type="text" name="href" required></td>';
cols += '<td><a href="#" role="button" class="btn btn-sm btn-xs-lg btn-default" type="button">' + lang.remove_row + '</a></td>';
cols += '<td><a href="#" role="button" class="btn btn-sm btn-xs-lg btn-secondary" type="button">' + lang.remove_row + '</a></td>';
} else if (type == "f2b_regex") {
cols = '<td><input style="text-align:center" class="input-sm input-xs-lg form-control" data-id="f2b_regex" type="text" value="+" disabled></td>';
cols += '<td><input class="input-sm input-xs-lg form-control regex-input" data-id="f2b_regex" type="text" name="regex" required></td>';
cols += '<td><a href="#" role="button" class="btn btn-sm btn-xs-lg btn-default" type="button">' + lang.remove_row + '</a></td>';
cols += '<td><a href="#" role="button" class="btn btn-sm btn-xs-lg btn-secondary" type="button">' + lang.remove_row + '</a></td>';
}
row.append(cols);
table_id.append(row);

File diff suppressed because it is too large Load Diff

View File

@@ -66,22 +66,14 @@ jQuery(function($){
return re.test(email);
}
function draw_wl_policy_domain_table() {
ft_wl_policy_mailbox_table = FooTable.init('#wl_policy_domain_table', {
"columns": [
{"name":"chkbox","title":"","style":{"maxWidth":"40px","width":"40px"},"filterable": false,"sortable": false,"type":"html"},
{"name":"prefid","style":{"maxWidth":"40px","width":"40px"},"title":"ID","filterable": false,"sortable": false},
{"sorted": true,"name":"value","title":lang_user.spamfilter_table_rule},
{"name":"object","title":"Scope"}
],
"empty": lang_user.empty,
"rows": $.ajax({
dataType: 'json',
$('#wl_policy_domain_table').DataTable({
processing: true,
serverSide: false,
language: lang_datatables,
ajax: {
type: "GET",
url: '/api/v1/get/policy_wl_domain/' + table_for_domain,
jsonp: false,
error: function () {
console.log('Cannot draw mailbox policy wl table');
},
success: function (data) {
dataSrc: function(data){
$.each(data, function (i, item) {
if (!validateEmail(item.object)) {
item.chkbox = '<input type="checkbox" data-id="policy_wl_domain" name="multi_select" value="' + item.prefid + '" />';
@@ -90,35 +82,50 @@ jQuery(function($){
item.chkbox = '<input type="checkbox" disabled title="' + lang_user.spamfilter_table_domain_policy + '" />';
}
});
return data;
}
}),
"paging": {
"enabled": true,
"limit": 5,
"size": pagination_size
},
"sorting": {
"enabled": true
}
columns: [
{
// placeholder, so checkbox will not block child row toggle
title: '',
data: null,
searchable: false,
orderable: false,
defaultContent: ''
},
{
title: '',
data: 'chkbox',
searchable: false,
orderable: false,
defaultContent: ''
},
{
title: 'ID',
data: 'prefid',
},
{
title: lang_user.spamfilter_table_rule,
data: 'value'
},
{
title: 'Scope',
data: 'object'
}
]
});
}
function draw_bl_policy_domain_table() {
ft_bl_policy_mailbox_table = FooTable.init('#bl_policy_domain_table', {
"columns": [
{"name":"chkbox","title":"","style":{"maxWidth":"40px","width":"40px"},"filterable": false,"sortable": false,"type":"html"},
{"name":"prefid","style":{"maxWidth":"40px","width":"40px"},"title":"ID","filterable": false,"sortable": false},
{"sorted": true,"name":"value","title":lang_user.spamfilter_table_rule},
{"name":"object","title":"Scope"}
],
"empty": lang_user.empty,
"rows": $.ajax({
dataType: 'json',
$('#bl_policy_domain_table').DataTable({
processing: true,
serverSide: false,
language: lang_datatables,
ajax: {
type: "GET",
url: '/api/v1/get/policy_bl_domain/' + table_for_domain,
jsonp: false,
error: function () {
console.log('Cannot draw mailbox policy bl table');
},
success: function (data) {
dataSrc: function(data){
$.each(data, function (i, item) {
if (!validateEmail(item.object)) {
item.chkbox = '<input type="checkbox" data-id="policy_bl_domain" name="multi_select" value="' + item.prefid + '" />';
@@ -127,18 +134,58 @@ jQuery(function($){
item.chkbox = '<input type="checkbox" disabled tooltip="' + lang_user.spamfilter_table_domain_policy + '" />';
}
});
return data;
}
}),
"paging": {
"enabled": true,
"limit": 5,
"size": pagination_size
},
"sorting": {
"enabled": true
}
columns: [
{
// placeholder, so checkbox will not block child row toggle
title: '',
data: null,
searchable: false,
orderable: false,
defaultContent: ''
},
{
title: '',
data: 'chkbox',
searchable: false,
orderable: false,
defaultContent: ''
},
{
title: 'ID',
data: 'prefid',
},
{
title: lang_user.spamfilter_table_rule,
data: 'value'
},
{
title: 'Scope',
data: 'object'
}
]
});
}
draw_wl_policy_domain_table();
draw_bl_policy_domain_table();
// detect element visibility changes
function onVisible(element, callback) {
$(element).ready(function() {
element_object = document.querySelector(element)
new IntersectionObserver((entries, observer) => {
entries.forEach(entry => {
if(entry.intersectionRatio > 0) {
callback(element_object);
observer.disconnect();
}
});
}).observe(element_object);
});
}
// Draw Table if tab is active
onVisible("[id^=wl_policy_domain_table]", () => draw_wl_policy_domain_table());
onVisible("[id^=bl_policy_domain_table]", () => draw_bl_policy_domain_table());
});

File diff suppressed because it is too large Load Diff

View File

@@ -40,17 +40,17 @@ jQuery(function($){
if (value.score > 0) highlightClass = 'negative'
else if (value.score < 0) highlightClass = 'positive'
else highlightClass = 'neutral'
$('#qid_detail_symbols').append('<span data-toggle="tooltip" class="rspamd-symbol ' + highlightClass + '" title="' + (value.options ? value.options.join(', ') : '') + '">' + value.name + ' (<span class="score">' + value.score + '</span>)</span>');
$('#qid_detail_symbols').append('<span data-bs-toggle="tooltip" class="rspamd-symbol ' + highlightClass + '" title="' + (value.options ? value.options.join(', ') : '') + '">' + value.name + ' (<span class="score">' + value.score + '</span>)</span>');
});
$('[data-toggle="tooltip"]').tooltip()
$('[data-bs-toggle="tooltip"]').tooltip()
}
if (typeof data.score !== 'undefined' && typeof data.action !== 'undefined') {
if (data.action === "add header") {
$('#qid_detail_score').append('<span class="label-rspamd-action label label-warning"><b>' + data.score + '</b> - ' + lang.junk_folder + '</span>');
$('#qid_detail_score').append('<span class="label-rspamd-action badge fs-5 bg-warning"><b>' + data.score + '</b> - ' + lang.junk_folder + '</span>');
} else if (data.action === "reject") {
$('#qid_detail_score').append('<span class="label-rspamd-action label label-danger"><b>' + data.score + '</b> - ' + lang.rejected + '</span>');
$('#qid_detail_score').append('<span class="label-rspamd-action badge fs-5 bg-danger"><b>' + data.score + '</b> - ' + lang.rejected + '</span>');
} else if (data.action === "rewrite subject") {
$('#qid_detail_score').append('<span class="label-rspamd-action label label-warning"><b>' + data.score + '</b> - ' + lang.rewrite_subject + '</span>');
$('#qid_detail_score').append('<span class="label-rspamd-action badge fs-5 bg-warning"><b>' + data.score + '</b> - ' + lang.rewrite_subject + '</span>');
}
}
if (typeof data.recipients !== 'undefined') {

View File

@@ -7,67 +7,20 @@ jQuery(function($){
var entityMap={"&":"&amp;","<":"&lt;",">":"&gt;",'"':"&quot;","'":"&#39;","/":"&#x2F;","`":"&#x60;","=":"&#x3D;"};
function escapeHtml(n){return String(n).replace(/[&<>"'`=\/]/g,function(n){return entityMap[n]})}
function humanFileSize(i){if(Math.abs(i)<1024)return i+" B";var B=["KiB","MiB","GiB","TiB","PiB","EiB","ZiB","YiB"],e=-1;do{i/=1024,++e}while(Math.abs(i)>=1024&&e<B.length-1);return i.toFixed(1)+" "+B[e]}
// Set paging
$('[data-page-size]').on('click', function(e){
e.preventDefault();
var new_size = $(this).data('page-size');
var parent_ul = $(this).closest('ul');
var table_id = $(parent_ul).data('table-id');
FooTable.get('#' + table_id).pageSize(new_size);
//$(this).parent().addClass('active').siblings().removeClass('active')
heading = $(this).parents('.panel').find('.panel-heading')
var n_results = $(heading).children('.table-lines').text().split(' / ')[1];
$(heading).children('.table-lines').text(function(){
if (new_size > n_results) {
new_size = n_results;
}
return new_size + ' / ' + n_results;
})
});
$(".refresh_table").on('click', function(e) {
e.preventDefault();
var table_name = $(this).data('table');
$('#' + table_name).find("tr.footable-empty").remove();
draw_table = $(this).data('draw');
eval(draw_table + '()');
$('#' + table_name).DataTable().ajax.reload();
});
function table_quarantine_ready(ft, name) {
$('.refresh_table').prop("disabled", false);
heading = ft.$el.parents('.panel').find('.panel-heading')
var ft_paging = ft.use(FooTable.Paging)
$(heading).children('.table-lines').text(function(){
var total_rows = ft_paging.totalRows;
var size = ft_paging.size;
if (size > total_rows) {
size = total_rows;
}
return size + ' / ' + total_rows;
})
}
function draw_quarantine_table() {
ft_quarantinetable = FooTable.init('#quarantinetable', {
"columns": [
{"name":"chkbox","title":"","style":{"maxWidth":"60px","width":"60px"},"filterable": false,"sortable": false,"type":"html"},
{"name":"id","type":"ID","filterable": false,"sorted": true,"direction":"DESC","title":"ID","style":{"width":"50px"}},
{"name":"qid","breakpoints":"all","type":"text","title":lang.qid,"style":{"width":"125px"}},
{"name":"sender","title":lang.sender},
{"name":"subject","title":lang.subj, "type": "text"},
{"name":"rspamdaction","title":lang.rspamd_result, "type": "html"},
{"name":"rcpt","title":lang.rcpt, "type": "text"},
{"name":"virus","title":lang.danger, "type": "text"},
{"name":"score","title": lang.spam_score, "type": "text"},
{"name":"notified","title":lang.notified, "type": "text"},
{"name":"created","formatter":function unix_time_format(tm) { var date = new Date(tm ? tm * 1000 : 0); return date.toLocaleDateString(undefined, {year: "numeric", month: "2-digit", day: "2-digit", hour: "2-digit", minute: "2-digit", second: "2-digit"});},"title":lang.received,"style":{"width":"170px"}},
{"name":"action","filterable": false,"sortable": false,"style":{"text-align":"right"},"style":{"min-width":"250px"},"type":"html","title":lang.action,"breakpoints":"xs sm md"}
],
"rows": $.ajax({
dataType: 'json',
url: '/api/v1/get/quarantine/all',
jsonp: false,
error: function () {
console.log('Cannot draw quarantine table');
},
success: function (data) {
$('#quarantinetable').DataTable({
processing: true,
serverSide: false,
language: lang_datatables,
ajax: {
type: "GET",
url: "/api/v1/get/quarantine/all",
dataSrc: function(data){
$.each(data, function (i, item) {
if (item.subject === null) {
item.subject = '';
@@ -78,16 +31,16 @@ jQuery(function($){
item.score = '-';
}
if (item.virus_flag > 0) {
item.virus = '<span class="label label-danger">' + lang.high_danger + '</span>';
item.virus = '<span class="badge fs-5 bg-danger">' + lang.high_danger + '</span>';
} else {
item.virus = '<span class="label label-default">' + lang.neutral_danger + '</span>';
item.virus = '<span class="badge fs-5 bg-secondary">' + lang.neutral_danger + '</span>';
}
if (item.action === "reject") {
item.rspamdaction = '<span class="label label-danger">' + lang.rejected + '</span>';
item.rspamdaction = '<span class="badge fs-5 bg-danger">' + lang.rejected + '</span>';
} else if (item.action === "add header") {
item.rspamdaction = '<span class="label label-warning">' + lang.junk_folder + '</span>';
item.rspamdaction = '<span class="badge fs-5 bg-warning">' + lang.junk_folder + '</span>';
} else if (item.action === "rewrite subject") {
item.rspamdaction = '<span class="label label-warning">' + lang.rewrite_subject + '</span>';
item.rspamdaction = '<span class="badge fs-5 bg-warning">' + lang.rewrite_subject + '</span>';
}
if(item.notified > 0) {
item.notified = '&#10004;';
@@ -95,7 +48,7 @@ jQuery(function($){
item.notified = '&#10006;';
}
if (acl_data.login_as === 1) {
item.action = '<div class="btn-group footable-actions">' +
item.action = '<div class="btn-group">' +
'<a href="#" data-item="' + encodeURI(item.id) + '" class="btn btn-xs btn-xs-half btn-info show_qid_info"><i class="bi bi-box-arrow-up-right"></i> ' + lang.show_item + '</a>' +
'<a href="#" data-action="delete_selected" data-id="del-single-qitem" data-api-url="delete/qitem" data-item="' + encodeURI(item.id) + '" class="btn btn-xs btn-xs-half btn-danger"><i class="bi bi-trash"></i> ' + lang.remove + '</a>' +
'</div>';
@@ -107,25 +60,76 @@ jQuery(function($){
}
item.chkbox = '<input type="checkbox" data-id="qitems" name="multi_select" value="' + item.id + '" />';
});
}
}),
"empty": lang.empty,
"paging": {"enabled": true,"limit": 5,"size": pagination_size},
"state": {"enabled": true},
"sorting": {"enabled": true},
"filtering": {"enabled": true,"position": "left","connectors": false,"placeholder": lang.filter_table},
"toggleSelector": "table tbody span.footable-toggle",
"on": {
"destroy.ft.table": function(e, ft){
$('.refresh_table').attr('disabled', 'true');
},
"ready.ft.table": function(e, ft){
table_quarantine_ready(ft, 'quarantinetable');
},
"after.ft.filtering": function(e, ft){
table_quarantine_ready(ft, 'quarantinetable');
return data;
}
},
columns: [
{
// placeholder, so checkbox will not block child row toggle
title: '',
data: null,
searchable: false,
orderable: false,
defaultContent: ''
},
{
title: '',
data: 'chkbox',
searchable: false,
orderable: false,
defaultContent: ''
},
{
title: 'ID',
data: 'id',
},
{
title: lang.qid,
data: 'qid'
},
{
title: lang.sender,
data: 'sender'
},
{
title: lang.subj,
data: 'sender'
},
{
title: lang.rspamd_result,
data: 'rspamdaction'
},
{
title: lang.rcpt,
data: 'rcpt'
},
{
title: lang.danger,
data: 'virus'
},
{
title: lang.spam_score,
data: 'score'
},
{
title: lang.notified,
data: 'notified'
},
{
title: lang.received,
data: 'created',
render: function (data,type) {
var date = new Date(data ? data * 1000 : 0);
return date.toLocaleDateString(undefined, {year: "numeric", month: "2-digit", day: "2-digit", hour: "2-digit", minute: "2-digit", second: "2-digit"});
}
},
{
title: lang.action,
data: 'action',
className: 'text-md-end dt-sm-head-hidden dt-body-right'
},
]
});
}
@@ -175,9 +179,9 @@ jQuery(function($){
if (value.score > 0) highlightClass = 'negative'
else if (value.score < 0) highlightClass = 'positive'
else highlightClass = 'neutral'
$('#qid_detail_symbols').append('<span data-toggle="tooltip" class="rspamd-symbol ' + highlightClass + '" title="' + (value.options ? value.options.join(', ') : '') + '">' + value.name + ' (<span class="score">' + value.score + '</span>)</span>');
$('#qid_detail_symbols').append('<span data-bs-toggle="tooltip" class="rspamd-symbol ' + highlightClass + '" title="' + (value.options ? value.options.join(', ') : '') + '">' + value.name + ' (<span class="score">' + value.score + '</span>)</span>');
});
$('[data-toggle="tooltip"]').tooltip()
$('[data-bs-toggle="tooltip"]').tooltip()
}
if (typeof data.fuzzy_hashes === 'object' && data.fuzzy_hashes !== null && data.fuzzy_hashes.length !== 0) {
$.each(data.fuzzy_hashes, function (index, value) {
@@ -188,11 +192,11 @@ jQuery(function($){
}
if (typeof data.score !== 'undefined' && typeof data.action !== 'undefined') {
if (data.action == "add header") {
$('#qid_detail_score').append('<span class="label-rspamd-action label label-warning"><b>' + data.score + '</b> - ' + lang.junk_folder + '</span>');
$('#qid_detail_score').append('<span class="label-rspamd-action badge fs-5 bg-warning"><b>' + data.score + '</b> - ' + lang.junk_folder + '</span>');
} else if (data.action == "reject") {
$('#qid_detail_score').append('<span class="label-rspamd-action label label-danger"><b>' + data.score + '</b> - ' + lang.rejected + '</span>');
$('#qid_detail_score').append('<span class="label-rspamd-action badge fs-5 bg-danger"><b>' + data.score + '</b> - ' + lang.rejected + '</span>');
} else if (data.action == "rewrite subject") {
$('#qid_detail_score').append('<span class="label-rspamd-action label label-warning"><b>' + data.score + '</b> - ' + lang.rewrite_subject + '</span>');
$('#qid_detail_score').append('<span class="label-rspamd-action badge fs-5 bg-warning"><b>' + data.score + '</b> - ' + lang.rewrite_subject + '</span>');
}
}
if (typeof data.recipients !== 'undefined') {

View File

@@ -101,7 +101,7 @@ jQuery(function($){
$.each(data.sasl, function (i, item) {
var datetime = new Date(item.datetime.replace(/-/g, "/"));
var local_datetime = datetime.toLocaleDateString(undefined, {year: "numeric", month: "2-digit", day: "2-digit", hour: "2-digit", minute: "2-digit", second: "2-digit"});
var service = '<div class="label label-default">' + item.service.toUpperCase() + '</div>';
var service = '<div class="badge fs-5 bg-secondary">' + item.service.toUpperCase() + '</div>';
var app_password = item.app_password ? ' <a href="/edit/app-passwd/' + item.app_password + '"><i class="bi bi-app-indicator"></i> ' + escapeHtml(item.app_password_name || "App") + '</a>' : '';
var real_rip = item.real_rip.startsWith("Web") ? item.real_rip : '<a href="https://bgp.he.net/ip/' + item.real_rip + '" target="_blank">' + item.real_rip + "</a>";
var ip_location = item.location ? ' <span class="flag-icon flag-icon-' + item.location.toLowerCase() + '"></span>' : '';
@@ -128,26 +128,18 @@ jQuery(function($){
}
function draw_tla_table() {
ft_tla_table = FooTable.init('#tla_table', {
"columns": [
{"name":"chkbox","title":"","style":{"min-width":"60px","width":"60px","text-align":"center"},"filterable": false,"sortable": false,"type":"html"},
{"name":"address","title":lang.alias},
{"name":"validity","formatter":function unix_time_format(tm) { var date = new Date(tm ? tm * 1000 : 0); return date.toLocaleDateString(undefined, {year: "numeric", month: "2-digit", day: "2-digit", hour: "2-digit", minute: "2-digit", second: "2-digit"});},"title":lang.alias_valid_until,"style":{"width":"170px"}},
{"sorted": true,"sortValue": function(value){res = new Date(value);return res.getTime();},"direction":"DESC","name":"created","formatter":function date_format(datetime) { var date = new Date(datetime.replace(/-/g, "/")); return date.toLocaleDateString(undefined, {year: "numeric", month: "2-digit", day: "2-digit", hour: "2-digit", minute: "2-digit", second: "2-digit"});},"title":lang.created_on,"style":{"width":"170px"}},
{"name":"action","filterable": false,"sortable": false,"style":{"text-align":"right","min-width":"220px","width":"220px"},"type":"html","title":lang.action,"breakpoints":"xs sm"}
],
"empty": lang.empty,
"rows": $.ajax({
dataType: 'json',
url: '/api/v1/get/time_limited_aliases',
jsonp: false,
error: function () {
console.log('Cannot draw tla table');
},
success: function (data) {
$('#tla_table').DataTable({
processing: true,
serverSide: false,
language: lang_datatables,
ajax: {
type: "GET",
url: "/api/v1/get/time_limited_aliases",
dataSrc: function(data){
console.log(data);
$.each(data, function (i, item) {
if (acl_data.spam_alias === 1) {
item.action = '<div class="btn-group footable-actions">' +
item.action = '<div class="btn-group">' +
'<a href="#" data-action="delete_selected" data-id="single-tla" data-api-url="delete/time_limited_alias" data-item="' + encodeURIComponent(item.address) + '" class="btn btn-xs btn-danger"><i class="bi bi-trash"></i> ' + lang.remove + '</a>' +
'</div>';
item.chkbox = '<input type="checkbox" data-id="tla" name="multi_select" value="' + encodeURIComponent(item.address) + '" />';
@@ -158,49 +150,59 @@ jQuery(function($){
item.action = '<span>-</span>';
}
});
return data;
}
}),
"paging": {
"enabled": true,
"limit": 5,
"size": pagination_size
},
"state": {"enabled": true},
"sorting": {
"enabled": true
},
"toggleSelector": "table tbody span.footable-toggle"
columns: [
{
// placeholder, so checkbox will not block child row toggle
title: '',
data: null,
searchable: false,
orderable: false,
defaultContent: ''
},
{
title: '',
data: 'chkbox',
searchable: false,
orderable: false,
defaultContent: ''
},
{
title: lang.alias,
data: 'address'
},
{
title: lang.alias_valid_until,
data: 'validity',
render: function (data, type) {
var date = new Date(data ? data * 1000 : 0);
return date.toLocaleDateString(undefined, {year: "numeric", month: "2-digit", day: "2-digit", hour: "2-digit", minute: "2-digit", second: "2-digit"});
}
},
{
title: lang.action,
data: 'action',
className: 'text-md-end dt-sm-head-hidden dt-body-right'
}
]
});
}
function draw_sync_job_table() {
ft_syncjob_table = FooTable.init('#sync_job_table', {
"columns": [
{"name":"chkbox","title":"","style":{"min-width":"60px","width":"60px","text-align":"center"},"filterable": false,"sortable": false,"type":"html"},
{"sorted": true,"name":"id","title":"ID","style":{"maxWidth":"60px","width":"60px","text-align":"center"}},
{"name":"server_w_port","title":"Server","breakpoints":"xs sm md","style":{"word-break":"break-all"}},
{"name":"enc1","title":lang.encryption,"breakpoints":"all"},
{"name":"user1","title":lang.username},
{"name":"exclude","title":lang.excludes,"breakpoints":"all"},
{"name":"mins_interval","title":lang.interval + " (min)","breakpoints":"all"},
{"name":"last_run","title":lang.last_run,"breakpoints":"xs sm md"},
{"name":"exit_status","filterable": false,"title":lang.syncjob_last_run_result},
{"name":"log","title":"Log"},
{"name":"active","filterable": false,"style":{"maxWidth":"70px","width":"70px"},"title":lang.active,"formatter": function(value){return 1==value?'<i class="bi bi-check-lg"></i>':0==value&&'<i class="bi bi-x-lg"></i>';}},
{"name":"is_running","filterable": false,"style":{"maxWidth":"120px","width":"100px"},"title":lang.status},
{"name":"action","filterable": false,"sortable": false,"style":{"text-align":"right","min-width":"260px","width":"260px"},"type":"html","title":lang.action,"breakpoints":"xs sm"}
],
"empty": lang.empty,
"rows": $.ajax({
dataType: 'json',
$('#sync_job_table').DataTable({
processing: true,
serverSide: false,
language: lang_datatables,
ajax: {
type: "GET",
url: '/api/v1/get/syncjobs/' + encodeURIComponent(mailcow_cc_username) + '/no_log',
jsonp: false,
error: function () {
console.log('Cannot draw sync job table');
},
success: function (data) {
dataSrc: function(data){
console.log(data);
$.each(data, function (i, item) {
item.user1 = escapeHtml(item.user1);
item.log = '<a href="#syncjobLogModal" data-toggle="modal" data-syncjob-id="' + item.id + '">' + lang.open_logs + '</a>'
item.log = '<a href="#syncjobLogModal" data-bs-toggle="modal" data-syncjob-id="' + item.id + '">' + lang.open_logs + '</a>'
if (!item.exclude > 0) {
item.exclude = '-';
} else {
@@ -208,8 +210,8 @@ jQuery(function($){
}
item.server_w_port = escapeHtml(item.user1 + '@' + item.host1 + ':' + item.port1);
if (acl_data.syncjobs === 1) {
item.action = '<div class="btn-group footable-actions">' +
'<a href="/edit/syncjob/' + item.id + '" class="btn btn-xs btn-xs-half btn-default"><i class="bi bi-pencil-fill"></i> ' + lang.edit + '</a>' +
item.action = '<div class="btn-group">' +
'<a href="/edit/syncjob/' + item.id + '" class="btn btn-xs btn-xs-half btn-secondary"><i class="bi bi-pencil-fill"></i> ' + lang.edit + '</a>' +
'<a href="#" data-action="delete_selected" data-id="single-syncjob" data-api-url="delete/syncjob" data-item="' + item.id + '" class="btn btn-xs btn-xs-half btn-danger"><i class="bi bi-trash"></i> ' + lang.remove + '</a>' +
'</div>';
item.chkbox = '<input type="checkbox" data-id="syncjob" name="multi_select" value="' + item.id + '" />';
@@ -219,9 +221,9 @@ jQuery(function($){
item.chkbox = '<input type="checkbox" disabled />';
}
if (item.is_running == 1) {
item.is_running = '<span id="active-script" class="label label-success">' + lang.running + '</span>';
item.is_running = '<span id="active-script" class="badge fs-5 bg-success">' + lang.running + '</span>';
} else {
item.is_running = '<span id="inactive-script" class="label label-warning">' + lang.waiting + '</span>';
item.is_running = '<span id="inactive-script" class="badge fs-5 bg-warning">' + lang.waiting + '</span>';
}
if (!item.last_run > 0) {
item.last_run = lang.waiting;
@@ -239,39 +241,91 @@ jQuery(function($){
}
item.exit_status = item.success + ' ' + item.exit_status;
});
return data;
}
}),
"paging": {
"enabled": true,
"limit": 5,
"size": pagination_size
},
"state": {"enabled": true},
"sorting": {
"enabled": true
},
"toggleSelector": "table tbody span.footable-toggle"
columns: [
{
// placeholder, so checkbox will not block child row toggle
title: '',
data: null,
searchable: false,
orderable: false,
defaultContent: ''
},
{
title: '',
data: 'chkbox',
searchable: false,
orderable: false,
defaultContent: ''
},
{
title: 'ID',
data: 'id'
},
{
title: 'Server',
data: 'server_w_port'
},
{
title: lang.encryption,
data: 'enc1'
},
{
title: lang.username,
data: 'user1'
},
{
title: lang.excludes,
data: 'exclude'
},
{
title: lang.interval + " (min)",
data: 'mins_interval'
},
{
title: lang.last_run,
data: 'last_run'
},
{
title: lang.syncjob_last_run_result,
data: 'exit_status'
},
{
title: 'Log',
data: 'log'
},
{
title: lang.active,
data: 'active',
render: function (data, type) {
return 1==data?'<i class="bi bi-check-lg"></i>':0==data&&'<i class="bi bi-x-lg"></i>'
}
},
{
title: lang.status,
data: 'is_running'
},
{
title: lang.action,
data: 'action',
className: 'text-md-end dt-sm-head-hidden dt-body-right'
}
]
});
}
function draw_app_passwd_table() {
ft_apppasswd_table = FooTable.init('#app_passwd_table', {
"columns": [
{"name":"chkbox","title":"","style":{"maxWidth":"60px","width":"60px","text-align":"center"},"filterable": false,"sortable": false,"type":"html"},
{"sorted": true,"name":"id","title":"ID","style":{"maxWidth":"60px","width":"60px","text-align":"center"}},
{"name":"name","title":lang.app_name},
{"name":"protocols","title":lang.allowed_protocols},
{"name":"active","filterable": false,"style":{"maxWidth":"70px","width":"70px"},"title":lang.active,"formatter": function(value){return 1==value?'<i class="bi bi-check-lg"></i>':0==value&&'<i class="bi bi-x-lg"></i>';}},
{"name":"action","filterable": false,"sortable": false,"style":{"text-align":"right","min-width":"220px","width":"220px"},"type":"html","title":lang.action,"breakpoints":"xs sm"}
],
"empty": lang.empty,
"rows": $.ajax({
dataType: 'json',
$('#app_passwd_table').DataTable({
processing: true,
serverSide: false,
language: lang_datatables,
ajax: {
type: "GET",
url: '/api/v1/get/app-passwd/all',
jsonp: false,
error: function () {
console.log('Cannot draw app passwd table');
},
success: function (data) {
dataSrc: function(data){
console.log(data);
$.each(data, function (i, item) {
item.name = escapeHtml(item.name)
item.protocols = []
@@ -283,8 +337,8 @@ jQuery(function($){
if (item.sieve_access == 1) { item.protocols.push("<code>Sieve</code>"); }
item.protocols = item.protocols.join(" ")
if (acl_data.app_passwds === 1) {
item.action = '<div class="btn-group footable-actions">' +
'<a href="/edit/app-passwd/' + item.id + '" class="btn btn-xs btn-xs-half btn-default"><i class="bi bi-pencil-fill"></i> ' + lang.edit + '</a>' +
item.action = '<div class="btn-group">' +
'<a href="/edit/app-passwd/' + item.id + '" class="btn btn-xs btn-xs-half btn-secondary"><i class="bi bi-pencil-fill"></i> ' + lang.edit + '</a>' +
'<a href="#" data-action="delete_selected" data-id="single-apppasswd" data-api-url="delete/app-passwd" data-item="' + item.id + '" class="btn btn-xs btn-xs-half btn-danger"><i class="bi bi-trash"></i> ' + lang.remove + '</a>' +
'</div>';
item.chkbox = '<input type="checkbox" data-id="apppasswd" name="multi_select" value="' + item.id + '" />';
@@ -294,37 +348,63 @@ jQuery(function($){
item.chkbox = '<input type="checkbox" disabled />';
}
});
return data;
}
}),
"paging": {
"enabled": true,
"limit": 5,
"size": pagination_size
},
"state": {"enabled": true},
"sorting": {
"enabled": true
},
"toggleSelector": "table tbody span.footable-toggle"
columns: [
{
// placeholder, so checkbox will not block child row toggle
title: '',
data: null,
searchable: false,
orderable: false,
defaultContent: ''
},
{
title: '',
data: 'chkbox',
searchable: false,
orderable: false,
defaultContent: ''
},
{
title: 'ID',
data: 'id'
},
{
title: lang.app_name,
data: 'name'
},
{
title: lang.allowed_protocols,
data: 'protocols'
},
{
title: lang.active,
data: 'active',
render: function (data, type) {
return 1==data?'<i class="bi bi-check-lg"></i>':0==data&&'<i class="bi bi-x-lg"></i>'
}
},
{
title: lang.action,
data: 'action',
className: 'text-md-end dt-sm-head-hidden dt-body-right'
}
]
});
}
function draw_wl_policy_mailbox_table() {
ft_wl_policy_mailbox_table = FooTable.init('#wl_policy_mailbox_table', {
"columns": [
{"name":"chkbox","title":"","style":{"maxWidth":"40px","width":"40px","text-align":"center"},"filterable": false,"sortable": false,"type":"html"},
{"name":"prefid","style":{"maxWidth":"40px","width":"40px"},"title":"ID","filterable": false,"sortable": false},
{"sorted": true,"name":"value","title":lang.spamfilter_table_rule},
{"name":"object","title":"Scope"}
],
"empty": lang.empty,
"rows": $.ajax({
dataType: 'json',
$('#wl_policy_mailbox_table').DataTable({
processing: true,
serverSide: false,
language: lang_datatables,
ajax: {
type: "GET",
url: '/api/v1/get/policy_wl_mailbox',
jsonp: false,
error: function () {
console.log('Cannot draw mailbox policy wl table');
},
success: function (data) {
dataSrc: function(data){
console.log(data);
$.each(data, function (i, item) {
if (validateEmail(item.object)) {
item.chkbox = '<input type="checkbox" data-id="policy_wl_mailbox" name="multi_select" value="' + item.prefid + '" />';
@@ -336,36 +416,51 @@ jQuery(function($){
item.chkbox = '<input type="checkbox" disabled />';
}
});
return data;
}
}),
"state": {"enabled": true},
"paging": {
"enabled": true,
"limit": 5,
"size": pagination_size
},
"sorting": {
"enabled": true
}
columns: [
{
// placeholder, so checkbox will not block child row toggle
title: '',
data: null,
searchable: false,
orderable: false,
defaultContent: ''
},
{
title: '',
data: 'chkbox',
searchable: false,
orderable: false,
defaultContent: ''
},
{
title: 'ID',
data: 'prefid'
},
{
title: lang.spamfilter_table_rule,
data: 'name'
},
{
title:'Scope',
data: 'object'
}
]
});
}
function draw_bl_policy_mailbox_table() {
ft_bl_policy_mailbox_table = FooTable.init('#bl_policy_mailbox_table', {
"columns": [
{"name":"chkbox","title":"","style":{"maxWidth":"40px","width":"40px","text-align":"center"},"filterable": false,"sortable": false,"type":"html"},
{"name":"prefid","style":{"maxWidth":"40px","width":"40px"},"title":"ID","filterable": false,"sortable": false},
{"sorted": true,"name":"value","title":lang.spamfilter_table_rule},
{"name":"object","title":"Scope"}
],
"empty": lang.empty,
"rows": $.ajax({
dataType: 'json',
$('#bl_policy_mailbox_table').DataTable({
processing: true,
serverSide: false,
language: lang_datatables,
ajax: {
type: "GET",
url: '/api/v1/get/policy_bl_mailbox',
jsonp: false,
error: function () {
console.log('Cannot draw mailbox policy bl table');
},
success: function (data) {
dataSrc: function(data){
console.log(data);
$.each(data, function (i, item) {
if (validateEmail(item.object)) {
item.chkbox = '<input type="checkbox" data-id="policy_bl_mailbox" name="multi_select" value="' + item.prefid + '" />';
@@ -377,31 +472,42 @@ jQuery(function($){
item.chkbox = '<input type="checkbox" disabled />';
}
});
return data;
}
}),
"paging": {
"enabled": true,
"limit": 5,
"size": pagination_size
},
"state": {"enabled": true},
"sorting": {
"enabled": true
}
columns: [
{
// placeholder, so checkbox will not block child row toggle
title: '',
data: null,
searchable: false,
orderable: false,
defaultContent: ''
},
{
title: '',
data: 'chkbox',
searchable: false,
orderable: false,
defaultContent: ''
},
{
title: 'ID',
data: 'prefid'
},
{
title: lang.spamfilter_table_rule,
data: 'name'
},
{
title:'Scope',
data: 'object'
}
]
});
}
$('body').on('click', 'span.footable-toggle', function () {
event.stopPropagation();
})
draw_sync_job_table();
draw_app_passwd_table();
draw_tla_table();
draw_wl_policy_mailbox_table();
draw_bl_policy_mailbox_table();
last_logins('get');
// FIDO2 friendly name modal
$('#fido2ChangeFn').on('show.bs.modal', function (e) {
rename_link = $(e.relatedTarget)
@@ -433,4 +539,27 @@ jQuery(function($){
$('#userFilterModal').on('hidden.bs.modal', function () {
$('#user_sieve_filter').text(lang.loading);
});
// detect element visibility changes
function onVisible(element, callback) {
$(element).ready(function() {
element_object = document.querySelector(element)
new IntersectionObserver((entries, observer) => {
entries.forEach(entry => {
if(entry.intersectionRatio > 0) {
callback(element_object);
observer.disconnect();
}
});
}).observe(element_object);
});
}
// Load only if the tab is visible
onVisible("[id^=tla_table]", () => draw_tla_table());
onVisible("[id^=bl_policy_mailbox_table]", () => draw_bl_policy_mailbox_table());
onVisible("[id^=wl_policy_mailbox_table]", () => draw_wl_policy_mailbox_table());
onVisible("[id^=sync_job_table]", () => draw_sync_job_table());
onVisible("[id^=app_passwd_table]", () => draw_app_passwd_table());
last_logins('get');
});