mirror of
https://github.com/EGroupware/egroupware.git
synced 2024-11-24 17:04:14 +01:00
Merge branch 'master' into web-components
This commit is contained in:
commit
ad00156113
@ -1081,7 +1081,7 @@ class AdminApp extends EgwApp
|
||||
|
||||
if(egw.app('policy'))
|
||||
{
|
||||
import(egw.link('/policy/js/app.js?'+((new Date).valueOf()/86400|0).toString())).then(() => {
|
||||
import(egw.link('/policy/js/app.min.js?'+((new Date).valueOf()/86400|0).toString())).then(() => {
|
||||
if(typeof app.policy === 'undefined' || typeof app.policy.confirm === 'undefined')
|
||||
{
|
||||
app.policy = new app.classes.policy();
|
||||
|
@ -396,17 +396,14 @@ egwFnct.prototype.setValue = function(_value)
|
||||
// check if we need a not yet included app.js object --> include it now and re-set when it arrives
|
||||
else if (i === 1 && typeof app.classes[parts[1]] === "undefined")
|
||||
{
|
||||
var self = this;
|
||||
return new Promise(function(resolve)
|
||||
{
|
||||
egw.includeJS("/"+parts[1]+"/js/app.js", function ()
|
||||
{
|
||||
if(typeof app.classes[parts[i]] !== "undefined")
|
||||
return import(egw.webserverUrl+"/"+parts[1]+"/js/app.min.js?"+((new Date).valueOf()/86400|0).toString())
|
||||
.then(() => {
|
||||
if(typeof app.classes[parts[i]] === "undefined")
|
||||
{
|
||||
resolve(this.setValue(_value));
|
||||
throw new Error("app.classes."+parts[i]+" not found!");
|
||||
}
|
||||
}.bind(this), self, egw.webserverUrl);
|
||||
}.bind(this));
|
||||
this.setValue(_value);
|
||||
});
|
||||
}
|
||||
// check if we need a not yet instantiated app.js object --> instantiate it now
|
||||
else if (i === 1 && typeof app.classes[parts[1]] === "function")
|
||||
|
@ -47,26 +47,35 @@ export function et2_loadXMLFromURL(_url : string, _callback? : Function, _contex
|
||||
{
|
||||
win = egw.top;
|
||||
}
|
||||
return win.jQuery.ajax({
|
||||
// we add the full url (protocol and domain) as sometimes just the path
|
||||
// gives a CSP error interpreting it as file:///path
|
||||
// (if there are a enough 404 errors in html content ...)
|
||||
url: (_url[0]=='/' ? location.protocol+'//'+location.host : '')+_url,
|
||||
context: _context,
|
||||
type: 'GET',
|
||||
dataType: 'xml',
|
||||
success: function(_data, _status, _xmlhttp){
|
||||
if (typeof _callback === 'function') {
|
||||
_callback.call(_context, _data.documentElement);
|
||||
// we add the full url (protocol and domain) as sometimes just the path
|
||||
// gives a CSP error interpreting it as file:///path
|
||||
// (if there are a enough 404 errors in html content ...)
|
||||
return win.fetch((_url[0] === '/' ? location.protocol+'//'+location.host : '')+_url, {
|
||||
method: 'GET'
|
||||
})
|
||||
.then((response) => {
|
||||
if (!response.ok) {
|
||||
throw response;
|
||||
}
|
||||
},
|
||||
error: function(_xmlhttp, _err) {
|
||||
egw().debug('error', 'Loading eTemplate from '+_url+' failed! '+_xmlhttp.status+' '+_xmlhttp.statusText);
|
||||
return response.text();
|
||||
})
|
||||
.then((xml) => {
|
||||
const parser = new window.DOMParser();
|
||||
return parser.parseFromString( xml, "text/xml" );
|
||||
})
|
||||
.then((xmldoc) => {
|
||||
if (typeof _callback === 'function') {
|
||||
_callback.call(_context, xmldoc.children[0]);
|
||||
}
|
||||
return xmldoc.children[0];
|
||||
})
|
||||
.catch((_err) => {
|
||||
egw().message('Loading eTemplate from '+_url+' failed!'+"\n\n"+
|
||||
(typeof _err.stack !== 'undefined' ? _err.stack : _err.status+' '+_err.statusText), 'error');
|
||||
if(typeof _fail_callback === 'function') {
|
||||
_fail_callback.call(_context, _err);
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
export function et2_directChildrenByTagName(_node : HTMLElement, _tagName : String) : HTMLElement[]
|
||||
|
@ -1469,60 +1469,40 @@ export class et2_selectbox extends et2_inputWidget
|
||||
// normalize options by removing trailing commas
|
||||
options_string = options_string.replace(/,+$/, '');
|
||||
|
||||
var cache_id = widget._type+'_'+options_string;
|
||||
var cache_owner = (
|
||||
// Todo: @new-js-loader et2_selectbox is no longer instanciated globaly --> caching needs to be fixed
|
||||
et2_selectbox
|
||||
/*egw.window.et2_selectbox ?
|
||||
egw.window.et2_selectbox :
|
||||
egw(window).window.et2_selectbox*/
|
||||
).type_cache;
|
||||
var cache = cache_owner[cache_id];
|
||||
const cache_id = widget._type+'_'+options_string;
|
||||
const cache_owner = egw.getCache('et2_selectbox');
|
||||
let cache = cache_owner[cache_id];
|
||||
|
||||
// Options for a selectbox in a nextmatch must be returned now, as the
|
||||
// widget we have is not enough to set the options later.
|
||||
var in_nextmatch = false;
|
||||
if(typeof cache === 'undefined' || typeof cache.length === 'undefined')
|
||||
{
|
||||
var parent = widget._parent;
|
||||
while(parent && !in_nextmatch)
|
||||
{
|
||||
in_nextmatch = parent && parent._type && parent._type === 'nextmatch';
|
||||
parent = parent._parent;
|
||||
}
|
||||
}
|
||||
if (typeof cache == 'undefined' || in_nextmatch)
|
||||
if (typeof cache === 'undefined')
|
||||
{
|
||||
// Fetch with json instead of jsonq because there may be more than
|
||||
// one widget listening for the response by the time it gets back,
|
||||
// and we can't do that when it's queued.
|
||||
var req = egw.json(
|
||||
const req = egw.json(
|
||||
'EGroupware\\Api\\Etemplate\\Widget\\Select::ajax_get_options',
|
||||
[widget._type,options_string,attrs.value]
|
||||
).sendRequest(!in_nextmatch);
|
||||
).sendRequest();
|
||||
if(typeof cache === 'undefined')
|
||||
{
|
||||
cache_owner[cache_id] = req;
|
||||
}
|
||||
cache = req;
|
||||
}
|
||||
if(typeof cache.done == 'function')
|
||||
if (typeof cache.then === 'function')
|
||||
{
|
||||
// pending, wait for it
|
||||
cache.done(jQuery.proxy(function(response) {
|
||||
cache.then((response) => {
|
||||
cache = cache_owner[cache_id] = response.response[0].data||undefined;
|
||||
// Set select_options in attributes in case we get a resonse before
|
||||
// Set select_options in attributes in case we get a response before
|
||||
// the widget is finished loading (otherwise it will re-set to {})
|
||||
attrs.select_options = cache;
|
||||
|
||||
egw.window.setTimeout(jQuery.proxy(function() {
|
||||
// Avoid errors if widget is destroyed before the timeout
|
||||
if(this.widget && typeof this.widget.id !== 'undefined')
|
||||
{
|
||||
this.widget.set_select_options(et2_selectbox.find_select_options(this.widget,{}, this.widget.options));
|
||||
}
|
||||
},this),1);
|
||||
},{widget:widget,cache_id:cache_id}));
|
||||
// Avoid errors if widget is destroyed before the timeout
|
||||
if (widget && typeof widget.id !== 'undefined')
|
||||
{
|
||||
widget.set_select_options(et2_selectbox.find_select_options(widget,{}, widget.options));
|
||||
}
|
||||
});
|
||||
return [];
|
||||
}
|
||||
else
|
||||
|
@ -75,9 +75,6 @@ egw.extend('json', egw.MODULE_WND_LOCAL, function(_app, _wnd)
|
||||
this.sender = _sender ? _sender : null;
|
||||
this.egw = _egw;
|
||||
|
||||
// We currently don't have a request object
|
||||
this.request = null;
|
||||
|
||||
// Some variables needed for notification about a JS files done loading
|
||||
this.onLoadFinish = null;
|
||||
this.jsFiles = 0;
|
||||
@ -191,7 +188,7 @@ egw.extend('json', egw.MODULE_WND_LOCAL, function(_app, _wnd)
|
||||
* @param {string} method ='POST' allow to eg. use a (cachable) 'GET' request instead of POST
|
||||
* @param {function} error option error callback(_xmlhttp, _err) used instead our default this.error
|
||||
*
|
||||
* @return {jqXHR|boolean} jQuery jqXHR request object or for async==="keepalive" boolean is returned
|
||||
* @return {Promise|boolean} Promise or for async==="keepalive" boolean is returned
|
||||
*/
|
||||
json_request.prototype.sendRequest = function(async, method, error)
|
||||
{
|
||||
@ -203,13 +200,13 @@ egw.extend('json', egw.MODULE_WND_LOCAL, function(_app, _wnd)
|
||||
if (typeof method === 'undefined') method = 'POST';
|
||||
|
||||
// Assemble the complete request
|
||||
var request_obj = JSON.stringify({
|
||||
const request_obj = JSON.stringify({
|
||||
request: {
|
||||
parameters: this.parameters
|
||||
}
|
||||
});
|
||||
|
||||
// send with keepalive===true or sendBeacon to be used in beforeunload event
|
||||
// send with keepalive===true for sendBeacon to be used in beforeunload event
|
||||
if (this.async === "keepalive" && typeof navigator.sendBeacon !== "undefined")
|
||||
{
|
||||
const data = new FormData();
|
||||
@ -218,53 +215,94 @@ egw.extend('json', egw.MODULE_WND_LOCAL, function(_app, _wnd)
|
||||
return navigator.sendBeacon(this.url, data);
|
||||
}
|
||||
|
||||
// Send the request via AJAX using the jquery ajax function
|
||||
// we need to use jQuery of window of egw object, as otherwise the one from main window is used!
|
||||
// (causing eg. apply from server with app.$app.method to run in main window instead of popup)
|
||||
this.request = (this.egw.window?this.egw.window.jQuery:jQuery).ajax({
|
||||
url: this.url,
|
||||
async: this.async,
|
||||
context: this,
|
||||
// only POST can send JSON as direct payload, GET can not
|
||||
data: method === 'GET' ? { json_data: request_obj } : request_obj,
|
||||
contentType: method === 'GET' ? false : 'application/json',
|
||||
dataType: 'json',
|
||||
type: method,
|
||||
success: this.handleResponse,
|
||||
jsonp: false,
|
||||
error: error || this.handleError
|
||||
});
|
||||
let url = this.url;
|
||||
let init = {
|
||||
method: method
|
||||
}
|
||||
if (method === 'GET')
|
||||
{
|
||||
url += (url.indexOf('?') === -1 ? '?' : '&') + new URLSearchParams({ json_data: request_obj });
|
||||
}
|
||||
else
|
||||
{
|
||||
init.headers = { 'Content-Type': 'application/json'};
|
||||
init.body = request_obj;
|
||||
}
|
||||
let promise;
|
||||
if (this.async)
|
||||
{
|
||||
promise = (this.egw.window?this.egw.window:window).fetch(url, init)
|
||||
.then((response) => {
|
||||
if (!response.ok) {
|
||||
throw response;
|
||||
}
|
||||
return response.json();
|
||||
})
|
||||
.then((data) => this.handleResponse(data) || data)
|
||||
.catch((_err) => {
|
||||
(error || this.handleError).call(this, _err)
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
console.trace("Synchronous AJAX request detected", this);
|
||||
const request = new XMLHttpRequest();
|
||||
request.open(method, url, false);
|
||||
if (method !== 'GET') request.setRequestHeader('Content-Type', 'application/json');
|
||||
request.send(init.body);
|
||||
if (request.status >= 200 && request.status < 300)
|
||||
{
|
||||
const json = JSON.parse(request.responseText);
|
||||
promise = Promise.resolve(this.handleResponse(json) || json);
|
||||
}
|
||||
else
|
||||
{
|
||||
(error || this.handleError).call(this, request, 'error')
|
||||
}
|
||||
}
|
||||
// compatibility with jQuery.ajax
|
||||
if (promise && typeof promise.then === 'function') promise.done = promise.then;
|
||||
|
||||
return this.request;
|
||||
return promise;
|
||||
};
|
||||
|
||||
/**
|
||||
* Default error callback displaying error via egw.message
|
||||
*
|
||||
* @param {XMLHTTP} _xmlhttp
|
||||
* @param {XMLHTTP|Response} response
|
||||
* @param {string} _err
|
||||
*/
|
||||
json_request.prototype.handleError = function(_xmlhttp, _err) {
|
||||
json_request.prototype.handleError = function(response, _err) {
|
||||
// Don't error about an abort
|
||||
if(_err !== 'abort')
|
||||
{
|
||||
// for fetch Response get json, as it's used below
|
||||
if (typeof response.headers === 'object' && response.headers.get('Content-Type') === 'application/json')
|
||||
{
|
||||
return response.json().then((json) => {
|
||||
response.responseJSON = json;
|
||||
this.handleError(response, 'error');
|
||||
})
|
||||
}
|
||||
const date = typeof response.headers === 'object' ? 'Date: '+response.headers.get('Date') :
|
||||
(typeof response.getAllResponseHeaders === 'function' ? response.getAllResponseHeaders().match(/^Date:.*$/mi)[0] : null) ||
|
||||
'Date: '+(new Date).toString();
|
||||
this.egw.message.call(this.egw,
|
||||
this.egw.lang('A request to the EGroupware server returned with an error')+
|
||||
': '+_xmlhttp.statusText+' ('+_xmlhttp.status+")\n\n"+
|
||||
': '+response.statusText+' ('+response.status+")\n\n"+
|
||||
this.egw.lang('Please reload the EGroupware desktop (F5 / Cmd+r).')+"\n"+
|
||||
this.egw.lang('If the error persists, contact your administrator for help and ask to check the error-log of the webserver.')+
|
||||
"\n\nURL: "+this.url+"\n"+
|
||||
(_xmlhttp.getAllResponseHeaders() ? (_xmlhttp.getAllResponseHeaders().match(/^Date:.*$/mi) ? _xmlhttp.getAllResponseHeaders().match(/^Date:.*$/mi)[0]:''):'')+
|
||||
"\n\nURL: "+this.url+"\n"+date+
|
||||
// if EGroupware send JSON payload with error, errno show it here too
|
||||
(_err === 'error' && _xmlhttp.status === 400 && typeof _xmlhttp.responseJSON === 'object' && _xmlhttp.responseJSON.error ?
|
||||
"\nError: "+_xmlhttp.responseJSON.error+' ('+_xmlhttp.responseJSON.errno+')' : '')
|
||||
(_err === 'error' && response.status === 400 && typeof response.responseJSON === 'object' && response.responseJSON.error ?
|
||||
"\nError: "+response.responseJSON.error+' ('+response.responseJSON.errno+')' : '')
|
||||
);
|
||||
|
||||
this.egw.debug('error', 'Ajax request to', this.url, ' failed: ', _err, _xmlhttp.status, _xmlhttp.statusText, _xmlhttp.responseJSON);
|
||||
this.egw.debug('error', 'Ajax request to', this.url, ' failed: ', _err, response.status, response.statusText, response.responseJSON);
|
||||
|
||||
// check of unparsable JSON on server-side, which might be caused by some network problem --> resend max. twice
|
||||
if (_err === 'error' && _xmlhttp.status === 400 && typeof _xmlhttp.responseJSON === 'object' &&
|
||||
_xmlhttp.responseJSON.errno && _xmlhttp.responseJSON.error.substr(0, 5) === 'JSON ')
|
||||
if (_err === 'error' && response.status === 400 && typeof response.responseJSON === 'object' &&
|
||||
response.responseJSON.errno && response.responseJSON.error.substr(0, 5) === 'JSON ')
|
||||
{
|
||||
// ToDo: resend request max. twice
|
||||
}
|
||||
@ -378,12 +416,11 @@ egw.extend('json', egw.MODULE_WND_LOCAL, function(_app, _wnd)
|
||||
}
|
||||
}
|
||||
// Call request callback, if provided
|
||||
if(this.callback != null && !only_data)
|
||||
if(typeof this.callback === 'function' && !only_data)
|
||||
{
|
||||
this.callback.call(this.context,res);
|
||||
}
|
||||
}
|
||||
this.request = null;
|
||||
};
|
||||
|
||||
var json = {
|
||||
@ -538,9 +575,9 @@ egw.extend('json', egw.MODULE_WND_LOCAL, function(_app, _wnd)
|
||||
// check if we need a not yet included app.js object --> include it now and return a Promise
|
||||
else if (i == 1 && parts[0] == 'app' && typeof app.classes[parts[1]] === 'undefined')
|
||||
{
|
||||
return import(this.webserverUrl+'/'+parts[1]+'/js/app.js?'+((new Date).valueOf()/86400|0).toString())
|
||||
return import(this.webserverUrl+'/'+parts[1]+'/js/app.min.js?'+((new Date).valueOf()/86400|0).toString())
|
||||
.then(() => this.applyFunc(_func, args, _context),
|
||||
(err) => {console.error("Failure loading /"+parts[1]+'/js/app.js' + " (" + err + ")\nAborting.")});
|
||||
(err) => {console.error("Failure loading /"+parts[1]+'/js/app.min.js' + " (" + err + ")\nAborting.")});
|
||||
}
|
||||
// check if we need a not yet instantiated app.js object --> instantiate it now
|
||||
else if (i == 1 && parts[0] == 'app' && typeof app.classes[parts[1]] === 'function')
|
||||
|
@ -53,31 +53,47 @@ egw.extend('preferences', egw.MODULE_GLOBAL, function()
|
||||
/**
|
||||
* Query an EGroupware user preference
|
||||
*
|
||||
* If a prefernce is not already loaded (only done for "common" by default), it is synchroniosly queryed from the server!
|
||||
* If a preference is not already loaded (only done for "common" by default),
|
||||
* it is synchronously queried from the server, if no _callback parameter is given!
|
||||
*
|
||||
* @param {string} _name name of the preference, eg. 'dateformat', or '*' to get all the application's preferences
|
||||
* @param {string} _app default 'common'
|
||||
* @param {function|false|undefined} _callback optional callback, if preference needs loading first
|
||||
* if false given and preference is not loaded, undefined is return and no (synchronious) request is send to server
|
||||
* @param {function|boolean|undefined} _callback optional callback, if preference needs loading first
|
||||
* - default/undefined: preference is synchronously queried, if not loaded, and returned
|
||||
* - function: if loaded, preference is returned, if not false and callback is called once it's loaded
|
||||
* - true: a promise for the preference is returned
|
||||
* - false: if preference is not loaded, undefined is return and no (synchronous) request is send to server
|
||||
* @param {object} _context context for callback
|
||||
* @return string|bool preference value or false, if callback given and preference not yet loaded
|
||||
* @return Promise|object|string|bool (Promise for) preference value or false, if callback given and preference not yet loaded
|
||||
*/
|
||||
preference: function(_name, _app, _callback, _context)
|
||||
{
|
||||
if (typeof _app == 'undefined') _app = 'common';
|
||||
if (typeof _app === 'undefined') _app = 'common';
|
||||
|
||||
if (typeof prefs[_app] == 'undefined')
|
||||
if (typeof prefs[_app] === 'undefined')
|
||||
{
|
||||
if (_callback === false) return undefined;
|
||||
var request = this.json('EGroupware\\Api\\Framework::ajax_get_preference', [_app], _callback, _context);
|
||||
request.sendRequest(typeof _callback == 'function', 'GET'); // use synchronous (cachable) GET request
|
||||
if (typeof prefs[_app] == 'undefined') prefs[_app] = {};
|
||||
if (typeof _callback == 'function') return false;
|
||||
const request = this.json('EGroupware\\Api\\Framework::ajax_get_preference', [_app], _callback, _context);
|
||||
const promise = request.sendRequest(typeof _callback !== 'undefined', 'GET');
|
||||
if (typeof prefs[_app] === 'undefined') prefs[_app] = {};
|
||||
if (_callback === true) return promise.then(() => this.preference(_name, _app));
|
||||
if (typeof _callback === 'function') return false;
|
||||
}
|
||||
if (_name == "*") return typeof prefs[_app] ==='object' ? jQuery.extend({},prefs[_app]) : prefs[_app];
|
||||
|
||||
return typeof prefs[_app][_name] === 'object' && prefs[_app][_name] !== null ?
|
||||
jQuery.extend({},prefs[_app][_name]) : prefs[_app][_name];
|
||||
let ret;
|
||||
if (_name === "*")
|
||||
{
|
||||
ret = typeof prefs[_app] === 'object' ? jQuery.extend({}, prefs[_app]) : prefs[_app];
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = typeof prefs[_app][_name] === 'object' && prefs[_app][_name] !== null ?
|
||||
jQuery.extend({}, prefs[_app][_name]) : prefs[_app][_name];
|
||||
}
|
||||
if (_callback === true)
|
||||
{
|
||||
return Promise.resolve(ret);
|
||||
}
|
||||
return ret;
|
||||
},
|
||||
|
||||
/**
|
||||
|
@ -145,9 +145,27 @@ egw.extend('utils', egw.MODULE_GLOBAL, function()
|
||||
|
||||
var uid_counter = 0;
|
||||
|
||||
/**
|
||||
* Global cache shared between all EGroupware windows
|
||||
* @type {{}}
|
||||
*/
|
||||
const cache = {};
|
||||
|
||||
// Create the utils object which contains references to all functions
|
||||
// covered by it.
|
||||
var utils = {
|
||||
/**
|
||||
* Get a cache object shared between all EGroupware windows
|
||||
*
|
||||
* @param {string} _name unique name for the cache-object
|
||||
* @return {*}
|
||||
*/
|
||||
getCache: function(_name)
|
||||
{
|
||||
if (typeof cache[_name] === 'undefined') cache[_name] = {};
|
||||
|
||||
return cache[_name];
|
||||
},
|
||||
|
||||
ajaxUrl: function(_menuaction) {
|
||||
if(_menuaction.indexOf('menuaction=') >= 0)
|
||||
|
@ -239,6 +239,11 @@ class Etemplate extends Etemplate\Widget\Template
|
||||
{
|
||||
Framework::includeJS($path);
|
||||
}
|
||||
// if app has no app.ts/js, we need to load etemplate2.js, otherwise popups wont work!
|
||||
else
|
||||
{
|
||||
Framework::includeJS('/api/js/etemplate/etemplate2.js');
|
||||
}
|
||||
// Category styles
|
||||
Categories::css($app);
|
||||
|
||||
|
@ -119,7 +119,7 @@ class Bundle
|
||||
$mod = $min_mod;
|
||||
}
|
||||
// use cache-buster only for entry-points / app.js, as the have no hash
|
||||
if (preg_match('#/js/app(\.min)?\.js$#', $file))
|
||||
if (preg_match('#/js/(app(\.min)?|etemplate/etemplate2)\.js$#', $file))
|
||||
{
|
||||
$to_include[$file] = $path.'?'.$mod.($query ? '&'.$query : '');
|
||||
}
|
||||
|
@ -636,6 +636,7 @@ class WebDAV extends HTTP_WebDAV_Server_Filesystem
|
||||
{
|
||||
if ($_SERVER['REQUEST_METHOD'] == 'GET' && (($this->force_download = strpos($_SERVER['REQUEST_URI'],'?download')) !== false))
|
||||
{
|
||||
$_SERVER['ORIG_REQUEST_URI'] = $_SERVER['REQUEST_URI'];
|
||||
$_SERVER['REQUEST_URI'] = substr($_SERVER['REQUEST_URI'],0,$this->force_download);
|
||||
}
|
||||
parent::__construct();
|
||||
|
20
api/user.php
20
api/user.php
@ -30,10 +30,16 @@ include '../header.inc.php';
|
||||
$GLOBALS['egw']->session->commit_session();
|
||||
|
||||
// use an etag over config and link-registry
|
||||
$preferences = json_encode($GLOBALS['egw_info']['user']['preferences']['common']);
|
||||
$ab_preferences = json_encode($GLOBALS['egw_info']['user']['preferences']['addressbook']);
|
||||
$preferences['common'] = $GLOBALS['egw_info']['user']['preferences']['common'];
|
||||
foreach(['addressbook', 'notifications', 'status', 'filemanager'] as $app)
|
||||
{
|
||||
if (!empty($GLOBALS['egw_info']['user']['apps'][$app]))
|
||||
{
|
||||
$preferences[$app] = $GLOBALS['egw_info']['user']['preferences'][$app];
|
||||
}
|
||||
}
|
||||
$user = $GLOBALS['egw']->accounts->json($GLOBALS['egw_info']['user']['account_id']);
|
||||
$etag = '"'.md5($preferences.$ab_preferences.$user).'"';
|
||||
$etag = '"'.md5(json_encode($preferences).$user).'"';
|
||||
|
||||
// headers to allow caching, egw_framework specifies etag on url to force reload, even with Expires header
|
||||
Api\Session::cache_control(86400); // cache for 1 day
|
||||
@ -47,9 +53,11 @@ if (isset($_SERVER['HTTP_IF_NONE_MATCH']) && $_SERVER['HTTP_IF_NONE_MATCH'] == $
|
||||
exit;
|
||||
}
|
||||
|
||||
$content = 'egw.set_preferences('.$preferences.", 'common', egw && egw.window !== window);\n";
|
||||
$content .= 'egw.set_preferences('.$ab_preferences.", 'addressbook', egw && egw.window !== window);\n";
|
||||
$content .= 'egw.set_user('.$user.", egw && egw.window !== window);\n";
|
||||
$content = 'egw.set_user('.$user.", egw && egw.window !== window);\n";
|
||||
foreach($preferences as $app => $data)
|
||||
{
|
||||
$content .= 'egw.set_preferences('.json_encode($data).', '.json_encode($app).", egw && egw.window !== window);\n";
|
||||
}
|
||||
|
||||
// we run our own gzip compression, to set a correct Content-Length of the encoded content
|
||||
if (in_array('gzip', explode(',',$_SERVER['HTTP_ACCEPT_ENCODING'])) && function_exists('gzencode'))
|
||||
|
@ -778,7 +778,7 @@ class InfologApp extends EgwApp
|
||||
|
||||
if (!app.stylite)
|
||||
{
|
||||
import(egw.webserverUrl+'/stylite/js/app.js?'+((new Date).valueOf()/86400|0).toString()).then(() =>
|
||||
import(egw.webserverUrl+'/stylite/js/app.min.js?'+((new Date).valueOf()/86400|0).toString()).then(() =>
|
||||
{
|
||||
app.stylite = new app.classes.stylite;
|
||||
app.stylite.et2 = this.et2;
|
||||
|
@ -908,7 +908,10 @@
|
||||
|
||||
var self = notifications;
|
||||
var langRequire = jQuery('#notifications_script_id').attr('data-langRequire');
|
||||
egw.langRequire(window, [JSON.parse(langRequire)]).then(()=>
|
||||
Promise.all([
|
||||
egw.langRequire(window, [JSON.parse(langRequire)]),
|
||||
egw.preference('notification_chain','notifications', true)
|
||||
]).then(() =>
|
||||
{
|
||||
var $egwpopup_fw = jQuery('#topmenu_info_notifications');
|
||||
switch (egw.preference('notification_chain','notifications'))
|
||||
|
@ -31,6 +31,7 @@ const config = {
|
||||
"pixelegg/js/fw_pixelegg.min": "pixelegg/js/fw_pixelegg.js",
|
||||
"pixelegg/js/fw_mobile.min": "pixelegg/js/fw_mobile.js",
|
||||
"api/js/jsapi/egw.min": "api/js/jsapi/egw_modules.js",
|
||||
"api/js/etemplate/etemplate2": "api/js/etemplate/etemplate2.ts",
|
||||
|
||||
// app.ts/js are added automatic by addAppsConfig() below
|
||||
},
|
||||
@ -158,7 +159,7 @@ export default function addAppsConfig()
|
||||
{
|
||||
try {
|
||||
statSync(file.name + '/js/app.ts');
|
||||
config.input[file.name + '/js/app'] = file.name + '/js/app.ts';
|
||||
config.input[file.name + '/js/app.min'] = file.name + '/js/app.ts';
|
||||
}
|
||||
catch (e) {
|
||||
try {
|
||||
|
Loading…
Reference in New Issue
Block a user