settings_bots: Migrate manage bot to user profile modal.

This commit migrates the "Manage Bot" modal to the user profile modal,
with the same explanation as in the "Manage User" modal commit.
However, in this commit, we changed the permission of the "Manage User"
tab so that non-admin users can also see the "Manage Bot" tab if they
have created the bot. Additionally, since we can't make changes to
system bots, we check if the bot is a system bot and hide the
"Manage Bot" tab accordingly.

Fixes: #21806
This commit is contained in:
palashb01 2023-07-20 17:20:04 +05:30 committed by Tim Abbott
parent 5d8e6b5f92
commit 61948d273b
6 changed files with 47 additions and 38 deletions

View File

@ -207,7 +207,7 @@ async function test_edit_bot_form(page: Page): Promise<void> {
); );
await common.fill_form(page, edit_form_selector, {full_name: "Bot one"}); await common.fill_form(page, edit_form_selector, {full_name: "Bot one"});
const save_btn_selector = "#edit_bot_modal .dialog_submit_button"; const save_btn_selector = "#user-profile-modal .dialog_submit_button";
await page.click(save_btn_selector); await page.click(save_btn_selector);
// The form gets closed on saving. So, assert it's closed by waiting for it to be hidden. // The form gets closed on saving. So, assert it's closed by waiting for it to be hidden.
@ -242,7 +242,7 @@ async function test_invalid_edit_bot_form(page: Page): Promise<void> {
); );
await common.fill_form(page, edit_form_selector, {full_name: "Bot 2"}); await common.fill_form(page, edit_form_selector, {full_name: "Bot 2"});
const save_btn_selector = "#edit_bot_modal .dialog_submit_button"; const save_btn_selector = "#user-profile-modal .dialog_submit_button";
await page.click(save_btn_selector); await page.click(save_btn_selector);
// The form should not get closed on saving. Errors should be visible on the form. // The form should not get closed on saving. Errors should be visible on the form.
@ -253,7 +253,7 @@ async function test_invalid_edit_bot_form(page: Page): Promise<void> {
"Failed: Name is already in use!", "Failed: Name is already in use!",
); );
const cancel_button_selector = "#edit_bot_modal .dialog_exit_button"; const cancel_button_selector = "#user-profile-modal .dialog_exit_button";
await page.waitForFunction( await page.waitForFunction(
(cancel_button_selector: string) => (cancel_button_selector: string) =>
!document.querySelector(cancel_button_selector)?.hasAttribute("disabled"), !document.querySelector(cancel_button_selector)?.hasAttribute("disabled"),

View File

@ -32,7 +32,6 @@ import * as popover_menus from "./popover_menus";
import * as realm_playground from "./realm_playground"; import * as realm_playground from "./realm_playground";
import * as resize from "./resize"; import * as resize from "./resize";
import * as rows from "./rows"; import * as rows from "./rows";
import * as settings_bots from "./settings_bots";
import * as settings_config from "./settings_config"; import * as settings_config from "./settings_config";
import * as settings_users from "./settings_users"; import * as settings_users from "./settings_users";
import * as stream_popover from "./stream_popover"; import * as stream_popover from "./stream_popover";
@ -955,11 +954,7 @@ export function register_click_handlers() {
hide_all(); hide_all();
const user_id = elem_to_user_id($(e.target).parents("ul")); const user_id = elem_to_user_id($(e.target).parents("ul"));
const user = people.get_by_user_id(user_id); const user = people.get_by_user_id(user_id);
if (user.is_bot) {
settings_bots.show_edit_bot_info_modal(user_id, true);
} else {
user_profile.show_user_profile(user, "manage-profile-tab"); user_profile.show_user_profile(user, "manage-profile-tab");
}
}); });
$("body").on("click", ".user_info_popover_manage_menu_btn", (e) => { $("body").on("click", ".user_info_popover_manage_menu_btn", (e) => {

View File

@ -338,12 +338,12 @@ export function confirm_bot_deactivation(bot_id, handle_confirm, loading_spinner
}); });
} }
export function show_edit_bot_info_modal(user_id, from_user_info_popover) { export function show_edit_bot_info_modal(user_id, $container) {
const bot = people.maybe_get_user_by_id(user_id); const bot = people.maybe_get_user_by_id(user_id);
const owner_id = bot_data.get(user_id).owner_id; const owner_id = bot_data.get(user_id).owner_id;
const owner_full_name = people.get_full_name(owner_id); const owner_full_name = people.get_full_name(owner_id);
if (!bot) { if (!bot || !bot_data.get(user_id)) {
return; return;
} }
@ -357,15 +357,15 @@ export function show_edit_bot_info_modal(user_id, from_user_info_popover) {
owner_full_name, owner_full_name,
current_bot_owner: bot.bot_owner_id, current_bot_owner: bot.bot_owner_id,
}); });
$container.append(html_body);
let avatar_widget; let avatar_widget;
const bot_type = bot.bot_type.toString(); const bot_type = bot.bot_type.toString();
const service = bot_data.get_services(bot.user_id)[0]; const service = bot_data.get_services(bot.user_id)[0];
edit_bot_post_render();
function submit_bot_details() { $("#user-profile-modal").on("click", ".dialog_submit_button", () => {
const role = Number.parseInt($("#bot-role-select").val().trim(), 10); const role = Number.parseInt($("#bot-role-select").val().trim(), 10);
const $full_name = $("#dialog_widget_modal").find("input[name='full_name']"); const $full_name = $("#bot-edit-form").find("input[name='full_name']");
const url = "/json/bots/" + encodeURIComponent(bot.user_id); const url = "/json/bots/" + encodeURIComponent(bot.user_id);
const formData = new FormData(); const formData = new FormData();
@ -395,6 +395,11 @@ export function show_edit_bot_info_modal(user_id, from_user_info_popover) {
formData.append("file-" + i, file); formData.append("file-" + i, file);
} }
const $submit_btn = $("#user-profile-modal .dialog_submit_button");
const $cancel_btn = $("#user-profile-modal .dialog_exit_button");
settings_users.show_button_spinner($submit_btn);
$cancel_btn.prop("disabled", true);
channel.patch({ channel.patch({
url, url,
data: formData, data: formData,
@ -402,14 +407,23 @@ export function show_edit_bot_info_modal(user_id, from_user_info_popover) {
contentType: false, contentType: false,
success() { success() {
avatar_widget.clear(); avatar_widget.clear();
dialog_widget.close_modal(); user_profile.hide_user_profile();
}, },
error(xhr) { error(xhr) {
ui_report.error($t_html({defaultMessage: "Failed"}), xhr, $("#dialog_error")); ui_report.error(
dialog_widget.hide_dialog_spinner(); $t_html({defaultMessage: "Failed"}),
xhr,
$("#bot-edit-form-error"),
);
// Scrolling modal to top, to make error visible to user.
$("#bot-edit-form")
.closest(".simplebar-content-wrapper")
.animate({scrollTop: 0}, "fast");
settings_users.hide_button_spinner($submit_btn);
$cancel_btn.prop("disabled", false);
}, },
}); });
} });
function edit_bot_post_render() { function edit_bot_post_render() {
$("#edit_bot_modal .dialog_submit_button").prop("disabled", true); $("#edit_bot_modal .dialog_submit_button").prop("disabled", true);
@ -488,21 +502,9 @@ export function show_edit_bot_info_modal(user_id, from_user_info_popover) {
const url = "/json/bots/" + encodeURIComponent(bot_id); const url = "/json/bots/" + encodeURIComponent(bot_id);
dialog_widget.submit_api_request(channel.del, url); dialog_widget.submit_api_request(channel.del, url);
} }
const open_deactivate_modal_callback = () =>
confirm_bot_deactivation(bot_id, handle_confirm, true); confirm_bot_deactivation(bot_id, handle_confirm, true);
dialog_widget.close_modal(open_deactivate_modal_callback);
}); });
} }
dialog_widget.launch({
html_heading: $t_html({defaultMessage: "Manage bot"}),
html_body,
id: "edit_bot_modal",
on_click: submit_bot_details,
post_render: edit_bot_post_render,
loading_spinner: from_user_info_popover,
update_submit_disabled_state_on_change: true,
});
} }
export function set_up() { export function set_up() {
@ -590,7 +592,8 @@ export function set_up() {
e.stopPropagation(); e.stopPropagation();
const $li = $(e.currentTarget).closest("li"); const $li = $(e.currentTarget).closest("li");
const bot_id = Number.parseInt($li.find(".bot_info").attr("data-user-id"), 10); const bot_id = Number.parseInt($li.find(".bot_info").attr("data-user-id"), 10);
show_edit_bot_info_modal(bot_id, false); const bot = people.get_by_user_id(bot_id);
user_profile.show_user_profile(bot, "manage-profile-tab");
}); });
$("#active_bots_list").on("click", "a.download_bot_zuliprc", function () { $("#active_bots_list").on("click", "a.download_bot_zuliprc", function () {

View File

@ -751,7 +751,8 @@ function handle_bot_form($tbody) {
popovers.hide_all(); popovers.hide_all();
const user_id = Number.parseInt($(e.currentTarget).attr("data-user-id"), 10); const user_id = Number.parseInt($(e.currentTarget).attr("data-user-id"), 10);
settings_bots.show_edit_bot_info_modal(user_id, false); const user = people.get_by_user_id(user_id);
user_profile.show_user_profile(user, 3);
}); });
} }

View File

@ -195,7 +195,11 @@ function render_user_group_list(groups, user) {
function render_manage_profile_content(user) { function render_manage_profile_content(user) {
const $container = $("#manage-profile-tab"); const $container = $("#manage-profile-tab");
$container.empty(); $container.empty();
if (user.is_bot) {
settings_bots.show_edit_bot_info_modal(user.user_id, $container);
} else {
settings_users.show_edit_user_info_modal(user.user_id, $container); settings_users.show_edit_user_info_modal(user.user_id, $container);
}
$("#user-profile-modal .modal__footer").show(); $("#user-profile-modal .modal__footer").show();
} }
@ -288,9 +292,11 @@ export function show_user_profile(user, default_tab_key = "profile-tab") {
!user.is_system_bot && !user.is_system_bot &&
people.is_person_active(user.user_id); people.is_person_active(user.user_id);
const groups_of_user = user_groups.get_user_groups_of_user(user.user_id); const groups_of_user = user_groups.get_user_groups_of_user(user.user_id);
// We currently have the main UI for editing your own profile in
// settings, so can_manage_profile is artificially false for those.
const can_manage_profile = const can_manage_profile =
people.is_person_active(user.user_id) && (people.can_admin_user(user) || page_params.is_admin) &&
page_params.is_admin && !user.is_system_bot &&
!people.is_my_user_id(user.user_id); !people.is_my_user_id(user.user_id);
const args = { const args = {
user_id: user.user_id, user_id: user.user_id,
@ -369,8 +375,11 @@ export function show_user_profile(user, default_tab_key = "profile-tab") {
}; };
if (can_manage_profile) { if (can_manage_profile) {
const manage_profile_label = user.is_bot
? $t({defaultMessage: "Manage bot"})
: $t({defaultMessage: "Manage user"});
const manage_profile_tab = { const manage_profile_tab = {
label: $t({defaultMessage: "Manage user"}), label: manage_profile_label,
key: "manage-profile-tab", key: "manage-profile-tab",
}; };
opts.values.push(manage_profile_tab); opts.values.push(manage_profile_tab);

View File

@ -1,5 +1,6 @@
<div id="bot-edit-form" data-user-id="{{user_id}}" data-email="{{email}}"> <div id="bot-edit-form" data-user-id="{{user_id}}" data-email="{{email}}">
<form class="new-style edit_bot_form name-setting"> <form class="new-style edit_bot_form name-setting">
<div class="alert" id="bot-edit-form-error"></div>
<div class="input-group name_change_container"> <div class="input-group name_change_container">
<label for="edit_bot_full_name">{{t "Name" }}</label> <label for="edit_bot_full_name">{{t "Name" }}</label>
<input type="text" autocomplete="off" name="full_name" id="edit_bot_full_name" class="modal_text_input" value="{{ full_name }}" /> <input type="text" autocomplete="off" name="full_name" id="edit_bot_full_name" class="modal_text_input" value="{{ full_name }}" />