settings_org: Improve robustness of organization settings.

This moves the configuration of widget type from settings_org to instead
live in respective HTML templates, via `data-widget-setting-type` and we
also remove `get_subsection_property_types` and refactor function
`populate_data_for_request` accordingly.

Fixes: #11708.
This commit is contained in:
Pragati Agrawal 2019-03-06 21:54:14 +05:30 committed by Tim Abbott
parent 222966b6ba
commit e630dde240
6 changed files with 79 additions and 124 deletions

View File

@ -225,15 +225,35 @@ function test_submit_settings_form(submit_form) {
success_callback = req.success;
};
ev.currentTarget = '#org-submit-other-permissions';
let stubs = createSaveButtons('other-permissions');
let subsection = 'other-permissions';
ev.currentTarget = `#org-submit-${subsection}`;
let stubs = createSaveButtons(subsection);
let save_button = stubs.save_button;
save_button.attr('id', 'org-submit-other-permissions');
save_button.attr('id', `org-submit-${subsection}`);
save_button.replace = () => {
return `${subsection}`;
};
$("#id_realm_create_stream_permission").val("by_anyone");
$("#id_realm_add_emoji_by_admins_only").val("by_anyone");
$("#id_realm_message_retention_days").val("15");
$("#id_realm_bot_creation_policy").val("1");
$("#id_realm_email_address_visibility").val("1");
const bot_creation_policy_elem = $("#id_realm_bot_creation_policy");
bot_creation_policy_elem.val("1");
bot_creation_policy_elem.attr('id', 'id_realm_bot_creation_policy');
bot_creation_policy_elem.data = () => {
return "integer";
};
const email_address_visibility_elem = $("#id_realm_email_address_visibility");
email_address_visibility_elem.val("1");
email_address_visibility_elem.attr('id', 'id_realm_email_address_visibility');
email_address_visibility_elem.data = () => {
return "integer";
};
let subsection_elem = $(`#org-${subsection}`);
subsection_elem.set_find_results('.setting-widget', [
bot_creation_policy_elem,
email_address_visibility_elem,
]);
patched = false;
submit_form(ev);
@ -250,13 +270,30 @@ function test_submit_settings_form(submit_form) {
assert.deepEqual(data, expected_value);
ev.currentTarget = '#org-submit-user-defaults';
stubs = createSaveButtons('user-defaults');
subsection = 'user-defaults';
ev.currentTarget = `#org-submit-${subsection}`;
stubs = createSaveButtons(subsection);
save_button = stubs.save_button;
save_button.attr('id', 'org-submit-user-defaults');
save_button.attr('id', `org-submit-${subsection}`);
$("#id_realm_default_language").val("en");
$("#id_realm_default_twenty_four_hour_time").prop("checked", true);
const realm_default_language_elem = $("#id_realm_default_language");
realm_default_language_elem.val("en");
realm_default_language_elem.attr('id', 'id_realm_default_language');
realm_default_language_elem.data = () => {
return "text";
};
const realm_default_twenty_four_hour_time_elem = $("#id_realm_default_twenty_four_hour_time");
realm_default_twenty_four_hour_time_elem.prop("checked", true);
realm_default_twenty_four_hour_time_elem.attr('id', 'id_realm_default_twenty_four_hour_time');
realm_default_twenty_four_hour_time_elem.data = () => {
return "bool";
};
subsection_elem = $(`#org-${subsection}`);
subsection_elem.set_find_results('.setting-widget', [
realm_default_language_elem,
realm_default_twenty_four_hour_time_elem,
]);
submit_form(ev);
assert(patched);

View File

@ -10,86 +10,6 @@ exports.reset = function () {
meta.loaded = false;
};
var org_profile = {
name: {
type: 'text',
},
description: {
type: 'text',
},
};
var org_settings = {
msg_editing: {
allow_edit_history: {
type: 'bool',
},
allow_community_topic_editing: {
type: 'bool',
},
},
other_settings: {
inline_image_preview: {
type: 'bool',
},
inline_url_embed_preview: {
type: 'bool',
},
mandatory_topics: {
type: 'bool',
},
video_chat_provider: {
type: 'text',
},
google_hangouts_domain: {
type: 'text',
},
zoom_user_id: {
type: 'text',
},
zoom_api_key: {
type: 'text',
},
zoom_api_secret: {
type: 'text',
},
message_content_allowed_in_email_notifications: {
type: 'bool',
},
},
user_defaults: {
default_language: {
type: 'text',
},
default_twenty_four_hour_time: {
type: 'bool',
},
},
notifications: {
send_welcome_emails: {
type: 'bool',
},
},
};
var org_permissions = {
user_identity: {
name_changes_disabled: {
type: 'bool',
},
email_changes_disabled: {
type: 'bool',
},
},
other_permissions: {
bot_creation_policy: {
type: 'integer',
},
email_address_visibility: {
type: 'integer',
},
},
};
exports.maybe_disable_widgets = function () {
if (page_params.is_admin) {
@ -131,17 +51,6 @@ exports.email_address_visibility_values = {
},
};
function get_subsection_property_types(subsection) {
if (_.has(org_settings, subsection)) {
return org_settings[subsection];
} else if (_.has(org_permissions, subsection)) {
return org_permissions[subsection];
} else if (subsection === 'org_profile') {
return org_profile;
}
return;
}
exports.get_realm_time_limits_in_minutes = function (property) {
var val = (page_params[property] / 60).toFixed(1);
if (parseFloat(val, 10) === parseInt(val, 10)) {
@ -622,19 +531,24 @@ exports.build_page = function () {
// Populate authentication methods table
exports.populate_auth_methods(page_params.realm_authentication_methods);
function populate_data_for_request(data, changing_property_types) {
_.each(changing_property_types, function (v, k) {
var field = changing_property_types[k];
if (field.type === 'bool') {
data[k] = JSON.stringify($('#id_realm_' + k).prop('checked'));
function populate_data_for_request(subsection) {
var data = {};
var subsection_elem = $('#org-' + subsection);
var input_elems = subsection_elem.find('.setting-widget');
_.each(input_elems, function (input_elem) {
input_elem = $(input_elem);
var input_type = input_elem.data("setting-widget-type");
var property_name = input_elem.attr('id').replace("id_realm_", "");
if (input_type === 'bool') {
data[property_name] = JSON.stringify(input_elem.prop('checked'));
return;
}
if (field.type === 'text') {
data[k] = JSON.stringify($('#id_realm_' + k).val().trim());
if (input_type === 'text') {
data[property_name] = JSON.stringify(input_elem.val().trim());
return;
}
if (field.type === 'integer') {
data[k] = JSON.stringify(parseInt($("#id_realm_" + k).val().trim(), 10));
if (input_type === 'integer') {
data[property_name] = JSON.stringify(parseInt(input_elem.val().trim(), 10));
}
});
return data;
@ -830,7 +744,7 @@ exports.build_page = function () {
var subsection_id = save_button.attr('id').replace("org-submit-", "");
var subsection = subsection_id.split('-').join('_');
var data = populate_data_for_request({}, get_subsection_property_types(subsection));
var data = populate_data_for_request(subsection_id);
var opts = get_complete_data_for_subsection(subsection);
data = _.extend(data, opts.data);
var success_continuation = opts.success_continuation;

View File

@ -78,7 +78,7 @@
<div class="input-group">
<label for="realm_bot_creation_policy">{{t "Who can add bots" }}</label>
<select name="realm_bot_creation_policy" id="id_realm_bot_creation_policy">
<select name="realm_bot_creation_policy" class="setting-widget" id="id_realm_bot_creation_policy" data-setting-widget-type="integer">
{{#each bot_creation_policy_values}}
<option value='{{this.code}}'>{{this.description}}</option>
{{/each}}
@ -95,7 +95,7 @@
<div class="input-group" {{#if development}}{{else}}style="display: none"{{/if}}>
<label for="realm_email_address_visibility">{{t "Who can see users email addresses" }}</label>
<select name="realm_email_address_visibility" id="id_realm_email_address_visibility">
<select name="realm_email_address_visibility" class="setting-widget" id="id_realm_email_address_visibility" data-setting-widget-type="integer">
{{#each email_address_visibility_values}}
<option value='{{this.code}}'>{{this.description}}</option>
{{/each}}

View File

@ -15,14 +15,14 @@
<div class="organization-settings-parent">
<div class="input-group admin-realm">
<label for="id_realm_name">{{t "Organization name" }}</label>
<input type="text" id="id_realm_name" name="realm_name" class="admin-realm-name"
autocomplete="off"
<input type="text" id="id_realm_name" name="realm_name" class="admin-realm-name setting-widget"
autocomplete="off" data-setting-widget-type="text"
value="{{ realm_name }}" maxlength="40" />
</div>
<div class="input-group admin-realm">
<label for="realm_description">{{t "Organization description" }}</label>
<textarea id="id_realm_description" name="realm_description" class="admin-realm-description"
maxlength="1000">{{ realm_description }}</textarea>
<textarea id="id_realm_description" name="realm_description" class="admin-realm-description setting-widget"
maxlength="1000" data-setting-widget-type="text">{{ realm_description }}</textarea>
</div>
</div>
</div>

View File

@ -132,7 +132,7 @@
<div class="inline-block organization-settings-parent">
<div class="input-group">
<label for="realm_default_language" class="dropdown-title">{{t "Default language" }}:</label>
<select name="realm_default_language" id="id_realm_default_language">
<select name="realm_default_language" class ="setting-widget" id="id_realm_default_language" data-setting-widget-type="text">
{{#each language_list}}
<option value='{{this.code}}'>{{this.name}}</option>
{{/each}}
@ -156,7 +156,7 @@
<label for="realm_video_chat_provider" class="dropdown-title">
{{t 'Video chat provider' }}
</label>
<select name="realm_video_chat_provider" id="id_realm_video_chat_provider">
<select name="realm_video_chat_provider" class ="setting-widget" id="id_realm_video_chat_provider" data-setting-widget-type="text">
{{#each realm_available_video_chat_providers}}
<option value='{{this}}'>{{this}}</option>
{{/each}}
@ -166,7 +166,8 @@
<input type="text" id="id_realm_google_hangouts_domain"
name="realm_google_hangouts_domain"
autocomplete="off"
class="admin-realm-google-hangouts-domain"/>
class="admin-realm-google-hangouts-domain setting-widget"
data-setting-widget-type="text"/>
</div>
<div id="zoom_help_text" class="zoom_credentials">
<p>
@ -179,21 +180,24 @@
<input type="text" id="id_realm_zoom_user_id"
name="realm_zoom_user_id"
autocomplete="off"
class="admin-realm-zoom-field"/>
class="admin-realm-zoom-field setting-widget"
data-setting-widget-type="text"/>
</div>
<div id="zoom_api_key" class="zoom_credentials">
<label>{{t 'Zoom API key (required)' }}:</label>
<input type="text" id="id_realm_zoom_api_key"
name="realm_zoom_api_key"
autocomplete="off"
class="admin-realm-zoom-field"/>
class="admin-realm-zoom-field setting-widget"
data-setting-widget-type="text"/>
</div>
<div id="zoom_api_secret" class="zoom_credentials">
<label>{{t 'Zoom API secret (required if changed)' }}:</label>
<input type="text" id="id_realm_zoom_api_secret"
name="realm_zoom_api_secret"
autocomplete="off"
class="admin-realm-zoom-field"/>
class="admin-realm-zoom-field setting-widget"
data-setting-widget-type="text"/>
</div>
</div>

View File

@ -1,6 +1,6 @@
<div class="input-group {{#if is_nested}}disableable{{/if}} {{#if_not_a_or_b_and_not_c is_parent_setting_enabled push_notifications_tooltip page_params.realm_push_notifications_enabled}}control-label-disabled{{/if_not_a_or_b_and_not_c}}">
<label class="checkbox">
<input type="checkbox" class="inline-block" name="{{setting_name}}"
<input type="checkbox" class="inline-block setting-widget" name="{{setting_name}}" data-setting-widget-type="bool"
id="{{prefix}}{{setting_name}}"
{{#if_not_a_or_b_and_not_c is_parent_setting_enabled push_notifications_tooltip page_params.realm_push_notifications_enabled}}disabled="disabled"{{/if_not_a_or_b_and_not_c}}
{{#if is_checked}}