mirror of
https://github.com/zulip/zulip.git
synced 2025-11-04 14:03:30 +00:00
There is a bug where invite button is not enabled again after sending
invite is failed, but it is enabled on successful completion of invite.
I am not able to figure out why it is behaving differently in success and
error cases, even when the code to enable button is in complete() function
and it is called in both the cases.
But, I can confirm that adding .button('reset') fixes this bug as button
is disabled using the .button('loading') call and this is according to the
bootstrap docs only. But the bootstrap docs mention that the .button(string)
method has been removed in v4.0 as mentioned here
https://getbootstrap.com/docs/3.4/javascript/.
So, as we would want to avoid using depereceated or removed methods, this
commit simply changes the code to disable the button and set the loading
text using simple jquery and this also solves the above mentioned bug.
227 lines
7.9 KiB
JavaScript
227 lines
7.9 KiB
JavaScript
import autosize from "autosize";
|
|
import ClipboardJS from "clipboard";
|
|
import $ from "jquery";
|
|
|
|
import copy_invite_link from "../templates/copy_invite_link.hbs";
|
|
import render_invitation_failed_error from "../templates/invitation_failed_error.hbs";
|
|
import render_invite_subscription from "../templates/invite_subscription.hbs";
|
|
import render_settings_dev_env_email_access from "../templates/settings/dev_env_email_access.hbs";
|
|
|
|
import * as browser_history from "./browser_history";
|
|
import * as channel from "./channel";
|
|
import * as common from "./common";
|
|
import {i18n} from "./i18n";
|
|
import * as overlays from "./overlays";
|
|
import {page_params} from "./page_params";
|
|
import * as stream_data from "./stream_data";
|
|
import * as ui from "./ui";
|
|
import * as ui_report from "./ui_report";
|
|
|
|
function reset_error_messages() {
|
|
$("#invite_status").hide().text("").removeClass(common.status_classes);
|
|
$("#multiuse_invite_status").hide().text("").removeClass(common.status_classes);
|
|
|
|
$("#invitee_emails").closest(".control-group").removeClass("warning error");
|
|
|
|
if (page_params.development_environment) {
|
|
$("#dev_env_msg").hide().text("").removeClass(common.status_classes);
|
|
}
|
|
}
|
|
|
|
function get_common_invitation_data() {
|
|
const invite_as = Number.parseInt($("#invite_as").val(), 10);
|
|
const stream_ids = [];
|
|
$("#invite-stream-checkboxes input:checked").each(function () {
|
|
const stream_id = Number.parseInt($(this).val(), 10);
|
|
stream_ids.push(stream_id);
|
|
});
|
|
const data = {
|
|
csrfmiddlewaretoken: $('input[name="csrfmiddlewaretoken"]').attr("value"),
|
|
invite_as,
|
|
stream_ids: JSON.stringify(stream_ids),
|
|
};
|
|
return data;
|
|
}
|
|
|
|
function beforeSend() {
|
|
reset_error_messages();
|
|
// TODO: You could alternatively parse the textarea here, and return errors to
|
|
// the user if they don't match certain constraints (i.e. not real email addresses,
|
|
// aren't in the right domain, etc.)
|
|
//
|
|
// OR, you could just let the server do it. Probably my temptation.
|
|
const loading_text = $("#submit-invitation").data("loading-text");
|
|
$("#submit-invitation").text(loading_text);
|
|
$("#submit-invitation").prop("disabled", true);
|
|
return true;
|
|
}
|
|
|
|
function submit_invitation_form() {
|
|
const invite_status = $("#invite_status");
|
|
const invitee_emails = $("#invitee_emails");
|
|
const invitee_emails_group = invitee_emails.closest(".control-group");
|
|
const data = get_common_invitation_data();
|
|
data.invitee_emails = $("#invitee_emails").val();
|
|
|
|
channel.post({
|
|
url: "/json/invites",
|
|
data,
|
|
beforeSend,
|
|
success() {
|
|
ui_report.success(i18n.t("User(s) invited successfully."), invite_status);
|
|
invitee_emails_group.removeClass("warning");
|
|
invitee_emails.val("");
|
|
|
|
if (page_params.development_environment) {
|
|
const rendered_email_msg = render_settings_dev_env_email_access();
|
|
$("#dev_env_msg").html(rendered_email_msg).addClass("alert-info").show();
|
|
}
|
|
},
|
|
error(xhr) {
|
|
const arr = JSON.parse(xhr.responseText);
|
|
if (arr.errors === undefined) {
|
|
// There was a fatal error, no partial processing occurred.
|
|
ui_report.error("", xhr, invite_status);
|
|
} else {
|
|
// Some users were not invited.
|
|
const invitee_emails_errored = [];
|
|
const error_list = [];
|
|
let is_invitee_deactivated = false;
|
|
for (const value of arr.errors) {
|
|
const [email, error_message, deactivated] = value;
|
|
error_list.push(`${email}: ${error_message}`);
|
|
if (deactivated) {
|
|
is_invitee_deactivated = true;
|
|
}
|
|
invitee_emails_errored.push(email);
|
|
}
|
|
|
|
const error_response = render_invitation_failed_error({
|
|
error_message: arr.msg,
|
|
error_list,
|
|
is_admin: page_params.is_admin,
|
|
is_invitee_deactivated,
|
|
});
|
|
ui_report.message(error_response, invite_status, "alert-warning");
|
|
invitee_emails_group.addClass("warning");
|
|
|
|
if (arr.sent_invitations) {
|
|
invitee_emails.val(invitee_emails_errored.join("\n"));
|
|
}
|
|
}
|
|
},
|
|
complete() {
|
|
$("#submit-invitation").text(i18n.t("Invite"));
|
|
$("#submit-invitation").prop("disabled", false);
|
|
$("#invitee_emails").focus();
|
|
ui.get_scroll_element($("#invite_user_form .modal-body"))[0].scrollTop = 0;
|
|
},
|
|
});
|
|
}
|
|
|
|
function generate_multiuse_invite() {
|
|
const invite_status = $("#multiuse_invite_status");
|
|
const data = get_common_invitation_data();
|
|
channel.post({
|
|
url: "/json/invites/multiuse",
|
|
data,
|
|
beforeSend,
|
|
success(data) {
|
|
const copy_link_html = copy_invite_link(data);
|
|
ui_report.success(copy_link_html, invite_status);
|
|
new ClipboardJS("#copy_generated_invite_link");
|
|
},
|
|
error(xhr) {
|
|
ui_report.error("", xhr, invite_status);
|
|
},
|
|
complete() {
|
|
$("#submit-invitation").text(i18n.t("Generate invite link"));
|
|
$("#submit-invitation").prop("disabled", false);
|
|
},
|
|
});
|
|
}
|
|
|
|
export function get_invite_streams() {
|
|
const streams = stream_data.get_invite_stream_data();
|
|
|
|
function compare_streams(a, b) {
|
|
return a.name.localeCompare(b.name);
|
|
}
|
|
streams.sort(compare_streams);
|
|
return streams;
|
|
}
|
|
|
|
function update_subscription_checkboxes() {
|
|
const data = {
|
|
streams: get_invite_streams(),
|
|
notifications_stream: stream_data.get_notifications_stream(),
|
|
};
|
|
const html = render_invite_subscription(data);
|
|
$("#streams_to_add").html(html);
|
|
}
|
|
|
|
function prepare_form_to_be_shown() {
|
|
update_subscription_checkboxes();
|
|
reset_error_messages();
|
|
}
|
|
|
|
export function launch() {
|
|
$("#submit-invitation").button();
|
|
prepare_form_to_be_shown();
|
|
|
|
overlays.open_overlay({
|
|
name: "invite",
|
|
overlay: $("#invite-user"),
|
|
on_close() {
|
|
browser_history.exit_overlay();
|
|
},
|
|
});
|
|
|
|
autosize($("#invitee_emails").trigger("focus"));
|
|
|
|
// Ctrl + Enter key to submit form
|
|
$("#invite-user").on("keydown", (e) => {
|
|
if (e.key === "Enter" && e.ctrlKey) {
|
|
submit_invitation_form();
|
|
}
|
|
});
|
|
}
|
|
|
|
export function initialize() {
|
|
$(document).on("click", "#invite_check_all_button", () => {
|
|
$("#streams_to_add :checkbox").prop("checked", true);
|
|
});
|
|
|
|
$(document).on("click", "#invite_uncheck_all_button", () => {
|
|
$("#streams_to_add :checkbox").prop("checked", false);
|
|
});
|
|
|
|
$("#submit-invitation").on("click", () => {
|
|
const is_generate_invite_link = $("#generate_multiuse_invite_radio").prop("checked");
|
|
if (is_generate_invite_link) {
|
|
generate_multiuse_invite();
|
|
} else {
|
|
submit_invitation_form();
|
|
}
|
|
});
|
|
|
|
$("#generate_multiuse_invite_button").on("click", () => {
|
|
$("#generate_multiuse_invite_radio").prop("checked", true);
|
|
$("#multiuse_radio_section").show();
|
|
$("#invite-method-choice").hide();
|
|
$("#invitee_emails").prop("disabled", true);
|
|
$("#submit-invitation").text(i18n.t("Generate invite link"));
|
|
$("#submit-invitation").data("loading-text", i18n.t("Generating link..."));
|
|
reset_error_messages();
|
|
});
|
|
|
|
$("#invite-user").on("change", "#generate_multiuse_invite_radio", () => {
|
|
$("#invitee_emails").prop("disabled", false);
|
|
$("#submit-invitation").text(i18n.t("Invite"));
|
|
$("#submit-invitation").data("loading-text", i18n.t("Inviting..."));
|
|
$("#multiuse_radio_section").hide();
|
|
$("#invite-method-choice").show();
|
|
reset_error_messages();
|
|
});
|
|
}
|