From aa8e94ca6d06537d6e4cdcc308ad7f973f4d33b4 Mon Sep 17 00:00:00 2001 From: Aman Agrawal Date: Wed, 19 Jul 2023 19:44:00 +0530 Subject: [PATCH] settings_org: Migrate dropdowns to new DropdownWidget. This also moves [Disabled] button inside the dropdown. --- web/e2e-tests/admin.test.ts | 41 ++----- web/src/settings_org.js | 106 +++++++++++++----- .../settings/organization_settings_admin.hbs | 19 ++-- web/tests/settings_org.test.js | 77 +------------ 4 files changed, 96 insertions(+), 147 deletions(-) diff --git a/web/e2e-tests/admin.test.ts b/web/e2e-tests/admin.test.ts index 7b77e83a92..e23c39fb4d 100644 --- a/web/e2e-tests/admin.test.ts +++ b/web/e2e-tests/admin.test.ts @@ -30,59 +30,34 @@ async function submit_notifications_stream_settings(page: Page): Promise { } async function test_change_new_stream_notifications_setting(page: Page): Promise { - await page.click("#realm_notifications_stream_id_widget button.dropdown-toggle"); - await page.waitForSelector("#realm_notifications_stream_id_widget ul.dropdown-menu", { + await page.click("#realm_notifications_stream_id_widget.dropdown-widget-button"); + await page.waitForSelector(".dropdown-list-container", { visible: true, }); - await page.type( - "#realm_notifications_stream_id_widget .dropdown-search > input[type=text]", - "rome", - ); + await page.type(".dropdown-list-search-input", "rome"); const rome_in_dropdown = await page.waitForSelector( - `xpath///*[@id="realm_notifications_stream_id_widget"]//*[${common.has_class_x( - "dropdown-list-body", - )} and count(li)=1]/li[normalize-space()="Rome"]`, + `xpath///*[${common.has_class_x("list-item")}][normalize-space()="Rome"]`, {visible: true}, ); assert.ok(rome_in_dropdown); await rome_in_dropdown.click(); await submit_notifications_stream_settings(page); - - const disable_stream_notifications = - "#realm_notifications_stream_id_widget .dropdown_list_reset_button"; - await page.waitForSelector(disable_stream_notifications, {visible: true}); - await page.click(disable_stream_notifications); - await submit_notifications_stream_settings(page); } async function test_change_signup_notifications_stream(page: Page): Promise { console.log('Changing signup notifications stream to Verona by filtering with "verona"'); - await page.click("#id_realm_signup_notifications_stream_id > button.dropdown-toggle"); - await page.waitForSelector( - "#realm_signup_notifications_stream_id_widget .dropdown-search > input[type=text]", - {visible: true}, - ); + await page.click("#realm_signup_notifications_stream_id_widget"); + await page.waitForSelector(".dropdown-list-search-input", {visible: true}); - await page.type( - "#realm_signup_notifications_stream_id_widget .dropdown-search > input[type=text]", - "verona", - ); - await page.waitForSelector( - "#realm_signup_notifications_stream_id_widget .dropdown-list-body > li.list_item", - {visible: true}, - ); + await page.type(".dropdown-list-search-input", "verona"); + await page.waitForSelector(".dropdown-list .list-item", {visible: true}); await page.keyboard.press("ArrowDown"); await page.keyboard.press("Enter"); await submit_notifications_stream_settings(page); - - const disable_signup_notifications = - "#realm_signup_notifications_stream_id_widget .dropdown_list_reset_button"; - await page.click(disable_signup_notifications); - await submit_notifications_stream_settings(page); } async function test_permissions_change_save_worked(page: Page): Promise { diff --git a/web/src/settings_org.js b/web/src/settings_org.js index 55fe5a5e42..68c8e159d0 100644 --- a/web/src/settings_org.js +++ b/web/src/settings_org.js @@ -8,7 +8,7 @@ import * as blueslip from "./blueslip"; import * as channel from "./channel"; import {csrf_token} from "./csrf"; import * as dialog_widget from "./dialog_widget"; -import {DropdownListWidget} from "./dropdown_list_widget"; +import * as dropdown_widget from "./dropdown_widget"; import {$t, $t_html, get_language_name} from "./i18n"; import * as keydown_util from "./keydown_util"; import * as loading from "./loading"; @@ -35,6 +35,7 @@ export function reset() { } const MAX_CUSTOM_TIME_LIMIT_SETTING_VALUE = 2147483647; +const DISABLED_STATE_ID = -1; export function maybe_disable_widgets() { if (page_params.is_owner) { @@ -1008,43 +1009,92 @@ export function save_discard_widget_status_handler($subsection, for_realm_defaul } export function init_dropdown_widgets() { - const streams = stream_settings_data.get_streams_for_settings_page(); - const notification_stream_options = { - data: streams.map((x) => ({ - name: x.name, - value: x.stream_id.toString(), - stream: x, - })), - on_update() { + const notification_stream_options = () => { + const streams = stream_settings_data.get_streams_for_settings_page(); + const options = streams.map((stream) => ({ + name: stream.name, + unique_id: stream.stream_id, + stream, + })); + + const disabled_option = { + is_setting_disabled: true, + unique_id: DISABLED_STATE_ID, + name: $t({defaultMessage: "Disabled"}), + }; + + options.unshift(disabled_option); + return options; + }; + + notifications_stream_widget = new dropdown_widget.DropdownWidget({ + widget_name: "realm_notifications_stream_id", + get_options: notification_stream_options, + $events_container: $("#settings_overlay_container #organization-settings"), + item_click_callback(event, dropdown) { + dropdown.hide(); + event.preventDefault(); + event.stopPropagation(); + notifications_stream_widget.render(); save_discard_widget_status_handler($("#org-notifications")); }, - default_text: $t({defaultMessage: "Disabled"}), - render_text: (x) => `#${x}`, - null_value: -1, - }; - notifications_stream_widget = new DropdownListWidget({ - widget_name: "realm_notifications_stream_id", - value: page_params.realm_notifications_stream_id, - ...notification_stream_options, + tippy_props: { + placement: "bottom-start", + }, + default_id: page_params.realm_notifications_stream_id, + unique_id_type: dropdown_widget.DATA_TYPES.NUMBER, }); notifications_stream_widget.setup(); - signup_notifications_stream_widget = new DropdownListWidget({ + + signup_notifications_stream_widget = new dropdown_widget.DropdownWidget({ widget_name: "realm_signup_notifications_stream_id", - value: page_params.realm_signup_notifications_stream_id, - ...notification_stream_options, + get_options: notification_stream_options, + $events_container: $("#settings_overlay_container #organization-settings"), + item_click_callback(event, dropdown) { + dropdown.hide(); + event.preventDefault(); + event.stopPropagation(); + signup_notifications_stream_widget.render(); + save_discard_widget_status_handler($("#org-notifications")); + }, + tippy_props: { + placement: "bottom-start", + }, + default_id: page_params.realm_signup_notifications_stream_id, + unique_id_type: dropdown_widget.DATA_TYPES.NUMBER, }); signup_notifications_stream_widget.setup(); - default_code_language_widget = new DropdownListWidget({ + + default_code_language_widget = new dropdown_widget.DropdownWidget({ widget_name: "realm_default_code_block_language", - data: Object.keys(pygments_data.langs).map((x) => ({ - name: x, - value: x, - })), - value: page_params.realm_default_code_block_language, - on_update() { + get_options() { + const options = Object.keys(pygments_data.langs).map((x) => ({ + name: x, + unique_id: x, + })); + + const disabled_option = { + is_setting_disabled: true, + unique_id: "", + name: $t({defaultMessage: "No language set"}), + }; + + options.unshift(disabled_option); + return options; + }, + $events_container: $("#settings_overlay_container #organization-settings"), + default_id: page_params.realm_default_code_block_language, + unique_id_type: dropdown_widget.DATA_TYPES.STRING, + tippy_props: { + placement: "bottom-start", + }, + item_click_callback(event, dropdown) { + dropdown.hide(); + event.preventDefault(); + event.stopPropagation(); + default_code_language_widget.render(); save_discard_widget_status_handler($("#org-other-settings")); }, - default_text: $t({defaultMessage: "No language set"}), }); default_code_language_widget.setup(); } diff --git a/web/templates/settings/organization_settings_admin.hbs b/web/templates/settings/organization_settings_admin.hbs index ad8c84656a..4cf3c3e5dd 100644 --- a/web/templates/settings/organization_settings_admin.hbs +++ b/web/templates/settings/organization_settings_admin.hbs @@ -16,19 +16,16 @@ help_link_widget_link="/help/configure-organization-language"}} - {{> dropdown_list_widget + {{> ../dropdown_widget_with_label widget_name="realm_notifications_stream_id" - list_placeholder=(t 'Filter streams') - reset_button_text=(t '[Disable]') label=admin_settings_label.realm_notifications_stream - value_type="number" }} + value_type="number"}} - {{> dropdown_list_widget + {{> ../dropdown_widget_with_label widget_name="realm_signup_notifications_stream_id" - list_placeholder=(t 'Filter streams') - reset_button_text=(t '[Disable]') label=admin_settings_label.realm_signup_notifications_stream - value_type="number" }} + value_type="number"}} + {{> settings_checkbox setting_name="realm_message_content_allowed_in_email_notifications" @@ -131,12 +128,10 @@ - {{> dropdown_list_widget + {{> ../dropdown_widget_with_label widget_name="realm_default_code_block_language" - list_placeholder=(t 'Filter languages') - reset_button_text=(t '[Unset]') label=admin_settings_label.realm_default_code_block_language - value_type="string" }} + value_type="string"}} {{> settings_checkbox setting_name="realm_mandatory_topics" diff --git a/web/tests/settings_org.test.js b/web/tests/settings_org.test.js index d8cd5b8f05..79c23d5d0e 100644 --- a/web/tests/settings_org.test.js +++ b/web/tests/settings_org.test.js @@ -16,9 +16,6 @@ const realm_icon = mock_esm("../src/realm_icon"); const channel = mock_esm("../src/channel"); mock_esm("../src/csrf", {csrf_token: "token-stub"}); -mock_esm("../src/list_widget", { - create: () => ({init: noop}), -}); mock_esm("../src/loading", { make_indicator: noop, destroy_indicator: noop, @@ -26,10 +23,9 @@ mock_esm("../src/loading", { const settings_config = zrequire("settings_config"); const settings_bots = zrequire("settings_bots"); -const stream_settings_data = zrequire("stream_settings_data"); const settings_account = zrequire("settings_account"); const settings_org = zrequire("settings_org"); -const dropdown_list_widget = zrequire("dropdown_list_widget"); +const dropdown_widget = zrequire("dropdown_widget"); function test(label, f) { run_test(label, (helpers) => { @@ -511,10 +507,9 @@ test("set_up", ({override, override_rewire}) => { upload_realm_logo_or_icon = f; }; - override_rewire(dropdown_list_widget, "DropdownListWidget", () => ({ + override_rewire(dropdown_widget, "DropdownWidget", () => ({ setup: noop, render: noop, - update: noop, })); $("#id_realm_message_content_edit_limit_minutes").set_parent( $.create(""), @@ -766,17 +761,11 @@ test("test get_sorted_options_list", () => { assert.deepEqual(settings_org.get_sorted_options_list(option_values_2), expected_option_values); }); -test("misc", ({override_rewire, mock_template}) => { +test("misc", () => { page_params.is_admin = false; $("#user-avatar-upload-widget").length = 1; $("#user_details_section").length = 1; - const $stub_notification_disable_parent = $.create(""), - ); - page_params.realm_name_changes_disabled = false; page_params.server_name_changes_disabled = false; settings_account.update_name_change_display(); @@ -837,64 +826,4 @@ test("misc", ({override_rewire, mock_template}) => { settings_account.update_avatar_change_display(); assert.ok(!$("#user-avatar-upload-widget .image_upload_button").hasClass("hide")); - - override_rewire(stream_settings_data, "get_streams_for_settings_page", () => [ - {name: "some_stream", stream_id: 75, invite_only: true, color: "red"}, - {name: "some_stream", stream_id: 42, color: "blue"}, - ]); - - // Set stubs for dropdown_list_widget: - const widget_settings = [ - "realm_notifications_stream_id", - "realm_signup_notifications_stream_id", - "realm_default_code_block_language", - ]; - const $dropdown_list_parent = $.create(""); - $dropdown_list_parent.set_find_results( - ".dropdown_list_reset_button", - $.create(""), - ); - for (const name of widget_settings) { - const $elem = $.create(`#${CSS.escape(name)}_widget #${CSS.escape(name)}_name`); - $elem.closest = () => $dropdown_list_parent; - } - - // We do not define any settings we need in page_params yet, but we don't need to for this test. - blueslip.expect( - "warn", - "dropdown-list-widget: Called without a default value; using null value", - 3, - ); - settings_org.init_dropdown_widgets(); - - let setting_name = "realm_notifications_stream_id"; - let $elem = $(`#${CSS.escape(setting_name)}_widget #${CSS.escape(setting_name)}_name`); - $elem.closest = () => $stub_notification_disable_parent; - let selected_stream_id = 42; - mock_template("inline_decorated_stream_name.hbs", true, (data, html) => { - assert.equal(data.stream.stream_id, selected_stream_id); - return html; - }); - - settings_org.notifications_stream_widget.render(42); - assert.ok($elem.html().indexOf("some_stream") > 0); - assert.ok($elem.html().indexOf("zulip-icon-hashtag") > 0); - assert.ok(!$elem.hasClass("text-warning")); - - settings_org.notifications_stream_widget.render(undefined); - assert.equal($elem.text(), "translated: Disabled"); - assert.ok($elem.hasClass("text-warning")); - - setting_name = "realm_signup_notifications_stream_id"; - $elem = $(`#${CSS.escape(setting_name)}_widget #${CSS.escape(setting_name)}_name`); - $elem.closest = () => $stub_notification_disable_parent; - selected_stream_id = 75; - settings_org.signup_notifications_stream_widget.render(75); - assert.ok($elem.html().indexOf("some_stream") > 0); - assert.ok($elem.html().indexOf("zulip-icon-lock") > 0); - assert.ok(!$elem.hasClass("text-warning")); - - settings_org.signup_notifications_stream_widget.render(undefined); - assert.equal($elem.text(), "translated: Disabled"); - assert.ok($elem.hasClass("text-warning")); });