user groups: Add live update support for user_group add event.

We add live update support for user group events as part of
https://github.com/zulip/zulip/issues/19526.
This however has a few TODOs:
1. Deciding on how we want to sort the group list on left of
   #groups overlay.
2. How we highlight the newly created groups after it is added
   to the list.
These will be covered as we add support for more groups events.
This commit is contained in:
m-e-l-u-h-a-n 2023-02-02 22:19:02 +05:30 committed by Tim Abbott
parent fdd9f018ad
commit 6147f2bd7a
6 changed files with 78 additions and 4 deletions

View File

@ -78,6 +78,8 @@ const ui = mock_esm("../../static/js/ui");
const unread_ops = mock_esm("../../static/js/unread_ops");
const user_events = mock_esm("../../static/js/user_events");
const user_groups = mock_esm("../../static/js/user_groups");
const overlays = mock_esm("../../static/js/overlays");
const user_groups_settings_ui = mock_esm("../../static/js/user_groups_settings_ui");
mock_esm("../../static/js/giphy");
const electron_bridge = set_global("electron_bridge", {});
@ -162,10 +164,20 @@ run_test("user groups", ({override}) => {
override(settings_user_groups_legacy, "reload", noop);
{
const stub = make_stub();
const user_group_settings_ui_stub = make_stub();
override(user_groups, "add", stub.f);
override(overlays, "groups_open", () => true);
override(user_groups_settings_ui, "add_group_to_table", user_group_settings_ui_stub.f);
dispatch(event);
assert.equal(stub.num_calls, 1);
const args = stub.get_args("group");
assert.equal(user_group_settings_ui_stub.num_calls, 1);
let args = stub.get_args("group");
assert_same(args.group, event.group);
args = user_group_settings_ui_stub.get_args("group");
assert_same(args.group, event.group);
}

View File

@ -39,6 +39,10 @@ export function streams_open() {
return open_overlay_name === "subscriptions";
}
export function groups_open() {
return (open_overlay_name = "groups");
}
export function lightbox_open() {
return open_overlay_name === "lightbox";
}

View File

@ -68,6 +68,7 @@ import * as typing_events from "./typing_events";
import * as unread_ops from "./unread_ops";
import * as user_events from "./user_events";
import * as user_groups from "./user_groups";
import * as user_groups_settings_ui from "./user_groups_settings_ui";
import {user_settings} from "./user_settings";
import * as user_status from "./user_status";
@ -754,6 +755,9 @@ export function dispatch_normal_event(event) {
switch (event.op) {
case "add":
user_groups.add(event.group);
if (overlays.groups_open()) {
user_groups_settings_ui.add_group_to_table(event.group);
}
break;
case "remove":
user_groups.remove(user_groups.get_user_group_from_id(event.group_id));

View File

@ -272,8 +272,8 @@ function create_stream() {
error(xhr) {
const msg = JSON.parse(xhr.responseText).msg;
if (msg.includes("access")) {
// If we can't access the stream, we can safely assume it's
// a duplicate stream that we are not invited to.
// If we can't access the stream, we can safely
// assume it's a duplicate stream that we are not invited to.
//
// BUG: This check should be using error codes, not
// parsing the error string, so it works correctly

View File

@ -10,6 +10,20 @@ import * as user_group_create_members_data from "./user_group_create_members_dat
import * as user_groups from "./user_groups";
import * as user_group_settings_ui from "./user_groups_settings_ui";
let created_group_name;
export function reset_name() {
created_group_name = undefined;
}
export function set_name(group_name) {
created_group_name = group_name;
}
export function get_name() {
return created_group_name;
}
class UserGroupMembershipError {
report_no_members_to_user_group() {
$("#user_group_membership_error").text(
@ -101,6 +115,7 @@ function create_user_group() {
const data = {};
const group_name = $("#create_user_group_name").val().trim();
const description = $("#create_user_group_description").val().trim();
set_name(group_name);
// Even though we already check to make sure that while typing the user cannot enter
// newline characters (by pressing the Enter key) it would still be possible to copy
@ -142,6 +157,7 @@ function create_user_group() {
xhr,
$(".user_group_create_info"),
);
reset_name();
loading.destroy_indicator($("#user_group_creating_indicator"));
},
});

View File

@ -1,6 +1,7 @@
import $ from "jquery";
import render_browse_user_groups_list_item from "../templates/user_group_settings/browse_user_groups_list_item.hbs";
import render_user_group_settings from "../templates/user_group_settings/user_group_settings.hbs";
import render_user_group_settings_overlay from "../templates/user_group_settings/user_group_settings_overlay.hbs";
import * as blueslip from "./blueslip";
@ -13,8 +14,11 @@ import * as scroll_util from "./scroll_util";
import * as settings_data from "./settings_data";
import * as ui from "./ui";
import * as user_group_create from "./user_group_create";
import * as user_group_edit from "./user_group_edit";
import * as user_groups from "./user_groups";
let group_list_widget;
export function set_up_click_handlers() {
$("#groups_overlay").on("click", ".left #clear_search_group_name", (e) => {
const $input = $("#groups_overlay .left #search_group_name");
@ -62,6 +66,10 @@ export function row_for_group_id(group_id) {
return $(`.group-row[data-group-id='${CSS.escape(group_id)}']`);
}
export function is_group_already_present(group) {
return row_for_group_id(group.id).length > 0;
}
export function get_active_data() {
const $active_row = $("div.group-row.active");
const valid_active_id = Number.parseInt($active_row.attr("data-group-id"), 10);
@ -95,6 +103,36 @@ function show_right_section() {
$(".user-groups-header").addClass("slide-left");
}
export function add_group_to_table(group) {
if (is_group_already_present(group)) {
// If a group is already listed/added in groups modal,
// then we simply return.
// This can happen in some corner cases (which might
// be backend bugs) where a realm administrator may
// get two user_group-add events.
return;
}
const settings_html = render_user_group_settings({
group,
can_edit: user_group_edit.can_edit(group.id),
});
group_list_widget.replace_list_data(user_groups.get_realm_user_groups());
ui.get_content_element($("#manage_groups_container .settings")).append($(settings_html));
// TODO: Address issue for visibility of newely created group.
if (user_group_create.get_name() === group.name) {
// This `user_group_create.get_name()` check tells us whether the
// group was just created in this browser window; it's a hack
// to work around the server_events code flow not having a
// good way to associate with this request because the group
// ID isn't known yet.
row_for_group_id(group.id).trigger("click");
user_group_create.reset_name();
}
}
export function change_state(section) {
if (!section) {
show_user_group_settings_pane.nothing_selected();
@ -132,7 +170,7 @@ export function setup_page(callback) {
const $container = $("#manage_groups_container .user-groups-list");
const user_groups_list = user_groups.get_realm_user_groups();
ListWidget.create($container, user_groups_list, {
group_list_widget = ListWidget.create($container, user_groups_list, {
name: "user-groups-overlay",
modifier(item) {
item.is_member = user_groups.is_direct_member_of(