From 42f81242420e67a0f7408d7063f3b9135b72da6b Mon Sep 17 00:00:00 2001 From: ralf Date: Thu, 22 Aug 2024 10:52:16 +0200 Subject: [PATCH] use et2-tree-dropdown for TZ selection in general preferences --- .../Et2Select/Select/Et2SelectCategory.ts | 2 +- api/src/Etemplate/Widget/Select.php | 2 +- api/src/Etemplate/Widget/Tree.php | 14 ----- calendar/inc/class.calendar_hooks.inc.php | 29 ++-------- .../inc/class.preferences_hooks.inc.php | 16 +++--- .../inc/class.preferences_settings.inc.php | 53 ++++++++++++------- 6 files changed, 51 insertions(+), 65 deletions(-) diff --git a/api/js/etemplate/Et2Select/Select/Et2SelectCategory.ts b/api/js/etemplate/Et2Select/Select/Et2SelectCategory.ts index 3985170142..9c610a750e 100644 --- a/api/js/etemplate/Et2Select/Select/Et2SelectCategory.ts +++ b/api/js/etemplate/Et2Select/Select/Et2SelectCategory.ts @@ -85,7 +85,7 @@ export class Et2SelectCategory extends Et2StaticSelectMixin(Et2Select) { super.willUpdate(changedProperties); - if(changedProperties.has("global_categories") || changedProperties.has("application") || changedProperties.has("parentCat")) + if(changedProperties.has("globalCategories") || changedProperties.has("application") || changedProperties.has("parentCat")) { this.fetchComplete = so.cat(this).then(options => { diff --git a/api/src/Etemplate/Widget/Select.php b/api/src/Etemplate/Widget/Select.php index cca5e9cc6f..b214e971aa 100644 --- a/api/src/Etemplate/Widget/Select.php +++ b/api/src/Etemplate/Widget/Select.php @@ -243,7 +243,7 @@ class Select extends Etemplate\Widget break; case 'select-timezone': - if (!calendar_timezones::tz2id($val)) + if (!calendar_timezones::tz2id($val) && !in_array($val, $allowed)) { self::set_validation_error($form_name, lang("'%1' is NOT a valid timezone!", $val)); } diff --git a/api/src/Etemplate/Widget/Tree.php b/api/src/Etemplate/Widget/Tree.php index 8d6600a155..c14100a6c7 100644 --- a/api/src/Etemplate/Widget/Tree.php +++ b/api/src/Etemplate/Widget/Tree.php @@ -320,20 +320,6 @@ class Tree extends Etemplate\Widget self::setElementAttribute($form_name, 'no_lang', $no_lang); } } - - // Make sure  s, etc. are properly encoded when sent, and not double-encoded - foreach(self::$request->sel_options[$form_name] as &$label) - { - if(!is_array($label)) - { - $label = html_entity_decode($label, ENT_NOQUOTES,'utf-8'); - } - elseif(!empty($label['label'])) - { - $label['label'] = html_entity_decode($label['label'], ENT_NOQUOTES,'utf-8'); - } - } - } /** diff --git a/calendar/inc/class.calendar_hooks.inc.php b/calendar/inc/class.calendar_hooks.inc.php index 9ba8ab1d1d..8595dbfd2a 100644 --- a/calendar/inc/class.calendar_hooks.inc.php +++ b/calendar/inc/class.calendar_hooks.inc.php @@ -251,28 +251,6 @@ class calendar_hooks $freebusy_url = '' . $freebusy_url . ''; $freebusy_help = lang('Should not loged in persons be able to see your freebusy information? You can set an extra password, different from your normal password, to protect this informations. The freebusy information is in iCal format and only include the times when you are busy. It does not include the event-name, description or locations. The URL to your freebusy information is'); $freebusy_help .= ' ' . $freebusy_url; - - // Timezone for file exports - $export_tzs = array(['value' => '0', 'label' => lang('Use Event TZ')]); - $tz_list = Api\DateTime::getTimezones(); - - // Format for select - $format = function ($key, $value) use (&$format, &$tzs) - { - if(is_array($value)) - { - $value = [ - 'label' => $key, - 'value' => array_map($format, array_keys($value), array_values($value)) - ]; - } - else - { - $value = ['label' => $value, 'value' => $key]; - } - return $value; - }; - $export_tzs = array_merge($export_tzs, array_map($format, array_keys($tz_list), array_values($tz_list))); } $link_title_options = calendar_bo::get_link_options(); $settings = array( @@ -694,10 +672,13 @@ class calendar_hooks $settings += array( 'export_timezone' => array( - 'type' => 'select', + 'type' => 'et2-select-timezone', 'label' => 'Timezone of event iCal file import/export', 'name' => 'export_timezone', - 'values' => $export_tzs, + 'values' => [ + '' => preferences_settings::defaultLabel($hook_data['type']), + '0' => lang('Use event timezone'), + ], 'help' => 'Use this timezone to import/export calendar data.', 'xmlrpc' => True, 'admin' => False, diff --git a/preferences/inc/class.preferences_hooks.inc.php b/preferences/inc/class.preferences_hooks.inc.php index 1f2ffbf5b8..727ffcc86d 100644 --- a/preferences/inc/class.preferences_hooks.inc.php +++ b/preferences/inc/class.preferences_hooks.inc.php @@ -54,8 +54,9 @@ class preferences_hooks if(is_array($value)) { $value = [ - 'label' => $key, - 'value' => array_map($format, array_keys($value), array_values($value)) + 'label' => $key ?: '', + 'value' => $key ?: '', + 'children' => array_map($format, array_keys($value), array_values($value)) ]; } else @@ -369,7 +370,7 @@ class preferences_hooks ) ), 'tz' => array( - 'type' => 'select', + 'type' => 'et2-tree-dropdown', 'label' => 'Time zone', 'name' => 'tz', 'values' => $tzs, @@ -378,11 +379,12 @@ class preferences_hooks 'admin' => False, 'default'=> date_default_timezone_get(), 'attributes' => array( - 'search' => true + 'search' => true, + 'leafOnly' => true, // don't allow to select continents ) ), 'tz_selection' => array( - 'type' => 'multiselect', + 'type' => 'et2-tree-dropdown', 'label' => 'Permanent time zone selection', 'name' => 'tz_selection', 'values' => $tzs, @@ -391,7 +393,9 @@ class preferences_hooks 'admin' => False, 'forced' => date_default_timezone_get(), 'attributes' => array( - 'search' => true + 'search' => true, + 'multiple' => true, + 'leafOnly' => true, ) ), 'dateformat' => array( diff --git a/preferences/inc/class.preferences_settings.inc.php b/preferences/inc/class.preferences_settings.inc.php index 516143a495..08696d7660 100644 --- a/preferences/inc/class.preferences_settings.inc.php +++ b/preferences/inc/class.preferences_settings.inc.php @@ -411,6 +411,21 @@ class preferences_settings return null; } + public static function defaultLabel(string $type='user') + { + switch($type) + { + default: + case 'user': + return lang('Use default'); + case 'default': + case 'group': + return lang('No default'); + case 'forced'; + return lang('Users choice'); + } + } + /** * Get content, sel_options and readonlys for given appname and type * @@ -540,40 +555,40 @@ class preferences_settings break; } // move values/options to sel_options array - if (isset($setting['values']) && is_array($setting['values']) && !$setting['no_sel_options']) + if (isset($setting['values']) && is_array($setting['values']) && empty($setting['no_sel_options'])) { - Select::fix_encoded_options($setting['values'], true); - if ($old_type != 'multiselect' && $old_type != 'notify') + // if you use an et2-* widget as type, it's your responsibility to encode options correct! + if (str_starts_with($old_type, 'et2-')) { - switch($type) + $setting['attributes']['placeholder'] = self::defaultLabel($type); + } + else + { + Select::fix_encoded_options($setting['values'], true); + + if ($old_type != 'multiselect' && $old_type != 'notify' && $old_type != 'et2-tree-dropdown') { - case 'user': + if($type === 'forced') + { $setting['values'] = array_merge( - array(['value' => '', 'label' => lang('Use default')]), + array(['value' => '**NULL**', 'label' => self::defaultLabel($type)]), $setting['values'] ); - break; - case 'default': - case 'group': + } + else + { $setting['values'] = array_merge( - array(['value' => '', 'label' => lang('No default')]), + array(['value' => '', 'label' => self::defaultLabel($type)]), $setting['values'] ); - break; - case 'forced'; - $setting['values'] = array_merge( - array(['value' => '**NULL**', 'label' => lang('Users choice')]), - $setting['values'] - ); - break; + } } } $sel_options[$setting['name']] = $setting['values']; } if ($type == 'user') { - $default = $GLOBALS['egw']->preferences->group[$appname][$setting['name']] ? - $GLOBALS['egw']->preferences->group[$appname][$setting['name']] : + $default = $GLOBALS['egw']->preferences->group[$appname][$setting['name']] ?: $GLOBALS['egw']->preferences->default[$appname][$setting['name']]; // replace default value(s) for selectboxes with selectbox labels