From 1948cb6a8949fe44b433193b09f3ea35236eaca5 Mon Sep 17 00:00:00 2001 From: Harshit Bansal Date: Sat, 25 Feb 2017 13:19:12 +0530 Subject: [PATCH] Add UI for changing the bot owners. Add neccesary UI in #administration and #settings for changing the bot owner. The bot owner select control is rendered dynamically in order to avoid performance issues in case of large number of users. Fixes: #2719. --- frontend_tests/node_tests/dispatch.js | 4 +- frontend_tests/node_tests/templates.js | 19 ++++++++ frontend_tests/node_tests/user_events.js | 5 +- static/js/admin.js | 48 ++++++++++++++------ static/js/server_events.js | 5 +- static/js/settings.js | 12 ++++- static/js/user_events.js | 2 +- static/templates/admin_user_list.handlebars | 5 ++ static/templates/bot_avatar_row.handlebars | 5 ++ static/templates/bot_owner_select.handlebars | 6 +++ 10 files changed, 88 insertions(+), 23 deletions(-) create mode 100644 static/templates/bot_owner_select.handlebars diff --git a/frontend_tests/node_tests/dispatch.js b/frontend_tests/node_tests/dispatch.js index 1f13dbc149..26e12f9d0a 100644 --- a/frontend_tests/node_tests/dispatch.js +++ b/frontend_tests/node_tests/dispatch.js @@ -547,12 +547,12 @@ run(function (override, capture, args) { event = event_fixtures.realm_bot__update; override('bot_data', 'update', capture(['email', 'bot'])); - override('admin', 'update_user_full_name', capture(['update_user_id', 'name'])); + override('admin', 'update_user_data', capture(['update_user_id', 'update_bot_data'])); dispatch(event); assert_same(args.email, event.bot.email); assert_same(args.bot, event.bot); assert_same(args.update_user_id, event.bot.user_id); - assert_same(args.name, event.bot.full_name); + assert_same(args.update_bot_data, event.bot); }); diff --git a/frontend_tests/node_tests/templates.js b/frontend_tests/node_tests/templates.js index af86dc2857..9729fa5388 100644 --- a/frontend_tests/node_tests/templates.js +++ b/frontend_tests/node_tests/templates.js @@ -354,6 +354,25 @@ function render(template_name, args) { assert.equal(img.attr('src'), '/hamlet/avatar/url'); }()); +(function bot_owner_select() { + var args = { + users_list: [ + { + email: "hamlet@zulip.com", + api_key: "123456ABCD", + full_name: "Hamlet", + avatar_url: "/hamlet/avatar/url", + }, + ], + }; + var html = render('bot_owner_select', args); + global.write_handlebars_output("bot_owner_select", html); + var option = $(html).find("option:last"); + assert.equal(option.val(), "hamlet@zulip.com"); + assert.equal(option.text(), "Hamlet"); +}()); + + (function compose_invite_users() { var args = { email: 'hamlet@zulip.com', diff --git a/frontend_tests/node_tests/user_events.js b/frontend_tests/node_tests/user_events.js index 8bd5c6490b..f199fcc46c 100644 --- a/frontend_tests/node_tests/user_events.js +++ b/frontend_tests/node_tests/user_events.js @@ -12,7 +12,7 @@ set_global('activity', { redraw: function () {}, }); set_global('admin', { - update_user_full_name: function () {}, + update_user_data: function () {}, show_or_hide_menu_item: function () {}, }); set_global('page_params', { @@ -79,6 +79,3 @@ initialize(); assert.equal(full_name, 'Me V2'); }()); - - - diff --git a/static/js/admin.js b/static/js/admin.js index a50b10e599..2fcb5cf1e5 100644 --- a/static/js/admin.js +++ b/static/js/admin.js @@ -30,19 +30,28 @@ function get_email_for_user_row(row) { return email; } -exports.update_user_full_name = function (user_id, new_full_name) { +exports.update_user_data = function (user_id, new_data) { if (!meta.loaded) { return; } var user_info = get_user_info(user_id); - var user_row = user_info.user_row; var form_row = user_info.form_row; - // Update the full name in the table - user_row.find(".user_name").text(new_full_name); - form_row.find("input[name='full_name']").val(new_full_name); + if (new_data.full_name !== undefined) { + // Update the full name in the table + user_row.find(".user_name").text(new_data.full_name); + form_row.find("input[name='full_name']").val(new_data.full_name); + } + + if (new_data.owner !== undefined) { + // Update the bot owner in the table + user_row.find(".owner").text(new_data.owner); + } + + // Remove the bot owner select control. + form_row.find(".edit_bot_owner_container select").remove(); // Hide name change form form_row.hide(); @@ -58,10 +67,6 @@ function failed_listing_streams(xhr) { ui.report_error(i18n.t("Error listing streams"), xhr, $("#administration-status")); } -function failed_changing_name(xhr) { - ui.report_error(i18n.t("Error changing name"), xhr, $("#administration-status")); -} - function populate_users(realm_people_data) { var users_table = $("#admin_users_table"); var deactivated_users_table = $("#admin_deactivated_users_table"); @@ -791,6 +796,9 @@ function _setup_page() { }); $(".admin_user_table, .admin_bot_table").on("click", ".open-user-form", function (e) { + var users_list = people.get_realm_persons().filter(function (person) { + return !person.is_bot; + }); var user_id = $(e.currentTarget).attr("data-user-id"); var user_info = get_user_info(user_id); var user_row = user_info.user_row; @@ -798,19 +806,25 @@ function _setup_page() { var reset_button = form_row.find(".reset_edit_user"); var submit_button = form_row.find(".submit_name_changes"); var full_name = form_row.find("input[name='full_name']"); + var owner_select = $(templates.render("bot_owner_select", {users_list: users_list})); var admin_status = $('#administration-status').expectOne(); - var person = people.get_person_from_user_id(user_id); if (!person) { return; } + // Dynamically add the owner select control in order to + // avoid performance issues in case of large number of users. + owner_select.val(bot_data.get(person.email).owner || ""); + form_row.find(".edit_bot_owner_container").append(owner_select); + // Show user form. user_row.hide(); form_row.show(); reset_button.on("click", function () { + owner_select.remove(); form_row.hide(); user_row.show(); }); @@ -819,18 +833,24 @@ function _setup_page() { e.preventDefault(); e.stopPropagation(); - var url = "/json/users/" + encodeURIComponent(person.email); + var url = "/json/bots/" + encodeURIComponent(person.email); var data = { - full_name: JSON.stringify(full_name.val()), + full_name: full_name.val(), }; + if (owner_select.val() !== undefined && owner_select.val() !== "") { + data.bot_owner = owner_select.val(); + } + channel.patch({ url: url, data: data, success: function () { - ui.report_success(i18n.t('Name successfully updated!'), admin_status); + ui.report_success(i18n.t('Updated successfully!'), admin_status); + }, + error: function () { + ui.report_error(i18n.t('Update failed!'), admin_status); }, - error: failed_changing_name, }); }); }); diff --git a/static/js/server_events.js b/static/js/server_events.js index c051e7cb49..048d5186bb 100644 --- a/static/js/server_events.js +++ b/static/js/server_events.js @@ -96,8 +96,11 @@ function dispatch_normal_event(event) { } else if (event.op === 'remove') { bot_data.remove(event.bot.email); } else if (event.op === 'update') { + if (_.has(event.bot, 'owner_id')) { + event.bot.owner = people.get_person_from_user_id(event.bot.owner_id).email; + } bot_data.update(event.bot.email, event.bot); - admin.update_user_full_name(event.bot.user_id, event.bot.full_name); + admin.update_user_data(event.bot.user_id, event.bot); } break; diff --git a/static/js/settings.js b/static/js/settings.js index f826e23402..6c186b89a4 100644 --- a/static/js/settings.js +++ b/static/js/settings.js @@ -719,15 +719,21 @@ function _setup_page() { var image_version = 0; $("#bots_list").on("click", "button.open_edit_bot_form", function (e) { + var users_list = people.get_realm_persons().filter(function (person) { + return !person.is_bot; + }); var li = $(e.currentTarget).closest('li'); var edit_div = li.find('div.edit_bot'); var form = li.find('.edit_bot_form'); var image = li.find(".image"); var bot_info = li.find(".bot_info"); var reset_edit_bot = li.find(".reset_edit_bot"); - + var owner_select = $(templates.render("bot_owner_select", {users_list:users_list})); var old_full_name = bot_info.find(".name").text(); + var old_owner = bot_data.get(bot_info.find(".email .value").text()).owner; form.find(".edit_bot_name").attr('value', old_full_name); + form.find(".edit-bot-owner .controls").append(owner_select); + form.find(".edit-bot-owner select").val(old_owner); image.hide(); bot_info.hide(); @@ -744,6 +750,7 @@ function _setup_page() { reset_edit_bot.click(function (event) { form.find(".edit_bot_name").val(old_full_name); + owner_select.remove(); show_row_again(); $(this).off(event); }); @@ -758,6 +765,7 @@ function _setup_page() { submitHandler: function () { var email = form.data('email'); var full_name = form.find('.edit_bot_name').val(); + var bot_owner = form.find('.edit-bot-owner select').val(); var file_input = li.find('.edit_bot_avatar_file_input'); var default_sending_stream = form.find('.edit_bot_default_sending_stream').val(); var default_events_register_stream = form.find('.edit_bot_default_events_register_stream').val(); @@ -767,6 +775,7 @@ function _setup_page() { formData.append('csrfmiddlewaretoken', csrf_token); formData.append('full_name', full_name); + formData.append('bot_owner', bot_owner); add_bot_default_streams_to_form(formData, default_sending_stream, default_events_register_stream); jQuery.each(file_input[0].files, function (i, file) { @@ -784,6 +793,7 @@ function _setup_page() { loading.destroy_indicator(spinner); errors.hide(); edit_button.show(); + owner_select.remove(); show_row_again(); bot_info.find('.name').text(full_name); if (data.avatar_url) { diff --git a/static/js/user_events.js b/static/js/user_events.js index a982f592ef..a95d877175 100644 --- a/static/js/user_events.js +++ b/static/js/user_events.js @@ -33,7 +33,7 @@ exports.update_person = function update(person) { if (_.has(person, 'full_name')) { people.set_full_name(person_obj, person.full_name); - admin.update_user_full_name(person.user_id, person.full_name); + admin.update_user_data(person.user_id, person); activity.redraw(); message_live_update.update_user_full_name(person.user_id, person.full_name); pm_list.update_private_messages(); diff --git a/static/templates/admin_user_list.handlebars b/static/templates/admin_user_list.handlebars index 5707a2955b..1b16c17146 100644 --- a/static/templates/admin_user_list.handlebars +++ b/static/templates/admin_user_list.handlebars @@ -52,6 +52,11 @@ + {{#if is_bot}} +
+ +
+ {{/if}}
diff --git a/static/templates/bot_avatar_row.handlebars b/static/templates/bot_avatar_row.handlebars index ceaecdd0df..4642882d6e 100644 --- a/static/templates/bot_avatar_row.handlebars +++ b/static/templates/bot_avatar_row.handlebars @@ -44,6 +44,11 @@
+
+ +
+
+
diff --git a/static/templates/bot_owner_select.handlebars b/static/templates/bot_owner_select.handlebars new file mode 100644 index 0000000000..559a8f469b --- /dev/null +++ b/static/templates/bot_owner_select.handlebars @@ -0,0 +1,6 @@ +