dialog_widget: Assign each dialog widget a unique id.

This makes it easy to check if the correct dialog widget is open
and to perform actions based on the state of dialog widget in
async callbacks.
This commit is contained in:
Aman Agrawal 2024-05-15 06:38:06 +00:00 committed by Tim Abbott
parent ab0fc402e0
commit e51962d6ac
10 changed files with 66 additions and 40 deletions

View File

@ -15,7 +15,7 @@ async function test_add_new_profile_field(page: Page): Promise<void> {
"Add a new custom profile field",
);
assert.strictEqual(
await common.get_text_from_selector(page, "#dialog_widget_modal .dialog_submit_button"),
await common.get_text_from_selector(page, ".micromodal .dialog_submit_button"),
"Add",
);
await page.waitForSelector(".admin-profile-field-form", {visible: true});
@ -23,7 +23,7 @@ async function test_add_new_profile_field(page: Page): Promise<void> {
field_type: "1",
name: "Teams",
});
await page.click("#dialog_widget_modal .dialog_submit_button");
await page.click(".micromodal .dialog_submit_button");
await common.wait_for_micromodal_to_close(page);
await page.waitForSelector(
@ -43,13 +43,13 @@ async function test_edit_profile_field(page: Page): Promise<void> {
"Edit custom profile field",
);
assert.strictEqual(
await common.get_text_from_selector(page, "#dialog_widget_modal .dialog_submit_button"),
await common.get_text_from_selector(page, ".micromodal .dialog_submit_button"),
"Save changes",
);
await common.fill_form(page, "form.name-setting", {
name: "team",
});
await page.click("#dialog_widget_modal .dialog_submit_button");
await page.click(".micromodal .dialog_submit_button");
await common.wait_for_micromodal_to_close(page);
await page.waitForSelector(
@ -69,10 +69,10 @@ async function test_delete_custom_profile_field(page: Page): Promise<void> {
"Delete custom profile field?",
);
assert.strictEqual(
await common.get_text_from_selector(page, "#dialog_widget_modal .dialog_submit_button"),
await common.get_text_from_selector(page, ".micromodal .dialog_submit_button"),
"Confirm",
);
await page.click("#dialog_widget_modal .dialog_submit_button");
await page.click(".micromodal .dialog_submit_button");
await common.wait_for_micromodal_to_close(page);
await page.waitForSelector("#admin-profile-field-status img", {visible: true});

View File

@ -70,7 +70,7 @@ async function test_edit_linkifier(page: Page): Promise<void> {
});
await page.click(".dialog_submit_button");
await page.waitForSelector("#dialog_widget_modal", {hidden: true});
await page.waitForSelector(".micromodal", {hidden: true});
await common.wait_for_micromodal_to_close(page);
await page.waitForSelector(".linkifier_row:nth-last-child(1)", {visible: true});
@ -117,7 +117,7 @@ async function test_edit_invalid_linkifier(page: Page): Promise<void> {
assert.strictEqual(edit_linkifier_template_status, "Failed: Invalid URL template.");
await page.click(".dialog_exit_button");
await page.waitForSelector("#dialog_widget_modal", {hidden: true});
await page.waitForSelector(".micromodal", {hidden: true});
await page.waitForSelector(".linkifier_row:nth-last-child(1)", {visible: true});
assert.strictEqual(

View File

@ -111,7 +111,7 @@ async function test_webhook_bot_creation(page: Page): Promise<void> {
"Unexpected title for deactivate user modal",
);
assert.strictEqual(
await common.get_text_from_selector(page, "#dialog_widget_modal .dialog_submit_button"),
await common.get_text_from_selector(page, ".micromodal .dialog_submit_button"),
"Add",
"Deactivate button has incorrect text.",
);
@ -121,7 +121,7 @@ async function test_webhook_bot_creation(page: Page): Promise<void> {
bot_type: OUTGOING_WEBHOOK_BOT_TYPE,
payload_url: "http://hostname.example.com/bots/followup",
});
await page.click("#dialog_widget_modal .dialog_submit_button");
await page.click(".micromodal .dialog_submit_button");
await common.wait_for_micromodal_to_close(page);
const bot_email = "1-bot@zulip.testserver";
@ -151,7 +151,7 @@ async function test_normal_bot_creation(page: Page): Promise<void> {
"Unexpected title for deactivate user modal",
);
assert.strictEqual(
await common.get_text_from_selector(page, "#dialog_widget_modal .dialog_submit_button"),
await common.get_text_from_selector(page, ".micromodal .dialog_submit_button"),
"Add",
"Deactivate button has incorrect text.",
);
@ -160,7 +160,7 @@ async function test_normal_bot_creation(page: Page): Promise<void> {
bot_short_name: "2",
bot_type: GENERIC_BOT_TYPE,
});
await page.click("#dialog_widget_modal .dialog_submit_button");
await page.click(".micromodal .dialog_submit_button");
await common.wait_for_micromodal_to_close(page);
const bot_email = "2-bot@zulip.testserver";

View File

@ -32,11 +32,11 @@ async function test_reactivation_confirmation_modal(page: Page, fullname: string
"Unexpected title for reactivate user modal",
);
assert.strictEqual(
await common.get_text_from_selector(page, "#dialog_widget_modal .dialog_submit_button"),
await common.get_text_from_selector(page, ".micromodal .dialog_submit_button"),
"Confirm",
"Reactivate button has incorrect text.",
);
await page.click("#dialog_widget_modal .dialog_submit_button");
await page.click(".micromodal .dialog_submit_button");
await common.wait_for_micromodal_to_close(page);
}
@ -53,11 +53,11 @@ async function test_deactivate_user(page: Page): Promise<void> {
"Unexpected title for deactivate user modal",
);
assert.strictEqual(
await common.get_text_from_selector(page, "#dialog_widget_modal .dialog_submit_button"),
await common.get_text_from_selector(page, ".micromodal .dialog_submit_button"),
"Deactivate",
"Deactivate button has incorrect text.",
);
await page.click("#dialog_widget_modal .dialog_submit_button");
await page.click(".micromodal .dialog_submit_button");
await common.wait_for_micromodal_to_close(page);
}
@ -116,11 +116,11 @@ async function test_bot_deactivation_and_reactivation(page: Page): Promise<void>
"Unexpected title for deactivate bot modal",
);
assert.strictEqual(
await common.get_text_from_selector(page, "#dialog_widget_modal .dialog_submit_button"),
await common.get_text_from_selector(page, ".micromodal .dialog_submit_button"),
"Deactivate",
"Deactivate button has incorrect text.",
);
await page.click("#dialog_widget_modal .dialog_submit_button");
await page.click(".micromodal .dialog_submit_button");
await common.wait_for_micromodal_to_close(page);
await page.waitForSelector(default_bot_user_row + ".deactivated_user", {visible: true});

View File

@ -2,8 +2,8 @@ import * as dialog_widget from "./dialog_widget";
import type {DialogWidgetConfig} from "./dialog_widget";
import {$t_html} from "./i18n";
export function launch(conf: DialogWidgetConfig): void {
dialog_widget.launch({
export function launch(conf: DialogWidgetConfig): string {
return dialog_widget.launch({
close_on_submit: true,
focus_submit_on_open: true,
html_submit_button: $t_html({defaultMessage: "Confirm"}),

View File

@ -9,6 +9,21 @@ import * as loading from "./loading";
import * as modals from "./modals";
import * as ui_report from "./ui_report";
// Since only one dialog widget can be active at a time
// and we don't support reopening already closed dialog widgets,
// this is also the id of the current / last open dialog widget.
// We will use this as id for current dialog widget assuming
// the caller has already checked that the dialog widget is open.
let widget_id_counter = 0;
function current_dialog_widget_id(): string {
return `dialog_widget_modal_${widget_id_counter}`;
}
function current_dialog_widget_selector(): string {
return `#${current_dialog_widget_id()}`;
}
/*
* Look for confirm_dialog in settings_user_groups
* to see an example of how to use this widget. It's
@ -60,7 +75,7 @@ export type DialogWidgetConfig = {
on_shown?: () => void;
on_hide?: () => void;
on_hidden?: () => void;
post_render?: () => void;
post_render?: (modal_unique_id: string) => void;
loading_spinner?: boolean;
update_submit_disabled_state_on_change?: boolean;
always_visible_scrollbar?: boolean;
@ -74,17 +89,19 @@ type RequestOpts = {
export function hide_dialog_spinner(): void {
$(".dialog_submit_button span").show();
$("#dialog_widget_modal .modal__btn").prop("disabled", false);
const dialog_widget_selector = current_dialog_widget_selector();
$(`${dialog_widget_selector} .modal__btn`).prop("disabled", false);
const $spinner = $("#dialog_widget_modal .modal__spinner");
const $spinner = $(`${dialog_widget_selector} .modal__spinner`);
loading.destroy_indicator($spinner);
}
export function show_dialog_spinner(): void {
const dialog_widget_selector = current_dialog_widget_selector();
// Disable both the buttons.
$("#dialog_widget_modal .modal__btn").prop("disabled", true);
$(`${dialog_widget_selector} .modal__btn`).prop("disabled", true);
const $spinner = $("#dialog_widget_modal .modal__spinner");
const $spinner = $(`${dialog_widget_selector} .modal__spinner`);
const dialog_submit_button_span_width = $(".dialog_submit_button span").width();
const dialog_submit_button_span_height = $(".dialog_submit_button span").height();
@ -100,10 +117,10 @@ export function show_dialog_spinner(): void {
// Supports a callback to be called once the modal finishes closing.
export function close(on_hidden_callback?: () => void): void {
modals.close("dialog_widget_modal", {on_hidden: on_hidden_callback});
modals.close(current_dialog_widget_id(), {on_hidden: on_hidden_callback});
}
export function launch(conf: DialogWidgetConfig): void {
export function launch(conf: DialogWidgetConfig): string {
// Mandatory fields:
// * html_heading
// * html_body
@ -135,9 +152,12 @@ export function launch(conf: DialogWidgetConfig): void {
// has scrollable content. Default behaviour is to hide the scrollbar when it is
// not in use.
widget_id_counter += 1;
const modal_unique_id = current_dialog_widget_id();
const html_submit_button = conf.html_submit_button ?? $t_html({defaultMessage: "Save changes"});
const html_exit_button = conf.html_exit_button ?? $t_html({defaultMessage: "Cancel"});
const html = render_dialog_widget({
modal_unique_id,
heading_text: conf.html_heading,
link: conf.help_link,
html_submit_button,
@ -151,7 +171,7 @@ export function launch(conf: DialogWidgetConfig): void {
$("body").append($dialog);
if (conf.post_render !== undefined) {
conf.post_render();
conf.post_render(modal_unique_id);
}
const $submit_button = $dialog.find(".dialog_submit_button");
@ -219,7 +239,7 @@ export function launch(conf: DialogWidgetConfig): void {
conf.on_click(e);
});
modals.open("dialog_widget_modal", {
modals.open(modal_unique_id, {
autoremove: true,
on_show() {
if (conf.focus_submit_on_open) {
@ -233,6 +253,7 @@ export function launch(conf: DialogWidgetConfig): void {
on_shown: conf?.on_shown,
on_hidden: conf?.on_hidden,
});
return modal_unique_id;
}
export function submit_api_request(

View File

@ -48,11 +48,11 @@ function open_linkifier_edit_form(linkifier_id: number): void {
url_template: linkifier.url_template,
});
function submit_linkifier_form(): void {
const $change_linkifier_button = $(".dialog_submit_button");
function submit_linkifier_form(dialog_widget_id: string): void {
const $modal = $(`#${dialog_widget_id}`);
const $change_linkifier_button = $modal.find(".dialog_submit_button");
$change_linkifier_button.prop("disabled", true);
const $modal = $("#dialog_widget_modal");
const url = "/json/realm/filters/" + encodeURIComponent(linkifier_id);
const pattern = $modal.find<HTMLInputElement>("input#edit-linkifier-pattern").val()!.trim();
const url_template = $modal
@ -101,10 +101,12 @@ function open_linkifier_edit_form(linkifier_id: number): void {
);
}
dialog_widget.launch({
const dialog_widget_id = dialog_widget.launch({
html_heading: $t_html({defaultMessage: "Edit linkfiers"}),
html_body,
on_click: submit_linkifier_form,
on_click() {
submit_linkifier_form(dialog_widget_id);
},
});
}

View File

@ -52,10 +52,12 @@ export function is_window_focused(): boolean {
export function confirm_mark_all_as_read(): void {
const html_body = render_confirm_mark_all_as_read();
confirm_dialog.launch({
const modal_id = confirm_dialog.launch({
html_heading: $t_html({defaultMessage: "Mark all messages as read?"}),
html_body,
on_click: mark_all_as_read,
on_click() {
mark_all_as_read(modal_id);
},
loading_spinner: true,
});
}

View File

@ -51,9 +51,10 @@ export function confirm_deactivation(
};
const html_body = render_settings_deactivation_user_modal(opts);
function set_email_field_visibility(): void {
const $send_email_checkbox = $("#dialog_widget_modal").find(".send_email");
const $email_field = $("#dialog_widget_modal").find(".email_field");
function set_email_field_visibility(dialog_widget_id: string): void {
const $modal = $(`#${dialog_widget_id}`);
const $send_email_checkbox = $modal.find(".send_email");
const $email_field = $modal.find(".email_field");
$email_field.hide();
$send_email_checkbox.on("change", () => {

View File

@ -1,4 +1,4 @@
<div class="micromodal" id="dialog_widget_modal" aria-hidden="true">
<div class="micromodal" id="{{modal_unique_id}}" aria-hidden="true">
<div class="modal__overlay" tabindex="-1">
<div {{#if id}}id="{{id}}" {{/if}}class="modal__container" role="dialog" aria-modal="true" aria-labelledby="dialog_title">
<header class="modal__header">