mirror of
https://github.com/zulip/zulip.git
synced 2025-11-04 14:03:30 +00:00
Previously, when you clicked the confirmation button in a dialog_widget, we'd display a loading spinner on top of an ugly grey button background. Remove the ugly grey background color, while making sure the loading spinner inside the button looks good and doesn't resize the button. Fixes: #22002
199 lines
6.7 KiB
JavaScript
199 lines
6.7 KiB
JavaScript
import $ from "jquery";
|
|
|
|
import render_dialog_widget from "../templates/dialog_widget.hbs";
|
|
|
|
import * as blueslip from "./blueslip";
|
|
import {$t_html} from "./i18n";
|
|
import * as loading from "./loading";
|
|
import * as overlays from "./overlays";
|
|
import * as ui_report from "./ui_report";
|
|
|
|
/*
|
|
* Look for confirm_dialog in settings_user_groups
|
|
* to see an example of how to use this widget. It's
|
|
* pretty simple to use!
|
|
*
|
|
* Some things to note:
|
|
* 1) We create DOM on the fly, and we remove
|
|
* the DOM once it's closed.
|
|
*
|
|
* 2) We attach the DOM for the modal to the body element
|
|
* to avoid interference from other elements.
|
|
*
|
|
* 3) For settings, we have a click handler in settings.js
|
|
* that will close the dialog via overlays.close_active_modal.
|
|
*
|
|
* 4) We assume that since this is a modal, you will
|
|
* only ever have one confirm dialog active at any
|
|
* time.
|
|
*
|
|
* 5) If a modal wants a loading spinner, it should pass loading_spinner: true.
|
|
* This will show a loading spinner when the yes button is clicked.
|
|
* The caller is responsible for calling hide_confirm_dialog_spinner()
|
|
* to hide the spinner in both success and error handlers.
|
|
*
|
|
* 6) If loading_spinner is used, don't hide it on `success`. This modal has a fade out
|
|
* animation. This causes the `Confirm` button to be shown for a split second if the
|
|
* spinner is hidden.
|
|
* Just close the modal. This will remove the whole modal from the DOM without
|
|
* needing to remove the spinner.
|
|
*
|
|
* 7) If a caller needs to run code after the modal body is added
|
|
* to DOM, it can do so by passing a post_render hook.
|
|
*/
|
|
|
|
export function hide_dialog_spinner() {
|
|
$(".dialog_submit_button span").show();
|
|
$("#dialog_widget_modal .modal__btn").prop("disabled", false);
|
|
|
|
const $spinner = $("#dialog_widget_modal .modal__spinner");
|
|
loading.destroy_indicator($spinner);
|
|
}
|
|
|
|
export function show_dialog_spinner() {
|
|
$(".dialog_submit_button span").hide();
|
|
// Disable both the buttons.
|
|
$("#dialog_widget_modal .modal__btn").prop("disabled", true);
|
|
|
|
const $spinner = $("#dialog_widget_modal .modal__spinner");
|
|
const dialog_submit_button_span_width = $(".dialog_submit_button span").width();
|
|
const dialog_submit_button_span_height = $(".dialog_submit_button span").height();
|
|
loading.make_indicator($spinner, {
|
|
width: dialog_submit_button_span_width,
|
|
height: dialog_submit_button_span_height,
|
|
});
|
|
}
|
|
|
|
// Supports a callback to be called once the modal finishes closing.
|
|
export function close_modal(on_hidden_callback) {
|
|
overlays.close_modal("dialog_widget_modal", {on_hidden: on_hidden_callback});
|
|
}
|
|
|
|
export function launch(conf) {
|
|
const mandatory_fields = [
|
|
// The html_ fields should be safe HTML. If callers
|
|
// interpolate user data into strings, they should use
|
|
// templates.
|
|
"html_heading",
|
|
"html_body",
|
|
"on_click",
|
|
];
|
|
|
|
// Optional parameters:
|
|
// * html_submit_button: Submit button text.
|
|
// * close_on_submit: Whether to close modal on clicking submit.
|
|
// * focus_submit_on_open: Whether to focus submit button on open.
|
|
// * help_link: A help link in the heading area.
|
|
// * id: Custom id to the container element to modify styles.
|
|
// * single_footer_button: If true, don't include the "Cancel" button.
|
|
// * form_id: Id of the form element in the modal if it exists.
|
|
// * validate_input: Function to validate the input of the modal.
|
|
// * on_show: Callback to run when the modal is triggered to show.
|
|
// * on_shown: Callback to run when the modal is shown.
|
|
// * on_hide: Callback to run when the modal is triggered to hide.
|
|
// * on_hidden: Callback to run when the modal is hidden.
|
|
// * post_render: Callback to run after the modal body is added to DOM.
|
|
|
|
for (const f of mandatory_fields) {
|
|
if (conf[f] === undefined) {
|
|
blueslip.error("programmer omitted " + f);
|
|
}
|
|
}
|
|
|
|
const html_submit_button = conf.html_submit_button || $t_html({defaultMessage: "Save changes"});
|
|
const html = render_dialog_widget({
|
|
heading_text: conf.html_heading,
|
|
link: conf.help_link,
|
|
html_submit_button,
|
|
html_body: conf.html_body,
|
|
id: conf.id,
|
|
single_footer_button: conf.single_footer_button,
|
|
});
|
|
const $dialog = $(html);
|
|
$("body").append($dialog);
|
|
|
|
if (conf.post_render !== undefined) {
|
|
conf.post_render();
|
|
}
|
|
|
|
const $submit_button = $dialog.find(".dialog_submit_button");
|
|
const $send_email_checkbox = $dialog.find(".send_email");
|
|
const $email_field = $dialog.find(".email_field");
|
|
|
|
$email_field.hide();
|
|
|
|
// This is used to link the submit button with the form, if present, in the modal.
|
|
// This makes it so that submitting this form by pressing Enter on an input element
|
|
// triggers a click on the submit button.
|
|
if (conf.form_id) {
|
|
$submit_button.attr("form", conf.form_id);
|
|
}
|
|
|
|
// Set up handlers.
|
|
$submit_button.on("click", (e) => {
|
|
if (conf.validate_input && !conf.validate_input(e)) {
|
|
return;
|
|
}
|
|
if (conf.loading_spinner) {
|
|
show_dialog_spinner();
|
|
} else if (conf.close_on_submit) {
|
|
close_modal();
|
|
}
|
|
$("#dialog_error").hide();
|
|
conf.on_click(e);
|
|
});
|
|
|
|
$send_email_checkbox.on("change", () => {
|
|
if ($send_email_checkbox.is(":checked")) {
|
|
$email_field.show();
|
|
} else {
|
|
$email_field.hide();
|
|
}
|
|
});
|
|
|
|
overlays.open_modal("dialog_widget_modal", {
|
|
autoremove: true,
|
|
on_show: () => {
|
|
if (conf.focus_submit_on_open) {
|
|
$submit_button.trigger("focus");
|
|
}
|
|
if (conf.on_show) {
|
|
conf.on_show();
|
|
}
|
|
},
|
|
on_hide: conf?.on_hide,
|
|
on_shown: conf?.on_shown,
|
|
on_hidden: conf?.on_hidden,
|
|
});
|
|
}
|
|
|
|
export function submit_api_request(
|
|
request_method,
|
|
url,
|
|
data = {},
|
|
{
|
|
failure_msg_html = $t_html({defaultMessage: "Failed"}),
|
|
success_continuation,
|
|
error_continuation,
|
|
} = {},
|
|
) {
|
|
show_dialog_spinner();
|
|
request_method({
|
|
url,
|
|
data,
|
|
success(reponse_data) {
|
|
close_modal();
|
|
if (success_continuation !== undefined) {
|
|
success_continuation(reponse_data);
|
|
}
|
|
},
|
|
error(xhr) {
|
|
ui_report.error(failure_msg_html, xhr, $("#dialog_error"));
|
|
hide_dialog_spinner();
|
|
if (error_continuation !== undefined) {
|
|
error_continuation(xhr);
|
|
}
|
|
},
|
|
});
|
|
}
|