settings: Refactor code that handles radio type settings.

This commit changes the settings code to consider the
parent div of the radio inputs as prop-element and not
individual input elements since all inputs are actually
for a single setting. We still need to handle these settings
as special cases at some places but that can also be fixed.

As a result of this change, we can use ID to get setting
name from the element in populate_data_for_request.
This commit is contained in:
Sahil Batra 2022-09-30 19:54:36 +05:30 committed by Tim Abbott
parent 662998d431
commit d00c428c88
2 changed files with 24 additions and 49 deletions

View File

@ -177,12 +177,11 @@ function get_property_value(property_name, for_realm_default_settings) {
export function extract_property_name($elem, for_realm_default_settings) {
if (for_realm_default_settings) {
// We use the name attribute, rather than the ID attribute,
// for realm_user_default_settings. This is because the
// display/notification settings elements do not always have
// IDs, and also the emojiset input is not compatible with the
// ID approach.
return $elem.attr("name");
// ID for realm_user_default_settings elements are of the form
// "realm_{settings_name}}" because both user and realm default
// settings use the same template and each element should have
// unique id.
return /^realm_(.*)$/.exec($elem.attr("id").replace(/-/g, "_"))[1];
}
if ($elem.attr("id").startsWith("id_authmethod")) {
@ -200,24 +199,6 @@ export function extract_property_name($elem, for_realm_default_settings) {
function get_subsection_property_elements(element) {
const $subsection = $(element).closest(".org-subsection-parent");
if ($subsection.hasClass("theme-settings")) {
// Because the emojiset widget has a unique radio button
// structure, it needs custom code.
const $color_scheme_elem = $subsection.find(".setting_color_scheme");
const $display_emoji_reaction_users_elem = $subsection.find(
".display_emoji_reaction_users",
);
const $emojiset_elem = $subsection.find("input[name='emojiset']:checked");
const $user_list_style_elem = $subsection.find("input[name='user_list_style']:checked");
const $translate_emoticons_elem = $subsection.find(".translate_emoticons");
return [
$color_scheme_elem,
$emojiset_elem,
$user_list_style_elem,
$translate_emoticons_elem,
$display_emoji_reaction_users_elem,
];
}
return Array.from($subsection.find(".prop-element"));
}
@ -559,20 +540,10 @@ function discard_property_element_changes(elem, for_realm_default_settings) {
);
break;
case "emojiset":
// Because this widget has a radio button structure, it
// needs custom reset code.
$elem
.closest(".org-subsection-parent")
.find(`.setting_emojiset_choice[value='${CSS.escape(property_value)}'`)
.prop("checked", true);
break;
case "user_list_style":
// Because this widget has a radio button structure, it
// needs custom reset code.
$elem
.closest(".org-subsection-parent")
.find(`.setting_user_list_style_choice[value='${CSS.escape(property_value)}']`)
.prop("checked", true);
$elem.find(`input[value='${CSS.escape(property_value)}']`).prop("checked", true);
break;
case "email_notifications_batching_period_seconds":
case "email_notification_batching_period_edit_minutes":
@ -744,11 +715,13 @@ export function get_input_element_value(input_elem, input_type) {
return $input_elem.val().trim();
case "number":
return Number.parseInt($input_elem.val().trim(), 10);
case "radio-group":
if ($input_elem.prop("checked")) {
return $input_elem.val().trim();
case "radio-group": {
const selected_val = $input_elem.find("input:checked").val();
if ($input_elem.data("setting-choice-type") === "number") {
return Number.parseInt(selected_val, 10);
}
return undefined;
return selected_val.trim();
}
case "time-limit":
return get_time_limit_setting_value($input_elem);
case "message-retention-setting":
@ -857,6 +830,10 @@ function check_property_changed(elem, for_realm_default_settings) {
"#org-notifications .language_selection_widget .language_selection_button span",
).attr("data-language-code");
break;
case "emojiset":
case "user_list_style":
proposed_val = get_input_element_value($elem, "radio-group");
break;
default:
if (current_val !== undefined) {
proposed_val = get_input_element_value($elem, typeof current_val);
@ -1066,12 +1043,10 @@ export function register_save_discard_widget_handlers(
if (input_value !== undefined) {
let property_name;
if (for_realm_default_settings) {
// We use the name attribute, rather than the ID attribute,
// for realm_user_default_settings. This is because the
// display/notification settings elements do not always have
// IDs, and also the emojiset input is not compatible with the
// ID approach.
property_name = $input_elem.attr("name");
property_name = extract_property_name(
$input_elem,
for_realm_default_settings,
);
} else if ($input_elem.attr("id").startsWith("id_authmethod")) {
// Authentication Method component IDs include authentication method name
// for uniqueness, anchored to "id_authmethod" prefix, e.g. "id_authmethodapple_<property_name>".

View File

@ -44,10 +44,10 @@
<div class="input-group">
<label class="emoji-theme title">{{t "Emoji theme" }}</label>
<div class="emojiset_choices grey-box">
<div class="emojiset_choices grey-box prop-element" id="{{prefix}}emojiset" data-setting-widget-type="radio-group" data-setting-choice-type="string">
{{#each settings_object.emojiset_choices}}
<label>
<input type="radio" class="setting_emojiset_choice prop-element" name="emojiset" value="{{this.key}}" data-setting-widget-type="radio-group"/>
<input type="radio" class="setting_emojiset_choice" name="emojiset" value="{{this.key}}"/>
<span>{{this.text}}</span>
<span class="right">
{{#if (eq this.key "text") }}
@ -82,10 +82,10 @@
<div class="input-group">
<label class="title">{{t "User list style" }}</label>
<div class="user_list_style_values grey-box">
<div class="user_list_style_values grey-box prop-element" id="{{prefix}}user_list_style" data-setting-widget-type="radio-group" data-setting-choice-type="number">
{{#each user_list_style_values}}
<label>
<input type="radio" class="setting_user_list_style_choice prop-element" name="user_list_style" value="{{this.code}}" data-setting-widget-type="radio-group"/>
<input type="radio" class="setting_user_list_style_choice" name="user_list_style" value="{{this.code}}"/>
<span>{{this.description}}</span>
<span class="right preview">
{{#if (eq this.code 1)}}