mirror of
https://github.com/EGroupware/egroupware.git
synced 2024-12-22 14:41:29 +01:00
fix many errors around et2-select emulating old taglist:
- preprocessor: translate attributes autocomplete_url -> searchUrl, autocomplete_params -> searchOptions, and allow options - sending search query as URL/GET parameter with default of app: <appname> - handle searchUrl like allowFreeEntries by adding selected result to select_options via createFreeEntries, as they otherwise get removed by fix_bad_value not finding the value in select_options - change taglist validation (again) to not validate search values - still requires changes in application code, as taglist always behaved like multiple=true (returning and expecting an array of values) and did automatically search from client-side for it's initial value(s) --> maybe more changes are in order to NOT require changing application code --> fixes editing Sieve rules
This commit is contained in:
parent
b0d1d82736
commit
e7eb9f42e3
@ -199,7 +199,7 @@ function send_template()
|
|||||||
}, $str);
|
}, $str);
|
||||||
|
|
||||||
// handling of select and taglist widget, incl. removing of type attribute
|
// handling of select and taglist widget, incl. removing of type attribute
|
||||||
$str = preg_replace_callback('#<(select|taglist|listbox)(-[^ ]+)? ([^>]+?)(/|>(.*?)</select)>#s', static function (array $matches)
|
$str = preg_replace_callback('#<(select|taglist|listbox)(-[^ ]+)? ([^>]+?)(/|>(.*?)</(select|taglist|listbox))>#s', static function (array $matches)
|
||||||
{
|
{
|
||||||
$attrs = parseAttrs($matches[3]);
|
$attrs = parseAttrs($matches[3]);
|
||||||
|
|
||||||
@ -209,18 +209,33 @@ function send_template()
|
|||||||
$attrs['multiple'] = 'true';
|
$attrs['multiple'] = 'true';
|
||||||
unset($attrs['tags']);
|
unset($attrs['tags']);
|
||||||
}
|
}
|
||||||
// taglist had allowFreeEntries and enableEditMode with a default of true, while et2-select has it with a default of false
|
// converting taglist to et2-select
|
||||||
if($matches['1'] === 'taglist' && !$matches[2])
|
if($matches['1'] === 'taglist')
|
||||||
{
|
{
|
||||||
if(!isset($attrs['allowFreeEntries']))
|
// taglist had allowFreeEntries and enableEditMode with a default of true, while et2-select has it with a default of false
|
||||||
|
if(!$matches[2] && !isset($attrs['allowFreeEntries']) && (empty($matches[5]) || !preg_match('#</?option(\s[^>]+|/)>#', $matches[5])))
|
||||||
{
|
{
|
||||||
$attrs['allowFreeEntries'] = 'true';
|
$attrs['allowFreeEntries'] = 'true';
|
||||||
}
|
|
||||||
if(!isset($attrs['editModeEnabled']))
|
if(!isset($attrs['editModeEnabled']))
|
||||||
{
|
{
|
||||||
$attrs['editModeEnabled'] = 'true';
|
$attrs['editModeEnabled'] = 'true';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (isset($attrs['autocomplete_url']))
|
||||||
|
{
|
||||||
|
$attrs['searchUrl'] = $attrs['autocomplete_url'];
|
||||||
|
if (isset($attrs['autocomplete_params']))
|
||||||
|
{
|
||||||
|
$attrs['searchOptions'] = $attrs['autocomplete_params'];
|
||||||
|
}
|
||||||
|
unset($attrs['autocomplete_url'], $attrs['autocomplete_params']);
|
||||||
|
}
|
||||||
|
if (isset($attrs['maxSelection']) && $attrs['maxSelection'] === '1')
|
||||||
|
{
|
||||||
|
unset($attrs['multiple'], $attrs['maxSelection']);
|
||||||
|
}
|
||||||
|
}
|
||||||
// no multiple="toggle" or expand_multiple_rows="N" currently, thought Shoelace's select multiple="true" is relative close
|
// no multiple="toggle" or expand_multiple_rows="N" currently, thought Shoelace's select multiple="true" is relative close
|
||||||
// until we find something better, just switch to multiple="true"
|
// until we find something better, just switch to multiple="true"
|
||||||
if (isset($attrs['multiple']) && $attrs['multiple'] === 'toggle' || !empty($attrs['expand_multiple_rows']))
|
if (isset($attrs['multiple']) && $attrs['multiple'] === 'toggle' || !empty($attrs['expand_multiple_rows']))
|
||||||
|
@ -235,7 +235,13 @@ export function cleanSelectOptions(options : SelectOption[] | string[] | object)
|
|||||||
// make sure value is a string, and label not an object with sub-options
|
// make sure value is a string, and label not an object with sub-options
|
||||||
options.forEach(option =>
|
options.forEach(option =>
|
||||||
{
|
{
|
||||||
if (typeof option.value !== 'string')
|
// old taglist used id, instead of value
|
||||||
|
if (typeof option.value === 'undefined' && typeof option.id !== 'undefined')
|
||||||
|
{
|
||||||
|
option.value = option.id;
|
||||||
|
delete option.id;
|
||||||
|
}
|
||||||
|
if (typeof option.value === 'number')
|
||||||
{
|
{
|
||||||
option.value = option.value.toString();
|
option.value = option.value.toString();
|
||||||
}
|
}
|
||||||
|
@ -239,7 +239,7 @@ export const Et2WithSearchMixin = <T extends Constructor<LitElement>>(superclass
|
|||||||
|
|
||||||
this.search = false;
|
this.search = false;
|
||||||
this.searchUrl = "";
|
this.searchUrl = "";
|
||||||
this.searchOptions = {};
|
this.searchOptions = {app: "addressbook"};
|
||||||
|
|
||||||
this.allowFreeEntries = false;
|
this.allowFreeEntries = false;
|
||||||
this.editModeEnabled = false;
|
this.editModeEnabled = false;
|
||||||
@ -402,13 +402,13 @@ export const Et2WithSearchMixin = <T extends Constructor<LitElement>>(superclass
|
|||||||
{
|
{
|
||||||
super.value = new_value;
|
super.value = new_value;
|
||||||
|
|
||||||
if(!new_value || !this.allowFreeEntries)
|
if(!new_value || !this.allowFreeEntries && !this.searchUrl)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Overridden to add options if allowFreeEntries=true
|
// Overridden to add options if allowFreeEntries=true
|
||||||
if(typeof this.value == "string" && !this._menuItems.find(o => o.value == this.value))
|
if(typeof this.value == "string" && !this._menuItems.find(o => o.value == this.value && !o.classList.contains('remote')))
|
||||||
{
|
{
|
||||||
this.createFreeEntry(this.value);
|
this.createFreeEntry(this.value);
|
||||||
}
|
}
|
||||||
@ -416,7 +416,7 @@ export const Et2WithSearchMixin = <T extends Constructor<LitElement>>(superclass
|
|||||||
{
|
{
|
||||||
this.value.forEach((e) =>
|
this.value.forEach((e) =>
|
||||||
{
|
{
|
||||||
if(!this._menuItems.find(o => o.value == e))
|
if(!this._menuItems.find(o => o.value == e && !o.classList.contains('remote')))
|
||||||
{
|
{
|
||||||
this.createFreeEntry(e);
|
this.createFreeEntry(e);
|
||||||
}
|
}
|
||||||
@ -696,7 +696,9 @@ export const Et2WithSearchMixin = <T extends Constructor<LitElement>>(superclass
|
|||||||
/**
|
/**
|
||||||
* Actually query the server.
|
* Actually query the server.
|
||||||
*
|
*
|
||||||
* This can be overridden to change request parameters
|
* This can be overridden to change request parameters or eg. send them as POST parameters.
|
||||||
|
*
|
||||||
|
* Default implementation here sends options as (additional) GET paramters plus search string as $_GET['query']!
|
||||||
*
|
*
|
||||||
* @param {string} search
|
* @param {string} search
|
||||||
* @param {object} options
|
* @param {object} options
|
||||||
@ -705,7 +707,7 @@ export const Et2WithSearchMixin = <T extends Constructor<LitElement>>(superclass
|
|||||||
*/
|
*/
|
||||||
protected remoteQuery(search : string, options : object)
|
protected remoteQuery(search : string, options : object)
|
||||||
{
|
{
|
||||||
return this.egw().request(this.searchUrl, [search, options]).then((result) =>
|
return this.egw().request(this.egw().link(this.egw().ajaxUrl(this.searchUrl), {query: search, ...options})).then((result) =>
|
||||||
{
|
{
|
||||||
this.processRemoteResults(result);
|
this.processRemoteResults(result);
|
||||||
});
|
});
|
||||||
|
@ -167,7 +167,7 @@ class Taglist extends Etemplate\Widget
|
|||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if(count($allowed) && !$this->attrs['allowFreeEntries'] && !array_key_exists($val,$allowed))
|
if(count($allowed) && !$this->attrs['allowFreeEntries'] && empty($this->attrs['autocomplete_url']) && !array_key_exists($val,$allowed))
|
||||||
{
|
{
|
||||||
self::set_validation_error($form_name,lang("'%1' is NOT allowed ('%2')!",$val,implode("','",array_keys($allowed))),'');
|
self::set_validation_error($form_name,lang("'%1' is NOT allowed ('%2')!",$val,implode("','",array_keys($allowed))),'');
|
||||||
unset($value[$key]);
|
unset($value[$key]);
|
||||||
|
@ -230,7 +230,7 @@ class mail_sieve
|
|||||||
{
|
{
|
||||||
//Instantiate an eTemplate object, representing sieve.edit template
|
//Instantiate an eTemplate object, representing sieve.edit template
|
||||||
$etmpl = new Etemplate('mail.sieve.edit');
|
$etmpl = new Etemplate('mail.sieve.edit');
|
||||||
$etmpl->setElementAttribute('action_folder_text','autocomplete_params', array('noPrefixId'=> true));
|
$etmpl->setElementAttribute('action_folder_text','searchOptions', array('noPrefixId'=> true));
|
||||||
if (!is_array($content))
|
if (!is_array($content))
|
||||||
{
|
{
|
||||||
if ( $this->getRules($_GET['ruleID']) && isset($_GET['ruleID']))
|
if ( $this->getRules($_GET['ruleID']) && isset($_GET['ruleID']))
|
||||||
@ -242,7 +242,7 @@ class mail_sieve
|
|||||||
switch ($rules['action'])
|
switch ($rules['action'])
|
||||||
{
|
{
|
||||||
case 'folder':
|
case 'folder':
|
||||||
$content['action_folder_text'][] = $rules['action_arg'];
|
$content['action_folder_text'] = $rules['action_arg'];
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case 'address':
|
case 'address':
|
||||||
@ -297,7 +297,7 @@ class mail_sieve
|
|||||||
switch ($content['action'])
|
switch ($content['action'])
|
||||||
{
|
{
|
||||||
case 'folder':
|
case 'folder':
|
||||||
$newRule['action_arg'] = implode($content['action_folder_text']);
|
$newRule['action_arg'] = $content['action_folder_text'];
|
||||||
break;
|
break;
|
||||||
case 'address':
|
case 'address':
|
||||||
$content['action_address_text'] = self::strip_rfc882_addresses($content['action_address_text']);
|
$content['action_address_text'] = self::strip_rfc882_addresses($content['action_address_text']);
|
||||||
@ -398,8 +398,10 @@ class mail_sieve
|
|||||||
$content['no_forward'] = $this->account->acc_smtp_type !== Api\Mail\Smtp::class && !$this->account->acc_user_forward;
|
$content['no_forward'] = $this->account->acc_smtp_type !== Api\Mail\Smtp::class && !$this->account->acc_user_forward;
|
||||||
|
|
||||||
//Set the preselect_options for mail/folders as we are not allow free entry for folder taglist
|
//Set the preselect_options for mail/folders as we are not allow free entry for folder taglist
|
||||||
$sel_options['action_folder_text'] = $this->ajax_getFolders(0,true,null,true);
|
if (!empty($content['action_folder_text']))
|
||||||
|
{
|
||||||
|
$sel_options['action_folder_text'] = [$content['action_folder_text'] => $content['action_folder_text']];
|
||||||
|
}
|
||||||
return $etmpl->exec('mail.mail_sieve.edit',$content,$sel_options,$readonlys,array(),2);
|
return $etmpl->exec('mail.mail_sieve.edit',$content,$sel_options,$readonlys,array(),2);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1300,4 +1302,3 @@ class mail_sieve
|
|||||||
$mailCompose->ajax_searchFolder($_searchStringLength, $_returnList, $_mailaccountToSearch, $_noPrefixId);
|
$mailCompose->ajax_searchFolder($_searchStringLength, $_returnList, $_mailaccountToSearch, $_noPrefixId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -149,13 +149,11 @@
|
|||||||
<checkbox label="Use regular expressions (see wikipedia for information on POSIX regular expressions)" id="regexp"/>
|
<checkbox label="Use regular expressions (see wikipedia for information on POSIX regular expressions)" id="regexp"/>
|
||||||
</row>
|
</row>
|
||||||
<row class="dialogFooterToolbar">
|
<row class="dialogFooterToolbar">
|
||||||
<hbox>
|
<hbox width="100%">
|
||||||
<button statustext="Saves this rule" label="Save" id="button[save]"/>
|
<button statustext="Saves this rule" label="Save" id="button[save]"/>
|
||||||
<button statustext="Applies the changes made" label="Apply" id="button[apply]"/>
|
<button statustext="Applies the changes made" label="Apply" id="button[apply]"/>
|
||||||
<button label="Cancel" id="button[cancel]"/>
|
<button label="Cancel" id="button[cancel]" onclick="window.close()"/>
|
||||||
<hbox align="right">
|
<button label="Delete" id="button[delete]" align="right"/>
|
||||||
<button label="Delete" id="button[delete]" />
|
|
||||||
</hbox>
|
|
||||||
</hbox>
|
</hbox>
|
||||||
</row>
|
</row>
|
||||||
</rows>
|
</rows>
|
||||||
|
Loading…
Reference in New Issue
Block a user