mirror of
https://github.com/EGroupware/egroupware.git
synced 2025-06-20 18:08:02 +02:00
Merge branch 'master' into web-components
This commit is contained in:
commit
2545c8fde1
@ -176,7 +176,7 @@ class admin_mail
|
|||||||
* Step 1: IMAP account
|
* Step 1: IMAP account
|
||||||
*
|
*
|
||||||
* @param array $content
|
* @param array $content
|
||||||
* @param type $msg
|
* @param string $msg
|
||||||
*/
|
*/
|
||||||
public function add(array $content=array(), $msg='', $msg_type='success')
|
public function add(array $content=array(), $msg='', $msg_type='success')
|
||||||
{
|
{
|
||||||
|
@ -338,7 +338,7 @@
|
|||||||
<row class="emailadmin_no_user dialogHeader2">
|
<row class="emailadmin_no_user dialogHeader2">
|
||||||
<description for="account_id" value="Valid for"/>
|
<description for="account_id" value="Valid for"/>
|
||||||
<hbox>
|
<hbox>
|
||||||
<select type="select-account" id="account_id" onchange="app.admin.account_hide_not_applying" options="Everyone,both" multiple="dynamic"/>
|
<select-account account_type="both" id="account_id" onchange="app.admin.account_hide_not_applying" empty_label="Everyone" multiple="dynamic"/>
|
||||||
<buttononly label="Select multiple" id="button[multiple]" onclick="app.admin.edit_multiple" options="users"/>
|
<buttononly label="Select multiple" id="button[multiple]" onclick="app.admin.edit_multiple" options="users"/>
|
||||||
<checkbox label="account editable by user" id="acc_user_editable"/>
|
<checkbox label="account editable by user" id="acc_user_editable"/>
|
||||||
</hbox>
|
</hbox>
|
||||||
|
@ -14,7 +14,7 @@ $setup_info['api']['title'] = 'EGroupware API';
|
|||||||
$setup_info['api']['version'] = '21.1.001';
|
$setup_info['api']['version'] = '21.1.001';
|
||||||
$setup_info['api']['versions']['current_header'] = '1.29';
|
$setup_info['api']['versions']['current_header'] = '1.29';
|
||||||
// maintenance release in sync with changelog in doc/rpm-build/debian.changes
|
// maintenance release in sync with changelog in doc/rpm-build/debian.changes
|
||||||
$setup_info['api']['versions']['maintenance_release'] = '21.1.20210923';
|
$setup_info['api']['versions']['maintenance_release'] = '21.1.20211130';
|
||||||
$setup_info['api']['enable'] = 3;
|
$setup_info['api']['enable'] = 3;
|
||||||
$setup_info['api']['app_order'] = 1;
|
$setup_info['api']['app_order'] = 1;
|
||||||
$setup_info['api']['license'] = 'GPL';
|
$setup_info['api']['license'] = 'GPL';
|
||||||
|
@ -764,7 +764,7 @@ class Contacts extends Contacts\Storage
|
|||||||
$data[$name] = DateTime::server2user($data[$name], $date_format);
|
$data[$name] = DateTime::server2user($data[$name], $date_format);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
$data['photo'] = $this->photo_src($data['id'],!empty($data['jpegphoto']) || (($data['files']??0) & self::FILES_BIT_PHOTO), '', $data['etag'] ?? null);
|
$data['photo'] = $this->photo_src($data['id'] ?? null,!empty($data['jpegphoto']) || (($data['files']??0) & self::FILES_BIT_PHOTO), '', $data['etag'] ?? null);
|
||||||
|
|
||||||
// set freebusy_uri for accounts
|
// set freebusy_uri for accounts
|
||||||
if (empty($data['freebusy_uri']) && empty($data['owner']) && !empty($data['account_id']) && empty($GLOBALS['egw_setup']))
|
if (empty($data['freebusy_uri']) && empty($data['owner']) && !empty($data['account_id']) && empty($GLOBALS['egw_setup']))
|
||||||
|
@ -482,13 +482,13 @@ class Sql extends Api\Storage
|
|||||||
$owner = isset($filter['owner']) ? $filter['owner'] : (isset($criteria['owner']) ? $criteria['owner'] : null);
|
$owner = isset($filter['owner']) ? $filter['owner'] : (isset($criteria['owner']) ? $criteria['owner'] : null);
|
||||||
|
|
||||||
// fix cat_id criteria to search in comma-separated multiple cats and return subcats
|
// fix cat_id criteria to search in comma-separated multiple cats and return subcats
|
||||||
if (is_array($criteria) && ($cats = $criteria['cat_id']))
|
if (is_array($criteria) && !empty($criteria['cat_id']))
|
||||||
{
|
{
|
||||||
$criteria = array_merge($criteria, $this->_cat_search($criteria['cat_id']));
|
$criteria = array_merge($criteria, $this->_cat_search($criteria['cat_id']));
|
||||||
unset($criteria['cat_id']);
|
unset($criteria['cat_id']);
|
||||||
}
|
}
|
||||||
// fix cat_id filter to search in comma-separated multiple cats and return subcats
|
// fix cat_id filter to search in comma-separated multiple cats and return subcats
|
||||||
if (($cats = $filter['cat_id']))
|
if (!empty($filter['cat_id']))
|
||||||
{
|
{
|
||||||
if ($filter['cat_id'][0] == '!')
|
if ($filter['cat_id'][0] == '!')
|
||||||
{
|
{
|
||||||
@ -680,7 +680,7 @@ class Sql extends Api\Storage
|
|||||||
{
|
{
|
||||||
$extra_cols[$key] = "$shared_with AS shared_with";
|
$extra_cols[$key] = "$shared_with AS shared_with";
|
||||||
}
|
}
|
||||||
switch ((string)$filter['shared_with'])
|
switch ($filter['shared_with'] ?? '')
|
||||||
{
|
{
|
||||||
case '': // filter not set
|
case '': // filter not set
|
||||||
break;
|
break;
|
||||||
|
@ -655,7 +655,7 @@ class Storage
|
|||||||
//error_log(__METHOD__.'('.array2string($criteria,true).','.array2string($only_keys).",'$order_by','$extra_cols','$wildcard','$empty','$op',".array2string($start).','.array2string($filter,true).",'$join')");
|
//error_log(__METHOD__.'('.array2string($criteria,true).','.array2string($only_keys).",'$order_by','$extra_cols','$wildcard','$empty','$op',".array2string($start).','.array2string($filter,true).",'$join')");
|
||||||
|
|
||||||
// Handle 'None' country option
|
// Handle 'None' country option
|
||||||
if(is_array($filter) && $filter['adr_one_countrycode'] == '-custom-')
|
if(is_array($filter) && isset($filter['adr_one_countrycode']) && $filter['adr_one_countrycode'] === '-custom-')
|
||||||
{
|
{
|
||||||
$filter[] = 'adr_one_countrycode IS NULL';
|
$filter[] = 'adr_one_countrycode IS NULL';
|
||||||
unset($filter['adr_one_countrycode']);
|
unset($filter['adr_one_countrycode']);
|
||||||
|
@ -1630,9 +1630,10 @@ class Db
|
|||||||
$not_null = is_array($column_definitions) && isset($column_definitions[$col]['nullable']) ? !$column_definitions[$col]['nullable'] : false;
|
$not_null = is_array($column_definitions) && isset($column_definitions[$col]['nullable']) ? !$column_definitions[$col]['nullable'] : false;
|
||||||
|
|
||||||
$maxlength = null;
|
$maxlength = null;
|
||||||
if ($truncate_varchar)
|
if ($truncate_varchar && !is_int($col) && isset($column_definitions[$col]) &&
|
||||||
|
in_array($column_definitions[$col]['type'], ['varchar','ascii']))
|
||||||
{
|
{
|
||||||
$maxlength = in_array($column_definitions[$col]['type'], array('varchar','ascii')) ? $column_definitions[$col]['precision'] : null;
|
$maxlength = $column_definitions[$col]['precision'];
|
||||||
}
|
}
|
||||||
// dont use IN ( ), if there's only one value, it's slower for MySQL
|
// dont use IN ( ), if there's only one value, it's slower for MySQL
|
||||||
if (is_array($data) && count($data) <= 1)
|
if (is_array($data) && count($data) <= 1)
|
||||||
|
@ -67,6 +67,10 @@ class Backup
|
|||||||
* @var string|boolean
|
* @var string|boolean
|
||||||
*/
|
*/
|
||||||
var $egw_tables = false;
|
var $egw_tables = false;
|
||||||
|
/**
|
||||||
|
* Regular expression to identify a Guacamole table OR view
|
||||||
|
*/
|
||||||
|
const GUACAMOLE_REGEXP = '/^guacamole_/';
|
||||||
/**
|
/**
|
||||||
* Backup directory.
|
* Backup directory.
|
||||||
*
|
*
|
||||||
@ -360,6 +364,8 @@ class Backup
|
|||||||
if (substr($this->db->Type,0,5) == 'mysql')
|
if (substr($this->db->Type,0,5) == 'mysql')
|
||||||
{
|
{
|
||||||
$this->db->query("SET SESSION sql_mode=(SELECT REPLACE(REPLACE(@@sql_mode,'STRICT_ALL_TABLES',''),'STRICT_TRANS_TABLES',''))", __LINE__, __FILE__);
|
$this->db->query("SET SESSION sql_mode=(SELECT REPLACE(REPLACE(@@sql_mode,'STRICT_ALL_TABLES',''),'STRICT_TRANS_TABLES',''))", __LINE__, __FILE__);
|
||||||
|
// disable foreign key checks, in case Guacamole is installed
|
||||||
|
$this->db->query('SET FOREIGN_KEY_CHECKS = 0');
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -371,7 +377,9 @@ class Backup
|
|||||||
foreach($this->adodb->MetaTables('TABLES') as $table)
|
foreach($this->adodb->MetaTables('TABLES') as $table)
|
||||||
{
|
{
|
||||||
if ($this->system_tables && preg_match($this->system_tables,$table) ||
|
if ($this->system_tables && preg_match($this->system_tables,$table) ||
|
||||||
$this->egw_tables && !preg_match($this->egw_tables,$table))
|
$this->egw_tables && !preg_match($this->egw_tables,$table) ||
|
||||||
|
// do NOT drop Guacamole tables and views
|
||||||
|
preg_match(self::GUACAMOLE_REGEXP, $table))
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -513,7 +521,7 @@ class Backup
|
|||||||
|
|
||||||
if (substr($line,0,9) == 'version: ')
|
if (substr($line,0,9) == 'version: ')
|
||||||
{
|
{
|
||||||
// currenty not used: $api_version = trim(substr($line,9));
|
// currently not used: $api_version = trim(substr($line,9));
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (substr($line,0,9) == 'charset: ')
|
if (substr($line,0,9) == 'charset: ')
|
||||||
@ -536,6 +544,12 @@ class Backup
|
|||||||
$this->schemas = json_php_unserialize(trim(substr($line,8)));
|
$this->schemas = json_php_unserialize(trim(substr($line,8)));
|
||||||
foreach($this->schemas as $table_name => $schema)
|
foreach($this->schemas as $table_name => $schema)
|
||||||
{
|
{
|
||||||
|
// do NOT create GUACAMOLE tables, just truncate them (as we have no abstraction to create the foreign keys)
|
||||||
|
if (preg_match(self::GUACAMOLE_REGEXP, $table_name))
|
||||||
|
{
|
||||||
|
$this->db->query('TRUNCATE TABLE '.$this->db->name_quote($table_name));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
// if column is longtext in current schema, convert text to longtext, in case user already updated column
|
// if column is longtext in current schema, convert text to longtext, in case user already updated column
|
||||||
foreach($schema['fd'] as $col => &$def)
|
foreach($schema['fd'] as $col => &$def)
|
||||||
{
|
{
|
||||||
@ -566,7 +580,7 @@ class Backup
|
|||||||
{
|
{
|
||||||
if ($data['type'] == 'blob') $blobs[] = $col;
|
if ($data['type'] == 'blob') $blobs[] = $col;
|
||||||
}
|
}
|
||||||
// check if we have an old PostgreSQL backup useing 't'/'f' for bool values
|
// check if we have an old PostgreSQL backup using 't'/'f' for bool values
|
||||||
// --> convert them to MySQL and our new PostgreSQL format of 1/0
|
// --> convert them to MySQL and our new PostgreSQL format of 1/0
|
||||||
$bools = array();
|
$bools = array();
|
||||||
foreach($this->schemas[$table]['fd'] as $col => $def)
|
foreach($this->schemas[$table]['fd'] as $col => $def)
|
||||||
|
@ -119,22 +119,22 @@ class Etemplate extends Etemplate\Widget\Template
|
|||||||
{
|
{
|
||||||
if (!empty($extra['data']) && is_array($extra['data']))
|
if (!empty($extra['data']) && is_array($extra['data']))
|
||||||
{
|
{
|
||||||
$content = array_merge($content, $extra['data']);
|
$content = array_merge_recursive($content, $extra['data']);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!empty($extra['preserve']) && is_array($extra['preserve']))
|
if (!empty($extra['preserve']) && is_array($extra['preserve']))
|
||||||
{
|
{
|
||||||
$preserv = array_merge($preserv, $extra['preserve']);
|
$preserv = array_merge_recursive($preserv, $extra['preserve']);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!empty($extra['readonlys']) && is_array($extra['readonlys']))
|
if (!empty($extra['readonlys']) && is_array($extra['readonlys']))
|
||||||
{
|
{
|
||||||
$readonlys = array_merge($readonlys, $extra['readonlys']);
|
$readonlys = array_merge_recursive($readonlys, $extra['readonlys']);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!empty($extra['sel_options']) && is_array($extra['sel_options']))
|
if (!empty($extra['sel_options']) && is_array($extra['sel_options']))
|
||||||
{
|
{
|
||||||
$sel_options = array_merge($sel_options, $extra['sel_options']);
|
$sel_options = array_merge_recursive($sel_options, $extra['sel_options']);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -569,7 +569,10 @@ class Widget
|
|||||||
$types = $paramType instanceof \ReflectionUnionType
|
$types = $paramType instanceof \ReflectionUnionType
|
||||||
? $paramType->getTypes()
|
? $paramType->getTypes()
|
||||||
: [$paramType];
|
: [$paramType];
|
||||||
if(in_array('array', array_map(fn(\ReflectionNamedType $t) => $t->getName(), $types)) && !is_array($params[$index]))
|
if(in_array('array', array_map(static function(\ReflectionNamedType $t)
|
||||||
|
{
|
||||||
|
return $t->getName();
|
||||||
|
}, $types)) && !is_array($params[$index]))
|
||||||
{
|
{
|
||||||
error_log("$method_name expects an array for {$param->getPosition()}: {$param->getName()}");
|
error_log("$method_name expects an array for {$param->getPosition()}: {$param->getName()}");
|
||||||
$params[$index] = (array)$params[$index];
|
$params[$index] = (array)$params[$index];
|
||||||
|
@ -75,11 +75,32 @@ class File extends Etemplate\Widget
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!($template = Template::instance(self::$request->template['name'], self::$request->template['template_set'],
|
try {
|
||||||
self::$request->template['version'], self::$request->template['load_via'])))
|
if (!($template = Template::instance(self::$request->template['name'], self::$request->template['template_set'],
|
||||||
{
|
self::$request->template['version'], self::$request->template['load_via'])))
|
||||||
// Can't use callback
|
{
|
||||||
error_log("Could not get template for file upload, callback skipped");
|
// Can't use callback
|
||||||
|
error_log("Could not get template for file upload, callback skipped");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (\Error $e) {
|
||||||
|
// retry 3 times, in case the problem (Call to undefined method EGroupware\Api\Etemplate\Widget\Vfs::set_attrs()) is caused by something internal in PHP 8.0
|
||||||
|
if (!isset($_REQUEST['retry']) || $_REQUEST['retry'] < 3)
|
||||||
|
{
|
||||||
|
$url = Api\Header\Http::schema().'://'.Api\Header\Http::host().$_SERVER['REQUEST_URI'];
|
||||||
|
if (strpos($url, '&retry=') === false)
|
||||||
|
{
|
||||||
|
$url .= '&retry=1';
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$url = preg_replace('/&retry=\d+/', '&retry='.($_REQUEST['retry']+1), $url);
|
||||||
|
}
|
||||||
|
header('Location: '.$url);
|
||||||
|
http_response_code(307);
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
throw new \Error('Error instantiating template '.json_encode(self::$request->template).', $_REQUEST='.json_encode($_REQUEST).': '.$e->getMessage(), $e->getCode(), $e);
|
||||||
}
|
}
|
||||||
|
|
||||||
$file_data = array();
|
$file_data = array();
|
||||||
|
@ -578,9 +578,9 @@ class calendar_ui
|
|||||||
// ignore failed discovery
|
// ignore failed discovery
|
||||||
unset($e);
|
unset($e);
|
||||||
}
|
}
|
||||||
if ($GLOBALS['egw_info']['user']['preferences']['calendar']['document_dir'])
|
if($GLOBALS['egw_info']['user']['preferences']['calendar']['document_dir'])
|
||||||
{
|
{
|
||||||
$sel_options['merge'] = calendar_merge::get_documents($GLOBALS['egw_info']['user']['preferences']['calendar']['document_dir'], '', null,'calendar');
|
$sel_options['merge'] = calendar_merge::get_documents($GLOBALS['egw_info']['user']['preferences']['calendar']['document_dir'], '', null, 'calendar');
|
||||||
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -588,6 +588,22 @@ class calendar_ui
|
|||||||
$readonlys['merge'] = true;
|
$readonlys['merge'] = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Add integration UI into sidemenu
|
||||||
|
$integration_data = Api\Hooks::process(array('location' => 'calendar_search_union'));
|
||||||
|
foreach($integration_data as $app => $app_hooks)
|
||||||
|
{
|
||||||
|
foreach($app_hooks as $data)
|
||||||
|
{
|
||||||
|
// App might have multiple hooks, let it specify something else
|
||||||
|
$app = $data['selects']['app'] ?: $app;
|
||||||
|
|
||||||
|
if(array_key_exists('sidebox_template', $data))
|
||||||
|
{
|
||||||
|
$cont['integration'][] = ['template' => $data['sidebox_template'], 'app' => $app];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Sidebox?
|
// Sidebox?
|
||||||
$sidebox->exec('calendar.calendar_ui.sidebox_etemplate', $cont, $sel_options, $readonlys);
|
$sidebox->exec('calendar.calendar_ui.sidebox_etemplate', $cont, $sel_options, $readonlys);
|
||||||
}
|
}
|
||||||
|
@ -861,10 +861,14 @@ export class CalendarApp extends EgwApp
|
|||||||
|
|
||||||
if(action.checked)
|
if(action.checked)
|
||||||
{
|
{
|
||||||
integration_preference.push(app);
|
if(integration_preference.indexOf(app) === -1)
|
||||||
|
{
|
||||||
|
integration_preference.push(app);
|
||||||
|
}
|
||||||
|
|
||||||
// After the preference change is done, get new info which should now include the app
|
// After the preference change is done, get new info which should now include the app
|
||||||
callback = callback ? callback : function() {
|
callback = callback ? callback : function()
|
||||||
|
{
|
||||||
this._fetch_data(this.state);
|
this._fetch_data(this.state);
|
||||||
}.bind(this);
|
}.bind(this);
|
||||||
}
|
}
|
||||||
|
@ -14,27 +14,52 @@ Egroupware
|
|||||||
<overlay>
|
<overlay>
|
||||||
<template id="calendar.sidebox">
|
<template id="calendar.sidebox">
|
||||||
<vbox parent_node="calendar-et2_target">
|
<vbox parent_node="calendar-et2_target">
|
||||||
<buttononly id="header_today" label="•" icon="nope" onclick="
|
<buttononly id="header_today" label="•" icon="nope" onclick="
|
||||||
var tempDate = new Date();
|
var tempDate = new Date();
|
||||||
var today = new Date(tempDate.getFullYear(), tempDate.getMonth(), tempDate.getDate(),0,-tempDate.getTimezoneOffset(),0);
|
var today = new Date(tempDate.getFullYear(), tempDate.getMonth(), tempDate.getDate(),0,-tempDate.getTimezoneOffset(),0);
|
||||||
var change = {date: today.toJSON()};
|
var change = {date: today.toJSON()};
|
||||||
app.calendar.update_state(change);
|
app.calendar.update_state(change);
|
||||||
widget.getRoot().getWidgetById('date').set_value(today);
|
widget.getRoot().getWidgetById('date').set_value(today);
|
||||||
return false;"/>
|
return false;"/>
|
||||||
<buttononly id="header_go" label="↵" icon="nope" class="ui-corner-all" onclick="var change = {date: widget.btn.attr('data-date')}; if ( app.calendar.state.view == 'listview') {change.filter='month';} else if (app.calendar.state.view == 'planner') {} else {change.view = 'month';}app.calendar.update_state(change);" />
|
<buttononly id="header_go" label="↵" icon="nope" class="ui-corner-all"
|
||||||
<date id="date" class="et2_fullWidth" inline="true" onchange="var view_change = app.calendar.sidebox_changes_views.indexOf(app.calendar.state.view);
|
onclick="var change = {date: widget.btn.attr('data-date')}; if ( app.calendar.state.view == 'listview') {change.filter='month';} else if (app.calendar.state.view == 'planner') {} else {change.view = 'month';}app.calendar.update_state(change);"/>
|
||||||
|
<date id="date" class="et2_fullWidth" inline="true" onchange="var view_change = app.calendar.sidebox_changes_views.indexOf(app.calendar.state.view);
|
||||||
var update = {date:widget.getValue()};
|
var update = {date:widget.getValue()};
|
||||||
if(view_change >= 0) {update.view = app.calendar.sidebox_changes_views[view_change ? view_change - 1 : view_change];} else if (app.calendar.state.view == 'listview') {update.filter = 'after';} else if (app.calendar.state.view =='planner') { update.planner_view = 'day'; } app.calendar.update_state(update);"/>
|
if(view_change >= 0) {update.view = app.calendar.sidebox_changes_views[view_change ? view_change - 1 : view_change];} else if (app.calendar.state.view == 'listview') {update.filter = 'after';} else if (app.calendar.state.view =='planner') { update.planner_view = 'day'; } app.calendar.update_state(update);"/>
|
||||||
<textbox type="hidden" id="first"/>
|
<textbox type="hidden" id="first"/>
|
||||||
<textbox type="hidden" id="last"/>
|
<textbox type="hidden" id="last"/>
|
||||||
<hrule/>
|
<hrule/>
|
||||||
<select-cat id="cat_id" empty_label="All categories" width="86%" onchange="app.calendar.update_state({cat_id: widget.getValue()});" expand_multiple_rows="4"/>
|
<select-cat id="cat_id" empty_label="All categories" width="86%"
|
||||||
<select id="status_filter" no_lang="true" class="et2_fullWidth" onchange="app.calendar.update_state({status_filter: widget.getValue()});"/>
|
onchange="app.calendar.update_state({cat_id: widget.getValue()});" expand_multiple_rows="4"/>
|
||||||
<hrule/>
|
<select id="status_filter" no_lang="true" class="et2_fullWidth"
|
||||||
<calendar-owner id="owner" class="et2_fullWidth" onchange="app.calendar.update_state({owner: widget.getValue()}); return false;" multiple="true" allowFreeEntries="false" autocomplete_params="{"checkgrants": true}"/>
|
onchange="app.calendar.update_state({status_filter: widget.getValue()});"/>
|
||||||
<hrule/>
|
<hrule/>
|
||||||
<select id="merge" empty_label="Insert in document" onchange="app.calendar.sidebox_merge" class="et2_fullWidth"/>
|
<calendar-owner id="owner" class="et2_fullWidth"
|
||||||
</vbox>
|
onchange="app.calendar.update_state({owner: widget.getValue()}); return false;"
|
||||||
<iframe id="iframe" width="100%" height="100%"/>
|
multiple="true" allowFreeEntries="false"
|
||||||
</template>
|
autocomplete_params="{"checkgrants": true}"/>
|
||||||
|
<hrule/>
|
||||||
|
<select id="merge" empty_label="Insert in document" onchange="app.calendar.sidebox_merge"
|
||||||
|
class="et2_fullWidth"/>
|
||||||
|
<box>
|
||||||
|
<grid id="integration" disabled="!@integration" width="100%">
|
||||||
|
<columns>
|
||||||
|
<column/>
|
||||||
|
</columns>
|
||||||
|
<rows>
|
||||||
|
<row>
|
||||||
|
<template id="$row_cont[template]" width="100%" content="$row_cont[app]"/>
|
||||||
|
</row>
|
||||||
|
</rows>
|
||||||
|
</grid>
|
||||||
|
</box>
|
||||||
|
</vbox>
|
||||||
|
<iframe id="iframe" width="100%" height="100%"/>
|
||||||
|
<styles>
|
||||||
|
#calendar-sidebox_integration: {
|
||||||
|
display: table;
|
||||||
|
width: 100%
|
||||||
|
}
|
||||||
|
</styles>
|
||||||
|
</template>
|
||||||
</overlay>
|
</overlay>
|
||||||
|
@ -118,7 +118,7 @@
|
|||||||
"egroupware/tracker": "self.version",
|
"egroupware/tracker": "self.version",
|
||||||
"egroupware/util": "^2.6.2",
|
"egroupware/util": "^2.6.2",
|
||||||
"egroupware/webdav": "^v0.3.2",
|
"egroupware/webdav": "^v0.3.2",
|
||||||
"egroupware/z-push-dev": "^2.5",
|
"egroupware/z-push-dev": "2.5.0.1",
|
||||||
"giggsey/libphonenumber-for-php": "^8.12",
|
"giggsey/libphonenumber-for-php": "^8.12",
|
||||||
"npm-asset/as-jqplot": "1.0.*",
|
"npm-asset/as-jqplot": "1.0.*",
|
||||||
"npm-asset/gridster": "0.5.*",
|
"npm-asset/gridster": "0.5.*",
|
||||||
|
14
composer.lock
generated
14
composer.lock
generated
@ -4,7 +4,7 @@
|
|||||||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||||
"This file is @generated automatically"
|
"This file is @generated automatically"
|
||||||
],
|
],
|
||||||
"content-hash": "beeabf26cf7c537dea75e236217d44c6",
|
"content-hash": "393ec43e69c00afa115414c62789e29a",
|
||||||
"packages": [
|
"packages": [
|
||||||
{
|
{
|
||||||
"name": "adldap2/adldap2",
|
"name": "adldap2/adldap2",
|
||||||
@ -207,7 +207,7 @@
|
|||||||
"version": "v2.3.4",
|
"version": "v2.3.4",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/fengyuanchen/cropper.git",
|
"url": "git@github.com:fengyuanchen/cropper.git",
|
||||||
"reference": "30c58b29ee21010e17e58ebab165fbd84285c685"
|
"reference": "30c58b29ee21010e17e58ebab165fbd84285c685"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
@ -305,7 +305,7 @@
|
|||||||
"version": "1.12.4",
|
"version": "1.12.4",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/jquery/jquery-dist.git",
|
"url": "git@github.com:jquery/jquery-dist.git",
|
||||||
"reference": "5e89585e0121e72ff47de177c5ef604f3089a53d"
|
"reference": "5e89585e0121e72ff47de177c5ef604f3089a53d"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
@ -1924,16 +1924,16 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "egroupware/z-push-dev",
|
"name": "egroupware/z-push-dev",
|
||||||
"version": "2.5.0",
|
"version": "2.5.0.1",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/EGroupware/z-push.git",
|
"url": "https://github.com/EGroupware/z-push.git",
|
||||||
"reference": "32da00e1024038a8f57c8a185c671179c3922ebe"
|
"reference": "7774018b19b5b55e24dbd1107693496597ab70ee"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/EGroupware/z-push/zipball/32da00e1024038a8f57c8a185c671179c3922ebe",
|
"url": "https://api.github.com/repos/EGroupware/z-push/zipball/7774018b19b5b55e24dbd1107693496597ab70ee",
|
||||||
"reference": "32da00e1024038a8f57c8a185c671179c3922ebe",
|
"reference": "7774018b19b5b55e24dbd1107693496597ab70ee",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
|
@ -1,3 +1,29 @@
|
|||||||
|
egroupware-docker (21.1.20211130) hardy; urgency=low
|
||||||
|
|
||||||
|
* PHP 8.0: tons of fixes to support 8.0, this is probably the last container using PHP 7.4 by default
|
||||||
|
* Addressbook: new REST API for contacts https://github.com/EGroupware/egroupware/tree/master/doc/REST-CalDAV-CardDAV
|
||||||
|
* LDAP/Addressbook: fix region contains for given country invalid value gives an LDAP error on update
|
||||||
|
* Admin/Filemanager: correctly encode user "WORKGROUP\$user" for SMB mounts and do NOT require mountpoints to exist
|
||||||
|
* Filemanager: fix not working variables eg. $user in GUI mount (Admin > Filemanager)
|
||||||
|
* Filemanager: fix video controller not working in filemanager gallery
|
||||||
|
* Filemanager: add action to unlock files
|
||||||
|
* Filemanager: fix super user could not remove other users' subscriptions
|
||||||
|
* Filemanager: add actions to convert editable files to PDF or PNG and a checkbox to merge file as PDF
|
||||||
|
* Collabora: merge placeholder dialogs
|
||||||
|
* All apps: add preference to set directory and filename of merged documents using placeholders
|
||||||
|
* Calendar: fix changing the recurrence end date did not add/remove the events in the UI
|
||||||
|
* InfoLog: fix not working overwrite check (optimistic locking) plus incrementing etag
|
||||||
|
* Mail: make sure pressing [del] key twice in a row does not delete the first row on the second press
|
||||||
|
* Mail: add set flags action into mail filters
|
||||||
|
* Mail: implements date extension for vacation rule. None imap admin user can also set vacation rule by date.
|
||||||
|
* Kanban: fix deleting card did not delete link to the board (includes a DB update to remove orphans from links)
|
||||||
|
* Resources: add inventory number to resource list columns
|
||||||
|
* smallPART/PostgreSQL: fix SQL error when opening a course
|
||||||
|
* smallPART/PostgreSQL: fix SQL error during update (you need to restore egw_smallpart* tables AND set egw_applications.app_version='21.1')
|
||||||
|
* API: update jQuery-ui to 1.13.0 and TinyMCE to 5.10.1
|
||||||
|
|
||||||
|
-- Ralf Becker <rb@egroupware.org> Tue, 30 Nov 2021 09:11:56 +0100
|
||||||
|
|
||||||
egroupware-docker (21.1.20210923) hardy; urgency=low
|
egroupware-docker (21.1.20210923) hardy; urgency=low
|
||||||
|
|
||||||
* smallPART: many new features and improvements for the new semester:
|
* smallPART: many new features and improvements for the new semester:
|
||||||
|
Loading…
x
Reference in New Issue
Block a user