Improve UX on custom header input (#7207)

pull/5964/merge
Aleksander Machniak 4 years ago
parent a47c558df4
commit 30d31c323b

@ -11,6 +11,7 @@ CHANGELOG Roundcube Webmail
- Extract RFC2231 attachment name from message headers (#6729, #6783) - Extract RFC2231 attachment name from message headers (#6729, #6783)
- Archive: Added options to split archive by year or year+month and folder (#7216) - Archive: Added options to split archive by year or year+month and folder (#7216)
- Managesieve: Allow display name with email address in vacation :from field (#6760) - Managesieve: Allow display name with email address in vacation :from field (#6760)
- Managesieve: Improve UX on custom header input (#7207)
- Password: Added 'pwned' password strength driver (#7274) - Password: Added 'pwned' password strength driver (#7274)
- Add support for SameSite cookie attribute via session_samesite option (req PHP >= 7.3.0) (#6772) - Add support for SameSite cookie attribute via session_samesite option (req PHP >= 7.3.0) (#6772)
- Elastic: Display a special icon for other users and shared namespace roots (#5012) - Elastic: Display a special icon for other users and shared namespace roots (#5012)

@ -1,3 +1,4 @@
- Improve UX on custom header input (#7207)
- Allow display name with email address in vacation :from field (#6760) - Allow display name with email address in vacation :from field (#6760)
- Replace "Filter disabled" with "Filter enabled" (#7028) - Replace "Filter disabled" with "Filter enabled" (#7028)
- Fix so modifier type select wasn't hidden after hiding modifier select on header change - Fix so modifier type select wasn't hidden after hiding modifier select on header change

@ -1773,11 +1773,17 @@ class rcube_sieve_engine
} }
// custom header and variable inputs // custom header and variable inputs
$aout .= $this->list_input($id, 'custom_header', $custom, isset($custom), $aout .= $this->list_input($id, 'custom_header', $custom, 15, false, array(
$this->error_class($id, 'test', 'header', 'custom_header'), 15) . "\n"; 'disabled' => !isset($custom),
'class' => $this->error_class($id, 'test', 'header', 'custom_header'),
$aout .= $this->list_input($id, 'custom_var', $customv, isset($customv), 'placeholder' => $this->plugin->gettext('headername'),
$this->error_class($id, 'test', 'header', 'custom_var'), 15) . "\n"; 'title' => $this->plugin->gettext('headername'),
)) . "\n";
$aout .= $this->list_input($id, 'custom_var', $customv, 15, false, array(
'disabled' => !isset($customv),
'class' => $this->error_class($id, 'test', 'header', 'custom_var')
)) . "\n";
$test = self::rule_test($rule); $test = self::rule_test($rule);
$target = ''; $target = '';
@ -1830,9 +1836,10 @@ class rcube_sieve_engine
} }
$tout .= $this->match_type_selector('rule_op', $id, $test, $rule['test']); $tout .= $this->match_type_selector('rule_op', $id, $test, $rule['test']);
$tout .= $this->list_input($id, 'rule_target', $target, $tout .= $this->list_input($id, 'rule_target', $target, null, false, array(
$rule['test'] != 'size' && $rule['test'] != 'exists' && $rule['test'] != 'duplicate', 'disabled' => $rule['test'] == 'size' || $rule['test'] == 'exists' || $rule['test'] == 'duplicate',
$this->error_class($id, 'test', 'target', 'rule_target')) . "\n"; 'class' => $this->error_class($id, 'test', 'target', 'rule_target')
)) . "\n";
$select_size_op = new html_select(array('name' => "_rule_size_op[$id]", 'id' => 'rule_size_op'.$id, 'class' => 'input-group-prepend')); $select_size_op = new html_select(array('name' => "_rule_size_op[$id]", 'id' => 'rule_size_op'.$id, 'class' => 'input-group-prepend'));
$select_size_op->add(rcube::Q($this->plugin->gettext('filterover')), 'over'); $select_size_op->add(rcube::Q($this->plugin->gettext('filterover')), 'over');
@ -1920,8 +1927,9 @@ class rcube_sieve_engine
$mout .= '<div id="rule_mime' .$id. '" class="adv input-group"' . (!$need_mime ? ' style="display:none"' : '') . '>'; $mout .= '<div id="rule_mime' .$id. '" class="adv input-group"' . (!$need_mime ? ' style="display:none"' : '') . '>';
$mout .= html::span('label input-group-prepend', html::span('input-group-text', rcube::Q($this->plugin->gettext('mime')))); $mout .= html::span('label input-group-prepend', html::span('input-group-text', rcube::Q($this->plugin->gettext('mime'))));
$mout .= $select_mime->show($mime_type); $mout .= $select_mime->show($mime_type);
$mout .= $this->list_input($id, 'rule_mime_param', $rule['mime-param'], true, $mout .= $this->list_input($id, 'rule_mime_param', $rule['mime-param'], 30, $mime_type != 'param', array(
$this->error_class($id, 'test', 'mime_param', 'rule_mime_param'), 30, $mime_type != 'param'); 'class' => $this->error_class($id, 'test', 'mime_param', 'rule_mime_param')
));
$mout .= '</div>'; $mout .= '</div>';
} }
@ -2256,8 +2264,9 @@ class rcube_sieve_engine
'class' => $this->error_class($id, 'action', 'from', 'action_from'), 'class' => $this->error_class($id, 'action', 'from', 'action_from'),
)); ));
$out .= '<br><span class="label">' .rcube::Q($this->plugin->gettext('vacationaddr')) . '</span><br>'; $out .= '<br><span class="label">' .rcube::Q($this->plugin->gettext('vacationaddr')) . '</span><br>';
$out .= $this->list_input($id, 'action_addresses', $action['addresses'], true, $out .= $this->list_input($id, 'action_addresses', $action['addresses'], 30, false, array(
$this->error_class($id, 'action', 'addresses', 'action_addresses'), 30) 'class' => $this->error_class($id, 'action', 'addresses', 'action_addresses')
))
. html::a(array('href' => '#', 'onclick' => rcmail_output::JS_OBJECT_NAME . ".managesieve_vacation_addresses($id)"), . html::a(array('href' => '#', 'onclick' => rcmail_output::JS_OBJECT_NAME . ".managesieve_vacation_addresses($id)"),
rcube::Q($this->plugin->gettext('filladdresses'))); rcube::Q($this->plugin->gettext('filladdresses')));
$out .= '<br><span class="label">' . rcube::Q($this->plugin->gettext('vacationinterval')) . '</span><br>'; $out .= '<br><span class="label">' . rcube::Q($this->plugin->gettext('vacationinterval')) . '</span><br>';
@ -2311,8 +2320,10 @@ class rcube_sieve_engine
. rcube::Q($this->plugin->gettext('flag'.$fidx))) . '<br>'; . rcube::Q($this->plugin->gettext('flag'.$fidx))) . '<br>';
} }
$flout .= $this->list_input($id, 'action_flags', $custom_flags, true, $flout .= $this->list_input($id, 'action_flags', $custom_flags, null, false, array(
$this->error_class($id, 'action', 'flag', 'action_flags_flag'), null, false, "action_flags_flag{$id}"); 'class' => $this->error_class($id, 'action', 'flag', 'action_flags_flag'),
'id' => "action_flags_flag{$id}"
));
$out .= html::div(array( $out .= html::div(array(
'id' => 'action_flags' . $id, 'id' => 'action_flags' . $id,
@ -2426,9 +2437,10 @@ class rcube_sieve_engine
$out .= '<br><span class="label">' . rcube::Q($this->plugin->gettext('notifyimportance')) . '</span><br>'; $out .= '<br><span class="label">' . rcube::Q($this->plugin->gettext('notifyimportance')) . '</span><br>';
$out .= $select_importance->show($action['importance'] ? (int) $action['importance'] : 2); $out .= $select_importance->show($action['importance'] ? (int) $action['importance'] : 2);
$out .= '<div id="action_notifyoption_div' . $id . '">' $out .= '<div id="action_notifyoption_div' . $id . '">'
.'<span class="label">' . rcube::Q($this->plugin->gettext('notifyoptions')) . '</span><br>' . '<span class="label">' . rcube::Q($this->plugin->gettext('notifyoptions')) . '</span><br>'
.$this->list_input($id, 'action_notifyoption', (array)$action['options'], true, . $this->list_input($id, 'action_notifyoption', (array) $action['options'], 30, false, array(
$this->error_class($id, 'action', 'options', 'action_notifyoption'), 30) . '</div>'; 'class' => $this->error_class($id, 'action', 'options', 'action_notifyoption')
)) . '</div>';
$out .= '</div>'; $out .= '</div>';
if (in_array('editheader', $this->exts)) { if (in_array('editheader', $this->exts)) {
@ -2484,8 +2496,9 @@ class rcube_sieve_engine
'class' => $this->error_class($id, 'action', 'name', 'action_delheader_name'), 'class' => $this->error_class($id, 'action', 'name', 'action_delheader_name'),
)); ));
$out .= '<br><label class="label" for="action_delheader_value' . $id .'">'. rcube::Q($this->plugin->gettext('headerpatterns')) .'</label><br>'; $out .= '<br><label class="label" for="action_delheader_value' . $id .'">'. rcube::Q($this->plugin->gettext('headerpatterns')) .'</label><br>';
$out .= $this->list_input($id, 'action_delheader_value', $action['value'], true, $out .= $this->list_input($id, 'action_delheader_value', $action['value'], null, false, array(
$this->error_class($id, 'action', 'value', 'action_delheader_value')) . "\n"; 'class' => $this->error_class($id, 'action', 'value', 'action_delheader_value')
)) . "\n";
$out .= '<br><div class="adv input-group">'; $out .= '<br><div class="adv input-group">';
$out .= html::span('label input-group-prepend', html::label(array( $out .= html::span('label input-group-prepend', html::label(array(
'class' => 'input-group-text', 'for' => 'action_delheader_op'.$id), rcube::Q($this->plugin->gettext('headermatchtype')))); 'class' => 'input-group-text', 'for' => 'action_delheader_op'.$id), rcube::Q($this->plugin->gettext('headermatchtype'))));
@ -2606,22 +2619,25 @@ class rcube_sieve_engine
$this->rc->output->add_script($script, 'docready'); $this->rc->output->add_script($script, 'docready');
} }
protected function list_input($id, $name, $value, $enabled, $class, $size = null, $hidden = false, $elem_id = null) protected function list_input($id, $name, $value, $size = null, $hidden = false, $attrib = array())
{ {
$value = (array) $value; $value = (array) $value;
$value = array_map(array('rcube', 'Q'), $value); $value = array_map(array('rcube', 'Q'), $value);
$value = implode("\n", $value); $value = implode("\n", $value);
return html::tag('textarea', array( $attrib = array_merge($attrib, array(
'data-type' => 'list', 'data-type' => 'list',
'data-size' => $size, 'data-size' => $size,
'data-hidden' => $hidden ?: null, 'data-hidden' => $hidden ?: null,
'name' => '_' . $name . '[' . $id . ']', 'name' => '_' . $name . '[' . $id . ']',
'id' => $elem_id ?: ($name.$id),
'disabled' => !$enabled,
'class' => $class,
'style' => 'display:none', 'style' => 'display:none',
), $value); ));
if (empty($attrib['id'])) {
$attrib['id'] = $name . $id;
}
return html::tag('textarea', $attrib, $value);
} }
/** /**
@ -3062,7 +3078,7 @@ class rcube_sieve_engine
'name' => "_{$name}[$id]", 'name' => "_{$name}[$id]",
'id' => "{$name}{$id}", 'id' => "{$name}{$id}",
'style' => 'display:' .(!in_array($rule, array('size', 'duplicate')) ? 'inline' : 'none'), 'style' => 'display:' .(!in_array($rule, array('size', 'duplicate')) ? 'inline' : 'none'),
'class' => 'operator_selector', 'class' => 'operator_selector col-6',
'onchange' => "{$name}_select(this, '{$id}')", 'onchange' => "{$name}_select(this, '{$id}')",
)); ));

@ -814,7 +814,7 @@ function smart_field_init(field)
// add input rows // add input rows
$.each(list, function(i, v) { $.each(list, function(i, v) {
area.append(smart_field_row(v, field.name, i, $(field).data('size'))); area.append(smart_field_row(v, i, field));
}); });
area.attr('id', id); area.attr('id', id);
@ -837,25 +837,26 @@ function smart_field_init(field)
} }
}; };
function smart_field_row(value, name, idx, size) function smart_field_row(value, idx, field)
{ {
// build row element content // build row element content
var input, content = '<span class="listelement">' var input, content = '<span class="listelement">'
+ '<span class="reset"></span><input type="text"></span>', + '<span class="reset"></span><input type="text"></span>',
elem = $(content), elem = $(content),
attrs = {value: value, name: name + '[]'}; attrs = {
value: value,
if (size) name: field.name + '[]',
attrs.size = size; size: $(field).data('size'),
title: field.title,
placeholder: $(field).attr('placeholder')
};
input = $('input', elem).attr(attrs).keydown(function(e) { input = elem.find('input').attr(attrs).keydown(function(e) {
var input = $(this); var input = $(this);
// element creation event (on Enter) // element creation event (on Enter)
if (e.which == 13) { if (e.which == 13) {
var name = input.attr('name').replace(/\[\]$/, ''), var elem = smart_field_row('', (new Date()).getTime(), field);
dt = (new Date()).getTime(),
elem = smart_field_row('', name, dt, size);
input.parent().after(elem); input.parent().after(elem);
$('input', elem).focus(); $('input', elem).focus();
@ -904,7 +905,7 @@ function smart_field_reset(field, data)
// add input rows // add input rows
$.each(list, function(i, v) { $.each(list, function(i, v) {
area.append(smart_field_row(v, field.name, i, $(field).data('size'))); area.append(smart_field_row(v, i, field));
}); });
} }

@ -3836,7 +3836,7 @@ function rcube_elastic_ui()
// add input rows // add input rows
$.each(list, function(i, v) { $.each(list, function(i, v) {
smart_field_row_add($('.content', area), v, field.name, i, $(field).data('size')); smart_field_row_add($('.content', area), v, i, field);
}); });
area.attr('id', id); area.attr('id', id);
@ -3862,28 +3862,26 @@ function rcube_elastic_ui()
} }
}; };
function smart_field_row_add(area, value, name, idx, size, after) function smart_field_row_add(area, value, idx, field, after)
{ {
// build row element content // build row element content
var input, elem = $('<div class="input-group">' var input,
elem = $('<div class="input-group">'
+ '<input type="text" class="form-control">' + '<input type="text" class="form-control">'
+ '<span class="input-group-append"><a class="icon reset input-group-text" href="#"></a></span>' + '<span class="input-group-append"><a class="icon reset input-group-text" href="#"></a></span>'
+ '</div>'), + '</div>');
attrs = {value: value, name: name + '[]'};
input = elem.find('input').attr({
if (size) { value: value,
attrs.size = size; name: field.name + '[]',
} size: $(field).data('size'),
title: field.title,
input = $('input', elem).attr(attrs) placeholder: field.placeholder
})
.keydown(function(e) { .keydown(function(e) {
var input = $(this);
// element creation event (on Enter) // element creation event (on Enter)
if (e.which == 13) { if (e.which == 13) {
var name = input.attr('name').replace(/\[\]$/, ''), var elem = smart_field_row_add(area, '', (new Date()).getTime(), field, input.parent());
dt = (new Date()).getTime(),
elem = smart_field_row_add(area, '', name, dt, size, input.parent());
$('input', elem).focus(); $('input', elem).focus();
} }
@ -3907,7 +3905,7 @@ function rcube_elastic_ui()
}); });
// element deletion event // element deletion event
$('a.reset', elem).click(function() { elem.find('a.reset').click(function() {
var record = $(this.parentNode.parentNode); var record = $(this.parentNode.parentNode);
if (area.children().length > 1) { if (area.children().length > 1) {
@ -3919,7 +3917,7 @@ function rcube_elastic_ui()
} }
}); });
$(elem).find('input,a') elem.find('input,a')
.on('focus', function() { area.addClass('focused'); }) .on('focus', function() { area.addClass('focused'); })
.on('blur', function() { area.removeClass('focused'); }); .on('blur', function() { area.removeClass('focused'); });
@ -3944,7 +3942,7 @@ function rcube_elastic_ui()
// add input rows // add input rows
$.each(list, function(i, v) { $.each(list, function(i, v) {
smart_field_row_add(area, v, field.name, i, $(field).data('size')); smart_field_row_add(area, v, i, field);
}); });
}; };

Loading…
Cancel
Save