From 59e810790f1a4870801602e3354c4ee4d7e1d16c Mon Sep 17 00:00:00 2001 From: Ganesh Pawar Date: Wed, 30 Mar 2022 11:56:33 +0530 Subject: [PATCH] user_groups: Convert inline form to modal. Fixes part of #21298. --- .../node_tests/settings_user_groups.js | 27 ++--- static/js/settings_user_groups.js | 108 ++++++++++++------ static/styles/settings.css | 16 ++- .../settings/add_user_group_modal.hbs | 10 ++ .../templates/settings/user_groups_admin.hbs | 22 +--- .../include/how-to-create-a-user-group.md | 4 +- tools/test-js-with-node | 1 + 7 files changed, 112 insertions(+), 76 deletions(-) create mode 100644 static/templates/settings/add_user_group_modal.hbs diff --git a/frontend_tests/node_tests/settings_user_groups.js b/frontend_tests/node_tests/settings_user_groups.js index 533350ff28..3e9508c43b 100644 --- a/frontend_tests/node_tests/settings_user_groups.js +++ b/frontend_tests/node_tests/settings_user_groups.js @@ -19,6 +19,7 @@ let create_item_handler; const channel = mock_esm("../../static/js/channel"); const confirm_dialog = mock_esm("../../static/js/confirm_dialog"); +const dialog_widget = mock_esm("../../static/js/dialog_widget"); const input_pill = mock_esm("../../static/js/input_pill"); const typeahead_helper = mock_esm("../../static/js/typeahead_helper"); const user_groups = mock_esm("../../static/js/user_groups", { @@ -327,10 +328,6 @@ test_ui("populate_user_groups", ({override_rewire, mock_template}) => { test_create_item(create_item_handler); // Tests for settings_user_groups.set_up workflow. - assert.equal( - typeof $(".organization form.admin-user-group-form").get_on_handler("submit"), - "function", - ); assert.equal(typeof $("#user-groups").get_on_handler("click", ".delete"), "function"); assert.equal( typeof $("#user-groups").get_on_handler("keypress", ".user-group h4 > span"), @@ -506,12 +503,12 @@ test_ui("on_events", ({override_rewire, mock_template}) => { override_rewire(settings_user_groups, "can_edit", () => true); (function test_admin_user_group_form_submit_triggered() { - const handler = $(".organization form.admin-user-group-form").get_on_handler("submit"); + const handler = settings_user_groups.add_user_group; const event = { stopPropagation: noop, preventDefault: noop, }; - const $fake_this = $.create("fake-form.admin-user-group-form"); + const $fake_this = $.create("#add-user-group-form"); const fake_object_array = [ { name: "fake-name", @@ -532,39 +529,39 @@ test_ui("on_events", ({override_rewire, mock_template}) => { assert.deepEqual(opts.data, data); (function test_post_success() { - $("#admin-user-group-status").show(); - $("form.admin-user-group-form input[type='text']").val("fake-content"); + $("#dialog_error").show(); + $("#add-user-group-form input[type='text']").val("fake-content"); ui_report.success = (text, ele) => { assert.equal(text, "translated HTML: User group added!"); - assert.equal(ele, $("#admin-user-group-status")); + assert.equal(ele, $("#dialog_error")); }; + dialog_widget.close_modal = () => {}; opts.success(); - assert.ok(!$("#admin-user-group-status").visible()); - assert.equal($("form.admin-user-group-form input[type='text']").val(), ""); + assert.ok(!$("#dialog_error").visible()); })(); (function test_post_error() { - $("#admin-user-group-status").show(); + $("#dialog_error").show(); ui_report.error = (error_msg, error_obj, ele) => { const xhr = { responseText: '{"msg":"fake-msg"}', }; assert.equal(error_msg, "translated HTML: Failed"); assert.deepEqual(error_obj, xhr); - assert.equal(ele, $("#admin-user-group-status")); + assert.equal(ele, $("#dialog_error")); }; const xhr = { responseText: '{"msg":"fake-msg", "attrib":"val"}', }; opts.error(xhr); - assert.ok(!$("#admin-user-group-status").visible()); + assert.ok(!$("#dialog_error").visible()); })(); }; - handler.call($fake_this, event); + handler(event); })(); (function test_user_groups_delete_click_triggered() { diff --git a/static/js/settings_user_groups.js b/static/js/settings_user_groups.js index b48c689d20..a0204e7a75 100644 --- a/static/js/settings_user_groups.js +++ b/static/js/settings_user_groups.js @@ -2,10 +2,12 @@ import $ from "jquery"; import _ from "lodash"; import render_confirm_delete_user from "../templates/confirm_dialog/confirm_delete_user.hbs"; +import render_add_user_group_modal from "../templates/settings/add_user_group_modal.hbs"; import render_admin_user_group_list from "../templates/settings/admin_user_group_list.hbs"; import * as channel from "./channel"; import * as confirm_dialog from "./confirm_dialog"; +import * as dialog_widget from "./dialog_widget"; import {$t, $t_html} from "./i18n"; import {page_params} from "./page_params"; import * as people from "./people"; @@ -297,48 +299,78 @@ export function populate_user_groups() { } } +export function add_user_group(e) { + e.preventDefault(); + e.stopPropagation(); + + const $user_group_status = $("#dialog_error"); + + const group = { + members: JSON.stringify([people.my_current_user_id()]), + }; + + for (const obj of $("#add-user-group-form").serializeArray()) { + if (obj.value.trim() === "") { + continue; + } + group[obj.name] = obj.value; + } + + channel.post({ + url: "/json/user_groups/create", + data: group, + success() { + $user_group_status.hide(); + ui_report.success($t_html({defaultMessage: "User group added!"}), $user_group_status); + dialog_widget.close_modal(); + }, + error(xhr) { + $user_group_status.hide(); + const errors = JSON.parse(xhr.responseText).msg; + xhr.responseText = JSON.stringify({msg: errors}); + ui_report.error($t_html({defaultMessage: "Failed"}), xhr, $user_group_status); + }, + }); +} + +function show_add_user_group_modal() { + const html_body = render_add_user_group_modal(); + + function add_user_group_post_render() { + const $add_user_group_input_element = $("#user_group_name"); + const $add_user_group_submit_button = $("#add-user-group-modal .dialog_submit_button"); + $add_user_group_submit_button.prop("disabled", true); + + $add_user_group_input_element.on("input", () => { + $add_user_group_submit_button.prop( + "disabled", + $add_user_group_input_element.val() === "", + ); + }); + } + + dialog_widget.launch({ + html_heading: $t_html({defaultMessage: "Add new user group"}), + html_body, + html_submit_button: $t_html({defaultMessage: "Save"}), + help_link: "/help/user-groups", + form_id: "add-user-group-form", + id: "add-user-group-modal", + on_click: add_user_group, + on_shown: () => $("#user_group_name").trigger("focus"), + post_render: add_user_group_post_render, + }); +} + export function set_up() { meta.loaded = true; populate_user_groups(); - $(".organization form.admin-user-group-form") - .off("submit") - .on("submit", function (e) { - e.preventDefault(); - e.stopPropagation(); - - const $user_group_status = $("#admin-user-group-status"); - - const group = { - members: JSON.stringify([people.my_current_user_id()]), - }; - - for (const obj of $(this).serializeArray()) { - if (obj.value.trim() === "") { - continue; - } - group[obj.name] = obj.value; - } - - channel.post({ - url: "/json/user_groups/create", - data: group, - success() { - $user_group_status.hide(); - ui_report.success( - $t_html({defaultMessage: "User group added!"}), - $user_group_status, - ); - $("form.admin-user-group-form input[type='text']").val(""); - }, - error(xhr) { - $user_group_status.hide(); - const errors = JSON.parse(xhr.responseText).msg; - xhr.responseText = JSON.stringify({msg: errors}); - ui_report.error($t_html({defaultMessage: "Failed"}), xhr, $user_group_status); - }, - }); - }); + $("#show-add-user-group-modal").on("click", (e) => { + e.preventDefault(); + e.stopPropagation(); + show_add_user_group_modal(); + }); $("#user-groups").on("click", ".delete", function () { const group_id = Number.parseInt($(this).parents(".user-group").attr("id"), 10); diff --git a/static/styles/settings.css b/static/styles/settings.css index 46a8c114c8..f989172a84 100644 --- a/static/styles/settings.css +++ b/static/styles/settings.css @@ -718,22 +718,32 @@ input[type="checkbox"] { text-align: right; } +#show-add-user-group-modal { + margin-bottom: 10px; +} + +#add-user-group-form { + margin: 0; + + /* This 14px is the border and padding of the input element */ + #user_group_description { + width: calc(100% - 14px); + } +} + .add-new-emoji-box, -.add-new-user-group-box, .add-new-alert-word-box, .add-new-export-box { margin-bottom: 20px; } .add-new-emoji-box .new-emoji-form, -.add-new-user-group-box .new-user-group-form, .add-new-alert-word-box .new-alert-word-form, .add-new-export-box { margin: 10px 0; } .add-new-emoji-box, -.add-new-user-group-box, .add-new-default-stream-box { input[type="text"] { padding: 6px; diff --git a/static/templates/settings/add_user_group_modal.hbs b/static/templates/settings/add_user_group_modal.hbs new file mode 100644 index 0000000000..8457ce5332 --- /dev/null +++ b/static/templates/settings/add_user_group_modal.hbs @@ -0,0 +1,10 @@ +
+
+ + +
+
+ + +
+
diff --git a/static/templates/settings/user_groups_admin.hbs b/static/templates/settings/user_groups_admin.hbs index b97981f367..6e9684d924 100644 --- a/static/templates/settings/user_groups_admin.hbs +++ b/static/templates/settings/user_groups_admin.hbs @@ -17,25 +17,9 @@ {{/tr}}

{{#if can_edit_user_groups}} -
-
-
-
{{t "Add a new user group" }}
-
-
- - -
-
- - -
- -
-
-
+ {{/if}} {{/unless}} diff --git a/templates/zerver/help/include/how-to-create-a-user-group.md b/templates/zerver/help/include/how-to-create-a-user-group.md index 01f70efc28..9d5327dd2a 100644 --- a/templates/zerver/help/include/how-to-create-a-user-group.md +++ b/templates/zerver/help/include/how-to-create-a-user-group.md @@ -2,7 +2,9 @@ {settings_tab|user-groups-admin} -1. Under **Add a new user group**, enter a **Name** and **Description**. +1. Click the **Add a new user group** button. + +1. Enter a **Name** and **Description**. 1. Click **Save**. diff --git a/tools/test-js-with-node b/tools/test-js-with-node index e84ebbec4a..fd24539ca3 100755 --- a/tools/test-js-with-node +++ b/tools/test-js-with-node @@ -163,6 +163,7 @@ EXEMPT_FILES = make_set( "static/js/settings_streams.js", "static/js/settings_toggle.js", "static/js/settings_ui.js", + "static/js/settings_user_groups.js", "static/js/settings_users.js", "static/js/setup.js", "static/js/spectators.js",